Skip to content

Commit f2bd0ad

Browse files
Merge pull request #196 from c00kiemon5ter/refactor-internal-data-deprecate-hashing
Refactor internal data to deprecate hashing - Use the hasher micro-service to restore previous behaviour - Use satosa.internal over satosa.internal_data - Use satosa.internal.InternalData over satosa.internal_data.InternalRequest, satosa.internal_data.InternalResponse and satosa.backends.saml2.SAMLInternalResponse For InternalData members: - Use subject_id over user_id or name_id - Use subject_type over user_id_hash_type - Use attributes over approved_attributes
2 parents 4fe3391 + f3db4d0 commit f2bd0ad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1086
-738
lines changed

doc/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ in the [example directory](../example).
4343
| `BACKEND_MODULES` | string[] | `[openid_connect_backend.yaml, saml2_backend.yaml]` | list of plugin configuration file paths, describing enabled backends |
4444
| `FRONTEND_MODULES` | string[] | `[saml2_frontend.yaml, openid_connect_frontend.yaml]` | list of plugin configuration file paths, describing enabled frontends |
4545
| `MICRO_SERVICES` | string[] | `[statistics_service.yaml]` | list of plugin configuration file paths, describing enabled microservices |
46-
| `USER_ID_HASH_SALT` | string | `61a89d2db0b9e1e2` | salt used when creating the persistent user identifier, will be overriden by the environment variable `SATOSA_USER_ID_HASH_SALT` if it is set |
46+
| `USER_ID_HASH_SALT` | string | `61a89d2db0b9e1e2` | **DEPRECATED - use the hasher micro-service** salt used when creating the persistent user identifier, will be overriden by the environment variable `SATOSA_USER_ID_HASH_SALT` if it is set |
4747
| `LOGGING` | dict | see [Python logging.conf](https://docs.python.org/3/library/logging.config.html) | optional configuration of application logging |
4848

4949

@@ -119,7 +119,7 @@ linking, the `user_id_to_attr` configuration parameter should be set, since that
119119
service will overwrite the user identifier generated by the proxy.
120120

121121

122-
### hash
122+
### hash **DEPRECATED - use the hasher micro-service**
123123
The proxy can hash any attribute value (e.g., for obfuscation) before passing
124124
it on to the client. The `hash` key should contain a list of all attribute names
125125
for which the corresponding attribute values should be hashed before being
@@ -410,7 +410,7 @@ which should be used when configuring the attribute mapping (see above).
410410
### Ping frontend for simple heartbeat monitoring
411411

412412
The ping frontend responds to a query with a simple
413-
200 OK and is intended to be used as a simple heartbeat monitor,
413+
200 OK and is intended to be used as a simple heartbeat monitor,
414414
for example by a load balancer. The default configuration file can
415415
be found [here](../example/plugins/frontends/ping_frontend.yaml.example).
416416

@@ -581,7 +581,7 @@ The SATOSA proxy is a Python WSGI application and so may be run using any WSGI c
581581

582582
Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX and is the server used most often
583583
to run the proxy. In a production deployment the Gunicorn server is often proxied by a
584-
full featured general purpose web server (in a reverse proxy architecture) such as Nginx or
584+
full featured general purpose web server (in a reverse proxy architecture) such as Nginx or
585585
Apache HTTP Server to help buffer slow clients and enable more sophisticated error page rendering.
586586

587587
Start the proxy server with the following command:

example/internal_attributes.yaml.example

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,5 @@ attributes:
4040
orcid: [name.family-name.value]
4141
openid: [family_name]
4242
saml: [sn, surname]
43-
hash: [edupersontargetedid]
4443
user_id_from_attrs: [edupersontargetedid]
4544
user_id_to_attr: edupersontargetedid
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module: satosa.micro_services.hasher.Hasher
2+
name: Hasher
3+
config:
4+
# default settings that apply to every requester
5+
"":
6+
# default salt configuration is required
7+
salt: abcdef0123456789
8+
9+
# the hash algorithm to use (default: sha512)
10+
alg: sha256
11+
12+
# whether subject_id should be hashed (default: yes)
13+
subject_id: yes
14+
15+
# a list of attributes to hash (default: [])
16+
attributes:
17+
- edupersontargetedid
18+
19+
# specific settings for requester 'some_entityid'
20+
some_entityid:
21+
# for this requester use sha1
22+
alg: sha1
23+
24+
# do not hash any attributes
25+
# if this is missing the defaults will be used
26+
attributes: []
27+
28+
# specific settings for requester 'some_other_entityid'
29+
some_other_entityid:
30+
# for this requester only use this salt
31+
salt: abcd1234
32+
33+
# do not hash subject_id
34+
subject_id: no
35+
36+
# only hash the following attributes
37+
attributes:
38+
- gender
39+
- identifier

example/proxy_conf.yaml.example

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ FRONTEND_MODULES:
1313
- "plugins/frontends/saml2_frontend.yaml"
1414
MICRO_SERVICES:
1515
- "plugins/microservices/static_attributes.yaml"
16-
USER_ID_HASH_SALT: "61a89d2db0b9e1e27d490d050b478fe71f352fddd3528a44157f43e339c6c62f2362fb413179937d96172bf84233317"
1716
LOGGING:
1817
version: 1
1918
formatters:
@@ -40,4 +39,4 @@ LOGGING:
4039
propagate: no
4140
root:
4241
level: INFO
43-
handlers: [info_file_handler]
42+
handlers: [info_file_handler]

src/satosa/backends/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class BackendModule(object):
1313
def __init__(self, auth_callback_func, internal_attributes, base_url, name):
1414
"""
1515
:type auth_callback_func:
16-
(satosa.context.Context, satosa.internal_data.InternalResponse) -> satosa.response.Response
16+
(satosa.context.Context, satosa.internal.InternalData) -> satosa.response.Response
1717
:type internal_attributes: dict[string, dict[str, str | list[str]]]
1818
:type base_url: str
1919
:type name: str
@@ -37,7 +37,7 @@ def start_auth(self, context, internal_request):
3737
This is the start up function of the backend authorization.
3838
3939
:type context: satosa.context.Context
40-
:type internal_request: satosa.internal_data.InternalRequest
40+
:type internal_request: satosa.internal.InternalData
4141
:rtype satosa.response.Response
4242
4343
:param context: the request context

src/satosa/backends/github.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
from oic.oauth2.message import AuthorizationResponse
1111

1212
from satosa.backends.oauth import _OAuthBackend
13-
from ..internal_data import InternalResponse
14-
from ..internal_data import AuthenticationInformation
15-
from ..response import Redirect
16-
from ..util import rndstr
13+
from satosa.internal import AuthenticationInformation
14+
from satosa.internal import InternalData
15+
from satosa.response import Redirect
16+
from satosa.util import rndstr
1717

1818
logger = logging.getLogger(__name__)
1919

@@ -32,7 +32,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name):
3232
:param base_url: base url of the service
3333
:param name: name of the plugin
3434
:type outgoing:
35-
(satosa.context.Context, satosa.internal_data.InternalResponse) ->
35+
(satosa.context.Context, satosa.internal.InternalData) ->
3636
satosa.response.Response
3737
:type internal_attributes: dict[string, dict[str, str | list[str]]]
3838
:type config: dict[str, dict[str, str] | list[str] | str]
@@ -51,7 +51,7 @@ def start_auth(self, context, internal_request, get_state=stateID):
5151
5252
:type get_state: Callable[[str, bytes], str]
5353
:type context: satosa.context.Context
54-
:type internal_request: satosa.internal_data.InternalRequest
54+
:type internal_request: satosa.internal.InternalData
5555
:rtype satosa.response.Redirect
5656
"""
5757
oauth_state = get_state(self.config["base_url"], rndstr().encode())
@@ -95,10 +95,10 @@ def _authn_response(self, context):
9595

9696
user_info = self.user_information(response["access_token"])
9797
auth_info = self.auth_info(context.request)
98-
internal_response = InternalResponse(auth_info=auth_info)
98+
internal_response = InternalData(auth_info=auth_info)
9999
internal_response.attributes = self.converter.to_internal(
100100
self.external_type, user_info)
101-
internal_response.user_id = str(user_info[self.user_id_attr])
101+
internal_response.subject_id = str(user_info[self.user_id_attr])
102102
del context.state[self.name]
103103
return self.auth_callback_func(context, internal_response)
104104

src/satosa/backends/linkedin.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
from oic.oauth2.message import AuthorizationResponse
1111

1212
from satosa.backends.oauth import _OAuthBackend
13-
from ..internal_data import InternalResponse
14-
from ..internal_data import AuthenticationInformation
15-
from ..response import Redirect
16-
from ..util import rndstr
13+
from satosa.internal import AuthenticationInformation
14+
from satosa.internal import InternalData
15+
from satosa.response import Redirect
16+
from satosa.util import rndstr
1717

1818

1919
logger = logging.getLogger(__name__)
@@ -33,7 +33,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name):
3333
:param base_url: base url of the service
3434
:param name: name of the plugin
3535
:type outgoing:
36-
(satosa.context.Context, satosa.internal_data.InternalResponse) ->
36+
(satosa.context.Context, satosa.internal.InternalData) ->
3737
satosa.response.Response
3838
:type internal_attributes: dict[string, dict[str, str | list[str]]]
3939
:type config: dict[str, dict[str, str] | list[str] | str]
@@ -52,7 +52,7 @@ def start_auth(self, context, internal_request, get_state=stateID):
5252
5353
:type get_state: Callable[[str, bytes], str]
5454
:type context: satosa.context.Context
55-
:type internal_request: satosa.internal_data.InternalRequest
55+
:type internal_request: satosa.internal.InternalData
5656
:rtype satosa.response.Redirect
5757
"""
5858
oauth_state = get_state(self.config["base_url"], rndstr().encode())
@@ -96,10 +96,10 @@ def _authn_response(self, context):
9696

9797
user_info = self.user_information(response["access_token"])
9898
auth_info = self.auth_info(context.request)
99-
internal_response = InternalResponse(auth_info=auth_info)
99+
internal_response = InternalData(auth_info=auth_info)
100100
internal_response.attributes = self.converter.to_internal(
101101
self.external_type, user_info)
102-
internal_response.user_id = user_info[self.user_id_attr]
102+
internal_response.subject_id = user_info[self.user_id_attr]
103103
del context.state[self.name]
104104
return self.auth_callback_func(context, internal_response)
105105

src/satosa/backends/oauth.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@
1010
from oic.oauth2.message import AuthorizationResponse
1111
from oic.utils.authn.authn_context import UNSPECIFIED
1212

13-
from .base import BackendModule
14-
from ..exception import SATOSAAuthenticationError
15-
from ..internal_data import InternalResponse, AuthenticationInformation
16-
from ..logging_util import satosa_logging
17-
from ..metadata_creation.description import OrganizationDesc, UIInfoDesc, ContactPersonDesc, MetadataDescription
18-
from ..response import Redirect
19-
from ..util import rndstr
13+
from satosa.internal import AuthenticationInformation
14+
from satosa.internal import InternalData
15+
from satosa.exception import SATOSAAuthenticationError
16+
from satosa.logging_util import satosa_logging
17+
from satosa.response import Redirect
18+
from satosa.util import rndstr
19+
from satosa.metadata_creation.description import (
20+
OrganizationDesc, UIInfoDesc, ContactPersonDesc, MetadataDescription
21+
)
22+
from satosa.backends.base import BackendModule
23+
2024

2125
logger = logging.getLogger(__name__)
2226

@@ -40,7 +44,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name, extern
4044
:param external_type: The name for this module in the internal attributes.
4145
4246
:type outgoing:
43-
(satosa.context.Context, satosa.internal_data.InternalResponse) -> satosa.response.Response
47+
(satosa.context.Context, satosa.internal.InternalData) -> satosa.response.Response
4448
:type internal_attributes: dict[string, dict[str, str | list[str]]]
4549
:type config: dict[str, dict[str, str] | list[str]]
4650
:type base_url: str
@@ -67,7 +71,7 @@ def start_auth(self, context, internal_request, get_state=stateID):
6771
6872
:type get_state: Callable[[str, bytes], str]
6973
:type context: satosa.context.Context
70-
:type internal_request: satosa.internal_data.InternalRequest
74+
:type internal_request: satosa.internal.InternalData
7175
:rtype satosa.response.Redirect
7276
"""
7377
oauth_state = get_state(self.config["base_url"], rndstr().encode())
@@ -132,9 +136,9 @@ def _authn_response(self, context):
132136
self._verify_state(atresp, state_data, context.state)
133137

