forked from Github-Mirrors/canaille
OIDC.JWT.MAPPING configuration option is really optional
This commit is contained in:
parent
7cd078bf81
commit
cc45ed4be9
7 changed files with 66 additions and 63 deletions
10
CHANGES.rst
10
CHANGES.rst
|
@ -3,11 +3,19 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
|
||||
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
|
||||
|
||||
|
||||
🚨Configuration files must be updated.🚨
|
||||
|
||||
Changed
|
||||
*******
|
||||
|
||||
- Renamed user model attributes to match SCIM naming convention. :pr:`123`
|
||||
🚨Configuration files must be updated. See the changes in the PR.🚨
|
||||
- Moved OIDC related configuration entries in ``OIDC``
|
||||
|
||||
Fixed
|
||||
*****
|
||||
|
||||
- ``OIDC.JWT.MAPPING`` is really optional now.
|
||||
|
||||
[0.0.24] - 2023-04-07
|
||||
=====================
|
||||
|
|
|
@ -187,17 +187,17 @@ PUBLIC_KEY = "canaille/conf/public.pem"
|
|||
# User objectClass.
|
||||
# {attribute} will be replaced by the user ldap attribute value.
|
||||
# Default values fits inetOrgPerson.
|
||||
SUB = "{{ user.user_name[0] }}"
|
||||
NAME = "{{ user.formatted_name[0] }}"
|
||||
PHONE_NUMBER = "{{ user.phone_number[0] }}"
|
||||
EMAIL = "{{ user.mail[0] }}"
|
||||
GIVEN_NAME = "{{ user.given_name[0] }}"
|
||||
FAMILY_NAME = "{{ user.family_name[0] }}"
|
||||
PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||
LOCALE = "{{ user.preferred_language }}"
|
||||
ADDRESS = "{{ user.formatted_address[0] }}"
|
||||
PICTURE = "{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}"
|
||||
WEBSITE = "{{ user.profile_url[0] }}"
|
||||
# SUB = "{{ user.user_name[0] }}"
|
||||
# NAME = "{{ user.formatted_name[0] }}"
|
||||
# PHONE_NUMBER = "{{ user.phone_number[0] }}"
|
||||
# EMAIL = "{{ user.mail[0] }}"
|
||||
# GIVEN_NAME = "{{ user.given_name[0] }}"
|
||||
# FAMILY_NAME = "{{ user.family_name[0] }}"
|
||||
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||
# LOCALE = "{{ user.preferred_language }}"
|
||||
# ADDRESS = "{{ user.formatted_address[0] }}"
|
||||
# PICTURE = "{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}"
|
||||
# WEBSITE = "{{ user.profile_url[0] }}"
|
||||
|
||||
# The SMTP server options. If not set, mail related features such as
|
||||
# user invitations, and password reset emails, will be disabled.
|
||||
|
|
|
@ -39,6 +39,19 @@ DEFAULT_JWT_KTY = "RSA"
|
|||
DEFAULT_JWT_ALG = "RS256"
|
||||
DEFAULT_JWT_EXP = 3600
|
||||
AUTHORIZATION_CODE_LIFETIME = 84400
|
||||
DEFAULT_JWT_MAPPING = {
|
||||
"SUB": "{{ user.user_name[0] }}",
|
||||
"NAME": "{{ user.formatted_name[0] }}",
|
||||
"PHONE_NUMBER": "{{ user.phone_number[0] }}",
|
||||
"EMAIL": "{{ user.email[0] }}",
|
||||
"GIVEN_NAME": "{{ user.given_name[0] }}",
|
||||
"FAMILY_NAME": "{{ user.family_name[0] }}",
|
||||
"PREFERRED_USERNAME": "{{ user.display_name }}",
|
||||
"LOCALE": "{{ user.preferred_language }}",
|
||||
"ADDRESS": "{{ user.formatted_address[0] }}",
|
||||
"PICTURE": "{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}",
|
||||
"WEBSITE": "{{ user.profile_url[0] }}",
|
||||
}
|
||||
|
||||
|
||||
def exists_nonce(nonce, req):
|
||||
|
@ -103,9 +116,11 @@ def generate_user_info(user, scope):
|
|||
|
||||
|
||||
def generate_user_claims(user, claims, jwt_mapping_config=None):
|
||||
jwt_mapping_config = (
|
||||
jwt_mapping_config or current_app.config["OIDC"]["JWT"]["MAPPING"]
|
||||
)
|
||||
jwt_mapping_config = {
|
||||
**DEFAULT_JWT_MAPPING,
|
||||
**current_app.config["OIDC"]["JWT"].get("MAPPING", {}),
|
||||
**(jwt_mapping_config or {}),
|
||||
}
|
||||
|
||||
data = {}
|
||||
for claim in claims:
|
||||
|
|
|
@ -192,17 +192,17 @@ PUBLIC_KEY = "conf/public.pem"
|
|||
# User objectClass.
|
||||
# {attribute} will be replaced by the user ldap attribute value.
|
||||
# Default values fits inetOrgPerson.
|
||||
SUB = "{{ user.user_name[0] }}"
|
||||
NAME = "{{ user.formatted_name[0] }}"
|
||||
PHONE_NUMBER = "{{ user.phone_number[0] }}"
|
||||
EMAIL = "{{ user.email[0] }}"
|
||||
GIVEN_NAME = "{{ user.given_name[0] }}"
|
||||
FAMILY_NAME = "{{ user.family_name[0] }}"
|
||||
PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||
LOCALE = "{{ user.preferred_language }}"
|
||||
ADDRESS = "{{ user.formatted_address[0] }}"
|
||||
PICTURE = "{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}"
|
||||
WEBSITE = "{{ user.profile_url[0] }}"
|
||||
# SUB = "{{ user.user_name[0] }}"
|
||||
# NAME = "{{ user.formatted_name[0] }}"
|
||||
# PHONE_NUMBER = "{{ user.phone_number[0] }}"
|
||||
# EMAIL = "{{ user.email[0] }}"
|
||||
# GIVEN_NAME = "{{ user.given_name[0] }}"
|
||||
# FAMILY_NAME = "{{ user.family_name[0] }}"
|
||||
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||
# LOCALE = "{{ user.preferred_language }}"
|
||||
# ADDRESS = "{{ user.formatted_address[0] }}"
|
||||
# PICTURE = "{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}"
|
||||
# WEBSITE = "{{ user.profile_url[0] }}"
|
||||
|
||||
# The SMTP server options. If not set, mail related features such as
|
||||
# user invitations, and password reset emails, will be disabled.
|
||||
|
|
|
@ -193,17 +193,17 @@ PUBLIC_KEY = "conf/public.pem"
|
|||
# User objectClass.
|
||||
# {attribute} will be replaced by the user ldap attribute value.
|
||||
# Default values fits inetOrgPerson.
|
||||
SUB = "{{ user.user_name[0] }}"
|
||||
NAME = "{{ user.formatted_name[0] }}"
|
||||
PHONE_NUMBER = "{{ user.phone_number[0] }}"
|
||||
EMAIL = "{{ user.email[0] }}"
|
||||
GIVEN_NAME = "{{ user.given_name[0] }}"
|
||||
FAMILY_NAME = "{{ user.family_name[0] }}"
|
||||
PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||
LOCALE = "{{ user.preferred_language }}"
|
||||
ADDRESS = "{{ user.formatted_address[0] }}"
|
||||
PICTURE = "{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}"
|
||||
WEBSITE = "{{ user.profile_url[0] }}"
|
||||
# SUB = "{{ user.user_name[0] }}"
|
||||
# NAME = "{{ user.formatted_name[0] }}"
|
||||
# PHONE_NUMBER = "{{ user.phone_number[0] }}"
|
||||
# EMAIL = "{{ user.email[0] }}"
|
||||
# GIVEN_NAME = "{{ user.given_name[0] }}"
|
||||
# FAMILY_NAME = "{{ user.family_name[0] }}"
|
||||
# PREFERRED_USERNAME = "{{ user.display_name }}"
|
||||
# LOCALE = "{{ user.preferred_language }}"
|
||||
# ADDRESS = "{{ user.formatted_address[0] }}"
|
||||
# PICTURE = "{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}"
|
||||
# WEBSITE = "{{ user.profile_url[0] }}"
|
||||
|
||||
# The SMTP server options. If not set, mail related features such as
|
||||
# user invitations, and password reset emails, will be disabled.
|
||||
|
|
|
@ -63,19 +63,6 @@ def configuration(configuration, keypair_path):
|
|||
"PUBLIC_KEY": public_key_path,
|
||||
"PRIVATE_KEY": private_key_path,
|
||||
"ISS": "https://auth.mydomain.tld",
|
||||
"MAPPING": {
|
||||
"SUB": "{{ user.user_name[0] }}",
|
||||
"NAME": "{{ user.formatted_name[0] }}",
|
||||
"PHONE_NUMBER": "{{ user.phone_number[0] }}",
|
||||
"EMAIL": "{{ user.email[0] }}",
|
||||
"GIVEN_NAME": "{{ user.given_name[0] }}",
|
||||
"FAMILY_NAME": "{{ user.family_name[0] }}",
|
||||
"PREFERRED_USERNAME": "{{ user.display_name }}",
|
||||
"LOCALE": "{{ user.preferred_language }}",
|
||||
"PICTURE": "{% if user.photo %}{{ url_for('account.photo', user_name=user.user_name[0], field='photo', _external=True) }}{% endif %}",
|
||||
"ADDRESS": "{{ user.formatted_address[0] }}",
|
||||
"WEBSITE": "{{ user.profile_url[0] }}",
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from canaille.oidc.oauth import claims_from_scope
|
||||
from canaille.oidc.oauth import DEFAULT_JWT_MAPPING
|
||||
from canaille.oidc.oauth import generate_user_claims
|
||||
|
||||
|
||||
|
@ -261,16 +262,6 @@ STANDARD_CLAIMS = [
|
|||
"address",
|
||||
"updated_at",
|
||||
]
|
||||
DEFAULT_JWT_MAPPING_CONFIG = {
|
||||
"SUB": "{{ user.user_name[0] }}",
|
||||
"NAME": "{{ user.formatted_name[0] }}",
|
||||
"PHONE_NUMBER": "{{ user.phone_number[0] }}",
|
||||
"EMAIL": "{{ user.email[0] }}",
|
||||
"GIVEN_NAME": "{{ user.given_name[0] }}",
|
||||
"FAMILY_NAME": "{{ user.family_name[0] }}",
|
||||
"PREFERRED_USERNAME": "{{ user.display_name }}",
|
||||
"LOCALE": "{{ user.preferred_language }}",
|
||||
}
|
||||
|
||||
|
||||
def test_generate_user_standard_claims_with_default_config(
|
||||
|
@ -278,9 +269,10 @@ def test_generate_user_standard_claims_with_default_config(
|
|||
):
|
||||
user.preferred_language = ["fr"]
|
||||
|
||||
data = generate_user_claims(user, STANDARD_CLAIMS, DEFAULT_JWT_MAPPING_CONFIG)
|
||||
data = generate_user_claims(user, STANDARD_CLAIMS, DEFAULT_JWT_MAPPING)
|
||||
|
||||
assert data == {
|
||||
"address": "1235, somewhere",
|
||||
"sub": "user",
|
||||
"name": "John (johnny) Doe",
|
||||
"family_name": "Doe",
|
||||
|
@ -288,13 +280,14 @@ def test_generate_user_standard_claims_with_default_config(
|
|||
"email": "john@doe.com",
|
||||
"locale": "fr",
|
||||
"phone_number": "555-000-000",
|
||||
"website": "https://john.example",
|
||||
}
|
||||
|
||||
|
||||
def test_custom_config_format_claim_is_well_formated(
|
||||
testclient, slapd_connection, user
|
||||
):
|
||||
jwt_mapping_config = DEFAULT_JWT_MAPPING_CONFIG.copy()
|
||||
jwt_mapping_config = DEFAULT_JWT_MAPPING.copy()
|
||||
jwt_mapping_config["EMAIL"] = "{{ user.user_name[0] }}@mydomain.tld"
|
||||
|
||||
data = generate_user_claims(user, STANDARD_CLAIMS, jwt_mapping_config)
|
||||
|
@ -308,6 +301,6 @@ def test_claim_is_omitted_if_empty(testclient, slapd_connection, user):
|
|||
user.email = ""
|
||||
user.save()
|
||||
|
||||
data = generate_user_claims(user, STANDARD_CLAIMS, DEFAULT_JWT_MAPPING_CONFIG)
|
||||
data = generate_user_claims(user, STANDARD_CLAIMS, DEFAULT_JWT_MAPPING)
|
||||
|
||||
assert "email" not in data
|
||||
|
|
Loading…
Reference in a new issue