From 264620852a52aef8c87d58378f70e67b284a007e Mon Sep 17 00:00:00 2001 From: Christian Albrecht Date: Sun, 8 Oct 2017 11:22:14 +0200 Subject: [PATCH 1/2] Fix pep8 issues --- back/taiga_contrib_saml_auth/settings.py | 61 ++++++++++++------------ 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/back/taiga_contrib_saml_auth/settings.py b/back/taiga_contrib_saml_auth/settings.py index 4633c5e..87f6245 100644 --- a/back/taiga_contrib_saml_auth/settings.py +++ b/back/taiga_contrib_saml_auth/settings.py @@ -1,41 +1,42 @@ from django.conf import settings from django.core.urlresolvers import reverse + def get_saml_settings(): base_url = '{scheme}://{domain}'.format( - scheme=settings.SITES['front']['scheme'], - domain=settings.SITES['front']['domain'], - ) + scheme=settings.SITES['front']['scheme'], + domain=settings.SITES['front']['domain'], + ) debug = settings.DEBUG saml_settings = { - 'strict': not debug, - 'debug': debug, - 'sp': { - 'entityId': base_url + reverse('taiga_contrib_saml_auth:metadata'), - 'assertionConsumerService': { - 'url': base_url + reverse('taiga_contrib_saml_auth:login_complete'), - }, - 'singleLogoutService': { - 'url': base_url + reverse('taiga_contrib_saml_auth:logout_complete'), - }, - 'NameIDFormat': settings.SAML_AUTH['sp'].get('nameIDFormat'), - 'x509cert': settings.SAML_AUTH['sp']['cert'], - 'privateKey': settings.SAML_AUTH['sp']['key'], - }, - 'idp': { - 'entityId': settings.SAML_AUTH['idp']['entityID'], - 'singleSignOnService': { - 'url': settings.SAML_AUTH['idp']['singleSignOnURL'], - }, - 'singleLogoutService': { - 'url': settings.SAML_AUTH['idp']['singleLogoutURL'], - }, - }, - 'security': settings.SAML_AUTH.get('security', {}), - 'organization': settings.SAML_AUTH.get('organization', {}), - 'contactPerson': settings.SAML_AUTH.get('contactPerson', {}), - } + 'strict': not debug, + 'debug': debug, + 'sp': { + 'entityId': base_url + reverse('taiga_contrib_saml_auth:metadata'), + 'assertionConsumerService': { + 'url': base_url + reverse('taiga_contrib_saml_auth:login_complete'), + }, + 'singleLogoutService': { + 'url': base_url + reverse('taiga_contrib_saml_auth:logout_complete'), + }, + 'NameIDFormat': settings.SAML_AUTH['sp'].get('nameIDFormat'), + 'x509cert': settings.SAML_AUTH['sp']['cert'], + 'privateKey': settings.SAML_AUTH['sp']['key'], + }, + 'idp': { + 'entityId': settings.SAML_AUTH['idp']['entityID'], + 'singleSignOnService': { + 'url': settings.SAML_AUTH['idp']['singleSignOnURL'], + }, + 'singleLogoutService': { + 'url': settings.SAML_AUTH['idp']['singleLogoutURL'], + }, + }, + 'security': settings.SAML_AUTH.get('security', {}), + 'organization': settings.SAML_AUTH.get('organization', {}), + 'contactPerson': settings.SAML_AUTH.get('contactPerson', {}), + } if 'cert' in settings.SAML_AUTH['idp']: saml_settings['idp']['x509cert'] = settings.SAML_AUTH['idp']['cert'] From ec27ff7be21ae5e35956844a985a1ff04e800157 Mon Sep 17 00:00:00 2001 From: Christian Albrecht Date: Sun, 8 Oct 2017 12:03:58 +0200 Subject: [PATCH 2/2] Change settings handling The syntax of the SAML_AUTH settings dict is now identical to the underlying python3-saml plugin. --- README.md | 308 +++++++++-------------- back/taiga_contrib_saml_auth/settings.py | 43 +--- 2 files changed, 129 insertions(+), 222 deletions(-) diff --git a/README.md b/README.md index 301c58b..08af132 100644 --- a/README.md +++ b/README.md @@ -23,98 +23,122 @@ Modify your `settings/local.py` and include the lines: INSTALLED_APPS += ["taiga_contrib_saml_auth"] SAML_AUTH = { - # Service Provider settings (yourself) - 'sp': { - # Uncomment if you want to specify a NameIDFormat - #'nameIDFormat': 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', - - # This is your own Service Provider certificate - 'cert': '''-----BEGIN CERTIFICATE----- - ... - -----END CERTIFICATE-----''', - - # This is your own Service Provider private key - 'key': '''-----BEGIN RSA PRIVATE KEY----- - ... - -----END RSA PRIVATE KEY-----''', - }, - - # Identity Provider settings (your partner doing the authentication) - # These settings can be found in their metadata - 'idp': { - 'entityID': 'YOUR_IDP_ENTITY_ID', - 'singleSignOnURL': 'YOUR_IDP_SSO_URL', - 'singleLogoutURL': 'YOUR_IDP_SLO_URL', - - # use either cert OR certFingerprint - # This is the Identity Provider certificate - 'cert': '''-----BEGIN CERTIFICATE----- - ... - -----END CERTIFICATE-----''', - # This is the Identify Provider certificate fingerprint - # (Generate it with: openssl x509 -in YOUR_IDP_CERTIFICATE -noout -fingerprint | cut -d'=' -f2 | tr -d : | tr A-Z a-z) - #'certFingerprint': 'YOUR_IDP_CERTIFICATE_FINGERPRINT', - }, - - # Security settings - 'security': { - # These are the defaults - #'nameIdEncrypted': False, - #'authnRequestsSigned': False, - #'logoutRequestSigned': False, - #'logoutResponseSigned': False, - #'signMetadata': False, - #'wantMessagesSigned': False, - #'wantAssertionsSigned': False, - #'wantNameId': True, - #'wantAssertionsEncrypted': False, - #'wantNameIdEncrypted': False, - #'wantAttributeStatement': True, - #'requestedAuthnContext': True, - }, - - 'organization': { - # Organization information template, the info in en_US lang is - # recommended, add more if required. - 'en-US': { - 'name': 'organization', - 'displayname': 'Organization Name', - 'url': 'https://www.example.org/', - }, - }, - - 'contactPerson': { - # Contact information template, it is recommended to suply a - # technical and support contacts. - 'technical': { - 'givenName': 'technical_name', - 'emailAddress': 'technical@example.com' - }, - 'support': { - 'givenName': 'support_name', - 'emailAddress': 'support@example.com' - }, - }, - - # Mapping between the SAML user and the Taiga user - 'mapping': { - # Uncomment to use a specific attribute as the SAML ID to link the Taiga user and the SAML user - # By default, the SAML NameID will be used - #'id': 'SAML_ATTRIBUTE_NAME', - - # You need to define at least email, username and full_name - # (username and full_name can map to the same SAML attribute, as the username will be derived as - # a unique slug from the given attribute) - 'attributes': { - 'email': 'SAML_ATTRIBUTE_NAME_EMAIL', - 'username': 'SAML_ATTRIBUTE_NAME_USERNAME', - 'full_name': 'SAML_ATTRIBUTE_NAME_FULLNAME', - #'bio': 'SAML_ATTRIBUTE_NAME_BIO', - #'lang': 'SAML_ATTRIBUTE_NAME_LANG', - #'timezone': 'SAML_ATTRIBUTE_NAME_TIMEZONE', - }, - }, - } + # Service Provider settings (yourself) + 'sp': { + # 'entityId', 'assertionConsumerService' and 'singleLogoutService' will be set automatically. + + # Uncomment if you want to specify a NameIDFormat + #'NameIDFormat': 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', + + # This is your own Service Provider certificate + 'x509cert': '''-----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE-----''', + + # This is your own Service Provider private key + 'privateKey': '''-----BEGIN RSA PRIVATE KEY----- + ... + -----END RSA PRIVATE KEY-----''', + }, + + # + # For more options and detailed description see https://github.com/onelogin/python3-saml + # + # Identity Provider settings (your partner doing the authentication) + # These settings can be found in their metadata + 'idp': { + # Identifier of the IdP entity (must be a URI) + 'entityID': 'YOUR_IDP_ENTITY_ID', + + # SSO endpoint info of the IdP. (Authentication Request protocol) + "singleSignOnService": { + # URL Target of the IdP where the Authentication Request Message + # will be sent. + "url": 'YOUR_IDP_SSO_URL', + # SAML protocol binding to be used when returning the + # message. OneLogin Toolkit supports the HTTP-Redirect binding + # only for this endpoint. + "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + }, + # SLO endpoint info of the IdP. + "singleLogoutService": { + # URL Location of the IdP where SLO Request will be sent. + "url": 'YOUR_IDP_SLO_URL', + # SAML protocol binding to be used when returning the + # message. OneLogin Toolkit supports the HTTP-Redirect binding + # only for this endpoint. + "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + }, + + # use either cert OR certFingerprint + # This is the Identity Provider certificate + 'x509cert': '''-----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE-----''', + # This is the Identify Provider certificate fingerprint + # (Generate it with: openssl x509 -in YOUR_IDP_CERTIFICATE -noout -fingerprint | cut -d'=' -f2 | tr -d : | tr A-Z a-z) + #'certFingerprint': 'YOUR_IDP_CERTIFICATE_FINGERPRINT', + }, + + # Security settings + 'security': { + # These are the defaults + #'nameIdEncrypted': False, + #'authnRequestsSigned': False, + #'logoutRequestSigned': False, + #'logoutResponseSigned': False, + #'signMetadata': False, + #'wantMessagesSigned': False, + #'wantAssertionsSigned': False, + #'wantNameId': True, + #'wantAssertionsEncrypted': False, + #'wantNameIdEncrypted': False, + #'wantAttributeStatement': True, + #'requestedAuthnContext': True, + }, + + 'organization': { + # Organization information template, the info in en_US lang is + # recommended, add more if required. + 'en-US': { + 'name': 'organization', + 'displayname': 'Organization Name', + 'url': 'https://www.example.org/', + }, + }, + + 'contactPerson': { + # Contact information template, it is recommended to suply a + # technical and support contacts. + 'technical': { + 'givenName': 'technical_name', + 'emailAddress': 'technical@example.com' + }, + 'support': { + 'givenName': 'support_name', + 'emailAddress': 'support@example.com' + }, + }, + + # Mapping between the SAML user and the Taiga user + 'mapping': { + # Uncomment to use a specific attribute as the SAML ID to link the Taiga user and the SAML user + # By default, the SAML NameID will be used + #'id': 'SAML_ATTRIBUTE_NAME', + + # You need to define at least email, username and full_name + # (username and full_name can map to the same SAML attribute, as the username will be derived as + # a unique slug from the given attribute) + 'attributes': { + 'email': 'SAML_ATTRIBUTE_NAME_EMAIL', + 'username': 'SAML_ATTRIBUTE_NAME_USERNAME', + 'full_name': 'SAML_ATTRIBUTE_NAME_FULLNAME', + # 'bio': 'SAML_ATTRIBUTE_NAME_BIO', + # 'lang': 'SAML_ATTRIBUTE_NAME_LANG', + # 'timezone': 'SAML_ATTRIBUTE_NAME_TIMEZONE', + }, + }, +} ``` @@ -184,106 +208,8 @@ workon taiga pip install -e . ``` -Modify `taiga-back/settings/local.py` and include the line: +Modify `taiga-back/settings/local.py`. See "Production env -> Taiga Back" section for content: -```python -INSTALLED_APPS += ["taiga_contrib_saml_auth"] - -SAML_AUTH = { - # Service Provider settings (yourself) - 'sp': { - # Uncomment if you want to specify a NameIDFormat - #'nameIDFormat': 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', - - # This is your own Service Provider certificate - 'cert': '''-----BEGIN CERTIFICATE----- - ... - -----END CERTIFICATE-----''', - - # This is your own Service Provider private key - 'key': '''-----BEGIN RSA PRIVATE KEY----- - ... - -----END RSA PRIVATE KEY-----''', - }, - - # Identity Provider settings (your partner doing the authentication) - # These settings can be found in their metadata - 'idp': { - 'entityID': 'YOUR_IDP_ENTITY_ID', - 'singleSignOnURL': 'YOUR_IDP_SSO_URL', - 'singleLogoutURL': 'YOUR_IDP_SLO_URL', - - # use either cert OR certFingerprint - # This is the Identity Provider certificate - 'cert': '''-----BEGIN CERTIFICATE----- - ... - -----END CERTIFICATE-----''', - # This is the Identify Provider certificate fingerprint - # (Generate it with: openssl x509 -in YOUR_IDP_CERTIFICATE -noout -fingerprint | cut -d'=' -f2 | tr -d : | tr A-Z a-z) - #'certFingerprint': 'YOUR_IDP_CERTIFICATE_FINGERPRINT', - }, - - # Security settings - 'security': { - # These are the defaults - #'nameIdEncrypted': False, - #'authnRequestsSigned': False, - #'logoutRequestSigned': False, - #'logoutResponseSigned': False, - #'signMetadata': False, - #'wantMessagesSigned': False, - #'wantAssertionsSigned': False, - #'wantNameId': True, - #'wantAssertionsEncrypted': False, - #'wantNameIdEncrypted': False, - #'wantAttributeStatement': True, - #'requestedAuthnContext': True, - }, - - 'organization': { - # Organization information template, the info in en_US lang is - # recommended, add more if required. - 'en-US': { - 'name': 'organization', - 'displayname': 'Organization Name', - 'url': 'https://www.example.org/', - }, - }, - - 'contactPerson': { - # Contact information template, it is recommended to suply a - # technical and support contacts. - 'technical': { - 'givenName': 'technical_name', - 'emailAddress': 'technical@example.com' - }, - 'support': { - 'givenName': 'support_name', - 'emailAddress': 'support@example.com' - }, - }, - - # Mapping between the SAML user and the Taiga user - 'mapping': { - # Uncomment to use a specific attribute as the SAML ID to link the Taiga user and the SAML user - # By default, the SAML NameID will be used - #'id': 'SAML_ATTRIBUTE_NAME', - - # You need to define at least email, username and full_name - # (username and full_name can map to the same SAML attribute, as the username will be derived as - # a unique slug from the given attribute) - 'attributes': { - 'email': 'SAML_ATTRIBUTE_NAME_EMAIL', - 'username': 'SAML_ATTRIBUTE_NAME_USERNAME', - 'full_name': 'SAML_ATTRIBUTE_NAME_FULLNAME', - #'bio': 'SAML_ATTRIBUTE_NAME_BIO', - #'lang': 'SAML_ATTRIBUTE_NAME_LANG', - #'timezone': 'SAML_ATTRIBUTE_NAME_TIMEZONE', - }, - }, - } - -``` Modify your `taiga/urls.py` and include these lines: diff --git a/back/taiga_contrib_saml_auth/settings.py b/back/taiga_contrib_saml_auth/settings.py index 87f6245..d1c7e21 100644 --- a/back/taiga_contrib_saml_auth/settings.py +++ b/back/taiga_contrib_saml_auth/settings.py @@ -9,38 +9,19 @@ def get_saml_settings(): ) debug = settings.DEBUG - saml_settings = { - 'strict': not debug, - 'debug': debug, - 'sp': { - 'entityId': base_url + reverse('taiga_contrib_saml_auth:metadata'), - 'assertionConsumerService': { - 'url': base_url + reverse('taiga_contrib_saml_auth:login_complete'), - }, - 'singleLogoutService': { - 'url': base_url + reverse('taiga_contrib_saml_auth:logout_complete'), - }, - 'NameIDFormat': settings.SAML_AUTH['sp'].get('nameIDFormat'), - 'x509cert': settings.SAML_AUTH['sp']['cert'], - 'privateKey': settings.SAML_AUTH['sp']['key'], + saml_settings = dict(settings.SAML_AUTH) + + saml_settings['strict'] = settings.SAML_AUTH.get('strict', not debug) + saml_settings['debug'] = settings.SAML_AUTH.get('debug', debug) + del(saml_settings['mapping']) + saml_settings['sp'].update({ + 'entityId': base_url + reverse('taiga_contrib_saml_auth:metadata'), + 'assertionConsumerService': { + 'url': base_url + reverse('taiga_contrib_saml_auth:login_complete'), }, - 'idp': { - 'entityId': settings.SAML_AUTH['idp']['entityID'], - 'singleSignOnService': { - 'url': settings.SAML_AUTH['idp']['singleSignOnURL'], - }, - 'singleLogoutService': { - 'url': settings.SAML_AUTH['idp']['singleLogoutURL'], - }, + 'singleLogoutService': { + 'url': base_url + reverse('taiga_contrib_saml_auth:logout_complete'), }, - 'security': settings.SAML_AUTH.get('security', {}), - 'organization': settings.SAML_AUTH.get('organization', {}), - 'contactPerson': settings.SAML_AUTH.get('contactPerson', {}), - } - - if 'cert' in settings.SAML_AUTH['idp']: - saml_settings['idp']['x509cert'] = settings.SAML_AUTH['idp']['cert'] - elif 'certFingerprint' in settings.SAML_AUTH['idp']: - saml_settings['idp']['certFingerprint'] = settings.SAML_AUTH['idp']['certFingerprint'] + }) return saml_settings