134138
user_info = self.user_information(atresp["access_token"])
135-
internal_response = InternalResponse(auth_info=self.auth_info(context.request))
139+
internal_response = InternalData(auth_info=self.auth_info(context.request))
136140
internal_response.attributes = self.converter.to_internal(self.external_type, user_info)
137-
internal_response.user_id = user_info[self.user_id_attr]
141+
internal_response.subject_id = user_info[self.user_id_attr]
138142
del context.state[self.name]
139143
return self.auth_callback_func(context, internal_response)
140144

@@ -187,7 +191,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name):
187191
:param name: name of the plugin
188192
189193
:type outgoing:
190-
(satosa.context.Context, satosa.internal_data.InternalResponse) -> satosa.response.Response
194+
(satosa.context.Context, satosa.internal.InternalData) -> satosa.response.Response
191195
:type internal_attributes: dict[string, dict[str, str | list[str]]]
192196
:type config: dict[str, dict[str, str] | list[str] | str]
193197
:type base_url: str

src/satosa/backends/openid_connect.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
from oic.utils.authn.authn_context import UNSPECIFIED
1313
from oic.utils.authn.client import CLIENT_AUTHN_METHOD
1414

15+
from satosa.internal import AuthenticationInformation
16+
from satosa.internal import InternalData
1517
from .base import BackendModule
1618
from .oauth import get_metadata_desc_for_oauth_backend
1719
from ..exception import SATOSAAuthenticationError, SATOSAError
18-
from ..internal_data import InternalResponse, AuthenticationInformation
1920
from ..logging_util import satosa_logging
2021
from ..response import Redirect
2122

