Skip to content

Commit 75be009

Browse files
committed
Refactor handling of nameid format
Signed-off-by: Ivan Kanakarakis <[email protected]>
1 parent 64ed196 commit 75be009

File tree

3 files changed

+60
-39
lines changed

3 files changed

+60
-39
lines changed

src/satosa/frontends/saml2.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
from saml2.config import IdPConfig
1717
from saml2.extension.ui import NAMESPACE as UI_NAMESPACE
1818
from saml2.metadata import create_metadata_string
19-
from saml2.saml import NameID, NAMEID_FORMAT_TRANSIENT, \
20-
NAMEID_FORMAT_PERSISTENT, NAMEID_FORMAT_EMAILADDRESS, \
21-
NAMEID_FORMAT_UNSPECIFIED
19+
from saml2.saml import NameID
20+
from saml2.saml import NAMEID_FORMAT_TRANSIENT
21+
from saml2.saml import NAMEID_FORMAT_PERSISTENT
22+
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS
23+
from saml2.saml import NAMEID_FORMAT_UNSPECIFIED
2224
from saml2.samlp import name_id_policy_from_string
2325
from saml2.server import Server
2426

@@ -45,14 +47,16 @@ def saml_name_id_format_to_hash_type(name_format):
4547
:param name_format: SAML2 name format
4648
:return: satosa format
4749
"""
48-
if name_format == NAMEID_FORMAT_PERSISTENT:
49-
return UserIdHashType.persistent
50-
elif name_format == NAMEID_FORMAT_EMAILADDRESS:
51-
return UserIdHashType.emailaddress
52-
elif name_format == NAMEID_FORMAT_UNSPECIFIED:
53-
return UserIdHashType.unspecified
50+
name_id_format_to_hash_type = {
51+
NAMEID_FORMAT_TRANSIENT: UserIdHashType.transient,
52+
NAMEID_FORMAT_PERSISTENT: UserIdHashType.persistent,
53+
NAMEID_FORMAT_EMAILADDRESS: UserIdHashType.emailaddress,
54+
NAMEID_FORMAT_UNSPECIFIED: UserIdHashType.unspecified,
55+
}
5456

55-
return UserIdHashType.transient
57+
return name_id_format_to_hash_type.get(
58+
name_format,
59+
UserIdHashType.transient)
5660

5761

5862
def hash_type_to_saml_name_id_format(hash_type):
@@ -64,16 +68,16 @@ def hash_type_to_saml_name_id_format(hash_type):
6468
:param hash_type: satosa format
6569
:return: pySAML2 name format
6670
"""
67-
if hash_type is UserIdHashType.transient:
68-
return NAMEID_FORMAT_TRANSIENT
69-
elif hash_type is UserIdHashType.persistent:
70-
return NAMEID_FORMAT_PERSISTENT
71-
elif hash_type is UserIdHashType.emailaddress:
72-
return NAMEID_FORMAT_EMAILADDRESS
73-
elif hash_type is UserIdHashType.unspecified:
74-
return NAMEID_FORMAT_UNSPECIFIED
75-
76-
return NAMEID_FORMAT_PERSISTENT
71+
hash_type_to_name_id_format = {
72+
UserIdHashType.transient: NAMEID_FORMAT_TRANSIENT,
73+
UserIdHashType.persistent: NAMEID_FORMAT_PERSISTENT,
74+
UserIdHashType.emailaddress: NAMEID_FORMAT_EMAILADDRESS,
75+
UserIdHashType.unspecified: NAMEID_FORMAT_UNSPECIFIED,
76+
}
77+
78+
return hash_type_to_name_id_format.get(
79+
hash_type,
80+
NAMEID_FORMAT_PERSISTENT)
7781

7882

7983
class SAMLFrontend(FrontendModule, SAMLBaseModule):

src/satosa/internal_data.py

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import hashlib
77
from enum import Enum
88

9+
910
class UserIdHashType(Enum):
1011
"""
1112
All different user id hash types
@@ -56,7 +57,9 @@ def hash_data(salt, value):
5657
:param value: value to hash together with the salt
5758
:return: hash value (SHA512)
5859
"""
59-
return hashlib.sha512((value + salt).encode("utf-8")).hexdigest()
60+
data = '{value}{salt}'.format(value=value, salt=salt).encode()
61+
hash = hashlib.sha512(data).hexdigest()
62+
return hash
6063

6164
@staticmethod
6265
def hash_type(state):
@@ -82,23 +85,36 @@ def hash_id(salt, user_id, requester, state):
8285
:param state: The current state
8386
:return: the internal_response containing the hashed user ID
8487
"""
88+
hash_type_to_format = {
89+
UserIdHashType.transient: '{id}{req}{time}',
90+
UserIdHashType.persistent: '{id}{req}',
91+
UserIdHashType.pairwise: '{id}{req}',
92+
UserIdHashType.public: '{id}',
93+
UserIdHashType.emailaddress: '{id}',
94+
UserIdHashType.unspecified: '{id}',
95+
}
96+
97+
format_args = {
98+
'id': user_id,
99+
'req': requester,
100+
'time': datetime.datetime.utcnow().timestamp(),
101+
}
102+
85103
hash_type = UserIdHasher.hash_type(state)
86-
if hash_type == UserIdHashType.transient:
87-
timestamp = datetime.datetime.now().time()
88-
user_id = "{req}{time}{id}".format(req=requester, time=timestamp,
89-
id=user_id)
90-
elif (hash_type == UserIdHashType.persistent or
91-
hash_type == UserIdHashType.pairwise):
92-
user_id = "{req}{id}".format(req=requester, id=user_id)
93-
elif hash_type == UserIdHashType.public:
94-
user_id = "{id}".format(id=user_id)
95-
elif (hash_type == UserIdHashType.emailaddress or
96-
hash_type == UserIdHashType.unspecified):
97-
return user_id
104+
try:
105+
fmt = hash_type_to_format[hash_type]
106+
except KeyError as e:
107+
raise ValueError('Unknown hash type: {}'.format(hash_type)) from e
98108
else:
99-
raise ValueError("Unknown hash type: '{}'".format(hash_type))
100-
101-
return UserIdHasher.hash_data(salt, user_id)
109+
user_id = fmt.format(**format_args)
110+
111+
hasher = (
112+
(lambda salt, value: value)
113+
if hash_type in [
114+
UserIdHashType.emailaddress,
115+
]
116+
else UserIdHasher.hash_data)
117+
return hasher(salt, user_id)
102118

103119

104120
class AuthenticationInformation(object):

tests/satosa/frontends/test_saml2.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
from saml2.entity_category.edugain import COCO
1515
from saml2.entity_category.refeds import RESEARCH_AND_SCHOLARSHIP
1616
from saml2.entity_category.swamid import SFS_1993_1153, RESEARCH_AND_EDUCATION, EU, HEI, NREN
17-
from saml2.saml import NameID, NAMEID_FORMAT_TRANSIENT, \
18-
NAMEID_FORMAT_PERSISTENT, NAMEID_FORMAT_EMAILADDRESS, \
19-
NAMEID_FORMAT_UNSPECIFIED
17+
from saml2.saml import NAMEID_FORMAT_TRANSIENT
18+
from saml2.saml import NAMEID_FORMAT_PERSISTENT
19+
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS
20+
from saml2.saml import NAMEID_FORMAT_UNSPECIFIED
2021
from saml2.samlp import NameIDPolicy
2122

2223
from satosa.attribute_mapping import AttributeMapper

0 commit comments

Comments
 (0)