👔(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:
@@ -87,7 +87,6 @@ jobs:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: src/satosa
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -1,6 +0,0 @@
|
||||
import pytest
|
||||
|
||||
|
||||
def test_dummy():
|
||||
actual = "hello"
|
||||
assert actual == "hello"
|
||||
Reference in New Issue
Block a user