Skip to content

Commit 4041df2

Browse files
committed
Rearrange class order
Signed-off-by: Ivan Kanakarakis <[email protected]>
1 parent fd64ece commit 4041df2

File tree

1 file changed

+103
-103
lines changed

1 file changed

+103
-103
lines changed

src/satosa/state.py

Lines changed: 103 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,109 @@
2525
_SESSION_ID_KEY = "SESSION_ID"
2626

2727

28+
class State(UserDict):
29+
"""
30+
This class holds a state attribute object. A state object must be able to be converted to
31+
a json string, otherwise will an exception be raised.
32+
"""
33+
34+
def __init__(self, urlstate_data=None, encryption_key=None):
35+
"""
36+
If urlstate is empty a new empty state instance will be returned.
37+
38+
If urlstate is not empty the constructor will rebuild the state attribute objects
39+
from the urlstate string.
40+
:type urlstate_data: str
41+
:type encryption_key: str
42+
:rtype: State
43+
44+
:param encryption_key: The key to be used for encryption.
45+
:param urlstate_data: A string created by the method urlstate in this class.
46+
:return: An instance of this class.
47+
"""
48+
self.delete = False
49+
50+
urlstate_data = {} if urlstate_data is None else urlstate_data
51+
if urlstate_data and not encryption_key:
52+
raise ValueError("If an 'urlstate_data' is supplied 'encrypt_key' must be specified.")
53+
54+
if urlstate_data:
55+
try:
56+
urlstate_data_bytes = urlstate_data.encode("utf-8")
57+
urlstate_data_b64decoded = base64.urlsafe_b64decode(urlstate_data_bytes)
58+
lzma = LZMADecompressor()
59+
urlstate_data_decompressed = lzma.decompress(urlstate_data_b64decoded)
60+
urlstate_data_decrypted = _AESCipher(encryption_key).decrypt(
61+
urlstate_data_decompressed
62+
)
63+
lzma = LZMADecompressor()
64+
urlstate_data_decrypted_decompressed = lzma.decompress(urlstate_data_decrypted)
65+
urlstate_data_obj = json.loads(urlstate_data_decrypted_decompressed)
66+
except Exception as e:
67+
error_context = {
68+
"message": "Failed to load state data. Reinitializing empty state.",
69+
"reason": str(e),
70+
"urlstate_data": urlstate_data,
71+
}
72+
logger.warning(error_context)
73+
urlstate_data = {}
74+
else:
75+
urlstate_data = urlstate_data_obj
76+
77+
session_id = (
78+
urlstate_data[_SESSION_ID_KEY]
79+
if urlstate_data and _SESSION_ID_KEY in urlstate_data
80+
else uuid4().urn
81+
)
82+
urlstate_data[_SESSION_ID_KEY] = session_id
83+
84+
super().__init__(urlstate_data)
85+
86+
@property
87+
def session_id(self):
88+
return self.data.get(_SESSION_ID_KEY)
89+
90+
def urlstate(self, encryption_key):
91+
"""
92+
Will return a url safe representation of the state.
93+
94+
:type encryption_key: Key used for encryption.
95+
:rtype: str
96+
97+
:return: Url representation av of the state.
98+
"""
99+
lzma = LZMACompressor()
100+
urlstate_data = json.dumps(self.data)
101+
urlstate_data = lzma.compress(urlstate_data.encode("UTF-8"))
102+
urlstate_data += lzma.flush()
103+
urlstate_data = _AESCipher(encryption_key).encrypt(urlstate_data)
104+
lzma = LZMACompressor()
105+
urlstate_data = lzma.compress(urlstate_data)
106+
urlstate_data += lzma.flush()
107+
urlstate_data = base64.urlsafe_b64encode(urlstate_data)
108+
return urlstate_data.decode("utf-8")
109+
110+
def copy(self):
111+
"""
112+
Returns a deepcopy of the state
113+
114+
:rtype: satosa.state.State
115+
116+
:return: A copy of the state
117+
"""
118+
state_copy = State()
119+
state_copy.data = copy.deepcopy(self.data)
120+
return state_copy
121+
122+
@property
123+
def state_dict(self):
124+
"""
125+
:rtype: dict[str, any]
126+
:return: A copy of the state as dictionary.
127+
"""
128+
return copy.deepcopy(self.data)
129+
130+
28131
def state_to_cookie(state, name, path, encryption_key):
29132
"""
30133
Saves a state to a cookie
@@ -156,106 +259,3 @@ def _unpad(b):
156259
:rtype: bytes
157260
"""
158261
return b[:-ord(b[len(b) - 1:])]
159-
160-
161-
class State(UserDict):
162-
"""
163-
This class holds a state attribute object. A state object must be able to be converted to
164-
a json string, otherwise will an exception be raised.
165-
"""
166-
167-
def __init__(self, urlstate_data=None, encryption_key=None):
168-
"""
169-
If urlstate is empty a new empty state instance will be returned.
170-
171-
If urlstate is not empty the constructor will rebuild the state attribute objects
172-
from the urlstate string.
173-
:type urlstate_data: str
174-
:type encryption_key: str
175-
:rtype: State
176-
177-
:param encryption_key: The key to be used for encryption.
178-
:param urlstate_data: A string created by the method urlstate in this class.
179-
:return: An instance of this class.
180-
"""
181-
self.delete = False
182-
183-
urlstate_data = {} if urlstate_data is None else urlstate_data
184-
if urlstate_data and not encryption_key:
185-
raise ValueError("If an 'urlstate_data' is supplied 'encrypt_key' must be specified.")
186-
187-
if urlstate_data:
188-
try:
189-
urlstate_data_bytes = urlstate_data.encode("utf-8")
190-
urlstate_data_b64decoded = base64.urlsafe_b64decode(urlstate_data_bytes)
191-
lzma = LZMADecompressor()
192-
urlstate_data_decompressed = lzma.decompress(urlstate_data_b64decoded)
193-
urlstate_data_decrypted = _AESCipher(encryption_key).decrypt(
194-
urlstate_data_decompressed
195-
)
196-
lzma = LZMADecompressor()
197-
urlstate_data_decrypted_decompressed = lzma.decompress(urlstate_data_decrypted)
198-
urlstate_data_obj = json.loads(urlstate_data_decrypted_decompressed)
199-
except Exception as e:
200-
error_context = {
201-
"message": "Failed to load state data. Reinitializing empty state.",
202-
"reason": str(e),
203-
"urlstate_data": urlstate_data,
204-
}
205-
logger.warning(error_context)
206-
urlstate_data = {}
207-
else:
208-
urlstate_data = urlstate_data_obj
209-
210-
session_id = (
211-
urlstate_data[_SESSION_ID_KEY]
212-
if urlstate_data and _SESSION_ID_KEY in urlstate_data
213-
else uuid4().urn
214-
)
215-
urlstate_data[_SESSION_ID_KEY] = session_id
216-
217-
super().__init__(urlstate_data)
218-
219-
@property
220-
def session_id(self):
221-
return self.data.get(_SESSION_ID_KEY)
222-
223-
def urlstate(self, encryption_key):
224-
"""
225-
Will return a url safe representation of the state.
226-
227-
:type encryption_key: Key used for encryption.
228-
:rtype: str
229-
230-
:return: Url representation av of the state.
231-
"""
232-
lzma = LZMACompressor()
233-
urlstate_data = json.dumps(self.data)
234-
urlstate_data = lzma.compress(urlstate_data.encode("UTF-8"))
235-
urlstate_data += lzma.flush()
236-
urlstate_data = _AESCipher(encryption_key).encrypt(urlstate_data)
237-
lzma = LZMACompressor()
238-
urlstate_data = lzma.compress(urlstate_data)
239-
urlstate_data += lzma.flush()
240-
urlstate_data = base64.urlsafe_b64encode(urlstate_data)
241-
return urlstate_data.decode("utf-8")
242-
243-
def copy(self):
244-
"""
245-
Returns a deepcopy of the state
246-
247-
:rtype: satosa.state.State
248-
249-
:return: A copy of the state
250-
"""
251-
state_copy = State()
252-
state_copy.data = copy.deepcopy(self.data)
253-
return state_copy
254-
255-
@property
256-
def state_dict(self):
257-
"""
258-
:rtype: dict[str, any]
259-
:return: A copy of the state as dictionary.
260-
"""
261-
return copy.deepcopy(self.data)

0 commit comments

Comments
 (0)