@@ -43,7 +44,7 @@ def __init__(self, auth_callback_func, internal_attributes, config, base_url, na
4344
:param name: name of the plugin
4445
4546
:type auth_callback_func:
46-
(satosa.context.Context, satosa.internal_data.InternalResponse) -> satosa.response.Response
47+
(satosa.context.Context, satosa.internal.InternalData) -> satosa.response.Response
4748
:type internal_attributes: dict[string, dict[str, str | list[str]]]
4849
:type config: dict[str, dict[str, str] | list[str]]
4950
:type base_url: str
@@ -66,7 +67,7 @@ def start_auth(self, context, request_info):
6667
"""
6768
See super class method satosa.backends.base#start_auth
6869
:type context: satosa.context.Context
69-
:type request_info: satosa.internal_data.InternalRequest
70+
:type request_info: satosa.internal.InternalData
7071
"""
7172
oidc_nonce = rndstr()
7273
oidc_state = rndstr()
@@ -213,17 +214,17 @@ def _translate_response(self, response, issuer):
213214
:type response: dict[str, str]
214215
:type issuer: str
215216
:type subject_type: str
216-
:rtype: InternalResponse
217+
:rtype: InternalData
217218
218219
:param response: Dictioary with attribute name as key.
219220
:param issuer: The oidc op that gave the repsonse.
220221
:param subject_type: public or pairwise according to oidc standard.
221222
:return: A SATOSA internal response.
222223
"""
223224
auth_info = AuthenticationInformation(UNSPECIFIED, str(datetime.now()), issuer)
224-
internal_resp = InternalResponse(auth_info=auth_info)
225+
internal_resp = InternalData(auth_info=auth_info)
225226
internal_resp.attributes = self.converter.to_internal("openid", response)
226-
internal_resp.user_id = response["sub"]
227+
internal_resp.subject_id = response["sub"]
227228
return internal_resp
228229

229230
def get_metadata_desc(self):

src/satosa/backends/orcid.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
from oic.oauth2.message import AuthorizationResponse
1212

1313
from satosa.backends.oauth import _OAuthBackend
14-
from ..internal_data import InternalResponse
15-
from ..internal_data import AuthenticationInformation
16-
from ..response import Redirect
14+
from satosa.internal import InternalData
15+
from satosa.internal import AuthenticationInformation
16+
from satosa.response import Redirect
1717

1818
logger = logging.getLogger(__name__)
1919

@@ -32,7 +32,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name):
3232
:param base_url: base url of the service
3333
:param name: name of the plugin
3434
:type outgoing:
35-
(satosa.context.Context, satosa.internal_data.InternalResponse) ->
35+
(satosa.context.Context, satosa.internal.InternalData) ->
3636
satosa.response.Response
3737
:type internal_attributes: dict[string, dict[str, str | list[str]]]
3838
:type config: dict[str, dict[str, str] | list[str] | str]
@@ -51,7 +51,7 @@ def start_auth(self, context, internal_request, get_state=stateID):
5151
5252
:type get_state: Callable[[str, bytes], str]
5353
:type context: satosa.context.Context
54-
:type internal_request: satosa.internal_data.InternalRequest
54+
:type internal_request: satosa.internal.InternalData
5555
:rtype satosa.response.Redirect
5656
"""
5757
request_args = dict(
@@ -85,10 +85,10 @@ def _authn_response(self, context):
8585
orcid, name = response['orcid'], response['name']
8686
user_info = self.user_information(token, orcid, name)
8787
auth_info = self.auth_info(context.request)
88-
internal_response = InternalResponse(auth_info=auth_info)
88+
internal_response = InternalData(auth_info=auth_info)
8989
internal_response.attributes = self.converter.to_internal(
9090
self.external_type, user_info)
91-
internal_response.user_id = orcid
91+
internal_response.subject_id = orcid
9292
return self.auth_callback_func(context, internal_response)
9393

9494
def user_information(self, access_token, orcid, name):

0 commit comments

Comments
 (0)