Skip to content

Commit c5b4e80

Browse files
committed
Deprecate UserIdHasher class
Signed-off-by: Ivan Kanakarakis <[email protected]>
1 parent 47e2f83 commit c5b4e80

File tree

4 files changed

+101
-179
lines changed

4 files changed

+101
-179
lines changed

src/satosa/deprecated.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import datetime
12
import warnings as _warnings
23
from enum import Enum
34

@@ -6,6 +7,8 @@
67
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS
78
from saml2.saml import NAMEID_FORMAT_UNSPECIFIED
89

10+
from satosa import util
11+
912

1013
_warnings.simplefilter("default")
1114

@@ -37,6 +40,96 @@ def from_string(cls, str):
3740
raise ValueError("Unknown hash type '{}'".format(str))
3841

3942

43+
class UserIdHasher(object):
44+
"""
45+
Class for creating different user id types
46+
"""
47+
48+
STATE_KEY = "IDHASHER"
49+
50+
@staticmethod
51+
def save_state(internal_request, state):
52+
"""
53+
Saves all necessary information needed by the UserIdHasher
54+
55+
:type internal_request: satosa.internal_data.InternalRequest
56+
57+
:param internal_request: The request
58+
:param state: The current state
59+
"""
60+
state_data = {"hash_type": internal_request.user_id_hash_type}
61+
state[UserIdHasher.STATE_KEY] = state_data
62+
63+
@staticmethod
64+
def hash_data(salt, value):
65+
"""
66+
Hashes a value together with a salt.
67+
:type salt: str
68+
:type value: str
69+
:param salt: hash salt
70+
:param value: value to hash together with the salt
71+
:return: hash value (SHA512)
72+
"""
73+
msg = "UserIdHasher is deprecated; use satosa.util.hash_data instead."
74+
_warnings.warn(msg, DeprecationWarning)
75+
return util.hash_data(salt, value)
76+
77+
@staticmethod
78+
def hash_type(state):
79+
state_data = state[UserIdHasher.STATE_KEY]
80+
hash_type = state_data["hash_type"]
81+
return hash_type
82+
83+
@staticmethod
84+
def hash_id(salt, user_id, requester, state):
85+
"""
86+
Sets a user id to the internal_response,
87+
in the format specified by the internal response
88+
89+
:type salt: str
90+
:type user_id: str
91+
:type requester: str
92+
:type state: satosa.state.State
93+
:rtype: str
94+
95+
:param salt: A salt string for the ID hashing
96+
:param user_id: the user id
97+
:param user_id_hash_type: Hashing type
98+
:param state: The current state
99+
:return: the internal_response containing the hashed user ID
100+
"""
101+
hash_type_to_format = {
102+
NAMEID_FORMAT_TRANSIENT: "{id}{req}{time}",
103+
NAMEID_FORMAT_PERSISTENT: "{id}{req}",
104+
"pairwise": "{id}{req}",
105+
"public": "{id}",
106+
NAMEID_FORMAT_EMAILADDRESS: "{id}",
107+
NAMEID_FORMAT_UNSPECIFIED: "{id}",
108+
}
109+
110+
format_args = {
111+
"id": user_id,
112+
"req": requester,
113+
"time": datetime.datetime.utcnow().timestamp(),
114+
}
115+
116+
hash_type = UserIdHasher.hash_type(state)
117+
try:
118+
fmt = hash_type_to_format[hash_type]
119+
except KeyError as e:
120+
raise ValueError("Unknown hash type: {}".format(hash_type)) from e
121+
else:
122+
user_id = fmt.format(**format_args)
123+
124+
hasher = (
125+
(lambda salt, value: value)
126+
if hash_type
127+
in [NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED]
128+
else util.hash_data
129+
)
130+
return hasher(salt, user_id)
131+
132+
40133
def saml_name_id_format_to_hash_type(name_format):
41134
"""
42135
Translate pySAML2 name format to satosa format

src/satosa/internal_data.py

Lines changed: 3 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,7 @@
1-
"""
2-
The module contains internal data representation in SATOSA and general converteras that can be used
3-
for converting from SAML/OAuth/OpenID connect to the internal representation.
4-
"""
5-
import datetime
6-
7-
from saml2.saml import NAMEID_FORMAT_TRANSIENT
8-
from saml2.saml import NAMEID_FORMAT_PERSISTENT
9-
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS
10-
from saml2.saml import NAMEID_FORMAT_UNSPECIFIED
11-
12-
import satosa.util as util
13-
from satosa.deprecated import UserIdHashType
14-
15-
16-
class UserIdHasher(object):
17-
"""
18-
Class for creating different user id types
19-
"""
20-
STATE_KEY = "IDHASHER"
21-
22-
@staticmethod
23-
def save_state(internal_request, state):
24-
"""
25-
Saves all necessary information needed by the UserIdHasher
26-
27-
:type internal_request: satosa.internal_data.InternalRequest
28-
29-
:param internal_request: The request
30-
:param state: The current state
31-
"""
32-
state_data = {
33-
"hash_type": internal_request.user_id_hash_type
34-
}
35-
state[UserIdHasher.STATE_KEY] = state_data
36-
37-
@staticmethod
38-
def hash_data(salt, value):
39-
"""
40-
Hashes a value together with a salt.
41-
:type salt: str
42-
:type value: str
43-
:param salt: hash salt
44-
:param value: value to hash together with the salt
45-
:return: hash value (SHA512)
46-
"""
47-
return util.hash_data(salt, value)
48-
49-
@staticmethod
50-
def hash_type(state):
51-
state_data = state[UserIdHasher.STATE_KEY]
52-
hash_type = state_data["hash_type"]
53-
return hash_type
54-
55-
@staticmethod
56-
def hash_id(salt, user_id, requester, state):
57-
"""
58-
Sets a user id to the internal_response,
59-
in the format specified by the internal response
1+
"""Internal data representation for SAML/OAuth/OpenID connect."""
602

