👔(oidc) generate required claims in user_info

Because SATOSA defaults to list-valued attributes, I had to add
a custom attribute processor to return strings in the userinfo
response.
This commit is contained in:
Jonathan Perret
2024-04-25 13:42:42 +02:00
parent b8037e7b69
commit 94cdbc9497
12 changed files with 88 additions and 36 deletions
-1
View File
@@ -87,7 +87,6 @@ jobs:
defaults:
run:
working-directory: src/satosa
steps:
- name: Checkout repository
uses: actions/checkout@v2
+2
View File
@@ -42,11 +42,13 @@ services:
environment:
OIDC_ROOT_URL: https://oidc-test-client.traefik.me
OIDC_PROVIDER: https://satosa.traefik.me
#OIDC_PROVIDER: https://oidc2fer-staging.beta.numerique.gouv.fr
OIDC_CLIENT_ID: oidc-test-client
OIDC_CLIENT_SECRET: oidc-test-secret
OIDC_DO_INTROSPECTION: false
OIDC_DO_REFRESH: false
OIDC_DO_USER_INFO: true
OIDC_SCOPES: openid,uid,given_name,usual_name,email
nginx:
image: nginx:1.25
+6 -1
View File
@@ -9,6 +9,8 @@ extension-pkg-whitelist=
# paths.
ignore=migrations
recursive=yes
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=
@@ -62,7 +64,10 @@ disable=bad-inline-option,
no-self-use,
raw-checker-failed,
suppressed-message,
useless-suppression
useless-suppression,
missing-module-docstring,
missing-class-docstring,
missing-function-docstring
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
+7 -27
View File
@@ -1,19 +1,4 @@
attributes:
address:
openid:
- address.street_address
saml:
- postaladdress
displayname:
openid:
- nickname
saml:
- displayName
edupersontargetedid:
openid:
- sub
saml:
- eduPersonTargetedID
givenname:
openid:
- given_name
@@ -27,23 +12,18 @@ attributes:
- email
- emailAddress
- mail
name:
usual_name:
openid:
- name
saml:
- cn
surname:
openid:
- family_name
- usual_name
saml:
- sn
- surname
- lastName
organization:
saml:
- o
openid:
- organization
acr:
openid:
- acr
uid:
openid:
- uid
saml:
- eduPersonPrincipalName
@@ -0,0 +1,21 @@
import logging
from satosa.micro_services.processors.base_processor import BaseProcessor
logger = logging.getLogger(__name__)
class FlatteningProcessor(BaseProcessor):
def __init__(self):
pass
# There's a bug in BaseProcessor, the 'self' argument is missing!
# pylint: disable-next=arguments-differ
def process(self, internal_data, attribute, **kwargs):
attributes = internal_data.attributes
if attribute in attributes:
values = attributes.get(attribute)
if isinstance(values, list):
new_value = " ".join(values)
logger.debug("flattening %s into %s", values, new_value)
attributes[attribute] = new_value
@@ -37,8 +37,20 @@ config:
client_registration_supported: no
response_types_supported: ["code", "id_token token"]
subject_types_supported: ["public"]
scopes_supported: ["openid", "email"]
scopes_supported:
- openid
- email
- uid
- given_name
- usual_name
id_token_lifetime: 3600
extra_scopes:
uid:
- uid
given_name:
- given_name
usual_name:
- usual_name
extra_id_token_claims:
oidc-test-client:
- acr
@@ -0,0 +1,12 @@
module: satosa.micro_services.attribute_processor.AttributeProcessor
name: AttributeProcessor
config:
process:
- attribute: uid
processors:
- module: oidc2fer.attribute_processors.flattening_processor
name: FlatteningProcessor
- attribute: usual_name
processors:
- module: oidc2fer.attribute_processors.flattening_processor
name: FlatteningProcessor
+1
View File
@@ -13,6 +13,7 @@ FRONTEND_MODULES:
- plugins/frontends/ping_frontend.yaml
MICRO_SERVICES:
- plugins/microservices/static_attributes.yaml
- plugins/microservices/attribute_processor.yaml
LOGGING:
version: 1
formatters:
@@ -0,0 +1,26 @@
from satosa.internal import InternalData
from oidc2fer.attribute_processors.flattening_processor import FlatteningProcessor
class TestFlatteningProcessor:
def test_flattens_values(self):
processor = FlatteningProcessor()
internal_data = InternalData()
internal_data.attributes = {"name": ["Albert", "Betty"]}
processor.process(internal_data, "name")
assert internal_data.attributes["name"] == "Albert Betty"
def test_ignores_missing_attribute(self):
processor = FlatteningProcessor()
internal_data = InternalData()
internal_data.attributes = {}
processor.process(internal_data, "name")
assert internal_data.attributes == {}
def test_leaves_string_alone(self):
processor = FlatteningProcessor()
internal_data = InternalData()
internal_data.attributes = {"name": "AlreadyFlat"}
processor.process(internal_data, "name")
assert internal_data.attributes["name"] == "AlreadyFlat"
-6
View File
@@ -1,6 +0,0 @@
import pytest
def test_dummy():
actual = "hello"
assert actual == "hello"