61-
:type salt: str
62-
:type user_id: str
63-
:type requester: str
64-
:type state: satosa.state.State
65-
:rtype: str
66-
67-
:param salt: A salt string for the ID hashing
68-
:param user_id: the user id
69-
:param user_id_hash_type: Hashing type
70-
:param state: The current state
71-
:return: the internal_response containing the hashed user ID
72-
"""
73-
hash_type_to_format = {
74-
NAMEID_FORMAT_TRANSIENT: '{id}{req}{time}',
75-
NAMEID_FORMAT_PERSISTENT: '{id}{req}',
76-
"pairwise": '{id}{req}',
77-
"public": '{id}',
78-
NAMEID_FORMAT_EMAILADDRESS: '{id}',
79-
NAMEID_FORMAT_UNSPECIFIED: '{id}',
80-
}
81-
82-
format_args = {
83-
'id': user_id,
84-
'req': requester,
85-
'time': datetime.datetime.utcnow().timestamp(),
86-
}
87-
88-
hash_type = UserIdHasher.hash_type(state)
89-
try:
90-
fmt = hash_type_to_format[hash_type]
91-
except KeyError as e:
92-
raise ValueError('Unknown hash type: {}'.format(hash_type)) from e
93-
else:
94-
user_id = fmt.format(**format_args)
95-
96-
hasher = (
97-
(lambda salt, value: value)
98-
if hash_type in [
99-
NAMEID_FORMAT_EMAILADDRESS,
100-
NAMEID_FORMAT_UNSPECIFIED,
101-
]
102-
else UserIdHasher.hash_data)
103-
return hasher(salt, user_id)
3+
from satosa.deprecated import UserIdHashType
4+
from satosa.deprecated import UserIdHasher
1045

1056

1067
class AuthenticationInformation(object):

tests/satosa/test_base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from saml2.saml import NAMEID_FORMAT_PERSISTENT
88

99
import satosa
10+
from satosa import util
1011
from satosa.base import SATOSABase
1112
from satosa.exception import SATOSAConfigurationError
1213
from satosa.internal_data import InternalResponse, AuthenticationInformation, UserIdHasher, InternalRequest
@@ -91,8 +92,10 @@ def test_auth_resp_callback_func_hashes_all_specified_attributes(self, context,
9192

9293
base._auth_resp_callback_func(context, internal_resp)
9394
for attr in satosa_config["INTERNAL_ATTRIBUTES"]["hash"]:
94-
assert internal_resp.attributes[attr] == [UserIdHasher.hash_data(satosa_config["USER_ID_HASH_SALT"], v)
95-
for v in attributes[attr]]
95+
assert internal_resp.attributes[attr] == [
96+
util.hash_data(satosa_config["USER_ID_HASH_SALT"], v)
97+
for v in attributes[attr]
98+
]
9699

97100
def test_auth_resp_callback_func_respects_user_id_to_attr(self, context, satosa_config):
98101
satosa_config["INTERNAL_ATTRIBUTES"]["user_id_to_attr"] = "user_id"

tests/satosa/test_id_hash.py

Lines changed: 0 additions & 75 deletions
This file was deleted.

0 commit comments

Comments
 (0)