diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 00000000..affd63bb --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,54 @@ +name-template: 'v$RESOLVED_VERSION' +tag-template: 'v$RESOLVED_VERSION' +categories: +- + title: 'Features' + labels: + - 'enhancement' + - 'feat' + - 'feature' +- + title: 'Bug Fixes' + labels: + - 'bug' + - 'bugfix' + - 'fix' +- + title: 'Maintenance' + labels: + - 'chore' + - 'style' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. +version-resolver: + major: + labels: ['major'] + minor: + labels: ['minor'] + patch: + labels: ['patch'] + default: patch +exclude-labels: ['skip'] +autolabeler: +- + label: 'bug' + branch: + - '/bug\/.+/' + - '/bugfix\/.+/' + - '/fix\/.+/' +- + label: 'enhancement' + branch: + - '/dependabot\/.+/' + - '/enhancement\/.+/' + - '/feat\/.+/' + - '/feature\/.+/' +- + label: 'chore' + branch: + - '/chore\/.+/' + - '/style\/.+/' +template: | + ## Release notes + + $CHANGES diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml new file mode 100644 index 00000000..6a89202f --- /dev/null +++ b/.github/workflows/python-app.yml @@ -0,0 +1,66 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +name: Satosa-Saml2Spid + +on: + push: + branches: [ master, dev ] + pull_request: + branches: [ master, dev ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + python-version: + - '3.7' + - '3.8' + - '3.9' + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install system dependencies + run: | + sudo apt update + sudo apt install -y libffi-dev libssl-dev python3-pip xmlsec1 procps libpcre3 libpcre3-dev + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + pip install -r example_sp/djangosaml2_sp/requirements.txt + pip install spid-sp-test>=0.9.2 + pip list -v + #- name: Lint with flake8 + #run: | + ## stop the build if there are Python syntax errors or undefined names + #flake8 oidc_provider --count --select=E9,F63,F7,F82 --show-source --statistics + ## exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + #flake8 oidc_provider --max-line-length 120 --count --exit-zero --statistics + - name: run djangosaml2 sp + run: | + cd example_sp/djangosaml2_sp/ + bash run.sh & + sleep 5 + - name: run satosa-saml2spid + run: | + cd example + mkdir -p metadata/idp + mkdir -p metadata/sp + export SATOSA_APP=`python3 -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])'` + uwsgi --wsgi-file $SATOSA_APP/satosa/wsgi.py --https 0.0.0.0:10000,./pki/cert.pem,./pki/privkey.pem --callable app -b 32768 & + sleep 5 + - name: spid-sp-test + run: | + cd example + spid_sp_test --idp-metadata > metadata/idp/spid-sp-test.xml + spid_sp_test --metadata-url https://localhost:10000/spidSaml2/metadata --authn-url "http://localhost:8000/saml2/login/?idp=https://localhost:10000/Saml2IDP/metadata&next=/saml2/echo_attributes&idphint=https%253A%252F%252Flocalhost%253A8080" -ap spid_sp_test.plugins.authn_request.SatosaSaml2Spid --extra --debug ERROR -tr diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 00000000..0916e298 --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,17 @@ +name: Release drafter + +on: + push: + branches: [master, dev] + pull_request: + types: [opened, reopened, synchronize] + +jobs: + update_release_draft: + name: Update draft release + runs-on: ubuntu-latest + steps: + - + uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 68400713..6fc3a3aa 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,4 @@ example/metadata/*.md *pyFF_example/.whoosh *pyFF_example/garr *pyFF_example/entities -example/pki/* +example_sp/djangosaml2_sp/sqlite3.db diff --git a/README.md b/README.md index e988ec97..74f727bf 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ source satosa.env/bin/activate ###### Dependencies ```` -sudo apt install -y libffi-dev libssl-dev xmlsec1 python3-pip xmlsec1 procps libpcre3 libpcre3-dev +sudo apt install -y libffi-dev libssl-dev python3-pip xmlsec1 procps libpcre3 libpcre3-dev git clone https://github.com/peppelinux/Satosa-Saml2Spid.git repository pip install -r repository/requirements.txt diff --git a/example/metadata/idp/spid-sp-test.xml b/example/metadata/idp/spid-sp-test.xml new file mode 100644 index 00000000..a498163c --- /dev/null +++ b/example/metadata/idp/spid-sp-test.xml @@ -0,0 +1 @@ +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urn:oasis:names:tc:SAML:2.0:nameid-format:transient \ No newline at end of file diff --git a/example/metadata/sp/djangosaml2_sp b/example/metadata/sp/djangosaml2_sp new file mode 100644 index 00000000..06f0e285 --- /dev/null +++ b/example/metadata/sp/djangosaml2_sp @@ -0,0 +1,35 @@ +MIIDETCCAfmgAwIBAgIUPw12Gkt4agBtLBntd7RzTWwLKAYwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNc3AxLnVuaWNhbC5pdDAeFw0xOTAzMjAxNDMxMTVaFw0y +OTAzMTcxNDMxMTVaMBgxFjAUBgNVBAMMDXNwMS51bmljYWwuaXQwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCj0BzOt58ECsSwT049bIhmD0p7q0Y+4L7c +jrvvJYcMT7HZE+tbO4M6upkXnP+3gvPpRccaEtwJoda3gYzvF35VMzp0fCW7OmXI +R8cJtySIfzkdmmO385Tbxlp1jRxZyQtc2nPzCKeV4xlQNEinQr94nI7tMFReDejj +XKwS5RABk8KQMo2M78xa9RQyxqDC1e0ioeVQRR2og99fF3u/WOJ/JB2aETTfvInr +FIyFA5XB0roBDyM44877nRKYeMBd4kVk+fs4yu6kZm7WOXHUXFLKRuXLeVxEbZYz +SSMjncsB1U35OAt+Ozkp+12qaqMAVdGKP+xso3zGAr/5AC6CuPnrAgMBAAGjUzBR +MB0GA1UdDgQWBBR6RRoajGB1UmdiMAKSmgpL3RD0mzAfBgNVHSMEGDAWgBR6RRoa +jGB1UmdiMAKSmgpL3RD0mzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA +A4IBAQBzRUa++T0EiR+Fq4iTpKIysigV+1CeMbS+u1JaPOnMXfWmboOOVDrHhnit +bpfxm+SpbafPTz40THtfw9EKvReMjNa4HQ4vFBMwZtmYZ4piGS5PferFDzYdZG1d +S/2vcCQA4Dya/R675XKEhBdWO8JfUOL1ImMoJBa5Z+ApU8OCk8hpiJUV0akpw7jA ++VO8+VR2T+SH+3h28KOrNdraWozZ99NKqB7GUFcaxouaOkPE7mi8JyAgLZMZvJae +QeJEUI9sfavSLmvBsfbusAeCjFYCVM9MM7uZNvK6gI0Dzppl+rN7vRWcBF+oYyiS +1EX9j2GqG1yWcdGvY60GJu5Er5id +MIIDETCCAfmgAwIBAgIUPw12Gkt4agBtLBntd7RzTWwLKAYwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNc3AxLnVuaWNhbC5pdDAeFw0xOTAzMjAxNDMxMTVaFw0y +OTAzMTcxNDMxMTVaMBgxFjAUBgNVBAMMDXNwMS51bmljYWwuaXQwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCj0BzOt58ECsSwT049bIhmD0p7q0Y+4L7c +jrvvJYcMT7HZE+tbO4M6upkXnP+3gvPpRccaEtwJoda3gYzvF35VMzp0fCW7OmXI +R8cJtySIfzkdmmO385Tbxlp1jRxZyQtc2nPzCKeV4xlQNEinQr94nI7tMFReDejj +XKwS5RABk8KQMo2M78xa9RQyxqDC1e0ioeVQRR2og99fF3u/WOJ/JB2aETTfvInr +FIyFA5XB0roBDyM44877nRKYeMBd4kVk+fs4yu6kZm7WOXHUXFLKRuXLeVxEbZYz +SSMjncsB1U35OAt+Ozkp+12qaqMAVdGKP+xso3zGAr/5AC6CuPnrAgMBAAGjUzBR +MB0GA1UdDgQWBBR6RRoajGB1UmdiMAKSmgpL3RD0mzAfBgNVHSMEGDAWgBR6RRoa +jGB1UmdiMAKSmgpL3RD0mzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA +A4IBAQBzRUa++T0EiR+Fq4iTpKIysigV+1CeMbS+u1JaPOnMXfWmboOOVDrHhnit +bpfxm+SpbafPTz40THtfw9EKvReMjNa4HQ4vFBMwZtmYZ4piGS5PferFDzYdZG1d +S/2vcCQA4Dya/R675XKEhBdWO8JfUOL1ImMoJBa5Z+ApU8OCk8hpiJUV0akpw7jA ++VO8+VR2T+SH+3h28KOrNdraWozZ99NKqB7GUFcaxouaOkPE7mi8JyAgLZMZvJae +QeJEUI9sfavSLmvBsfbusAeCjFYCVM9MM7uZNvK6gI0Dzppl+rN7vRWcBF+oYyiS +1EX9j2GqG1yWcdGvY60GJu5Er5id +urn:oasis:names:tc:SAML:2.0:nameid-format:persistenturn:oasis:names:tc:SAML:2.0:nameid-format:transientUnicalUnicalUnicalUnicalhttp://www.unical.ithttp://www.unical.itUniversita della CalabriaGiuseppeDe Marcogiuseppe.demarco@unical.itUniversita della CalabriaGiuseppeDe Marcogiuseppe.demarco@unical.it \ No newline at end of file diff --git a/example/pki/build_spid_certs.sh b/example/pki/build_spid_certs.sh new file mode 100644 index 00000000..787e446f --- /dev/null +++ b/example/pki/build_spid_certs.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +set -euo pipefail + +openssl_conf=$(mktemp) + +# check input parameters + +COMMON_NAME=${COMMON_NAME:=""} +if [ "X${COMMON_NAME}" == "X" ]; then + echo "[E] COMMON_NAME must be set" + exit 1 +fi + +LOCALITY_NAME=${LOCALITY_NAME:=""} +if [ "X${LOCALITY_NAME}" == "X" ]; then + echo "[E] LOCALITY_NAME must be set" + exit 1 +fi + +ORGANIZATION_IDENTIFIER=${ORGANIZATION_IDENTIFIER:=""} +if [ "X${ORGANIZATION_IDENTIFIER}" == "X" ]; then + echo "[E] ORGANIZATION_IDENTIFIER must be set" + exit 1 +fi + +if [ $(echo ${ORGANIZATION_IDENTIFIER} | grep -c '^PA:IT-') -ne 1 ]; then + echo "[E] ORGANIZATION_IDENTIFIER must be in the format of 'PA:IT-'" + exit 1 +fi + +ORGANIZATION_NAME=${ORGANIZATION_NAME:=""} +if [ "X${ORGANIZATION_NAME}" == "X" ]; then + echo "[E] ORGANIZATION_NAME must be set" + exit 1 +fi + +SERIAL_NUMBER=${SERIAL_NUMBER:=""} +if [ "X${SERIAL_NUMBER}" == "X" ]; then + echo "[E] SERIAL_NUMBER must be set" + exit 1 +fi + +URI=${URI:=""} +if [ "X${URI}" == "X" ]; then + echo "[E] URI must be set" + exit 1 +fi + +SPID_SECTOR=${SPID_SECTOR:=""} +if [ "X${SPID_SECTOR}" == "X" ]; then + echo "[E] SPID_SECTOR must be set" + exit 1 +fi + +case ${SPID_SECTOR} in + public) + POLICY_IDENTIFIER="spid-publicsector-SP" + ;; + private) + POLICY_IDENTIFIER="spid-privatesector-SP" + ;; + *) + echo "[E] SPID_SECTOR must be one of ['public', 'private']" + exit 1 + ;; +esac + +# generate configuration file + +cat > ${openssl_conf} <3.0<4.0 + +git+https://github.com/peppelinux/pysaml2.git@pplnx-7.0.1 +cffi + +# django saml2 SP +djangosaml2>=1.0.0 diff --git a/example_sp/djangosaml2_sp/run.sh b/example_sp/djangosaml2_sp/run.sh new file mode 100755 index 00000000..f84aac39 --- /dev/null +++ b/example_sp/djangosaml2_sp/run.sh @@ -0,0 +1,2 @@ +python -B ./manage.py migrate +python -B ./manage.py runserver 0.0.0.0:8000 diff --git a/example_sp/djangosaml2_sp/saml2_sp/__init__.py b/example_sp/djangosaml2_sp/saml2_sp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/__init__.py b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/adfs_v1x.py b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/adfs_v1x.py new file mode 100644 index 00000000..b0b8d327 --- /dev/null +++ b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/adfs_v1x.py @@ -0,0 +1,20 @@ +# See http://technet.microsoft.com/en-us/library/cc733065(v=ws.10).aspx +# and http://technet.microsoft.com/en-us/library/ee913589(v=ws.10).aspx +# for information regarding the default claim types supported by +# Microsoft ADFS v1.x. + +MAP = { + "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified", + "fro": { + 'http://schemas.xmlsoap.org/claims/commonname': 'commonName', + 'http://schemas.xmlsoap.org/claims/emailaddress': 'emailAddress', + 'http://schemas.xmlsoap.org/claims/group': 'group', + 'http://schemas.xmlsoap.org/claims/upn': 'upn', + }, + "to": { + 'commonName': 'http://schemas.xmlsoap.org/claims/commonname', + 'emailAddress': 'http://schemas.xmlsoap.org/claims/emailaddress', + 'group': 'http://schemas.xmlsoap.org/claims/group', + 'upn': 'http://schemas.xmlsoap.org/claims/upn', + } +} diff --git a/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/adfs_v20.py b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/adfs_v20.py new file mode 100644 index 00000000..f1d35efa --- /dev/null +++ b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/adfs_v20.py @@ -0,0 +1,47 @@ +# See http://technet.microsoft.com/en-us/library/ee913589(v=ws.10).aspx +# for information regarding the default claim types supported by +# Microsoft ADFS v2.0. + +MAP = { + "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified", + "fro": { + 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress': 'emailAddress', + 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname': 'givenName', + 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name': 'name', + 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn': 'upn', + 'http://schemas.xmlsoap.org/claims/commonname': 'commonName', + 'http://schemas.xmlsoap.org/claims/group': 'group', + 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role': 'role', + 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname': 'surname', + 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier': 'privatePersonalId', + 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier': 'nameId', + 'http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod': 'authenticationMethod', + 'http://schemas.xmlsoap.com/ws/2005/05/identity/claims/denyonlysid': 'denyOnlySid', + 'http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid': 'denyOnlyPrimarySid', + 'http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid': 'denyOnlyPrimaryGroupSid', + 'http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid': 'groupSid', + 'http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid': 'primaryGroupSid', + 'http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid': 'primarySid', + 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname': 'windowsAccountName', + }, + "to": { + 'emailAddress': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress', + 'givenName': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname', + 'name': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name', + 'upn': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn', + 'commonName': 'http://schemas.xmlsoap.org/claims/commonname', + 'group': 'http://schemas.xmlsoap.org/claims/group', + 'role': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role', + 'surname': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname', + 'privatePersonalId': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier', + 'nameId': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier', + 'authenticationMethod': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod', + 'denyOnlySid': 'http://schemas.xmlsoap.com/ws/2005/05/identity/claims/denyonlysid', + 'denyOnlyPrimarySid': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid', + 'denyOnlyPrimaryGroupSid': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid', + 'groupSid': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid', + 'primaryGroupSid': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid', + 'primarySid': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid', + 'windowsAccountName': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname', + } +} diff --git a/example_sp/sp-repoze/attributemaps/basic.py b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/basic.py similarity index 100% rename from example_sp/sp-repoze/attributemaps/basic.py rename to example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/basic.py diff --git a/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/django_saml_uri.py b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/django_saml_uri.py new file mode 100644 index 00000000..784228a7 --- /dev/null +++ b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/django_saml_uri.py @@ -0,0 +1,19 @@ +X500ATTR_OID = 'urn:oid:2.5.4.' +PKCS_9 = 'urn:oid:1.2.840.113549.1.9.1.' +UCL_DIR_PILOT = 'urn:oid:0.9.2342.19200300.100.1.' + +MAP = { + 'identifier': 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri', + 'fro': { + X500ATTR_OID+'3': 'first_name', # cn + X500ATTR_OID+'4': 'last_name', # sn + PKCS_9+'1': 'email', + UCL_DIR_PILOT+'1': 'uid', + }, + 'to': { + 'first_name': X500ATTR_OID+'3', + 'last_name': X500ATTR_OID+'4', + 'email' : PKCS_9+'1', + 'uid': UCL_DIR_PILOT+'1', + } +} diff --git a/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/saml_uri.py b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/saml_uri.py new file mode 100644 index 00000000..40f7b778 --- /dev/null +++ b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/saml_uri.py @@ -0,0 +1,354 @@ +EDUCOURSE_OID = 'urn:oid:1.3.6.1.4.1.5923.1.6.1.' +EDUPERSON_OID = 'urn:oid:1.3.6.1.4.1.5923.1.1.1.' +EDUMEMBER1_OID = 'urn:oid:1.3.6.1.4.1.5923.1.5.1.' + +# ldap.gv.at definitions as specified in: +# http://www.ref.gv.at/AG-IZ-PVP2-Version-2-1-0-2.2754.0.html +LDAPGVAT_OID = 'urn:oid:1.2.40.0.10.2.1.1.' + +UCL_DIR_PILOT = 'urn:oid:0.9.2342.19200300.100.1.' +X500ATTR_OID = 'urn:oid:2.5.4.' +LDAPGVAT_UCL_DIR_PILOT = UCL_DIR_PILOT +LDAPGVAT_X500ATTR_OID = X500ATTR_OID +NETSCAPE_LDAP = 'urn:oid:2.16.840.1.113730.3.1.' +NOREDUPERSON_OID = 'urn:oid:1.3.6.1.4.1.2428.90.1.' +PKCS_9 = 'urn:oid:1.2.840.113549.1.9.1.' +SCHAC = 'urn:oid:1.3.6.1.4.1.25178.1.2.' +SIS = 'urn:oid:1.2.752.194.10.2.' +UMICH = 'urn:oid:1.3.6.1.4.1.250.1.57.' + +# openosi-0.82.schema http://www.openosi.org/osi/display/ldap/Home +OPENOSI_OID = 'urn:oid:1.3.6.1.4.1.27630.2.1.1.' + +EIDAS_NATURALPERSON = 'http://eidas.europa.eu/attributes/naturalperson/' +EIDAS_LEGALPERSON = 'http://eidas.europa.eu/attributes/legalperson/' + +MAP = { + 'identifier': 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri', + 'fro': { + EIDAS_LEGALPERSON+'LegalPersonIdentifier': 'LegalPersonIdentifier', + EIDAS_LEGALPERSON+'LegalAddress': 'LegalAddress', + EIDAS_LEGALPERSON+'LegalName': 'LegalName', + EIDAS_LEGALPERSON+'VATRegistration': 'VATRegistration', + EIDAS_LEGALPERSON+'TaxReference': 'TaxReference', + EIDAS_LEGALPERSON+'BusinessCodes': 'BusinessCodes', + EIDAS_LEGALPERSON+'LEI': 'LEI', + EIDAS_LEGALPERSON+'EORI': 'EORI', + EIDAS_LEGALPERSON+'SEED': 'SEED', + EIDAS_LEGALPERSON+'SIC': 'SIC', + EIDAS_LEGALPERSON+'D-2012-17-EUIdentifier': 'D-2012-17-EUIdentifier', + EIDAS_NATURALPERSON+'PersonIdentifier': 'PersonIdentifier', + EIDAS_NATURALPERSON+'CurrentFamilyName': 'FamilyName', + EIDAS_NATURALPERSON+'CurrentGivenName': 'FirstName', + EIDAS_NATURALPERSON+'DateOfBirth': 'DateOfBirth', + EIDAS_NATURALPERSON+'BirthName': 'BirthName', + EIDAS_NATURALPERSON+'PlaceOfBirth': 'PlaceOfBirth', + EIDAS_NATURALPERSON+'CurrentAddress': 'CurrentAddress', + EIDAS_NATURALPERSON+'Gender': 'Gender', + EDUCOURSE_OID+'1': 'eduCourseOffering', + EDUCOURSE_OID+'2': 'eduCourseMember', + EDUMEMBER1_OID+'1': 'isMemberOf', + EDUPERSON_OID+'1': 'eduPersonAffiliation', + EDUPERSON_OID+'2': 'eduPersonNickname', + EDUPERSON_OID+'3': 'eduPersonOrgDN', + EDUPERSON_OID+'4': 'eduPersonOrgUnitDN', + EDUPERSON_OID+'5': 'eduPersonPrimaryAffiliation', + EDUPERSON_OID+'6': 'eduPersonPrincipalName', + EDUPERSON_OID+'7': 'eduPersonEntitlement', + EDUPERSON_OID+'8': 'eduPersonPrimaryOrgUnitDN', + EDUPERSON_OID+'9': 'eduPersonScopedAffiliation', + EDUPERSON_OID+'10': 'eduPersonTargetedID', + EDUPERSON_OID+'11': 'eduPersonAssurance', + EDUPERSON_OID+'12': 'eduPersonPrincipalNamePrior', + EDUPERSON_OID+'13': 'eduPersonUniqueId', + EDUPERSON_OID+'16': 'eduPersonOrcid', + LDAPGVAT_OID+'1': 'PVP-GID', + LDAPGVAT_OID+'149': 'PVP-BPK', + LDAPGVAT_OID+'153': 'PVP-OU-OKZ', + LDAPGVAT_OID+'261.10': 'PVP-VERSION', + LDAPGVAT_OID+'261.20': 'PVP-PRINCIPAL-NAME', + LDAPGVAT_OID+'261.24': 'PVP-PARTICIPANT-OKZ', + LDAPGVAT_OID+'261.30': 'PVP-ROLES', + LDAPGVAT_OID+'261.40': 'PVP-INVOICE-RECPT-ID', + LDAPGVAT_OID+'261.50': 'PVP-COST-CENTER-ID', + LDAPGVAT_OID+'261.60': 'PVP-CHARGE-CODE', + LDAPGVAT_OID+'3': 'PVP-OU-GV-OU-ID', + LDAPGVAT_OID+'33': 'PVP-FUNCTION', + LDAPGVAT_OID+'55': 'PVP-BIRTHDATE', + LDAPGVAT_OID+'71': 'PVP-PARTICIPANT-ID', + LDAPGVAT_UCL_DIR_PILOT+'1': 'PVP-USERID', + LDAPGVAT_UCL_DIR_PILOT+'3': 'PVP-MAIL', + LDAPGVAT_X500ATTR_OID+'11': 'PVP-OU', + LDAPGVAT_X500ATTR_OID+'20': 'PVP-TEL', + LDAPGVAT_X500ATTR_OID+'42': 'PVP-GIVENNAME', + NETSCAPE_LDAP+'1': 'carLicense', + NETSCAPE_LDAP+'2': 'departmentNumber', + NETSCAPE_LDAP+'3': 'employeeNumber', + NETSCAPE_LDAP+'4': 'employeeType', + NETSCAPE_LDAP+'39': 'preferredLanguage', + NETSCAPE_LDAP+'40': 'userSMIMECertificate', + NETSCAPE_LDAP+'216': 'userPKCS12', + NETSCAPE_LDAP+'241': 'displayName', + NOREDUPERSON_OID+'1': 'norEduOrgUniqueNumber', + NOREDUPERSON_OID+'2': 'norEduOrgUnitUniqueNumber', + NOREDUPERSON_OID+'3': 'norEduPersonBirthDate', + NOREDUPERSON_OID+'4': 'norEduPersonLIN', + NOREDUPERSON_OID+'5': 'norEduPersonNIN', + NOREDUPERSON_OID+'6': 'norEduOrgAcronym', + NOREDUPERSON_OID+'7': 'norEduOrgUniqueIdentifier', + NOREDUPERSON_OID+'8': 'norEduOrgUnitUniqueIdentifier', + NOREDUPERSON_OID+'9': 'federationFeideSchemaVersion', + NOREDUPERSON_OID+'10': 'norEduPersonLegalName', + NOREDUPERSON_OID+'11': 'norEduOrgSchemaVersion', + NOREDUPERSON_OID+'12': 'norEduOrgNIN', + OPENOSI_OID+'17': 'osiHomeUrl', + OPENOSI_OID+'19': 'osiPreferredTZ', + OPENOSI_OID+'72': 'osiICardTimeLastUpdated', + OPENOSI_OID+'104': 'osiMiddleName', + OPENOSI_OID+'107': 'osiOtherEmail', + OPENOSI_OID+'109': 'osiOtherHomePhone', + OPENOSI_OID+'120': 'osiWorkURL', + PKCS_9+'1': 'email', + SCHAC+'1': 'schacMotherTongue', + SCHAC+'2': 'schacGender', + SCHAC+'3': 'schacDateOfBirth', + SCHAC+'4': 'schacPlaceOfBirth', + SCHAC+'5': 'schacCountryOfCitizenship', + SCHAC+'6': 'schacSn1', + SCHAC+'7': 'schacSn2', + SCHAC+'8': 'schacPersonalTitle', + SCHAC+'9': 'schacHomeOrganization', + SCHAC+'10': 'schacHomeOrganizationType', + SCHAC+'11': 'schacCountryOfResidence', + SCHAC+'12': 'schacUserPresenceID', + SCHAC+'13': 'schacPersonalPosition', + SCHAC+'14': 'schacPersonalUniqueCode', + SCHAC+'15': 'schacPersonalUniqueID', + SCHAC+'17': 'schacExpiryDate', + SCHAC+'18': 'schacUserPrivateAttribute', + SCHAC+'19': 'schacUserStatus', + SCHAC+'20': 'schacProjectMembership', + SCHAC+'21': 'schacProjectSpecificRole', + SIS+'1': 'sisLegalGuardianFor', + SIS+'2': 'sisSchoolGrade', + UCL_DIR_PILOT+'1': 'uid', + UCL_DIR_PILOT+'3': 'mail', + UCL_DIR_PILOT+'25': 'dc', + UCL_DIR_PILOT+'37': 'associatedDomain', + UCL_DIR_PILOT+'43': 'co', + UCL_DIR_PILOT+'60': 'jpegPhoto', + UMICH+'57': 'labeledURI', + X500ATTR_OID+'2': 'knowledgeInformation', + X500ATTR_OID+'3': 'cn', + X500ATTR_OID+'4': 'sn', + X500ATTR_OID+'5': 'serialNumber', + X500ATTR_OID+'6': 'c', + X500ATTR_OID+'7': 'l', + X500ATTR_OID+'8': 'st', + X500ATTR_OID+'9': 'street', + X500ATTR_OID+'10': 'o', + X500ATTR_OID+'11': 'ou', + X500ATTR_OID+'12': 'title', + X500ATTR_OID+'14': 'searchGuide', + X500ATTR_OID+'15': 'businessCategory', + X500ATTR_OID+'16': 'postalAddress', + X500ATTR_OID+'17': 'postalCode', + X500ATTR_OID+'18': 'postOfficeBox', + X500ATTR_OID+'19': 'physicalDeliveryOfficeName', + X500ATTR_OID+'20': 'telephoneNumber', + X500ATTR_OID+'21': 'telexNumber', + X500ATTR_OID+'22': 'teletexTerminalIdentifier', + X500ATTR_OID+'23': 'facsimileTelephoneNumber', + X500ATTR_OID+'24': 'x121Address', + X500ATTR_OID+'25': 'internationaliSDNNumber', + X500ATTR_OID+'26': 'registeredAddress', + X500ATTR_OID+'27': 'destinationIndicator', + X500ATTR_OID+'28': 'preferredDeliveryMethod', + X500ATTR_OID+'29': 'presentationAddress', + X500ATTR_OID+'30': 'supportedApplicationContext', + X500ATTR_OID+'31': 'member', + X500ATTR_OID+'32': 'owner', + X500ATTR_OID+'33': 'roleOccupant', + X500ATTR_OID+'36': 'userCertificate', + X500ATTR_OID+'37': 'cACertificate', + X500ATTR_OID+'38': 'authorityRevocationList', + X500ATTR_OID+'39': 'certificateRevocationList', + X500ATTR_OID+'40': 'crossCertificatePair', + X500ATTR_OID+'42': 'givenName', + X500ATTR_OID+'43': 'initials', + X500ATTR_OID+'44': 'generationQualifier', + X500ATTR_OID+'45': 'x500UniqueIdentifier', + X500ATTR_OID+'46': 'dnQualifier', + X500ATTR_OID+'47': 'enhancedSearchGuide', + X500ATTR_OID+'48': 'protocolInformation', + X500ATTR_OID+'50': 'uniqueMember', + X500ATTR_OID+'51': 'houseIdentifier', + X500ATTR_OID+'52': 'supportedAlgorithms', + X500ATTR_OID+'53': 'deltaRevocationList', + X500ATTR_OID+'54': 'dmdName', + X500ATTR_OID+'65': 'pseudonym', + }, + 'to': { + 'LegalPersonIdentifier': EIDAS_LEGALPERSON+'LegalPersonIdentifier', + 'LegalAddress': EIDAS_LEGALPERSON+'LegalAddress', + 'LegalName': EIDAS_LEGALPERSON+'LegalName', + 'VATRegistration': EIDAS_LEGALPERSON+'VATRegistration', + 'TaxReference': EIDAS_LEGALPERSON+'TaxReference', + 'BusinessCodes': EIDAS_LEGALPERSON+'BusinessCodes', + 'LEI': EIDAS_LEGALPERSON+'LEI', + 'EORI': EIDAS_LEGALPERSON+'EORI', + 'SEED': EIDAS_LEGALPERSON+'SEED', + 'SIC': EIDAS_LEGALPERSON+'SIC', + 'D-2012-17-EUIdentifier': EIDAS_LEGALPERSON+'D-2012-17-EUIdentifier', + 'PersonIdentifier': EIDAS_NATURALPERSON+'PersonIdentifier', + 'FamilyName': EIDAS_NATURALPERSON+'CurrentFamilyName', + 'FirstName': EIDAS_NATURALPERSON+'CurrentGivenName', + 'DateOfBirth': EIDAS_NATURALPERSON+'DateOfBirth', + 'BirthName': EIDAS_NATURALPERSON+'BirthName', + 'PlaceOfBirth': EIDAS_NATURALPERSON+'PlaceOfBirth', + 'CurrentAddress': EIDAS_NATURALPERSON+'CurrentAddress', + 'Gender': EIDAS_NATURALPERSON+'Gender', + 'associatedDomain': UCL_DIR_PILOT+'37', + 'authorityRevocationList': X500ATTR_OID+'38', + 'businessCategory': X500ATTR_OID+'15', + 'c': X500ATTR_OID+'6', + 'cACertificate': X500ATTR_OID+'37', + 'carLicense': NETSCAPE_LDAP+'1', + 'certificateRevocationList': X500ATTR_OID+'39', + 'cn': X500ATTR_OID+'3', + 'co': UCL_DIR_PILOT+'43', + 'crossCertificatePair': X500ATTR_OID+'40', + 'dc': UCL_DIR_PILOT+'25', + 'deltaRevocationList': X500ATTR_OID+'53', + 'departmentNumber': NETSCAPE_LDAP+'2', + 'destinationIndicator': X500ATTR_OID+'27', + 'displayName': NETSCAPE_LDAP+'241', + 'dmdName': X500ATTR_OID+'54', + 'dnQualifier': X500ATTR_OID+'46', + 'eduCourseMember': EDUCOURSE_OID+'2', + 'eduCourseOffering': EDUCOURSE_OID+'1', + 'eduPersonAffiliation': EDUPERSON_OID+'1', + 'eduPersonEntitlement': EDUPERSON_OID+'7', + 'eduPersonNickname': EDUPERSON_OID+'2', + 'eduPersonOrgDN': EDUPERSON_OID+'3', + 'eduPersonOrgUnitDN': EDUPERSON_OID+'4', + 'eduPersonPrimaryAffiliation': EDUPERSON_OID+'5', + 'eduPersonPrimaryOrgUnitDN': EDUPERSON_OID+'8', + 'eduPersonPrincipalName': EDUPERSON_OID+'6', + 'eduPersonPrincipalNamePrior': EDUPERSON_OID+'12', + 'eduPersonScopedAffiliation': EDUPERSON_OID+'9', + 'eduPersonTargetedID': EDUPERSON_OID+'10', + 'eduPersonAssurance': EDUPERSON_OID+'11', + 'eduPersonUniqueId': EDUPERSON_OID+'13', + 'eduPersonOrcid': EDUPERSON_OID+'16', + 'email': PKCS_9+'1', + 'employeeNumber': NETSCAPE_LDAP+'3', + 'employeeType': NETSCAPE_LDAP+'4', + 'enhancedSearchGuide': X500ATTR_OID+'47', + 'facsimileTelephoneNumber': X500ATTR_OID+'23', + 'federationFeideSchemaVersion': NOREDUPERSON_OID+'9', + 'generationQualifier': X500ATTR_OID+'44', + 'givenName': X500ATTR_OID+'42', + 'houseIdentifier': X500ATTR_OID+'51', + 'initials': X500ATTR_OID+'43', + 'internationaliSDNNumber': X500ATTR_OID+'25', + 'isMemberOf': EDUMEMBER1_OID+'1', + 'jpegPhoto': UCL_DIR_PILOT+'60', + 'knowledgeInformation': X500ATTR_OID+'2', + 'l': X500ATTR_OID+'7', + 'labeledURI': UMICH+'57', + 'mail': UCL_DIR_PILOT+'3', + 'member': X500ATTR_OID+'31', + 'norEduOrgAcronym': NOREDUPERSON_OID+'6', + 'norEduOrgNIN': NOREDUPERSON_OID+'12', + 'norEduOrgSchemaVersion': NOREDUPERSON_OID+'11', + 'norEduOrgUniqueIdentifier': NOREDUPERSON_OID+'7', + 'norEduOrgUniqueNumber': NOREDUPERSON_OID+'1', + 'norEduOrgUnitUniqueIdentifier': NOREDUPERSON_OID+'8', + 'norEduOrgUnitUniqueNumber': NOREDUPERSON_OID+'2', + 'norEduPersonBirthDate': NOREDUPERSON_OID+'3', + 'norEduPersonLIN': NOREDUPERSON_OID+'4', + 'norEduPersonLegalName': NOREDUPERSON_OID+'10', + 'norEduPersonNIN': NOREDUPERSON_OID+'5', + 'o': X500ATTR_OID+'10', + 'osiHomeUrl': OPENOSI_OID+'17', + 'osiPreferredTZ': OPENOSI_OID+'19', + 'osiICardTimeLastUpdated': OPENOSI_OID+'72', + 'osiMiddleName': OPENOSI_OID+'104', + 'osiOtherEmail': OPENOSI_OID+'107', + 'osiOtherHomePhone': OPENOSI_OID+'109', + 'osiWorkURL': OPENOSI_OID+'120', + 'ou': X500ATTR_OID+'11', + 'owner': X500ATTR_OID+'32', + 'physicalDeliveryOfficeName': X500ATTR_OID+'19', + 'postOfficeBox': X500ATTR_OID+'18', + 'postalAddress': X500ATTR_OID+'16', + 'postalCode': X500ATTR_OID+'17', + 'preferredDeliveryMethod': X500ATTR_OID+'28', + 'preferredLanguage': NETSCAPE_LDAP+'39', + 'presentationAddress': X500ATTR_OID+'29', + 'protocolInformation': X500ATTR_OID+'48', + 'pseudonym': X500ATTR_OID+'65', + 'PVP-USERID': LDAPGVAT_UCL_DIR_PILOT+'1', + 'PVP-MAIL': LDAPGVAT_UCL_DIR_PILOT+'3', + 'PVP-GID': LDAPGVAT_OID+'1', + 'PVP-BPK': LDAPGVAT_OID+'149', + 'PVP-OU-OKZ': LDAPGVAT_OID+'153', + 'PVP-VERSION': LDAPGVAT_OID+'261.10', + 'PVP-PRINCIPAL-NAME': LDAPGVAT_OID+'261.20', + 'PVP-PARTICIPANT-OKZ': LDAPGVAT_OID+'261.24', + 'PVP-ROLES': LDAPGVAT_OID+'261.30', + 'PVP-INVOICE-RECPT-ID': LDAPGVAT_OID+'261.40', + 'PVP-COST-CENTER-ID': LDAPGVAT_OID+'261.50', + 'PVP-CHARGE-CODE': LDAPGVAT_OID+'261.60', + 'PVP-OU-GV-OU-ID': LDAPGVAT_OID+'3', + 'PVP-FUNCTION': LDAPGVAT_OID+'33', + 'PVP-BIRTHDATE': LDAPGVAT_OID+'55', + 'PVP-PARTICIPANT-ID': LDAPGVAT_OID+'71', + 'PVP-OU': LDAPGVAT_X500ATTR_OID+'11', + 'PVP-TEL': LDAPGVAT_X500ATTR_OID+'20', + 'PVP-GIVENNAME': LDAPGVAT_X500ATTR_OID+'42', + 'registeredAddress': X500ATTR_OID+'26', + 'roleOccupant': X500ATTR_OID+'33', + 'schacCountryOfCitizenship': SCHAC+'5', + 'schacCountryOfResidence': SCHAC+'11', + 'schacDateOfBirth': SCHAC+'3', + 'schacExpiryDate': SCHAC+'17', + 'schacGender': SCHAC+'2', + 'schacHomeOrganization': SCHAC+'9', + 'schacHomeOrganizationType': SCHAC+'10', + 'schacMotherTongue': SCHAC+'1', + 'schacPersonalPosition': SCHAC+'13', + 'schacPersonalTitle': SCHAC+'8', + 'schacPersonalUniqueCode': SCHAC+'14', + 'schacPersonalUniqueID': SCHAC+'15', + 'schacPlaceOfBirth': SCHAC+'4', + 'schacProjectMembership': SCHAC+'20', + 'schacProjectSpecificRole': SCHAC+'21', + 'schacSn1': SCHAC+'6', + 'schacSn2': SCHAC+'7', + 'schacUserPresenceID': SCHAC+'12', + 'schacUserPrivateAttribute': SCHAC+'18', + 'schacUserStatus': SCHAC+'19', + 'searchGuide': X500ATTR_OID+'14', + 'serialNumber': X500ATTR_OID+'5', + 'sisLegalGuardianFor': SIS+'1', + 'sisSchoolGrade': SIS+'2', + 'sn': X500ATTR_OID+'4', + 'st': X500ATTR_OID+'8', + 'street': X500ATTR_OID+'9', + 'supportedAlgorithms': X500ATTR_OID+'52', + 'supportedApplicationContext': X500ATTR_OID+'30', + 'telephoneNumber': X500ATTR_OID+'20', + 'teletexTerminalIdentifier': X500ATTR_OID+'22', + 'telexNumber': X500ATTR_OID+'21', + 'title': X500ATTR_OID+'12', + 'uid': UCL_DIR_PILOT+'1', + 'uniqueMember': X500ATTR_OID+'50', + 'userCertificate': X500ATTR_OID+'36', + 'userPKCS12': NETSCAPE_LDAP+'216', + 'userSMIMECertificate': NETSCAPE_LDAP+'40', + 'x121Address': X500ATTR_OID+'24', + 'x500UniqueIdentifier': X500ATTR_OID+'45', + } +} diff --git a/example_sp/sp-repoze/attributemaps/shibboleth_uri.py b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/shibboleth_uri.py similarity index 100% rename from example_sp/sp-repoze/attributemaps/shibboleth_uri.py rename to example_sp/djangosaml2_sp/saml2_sp/saml2_config/attribute-maps/shibboleth_uri.py diff --git a/example_sp/djangosaml2_sp/saml2_sp/saml2_config/satosa-saml2spid.xml b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/satosa-saml2spid.xml new file mode 100644 index 00000000..93cf71cc --- /dev/null +++ b/example_sp/djangosaml2_sp/saml2_sp/saml2_config/satosa-saml2spid.xml @@ -0,0 +1,55 @@ +Authentication ProxyAuthentication ProxyAuthentication Proxy IdP ITAuthentication Proxy IdP ENhttps://www.spid.gov.it/assets/img/spid-ico-circle-bb.svghttps://www.example.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 +urn:oasis:names:tc:SAML:2.0:nameid-format:transientproxy.authSaml2 Authentication Proxyhttps://spid.proxy.example.orgTechnicalmailto:supporto.tecnico@example.orgSupportmailto:richieste.ict@example.org \ No newline at end of file diff --git a/example_sp/djangosaml2_sp/saml2_sp/urls.py b/example_sp/djangosaml2_sp/saml2_sp/urls.py new file mode 100644 index 00000000..d480b46d --- /dev/null +++ b/example_sp/djangosaml2_sp/saml2_sp/urls.py @@ -0,0 +1,9 @@ +from django.conf import settings +from django.contrib import admin +from django.urls import include, path + +from . import views + +urlpatterns = [ + path('', views.index), +] diff --git a/example_sp/djangosaml2_sp/saml2_sp/utils.py b/example_sp/djangosaml2_sp/saml2_sp/utils.py new file mode 100644 index 00000000..8137f648 --- /dev/null +++ b/example_sp/djangosaml2_sp/saml2_sp/utils.py @@ -0,0 +1,24 @@ +import base64 +import xml.dom.minidom +import zlib + +from xml.parsers.expat import ExpatError + + +def repr_saml(saml_str, b64=False): + """ Decode SAML from b64 and b64 deflated and + return a pretty printed representation + """ + try: + msg = base64.b64decode(saml_str).decode() if b64 else saml_str + dom = xml.dom.minidom.parseString(msg) + except (UnicodeDecodeError, ExpatError): + # in HTTP-REDIRECT the base64 must be inflated + msg = base64.b64decode(saml_str) + inflated = zlib.decompress(msg, -15) + dom = xml.dom.minidom.parseString(inflated.decode()) + return dom.toprettyxml() + + +def encode_http_redirect_saml(saml_envelope): + return base64.b64encode(zlib.compress(saml_envelope.encode())) diff --git a/example_sp/djangosaml2_sp/saml2_sp/views.py b/example_sp/djangosaml2_sp/saml2_sp/views.py new file mode 100644 index 00000000..a1826cf1 --- /dev/null +++ b/example_sp/djangosaml2_sp/saml2_sp/views.py @@ -0,0 +1,54 @@ +import base64 +import logging +import saml2 + +from django.conf import settings +from django.contrib.auth.models import User +from django.dispatch import receiver +from django.http import HttpResponse +from django.shortcuts import render +from django.template import TemplateDoesNotExist +from djangosaml2.conf import get_config +from djangosaml2.cache import IdentityCache, OutstandingQueriesCache +from djangosaml2.cache import StateCache +from djangosaml2.conf import get_config +from djangosaml2.overrides import Saml2Client +from djangosaml2.signals import post_authenticated, pre_user_save +from djangosaml2.utils import ( + available_idps, get_custom_setting, + get_idp_sso_supported_bindings, get_location +) +from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST +from saml2.authn_context import requested_authn_context +from saml2.metadata import entity_descriptor + +from .utils import repr_saml + + +logger = logging.getLogger('djangosaml2') + + +def index(request): + """ Barebone 'diagnostics' view, print user attributes if logged in + login/logout links. + """ + if request.user.is_authenticated: + out = "LOGGED IN: LOGOUT
".format(settings.LOGOUT_URL) + out += "".join(['%s: %s
' % (field.name, getattr(request.user, field.name)) + for field in request.user._meta.get_fields() + if field.concrete]) + return HttpResponse(out) + else: + return HttpResponse("LOGGED OUT: LOGIN".format(settings.LOGIN_URL)) + + +# TODO fix this in IdP side? +@receiver(pre_user_save, sender=User) +def custom_update_user(sender, instance, attributes, user_modified, **kargs): + """ Default behaviour does not play nice with booleans encoded in SAML as u'true'/u'false'. + This will convert those attributes to real booleans when saving. + """ + for k, v in attributes.items(): + u = set.intersection(set(v), set([u'true', u'false'])) + if u: + setattr(instance, k, u.pop() == u'true') + return True # I modified the user object diff --git a/example_sp/djangosaml2_sp/tests/request_saml_auth.py b/example_sp/djangosaml2_sp/tests/request_saml_auth.py new file mode 100644 index 00000000..2f09b59a --- /dev/null +++ b/example_sp/djangosaml2_sp/tests/request_saml_auth.py @@ -0,0 +1,175 @@ +import copy +import os +import sys + +sys.path.append(os.getcwd()) + +from djangosaml2_sp.sp_pysaml2_shibidp import (SAML_CONFIG, + BASE_URL, + BASE_DIR, + IDP_URL) + +from pprint import pprint + +from saml2.config import SPConfig +from saml2.response import AuthnResponse +from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST +from saml2.client import Saml2Client + + +# OutStanding Queries +# outstanding = {'id-R3qGBIK1FKbybkEOo': '/', 'id-vV5JVaBZCuC2LHP9Y': '/', 'id-TH9lfrLJL4KtNuEZJ': '/', 'id-KeYf8iMkonCWaqGrd': '/', 'id-S8lzm7lkEYIwokDVZ': '/', 'id-1naCBqIuGqm31mFnC': '/', 'id-D5bhbXLDxt6nS2QtZ': '/', 'id-UCjbQ7AS1nGG5wSN5': '/', 'id-EdrCM5hBIDix23Bf5': '/', 'id-p3yvaSmx6TJPZ0qK7': '/', 'id-DgwqMaGwOJYRxnzQe': '/'} + +outstanding = None +outstanding_certs = None +conv_info = None + +conf = SPConfig() + +conf.load(copy.deepcopy(SAML_CONFIG)) +client = Saml2Client(conf) + +# client arguments +selected_idp = None +came_from = '/' +# conf['sp']['authn_requests_signed'] determines if saml2.BINDING_HTTP_POST or saml2.BINDING_HTTP_REDIRECT +binding = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' # saml2.BINDING_HTTP_REDIRECT +sign=False +sigalg=None +nsprefix = {'ds': 'http://www.w3.org/2000/09/xmldsig#', 'md': 'urn:oasis:names:tc:SAML:2.0:metadata', 'samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', 'xenc': 'http://www.w3.org/2001/04/xmlenc#', 'saml': 'urn:oasis:names:tc:SAML:2.0:assertion'} + +# craft SAML Request +session_id, result = client.prepare_for_authenticate( + entityid=selected_idp, + relay_state=came_from, + binding=binding, + sign=sign, + sigalg=sigalg, + nsprefix=nsprefix + ) + +target = result.get('headers')[0][1] + +# browser init +import requests + +r = requests.Session() +# SAMLRequest is in target URL +sp_saml_request = r.get(target, verify=False) +if not sp_saml_request.ok: raise ('SP SAML Request Failed') + + +# fetch post ACTION url from form then POST +import re +action_post_regexp ='(?Paction)="(?P[a-zA-Z0-9\.\:\/\_\?\=]*)"' +s = re.search(action_post_regexp, sp_saml_request.text) +if not s: raise ('IDP Login POST doesn\'t returns correctly') + +post_target = target.split('?')[0]+'?'+s.groupdict()['value'].split('?')[1] + +payload = { +'j_username': 'mario', +'j_password': 'cimpa12', +'donotcache': 1, +'_shib_idp_revokeConsent': True, +'_eventId_proceed': '' +} + +# post target is in one of the but we already fetched it in the previous FORM. +# IDP supports all those defined in its Metadata +# +# +# +# + +idp_login_response = r.post(post_target, data=payload, verify=False) +if not idp_login_response.ok: raise ('IDP Login response Failed') + +# Response +# extract SAML2 authn response from IDP response +saml2_response_regexp ='name="(?PSAMLResponse)" value="(?P[a-zA-Z0-9\.\:\/\_\?\=\+\-]*)"' +sr = re.search(saml2_response_regexp, idp_login_response.text) +if not sr: + print(idp_login_response.text) + raise ('IDP Response doesn\'t contain a valid SAML value') + + +# Decode SAML2 base64 String +import base64 + +saml_auth_response_b64 = sr.groupdict().get('value') +saml_auth_response = base64.b64decode(saml_auth_response_b64) +xmlstr = saml_auth_response.decode('ascii') + +# Fancy SAML print +# from lxml import etree +# root = etree.XML(xmlstr.encode('ascii')) +# print(etree.tostring(root, pretty_print=True).decode('utf-8')) + +# pySAML2 parse authn response (sign and decrypt features included) + +kwargs = { + "outstanding_queries": outstanding, + "outstanding_certs": outstanding_certs, + "allow_unsolicited": conf._sp_allow_unsolicited, + "want_assertions_signed": conf._sp_want_assertions_signed, + "want_response_signed": conf._sp_want_response_signed, + "return_addrs": conf.endpoint("assertion_consumer_service", binding, "sp"), + "entity_id": conf.entityid, + "attribute_converters": conf.attribute_converters, + "allow_unknown_attributes": conf.allow_unknown_attributes, + 'conv_info': conv_info + } + +# xml unravel fails bacause of b64 inflate method +# pr = client.parse_authn_request_response(saml_auth_response_b64, + # binding, + # outstanding=outstanding, + # outstanding_certs=None, + # conv_info=None) + +authn_response = AuthnResponse(client.sec, **kwargs) + +# response.loads(xmlstr, False, origxml=origxml) +# authn_response.loads(xmlstr, False, origxml=xmlstr) + +# response.py -> AuthnResponse +# in response.loads -> ._loads -> +# authn_response.signature_check(xmldata, origdoc=origxml, must=self.require_signature, +# require_response_signature=self.require_response_signature, +# **args) + +# HERE err=18;msg=self signed certificate ! +#samlp_response = authn_response.signature_check(xmlstr, must=0, require_response_signature=0) + +# ea = samlp_response.encrypted_assertion[0] +# ea.encrypted_data.cipher_data.cipher_value.text + +# consulta python-xmlsec +# https://github.com/mehcode/python-xmlsec/issues/22 + +from lxml import etree +import xmlsec + +xmlsec.enable_debug_trace(True) +km = xmlsec.KeysManager() + +km.add_key(xmlsec.Key.from_file(conf.key_file, + xmlsec.KeyFormat.PEM)) +enc_ctx = xmlsec.EncryptionContext(km) + +# root = etree.parse("response.xml").getroot() +root = etree.XML(xmlstr.encode('ascii')) +node = root.xpath( + "//enc:EncryptedData", + namespaces={'enc': 'http://www.w3.org/2001/04/xmlenc#'}, +) +enc_data = node[0] + +print() +print(etree.tostring(enc_data)) +print() +decrypted = enc_ctx.decrypt(enc_data) + +print() +print(etree.tostring(decrypted)) diff --git a/example_sp/README.md b/example_sp/pysaml2/README.md similarity index 100% rename from example_sp/README.md rename to example_sp/pysaml2/README.md diff --git a/example_sp/requirements.txt b/example_sp/pysaml2/requirements.txt similarity index 100% rename from example_sp/requirements.txt rename to example_sp/pysaml2/requirements.txt diff --git a/example_sp/pysaml2/sp-repoze/attributemaps/basic.py b/example_sp/pysaml2/sp-repoze/attributemaps/basic.py new file mode 100644 index 00000000..9311d547 --- /dev/null +++ b/example_sp/pysaml2/sp-repoze/attributemaps/basic.py @@ -0,0 +1,326 @@ + +MAP = { + "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:basic", + "fro": { + 'urn:mace:dir:attribute-def:aRecord': 'aRecord', + 'urn:mace:dir:attribute-def:aliasedEntryName': 'aliasedEntryName', + 'urn:mace:dir:attribute-def:aliasedObjectName': 'aliasedObjectName', + 'urn:mace:dir:attribute-def:associatedDomain': 'associatedDomain', + 'urn:mace:dir:attribute-def:associatedName': 'associatedName', + 'urn:mace:dir:attribute-def:audio': 'audio', + 'urn:mace:dir:attribute-def:authorityRevocationList': 'authorityRevocationList', + 'urn:mace:dir:attribute-def:buildingName': 'buildingName', + 'urn:mace:dir:attribute-def:businessCategory': 'businessCategory', + 'urn:mace:dir:attribute-def:c': 'c', + 'urn:mace:dir:attribute-def:cACertificate': 'cACertificate', + 'urn:mace:dir:attribute-def:cNAMERecord': 'cNAMERecord', + 'urn:mace:dir:attribute-def:carLicense': 'carLicense', + 'urn:mace:dir:attribute-def:certificateRevocationList': 'certificateRevocationList', + 'urn:mace:dir:attribute-def:cn': 'cn', + 'urn:mace:dir:attribute-def:co': 'co', + 'urn:mace:dir:attribute-def:commonName': 'commonName', + 'urn:mace:dir:attribute-def:countryName': 'countryName', + 'urn:mace:dir:attribute-def:crossCertificatePair': 'crossCertificatePair', + 'urn:mace:dir:attribute-def:dITRedirect': 'dITRedirect', + 'urn:mace:dir:attribute-def:dSAQuality': 'dSAQuality', + 'urn:mace:dir:attribute-def:dc': 'dc', + 'urn:mace:dir:attribute-def:deltaRevocationList': 'deltaRevocationList', + 'urn:mace:dir:attribute-def:departmentNumber': 'departmentNumber', + 'urn:mace:dir:attribute-def:description': 'description', + 'urn:mace:dir:attribute-def:destinationIndicator': 'destinationIndicator', + 'urn:mace:dir:attribute-def:displayName': 'displayName', + 'urn:mace:dir:attribute-def:distinguishedName': 'distinguishedName', + 'urn:mace:dir:attribute-def:dmdName': 'dmdName', + 'urn:mace:dir:attribute-def:dnQualifier': 'dnQualifier', + 'urn:mace:dir:attribute-def:documentAuthor': 'documentAuthor', + 'urn:mace:dir:attribute-def:documentIdentifier': 'documentIdentifier', + 'urn:mace:dir:attribute-def:documentLocation': 'documentLocation', + 'urn:mace:dir:attribute-def:documentPublisher': 'documentPublisher', + 'urn:mace:dir:attribute-def:documentTitle': 'documentTitle', + 'urn:mace:dir:attribute-def:documentVersion': 'documentVersion', + 'urn:mace:dir:attribute-def:domainComponent': 'domainComponent', + 'urn:mace:dir:attribute-def:drink': 'drink', + 'urn:mace:dir:attribute-def:eduOrgHomePageURI': 'eduOrgHomePageURI', + 'urn:mace:dir:attribute-def:eduOrgIdentityAuthNPolicyURI': 'eduOrgIdentityAuthNPolicyURI', + 'urn:mace:dir:attribute-def:eduOrgLegalName': 'eduOrgLegalName', + 'urn:mace:dir:attribute-def:eduOrgSuperiorURI': 'eduOrgSuperiorURI', + 'urn:mace:dir:attribute-def:eduOrgWhitePagesURI': 'eduOrgWhitePagesURI', + 'urn:mace:dir:attribute-def:eduPersonAffiliation': 'eduPersonAffiliation', + 'urn:mace:dir:attribute-def:eduPersonEntitlement': 'eduPersonEntitlement', + 'urn:mace:dir:attribute-def:eduPersonNickname': 'eduPersonNickname', + 'urn:mace:dir:attribute-def:eduPersonOrgDN': 'eduPersonOrgDN', + 'urn:mace:dir:attribute-def:eduPersonOrgUnitDN': 'eduPersonOrgUnitDN', + 'urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation': 'eduPersonPrimaryAffiliation', + 'urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN': 'eduPersonPrimaryOrgUnitDN', + 'urn:mace:dir:attribute-def:eduPersonPrincipalName': 'eduPersonPrincipalName', + 'urn:mace:dir:attribute-def:eduPersonScopedAffiliation': 'eduPersonScopedAffiliation', + 'urn:mace:dir:attribute-def:eduPersonTargetedID': 'eduPersonTargetedID', + 'urn:mace:dir:attribute-def:email': 'email', + 'urn:mace:dir:attribute-def:emailAddress': 'emailAddress', + 'urn:mace:dir:attribute-def:employeeNumber': 'employeeNumber', + 'urn:mace:dir:attribute-def:employeeType': 'employeeType', + 'urn:mace:dir:attribute-def:enhancedSearchGuide': 'enhancedSearchGuide', + 'urn:mace:dir:attribute-def:facsimileTelephoneNumber': 'facsimileTelephoneNumber', + 'urn:mace:dir:attribute-def:favouriteDrink': 'favouriteDrink', + 'urn:mace:dir:attribute-def:fax': 'fax', + 'urn:mace:dir:attribute-def:federationFeideSchemaVersion': 'federationFeideSchemaVersion', + 'urn:mace:dir:attribute-def:friendlyCountryName': 'friendlyCountryName', + 'urn:mace:dir:attribute-def:generationQualifier': 'generationQualifier', + 'urn:mace:dir:attribute-def:givenName': 'givenName', + 'urn:mace:dir:attribute-def:gn': 'gn', + 'urn:mace:dir:attribute-def:homePhone': 'homePhone', + 'urn:mace:dir:attribute-def:homePostalAddress': 'homePostalAddress', + 'urn:mace:dir:attribute-def:homeTelephoneNumber': 'homeTelephoneNumber', + 'urn:mace:dir:attribute-def:host': 'host', + 'urn:mace:dir:attribute-def:houseIdentifier': 'houseIdentifier', + 'urn:mace:dir:attribute-def:info': 'info', + 'urn:mace:dir:attribute-def:initials': 'initials', + 'urn:mace:dir:attribute-def:internationaliSDNNumber': 'internationaliSDNNumber', + 'urn:mace:dir:attribute-def:janetMailbox': 'janetMailbox', + 'urn:mace:dir:attribute-def:jpegPhoto': 'jpegPhoto', + 'urn:mace:dir:attribute-def:knowledgeInformation': 'knowledgeInformation', + 'urn:mace:dir:attribute-def:l': 'l', + 'urn:mace:dir:attribute-def:labeledURI': 'labeledURI', + 'urn:mace:dir:attribute-def:localityName': 'localityName', + 'urn:mace:dir:attribute-def:mDRecord': 'mDRecord', + 'urn:mace:dir:attribute-def:mXRecord': 'mXRecord', + 'urn:mace:dir:attribute-def:mail': 'mail', + 'urn:mace:dir:attribute-def:mailPreferenceOption': 'mailPreferenceOption', + 'urn:mace:dir:attribute-def:manager': 'manager', + 'urn:mace:dir:attribute-def:member': 'member', + 'urn:mace:dir:attribute-def:mobile': 'mobile', + 'urn:mace:dir:attribute-def:mobileTelephoneNumber': 'mobileTelephoneNumber', + 'urn:mace:dir:attribute-def:nSRecord': 'nSRecord', + 'urn:mace:dir:attribute-def:name': 'name', + 'urn:mace:dir:attribute-def:norEduOrgAcronym': 'norEduOrgAcronym', + 'urn:mace:dir:attribute-def:norEduOrgNIN': 'norEduOrgNIN', + 'urn:mace:dir:attribute-def:norEduOrgSchemaVersion': 'norEduOrgSchemaVersion', + 'urn:mace:dir:attribute-def:norEduOrgUniqueIdentifier': 'norEduOrgUniqueIdentifier', + 'urn:mace:dir:attribute-def:norEduOrgUniqueNumber': 'norEduOrgUniqueNumber', + 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueIdentifier': 'norEduOrgUnitUniqueIdentifier', + 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueNumber': 'norEduOrgUnitUniqueNumber', + 'urn:mace:dir:attribute-def:norEduPersonBirthDate': 'norEduPersonBirthDate', + 'urn:mace:dir:attribute-def:norEduPersonLIN': 'norEduPersonLIN', + 'urn:mace:dir:attribute-def:norEduPersonNIN': 'norEduPersonNIN', + 'urn:mace:dir:attribute-def:o': 'o', + 'urn:mace:dir:attribute-def:objectClass': 'objectClass', + 'urn:mace:dir:attribute-def:organizationName': 'organizationName', + 'urn:mace:dir:attribute-def:organizationalStatus': 'organizationalStatus', + 'urn:mace:dir:attribute-def:organizationalUnitName': 'organizationalUnitName', + 'urn:mace:dir:attribute-def:otherMailbox': 'otherMailbox', + 'urn:mace:dir:attribute-def:ou': 'ou', + 'urn:mace:dir:attribute-def:owner': 'owner', + 'urn:mace:dir:attribute-def:pager': 'pager', + 'urn:mace:dir:attribute-def:pagerTelephoneNumber': 'pagerTelephoneNumber', + 'urn:mace:dir:attribute-def:personalSignature': 'personalSignature', + 'urn:mace:dir:attribute-def:personalTitle': 'personalTitle', + 'urn:mace:dir:attribute-def:photo': 'photo', + 'urn:mace:dir:attribute-def:physicalDeliveryOfficeName': 'physicalDeliveryOfficeName', + 'urn:mace:dir:attribute-def:pkcs9email': 'pkcs9email', + 'urn:mace:dir:attribute-def:postOfficeBox': 'postOfficeBox', + 'urn:mace:dir:attribute-def:postalAddress': 'postalAddress', + 'urn:mace:dir:attribute-def:postalCode': 'postalCode', + 'urn:mace:dir:attribute-def:preferredDeliveryMethod': 'preferredDeliveryMethod', + 'urn:mace:dir:attribute-def:preferredLanguage': 'preferredLanguage', + 'urn:mace:dir:attribute-def:presentationAddress': 'presentationAddress', + 'urn:mace:dir:attribute-def:protocolInformation': 'protocolInformation', + 'urn:mace:dir:attribute-def:pseudonym': 'pseudonym', + 'urn:mace:dir:attribute-def:registeredAddress': 'registeredAddress', + 'urn:mace:dir:attribute-def:rfc822Mailbox': 'rfc822Mailbox', + 'urn:mace:dir:attribute-def:roleOccupant': 'roleOccupant', + 'urn:mace:dir:attribute-def:roomNumber': 'roomNumber', + 'urn:mace:dir:attribute-def:sOARecord': 'sOARecord', + 'urn:mace:dir:attribute-def:searchGuide': 'searchGuide', + 'urn:mace:dir:attribute-def:secretary': 'secretary', + 'urn:mace:dir:attribute-def:seeAlso': 'seeAlso', + 'urn:mace:dir:attribute-def:serialNumber': 'serialNumber', + 'urn:mace:dir:attribute-def:singleLevelQuality': 'singleLevelQuality', + 'urn:mace:dir:attribute-def:sn': 'sn', + 'urn:mace:dir:attribute-def:st': 'st', + 'urn:mace:dir:attribute-def:stateOrProvinceName': 'stateOrProvinceName', + 'urn:mace:dir:attribute-def:street': 'street', + 'urn:mace:dir:attribute-def:streetAddress': 'streetAddress', + 'urn:mace:dir:attribute-def:subtreeMaximumQuality': 'subtreeMaximumQuality', + 'urn:mace:dir:attribute-def:subtreeMinimumQuality': 'subtreeMinimumQuality', + 'urn:mace:dir:attribute-def:supportedAlgorithms': 'supportedAlgorithms', + 'urn:mace:dir:attribute-def:supportedApplicationContext': 'supportedApplicationContext', + 'urn:mace:dir:attribute-def:surname': 'surname', + 'urn:mace:dir:attribute-def:telephoneNumber': 'telephoneNumber', + 'urn:mace:dir:attribute-def:teletexTerminalIdentifier': 'teletexTerminalIdentifier', + 'urn:mace:dir:attribute-def:telexNumber': 'telexNumber', + 'urn:mace:dir:attribute-def:textEncodedORAddress': 'textEncodedORAddress', + 'urn:mace:dir:attribute-def:title': 'title', + 'urn:mace:dir:attribute-def:uid': 'uid', + 'urn:mace:dir:attribute-def:uniqueIdentifier': 'uniqueIdentifier', + 'urn:mace:dir:attribute-def:uniqueMember': 'uniqueMember', + 'urn:mace:dir:attribute-def:userCertificate': 'userCertificate', + 'urn:mace:dir:attribute-def:userClass': 'userClass', + 'urn:mace:dir:attribute-def:userPKCS12': 'userPKCS12', + 'urn:mace:dir:attribute-def:userPassword': 'userPassword', + 'urn:mace:dir:attribute-def:userSMIMECertificate': 'userSMIMECertificate', + 'urn:mace:dir:attribute-def:userid': 'userid', + 'urn:mace:dir:attribute-def:x121Address': 'x121Address', + 'urn:mace:dir:attribute-def:x500UniqueIdentifier': 'x500UniqueIdentifier', + }, + "to": { + 'aRecord': 'urn:mace:dir:attribute-def:aRecord', + 'aliasedEntryName': 'urn:mace:dir:attribute-def:aliasedEntryName', + 'aliasedObjectName': 'urn:mace:dir:attribute-def:aliasedObjectName', + 'associatedDomain': 'urn:mace:dir:attribute-def:associatedDomain', + 'associatedName': 'urn:mace:dir:attribute-def:associatedName', + 'audio': 'urn:mace:dir:attribute-def:audio', + 'authorityRevocationList': 'urn:mace:dir:attribute-def:authorityRevocationList', + 'buildingName': 'urn:mace:dir:attribute-def:buildingName', + 'businessCategory': 'urn:mace:dir:attribute-def:businessCategory', + 'c': 'urn:mace:dir:attribute-def:c', + 'cACertificate': 'urn:mace:dir:attribute-def:cACertificate', + 'cNAMERecord': 'urn:mace:dir:attribute-def:cNAMERecord', + 'carLicense': 'urn:mace:dir:attribute-def:carLicense', + 'certificateRevocationList': 'urn:mace:dir:attribute-def:certificateRevocationList', + 'cn': 'urn:mace:dir:attribute-def:cn', + 'co': 'urn:mace:dir:attribute-def:co', + 'commonName': 'urn:mace:dir:attribute-def:commonName', + 'countryName': 'urn:mace:dir:attribute-def:countryName', + 'crossCertificatePair': 'urn:mace:dir:attribute-def:crossCertificatePair', + 'dITRedirect': 'urn:mace:dir:attribute-def:dITRedirect', + 'dSAQuality': 'urn:mace:dir:attribute-def:dSAQuality', + 'dc': 'urn:mace:dir:attribute-def:dc', + 'deltaRevocationList': 'urn:mace:dir:attribute-def:deltaRevocationList', + 'departmentNumber': 'urn:mace:dir:attribute-def:departmentNumber', + 'description': 'urn:mace:dir:attribute-def:description', + 'destinationIndicator': 'urn:mace:dir:attribute-def:destinationIndicator', + 'displayName': 'urn:mace:dir:attribute-def:displayName', + 'distinguishedName': 'urn:mace:dir:attribute-def:distinguishedName', + 'dmdName': 'urn:mace:dir:attribute-def:dmdName', + 'dnQualifier': 'urn:mace:dir:attribute-def:dnQualifier', + 'documentAuthor': 'urn:mace:dir:attribute-def:documentAuthor', + 'documentIdentifier': 'urn:mace:dir:attribute-def:documentIdentifier', + 'documentLocation': 'urn:mace:dir:attribute-def:documentLocation', + 'documentPublisher': 'urn:mace:dir:attribute-def:documentPublisher', + 'documentTitle': 'urn:mace:dir:attribute-def:documentTitle', + 'documentVersion': 'urn:mace:dir:attribute-def:documentVersion', + 'domainComponent': 'urn:mace:dir:attribute-def:domainComponent', + 'drink': 'urn:mace:dir:attribute-def:drink', + 'eduOrgHomePageURI': 'urn:mace:dir:attribute-def:eduOrgHomePageURI', + 'eduOrgIdentityAuthNPolicyURI': 'urn:mace:dir:attribute-def:eduOrgIdentityAuthNPolicyURI', + 'eduOrgLegalName': 'urn:mace:dir:attribute-def:eduOrgLegalName', + 'eduOrgSuperiorURI': 'urn:mace:dir:attribute-def:eduOrgSuperiorURI', + 'eduOrgWhitePagesURI': 'urn:mace:dir:attribute-def:eduOrgWhitePagesURI', + 'eduPersonAffiliation': 'urn:mace:dir:attribute-def:eduPersonAffiliation', + 'eduPersonEntitlement': 'urn:mace:dir:attribute-def:eduPersonEntitlement', + 'eduPersonNickname': 'urn:mace:dir:attribute-def:eduPersonNickname', + 'eduPersonOrgDN': 'urn:mace:dir:attribute-def:eduPersonOrgDN', + 'eduPersonOrgUnitDN': 'urn:mace:dir:attribute-def:eduPersonOrgUnitDN', + 'eduPersonPrimaryAffiliation': 'urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation', + 'eduPersonPrimaryOrgUnitDN': 'urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN', + 'eduPersonPrincipalName': 'urn:mace:dir:attribute-def:eduPersonPrincipalName', + 'eduPersonScopedAffiliation': 'urn:mace:dir:attribute-def:eduPersonScopedAffiliation', + 'eduPersonTargetedID': 'urn:mace:dir:attribute-def:eduPersonTargetedID', + 'email': 'urn:mace:dir:attribute-def:email', + 'emailAddress': 'urn:mace:dir:attribute-def:emailAddress', + 'employeeNumber': 'urn:mace:dir:attribute-def:employeeNumber', + 'employeeType': 'urn:mace:dir:attribute-def:employeeType', + 'enhancedSearchGuide': 'urn:mace:dir:attribute-def:enhancedSearchGuide', + 'facsimileTelephoneNumber': 'urn:mace:dir:attribute-def:facsimileTelephoneNumber', + 'favouriteDrink': 'urn:mace:dir:attribute-def:favouriteDrink', + 'fax': 'urn:mace:dir:attribute-def:fax', + 'federationFeideSchemaVersion': 'urn:mace:dir:attribute-def:federationFeideSchemaVersion', + 'friendlyCountryName': 'urn:mace:dir:attribute-def:friendlyCountryName', + 'generationQualifier': 'urn:mace:dir:attribute-def:generationQualifier', + 'givenName': 'urn:mace:dir:attribute-def:givenName', + 'gn': 'urn:mace:dir:attribute-def:gn', + 'homePhone': 'urn:mace:dir:attribute-def:homePhone', + 'homePostalAddress': 'urn:mace:dir:attribute-def:homePostalAddress', + 'homeTelephoneNumber': 'urn:mace:dir:attribute-def:homeTelephoneNumber', + 'host': 'urn:mace:dir:attribute-def:host', + 'houseIdentifier': 'urn:mace:dir:attribute-def:houseIdentifier', + 'info': 'urn:mace:dir:attribute-def:info', + 'initials': 'urn:mace:dir:attribute-def:initials', + 'internationaliSDNNumber': 'urn:mace:dir:attribute-def:internationaliSDNNumber', + 'janetMailbox': 'urn:mace:dir:attribute-def:janetMailbox', + 'jpegPhoto': 'urn:mace:dir:attribute-def:jpegPhoto', + 'knowledgeInformation': 'urn:mace:dir:attribute-def:knowledgeInformation', + 'l': 'urn:mace:dir:attribute-def:l', + 'labeledURI': 'urn:mace:dir:attribute-def:labeledURI', + 'localityName': 'urn:mace:dir:attribute-def:localityName', + 'mDRecord': 'urn:mace:dir:attribute-def:mDRecord', + 'mXRecord': 'urn:mace:dir:attribute-def:mXRecord', + 'mail': 'urn:mace:dir:attribute-def:mail', + 'mailPreferenceOption': 'urn:mace:dir:attribute-def:mailPreferenceOption', + 'manager': 'urn:mace:dir:attribute-def:manager', + 'member': 'urn:mace:dir:attribute-def:member', + 'mobile': 'urn:mace:dir:attribute-def:mobile', + 'mobileTelephoneNumber': 'urn:mace:dir:attribute-def:mobileTelephoneNumber', + 'nSRecord': 'urn:mace:dir:attribute-def:nSRecord', + 'name': 'urn:mace:dir:attribute-def:name', + 'norEduOrgAcronym': 'urn:mace:dir:attribute-def:norEduOrgAcronym', + 'norEduOrgNIN': 'urn:mace:dir:attribute-def:norEduOrgNIN', + 'norEduOrgSchemaVersion': 'urn:mace:dir:attribute-def:norEduOrgSchemaVersion', + 'norEduOrgUniqueIdentifier': 'urn:mace:dir:attribute-def:norEduOrgUniqueIdentifier', + 'norEduOrgUniqueNumber': 'urn:mace:dir:attribute-def:norEduOrgUniqueNumber', + 'norEduOrgUnitUniqueIdentifier': 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueIdentifier', + 'norEduOrgUnitUniqueNumber': 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueNumber', + 'norEduPersonBirthDate': 'urn:mace:dir:attribute-def:norEduPersonBirthDate', + 'norEduPersonLIN': 'urn:mace:dir:attribute-def:norEduPersonLIN', + 'norEduPersonNIN': 'urn:mace:dir:attribute-def:norEduPersonNIN', + 'o': 'urn:mace:dir:attribute-def:o', + 'objectClass': 'urn:mace:dir:attribute-def:objectClass', + 'organizationName': 'urn:mace:dir:attribute-def:organizationName', + 'organizationalStatus': 'urn:mace:dir:attribute-def:organizationalStatus', + 'organizationalUnitName': 'urn:mace:dir:attribute-def:organizationalUnitName', + 'otherMailbox': 'urn:mace:dir:attribute-def:otherMailbox', + 'ou': 'urn:mace:dir:attribute-def:ou', + 'owner': 'urn:mace:dir:attribute-def:owner', + 'pager': 'urn:mace:dir:attribute-def:pager', + 'pagerTelephoneNumber': 'urn:mace:dir:attribute-def:pagerTelephoneNumber', + 'personalSignature': 'urn:mace:dir:attribute-def:personalSignature', + 'personalTitle': 'urn:mace:dir:attribute-def:personalTitle', + 'photo': 'urn:mace:dir:attribute-def:photo', + 'physicalDeliveryOfficeName': 'urn:mace:dir:attribute-def:physicalDeliveryOfficeName', + 'pkcs9email': 'urn:mace:dir:attribute-def:pkcs9email', + 'postOfficeBox': 'urn:mace:dir:attribute-def:postOfficeBox', + 'postalAddress': 'urn:mace:dir:attribute-def:postalAddress', + 'postalCode': 'urn:mace:dir:attribute-def:postalCode', + 'preferredDeliveryMethod': 'urn:mace:dir:attribute-def:preferredDeliveryMethod', + 'preferredLanguage': 'urn:mace:dir:attribute-def:preferredLanguage', + 'presentationAddress': 'urn:mace:dir:attribute-def:presentationAddress', + 'protocolInformation': 'urn:mace:dir:attribute-def:protocolInformation', + 'pseudonym': 'urn:mace:dir:attribute-def:pseudonym', + 'registeredAddress': 'urn:mace:dir:attribute-def:registeredAddress', + 'rfc822Mailbox': 'urn:mace:dir:attribute-def:rfc822Mailbox', + 'roleOccupant': 'urn:mace:dir:attribute-def:roleOccupant', + 'roomNumber': 'urn:mace:dir:attribute-def:roomNumber', + 'sOARecord': 'urn:mace:dir:attribute-def:sOARecord', + 'searchGuide': 'urn:mace:dir:attribute-def:searchGuide', + 'secretary': 'urn:mace:dir:attribute-def:secretary', + 'seeAlso': 'urn:mace:dir:attribute-def:seeAlso', + 'serialNumber': 'urn:mace:dir:attribute-def:serialNumber', + 'singleLevelQuality': 'urn:mace:dir:attribute-def:singleLevelQuality', + 'sn': 'urn:mace:dir:attribute-def:sn', + 'st': 'urn:mace:dir:attribute-def:st', + 'stateOrProvinceName': 'urn:mace:dir:attribute-def:stateOrProvinceName', + 'street': 'urn:mace:dir:attribute-def:street', + 'streetAddress': 'urn:mace:dir:attribute-def:streetAddress', + 'subtreeMaximumQuality': 'urn:mace:dir:attribute-def:subtreeMaximumQuality', + 'subtreeMinimumQuality': 'urn:mace:dir:attribute-def:subtreeMinimumQuality', + 'supportedAlgorithms': 'urn:mace:dir:attribute-def:supportedAlgorithms', + 'supportedApplicationContext': 'urn:mace:dir:attribute-def:supportedApplicationContext', + 'surname': 'urn:mace:dir:attribute-def:surname', + 'telephoneNumber': 'urn:mace:dir:attribute-def:telephoneNumber', + 'teletexTerminalIdentifier': 'urn:mace:dir:attribute-def:teletexTerminalIdentifier', + 'telexNumber': 'urn:mace:dir:attribute-def:telexNumber', + 'textEncodedORAddress': 'urn:mace:dir:attribute-def:textEncodedORAddress', + 'title': 'urn:mace:dir:attribute-def:title', + 'uid': 'urn:mace:dir:attribute-def:uid', + 'uniqueIdentifier': 'urn:mace:dir:attribute-def:uniqueIdentifier', + 'uniqueMember': 'urn:mace:dir:attribute-def:uniqueMember', + 'userCertificate': 'urn:mace:dir:attribute-def:userCertificate', + 'userClass': 'urn:mace:dir:attribute-def:userClass', + 'userPKCS12': 'urn:mace:dir:attribute-def:userPKCS12', + 'userPassword': 'urn:mace:dir:attribute-def:userPassword', + 'userSMIMECertificate': 'urn:mace:dir:attribute-def:userSMIMECertificate', + 'userid': 'urn:mace:dir:attribute-def:userid', + 'x121Address': 'urn:mace:dir:attribute-def:x121Address', + 'x500UniqueIdentifier': 'urn:mace:dir:attribute-def:x500UniqueIdentifier', + } +} \ No newline at end of file diff --git a/example_sp/sp-repoze/attributemaps/saml_uri.py b/example_sp/pysaml2/sp-repoze/attributemaps/saml_uri.py similarity index 100% rename from example_sp/sp-repoze/attributemaps/saml_uri.py rename to example_sp/pysaml2/sp-repoze/attributemaps/saml_uri.py diff --git a/example_sp/pysaml2/sp-repoze/attributemaps/shibboleth_uri.py b/example_sp/pysaml2/sp-repoze/attributemaps/shibboleth_uri.py new file mode 100644 index 00000000..d26bf006 --- /dev/null +++ b/example_sp/pysaml2/sp-repoze/attributemaps/shibboleth_uri.py @@ -0,0 +1,190 @@ +EDUPERSON_OID = "urn:oid:1.3.6.1.4.1.5923.1.1.1." +X500ATTR = "urn:oid:2.5.4." +NOREDUPERSON_OID = "urn:oid:1.3.6.1.4.1.2428.90.1." +NETSCAPE_LDAP = "urn:oid:2.16.840.1.113730.3.1." +UCL_DIR_PILOT = "urn:oid:0.9.2342.19200300.100.1." +PKCS_9 = "urn:oid:1.2.840.113549.1.9." +UMICH = "urn:oid:1.3.6.1.4.1.250.1.57." + +MAP = { + "identifier": "urn:mace:shibboleth:1.0:attributeNamespace:uri", + "fro": { + EDUPERSON_OID+'2': 'eduPersonNickname', + EDUPERSON_OID+'9': 'eduPersonScopedAffiliation', + EDUPERSON_OID+'11': 'eduPersonAssurance', + EDUPERSON_OID+'10': 'eduPersonTargetedID', + EDUPERSON_OID+'4': 'eduPersonOrgUnitDN', + NOREDUPERSON_OID+'6': 'norEduOrgAcronym', + NOREDUPERSON_OID+'7': 'norEduOrgUniqueIdentifier', + NOREDUPERSON_OID+'4': 'norEduPersonLIN', + EDUPERSON_OID+'1': 'eduPersonAffiliation', + NOREDUPERSON_OID+'2': 'norEduOrgUnitUniqueNumber', + NETSCAPE_LDAP+'40': 'userSMIMECertificate', + NOREDUPERSON_OID+'1': 'norEduOrgUniqueNumber', + NETSCAPE_LDAP+'241': 'displayName', + UCL_DIR_PILOT+'37': 'associatedDomain', + EDUPERSON_OID+'6': 'eduPersonPrincipalName', + NOREDUPERSON_OID+'8': 'norEduOrgUnitUniqueIdentifier', + NOREDUPERSON_OID+'9': 'federationFeideSchemaVersion', + X500ATTR+'53': 'deltaRevocationList', + X500ATTR+'52': 'supportedAlgorithms', + X500ATTR+'51': 'houseIdentifier', + X500ATTR+'50': 'uniqueMember', + X500ATTR+'19': 'physicalDeliveryOfficeName', + X500ATTR+'18': 'postOfficeBox', + X500ATTR+'17': 'postalCode', + X500ATTR+'16': 'postalAddress', + X500ATTR+'15': 'businessCategory', + X500ATTR+'14': 'searchGuide', + EDUPERSON_OID+'5': 'eduPersonPrimaryAffiliation', + X500ATTR+'12': 'title', + X500ATTR+'11': 'ou', + X500ATTR+'10': 'o', + X500ATTR+'37': 'cACertificate', + X500ATTR+'36': 'userCertificate', + X500ATTR+'31': 'member', + X500ATTR+'30': 'supportedApplicationContext', + X500ATTR+'33': 'roleOccupant', + X500ATTR+'32': 'owner', + NETSCAPE_LDAP+'1': 'carLicense', + PKCS_9+'1': 'email', + NETSCAPE_LDAP+'3': 'employeeNumber', + NETSCAPE_LDAP+'2': 'departmentNumber', + X500ATTR+'39': 'certificateRevocationList', + X500ATTR+'38': 'authorityRevocationList', + NETSCAPE_LDAP+'216': 'userPKCS12', + EDUPERSON_OID+'8': 'eduPersonPrimaryOrgUnitDN', + X500ATTR+'9': 'street', + X500ATTR+'8': 'st', + NETSCAPE_LDAP+'39': 'preferredLanguage', + EDUPERSON_OID+'7': 'eduPersonEntitlement', + X500ATTR+'2': 'knowledgeInformation', + X500ATTR+'7': 'l', + X500ATTR+'6': 'c', + X500ATTR+'5': 'serialNumber', + X500ATTR+'4': 'sn', + UCL_DIR_PILOT+'60': 'jpegPhoto', + X500ATTR+'65': 'pseudonym', + NOREDUPERSON_OID+'5': 'norEduPersonNIN', + UCL_DIR_PILOT+'3': 'mail', + UCL_DIR_PILOT+'25': 'dc', + X500ATTR+'40': 'crossCertificatePair', + X500ATTR+'42': 'givenName', + X500ATTR+'43': 'initials', + X500ATTR+'44': 'generationQualifier', + X500ATTR+'45': 'x500UniqueIdentifier', + X500ATTR+'46': 'dnQualifier', + X500ATTR+'47': 'enhancedSearchGuide', + X500ATTR+'48': 'protocolInformation', + X500ATTR+'54': 'dmdName', + NETSCAPE_LDAP+'4': 'employeeType', + X500ATTR+'22': 'teletexTerminalIdentifier', + X500ATTR+'23': 'facsimileTelephoneNumber', + X500ATTR+'20': 'telephoneNumber', + X500ATTR+'21': 'telexNumber', + X500ATTR+'26': 'registeredAddress', + X500ATTR+'27': 'destinationIndicator', + X500ATTR+'24': 'x121Address', + X500ATTR+'25': 'internationaliSDNNumber', + X500ATTR+'28': 'preferredDeliveryMethod', + X500ATTR+'29': 'presentationAddress', + EDUPERSON_OID+'3': 'eduPersonOrgDN', + NOREDUPERSON_OID+'3': 'norEduPersonBirthDate', + }, + "to":{ + 'roleOccupant': X500ATTR+'33', + 'gn': X500ATTR+'42', + 'norEduPersonNIN': NOREDUPERSON_OID+'5', + 'title': X500ATTR+'12', + 'facsimileTelephoneNumber': X500ATTR+'23', + 'mail': UCL_DIR_PILOT+'3', + 'postOfficeBox': X500ATTR+'18', + 'fax': X500ATTR+'23', + 'telephoneNumber': X500ATTR+'20', + 'norEduPersonBirthDate': NOREDUPERSON_OID+'3', + 'rfc822Mailbox': UCL_DIR_PILOT+'3', + 'dc': UCL_DIR_PILOT+'25', + 'countryName': X500ATTR+'6', + 'emailAddress': PKCS_9+'1', + 'employeeNumber': NETSCAPE_LDAP+'3', + 'organizationName': X500ATTR+'10', + 'eduPersonAssurance': EDUPERSON_OID+'11', + 'norEduOrgAcronym': NOREDUPERSON_OID+'6', + 'registeredAddress': X500ATTR+'26', + 'physicalDeliveryOfficeName': X500ATTR+'19', + 'associatedDomain': UCL_DIR_PILOT+'37', + 'l': X500ATTR+'7', + 'stateOrProvinceName': X500ATTR+'8', + 'federationFeideSchemaVersion': NOREDUPERSON_OID+'9', + 'pkcs9email': PKCS_9+'1', + 'givenName': X500ATTR+'42', + 'x500UniqueIdentifier': X500ATTR+'45', + 'eduPersonNickname': EDUPERSON_OID+'2', + 'houseIdentifier': X500ATTR+'51', + 'street': X500ATTR+'9', + 'supportedAlgorithms': X500ATTR+'52', + 'preferredLanguage': NETSCAPE_LDAP+'39', + 'postalAddress': X500ATTR+'16', + 'email': PKCS_9+'1', + 'norEduOrgUnitUniqueIdentifier': NOREDUPERSON_OID+'8', + 'eduPersonPrimaryOrgUnitDN': EDUPERSON_OID+'8', + 'c': X500ATTR+'6', + 'teletexTerminalIdentifier': X500ATTR+'22', + 'o': X500ATTR+'10', + 'cACertificate': X500ATTR+'37', + 'telexNumber': X500ATTR+'21', + 'ou': X500ATTR+'11', + 'initials': X500ATTR+'43', + 'eduPersonOrgUnitDN': EDUPERSON_OID+'4', + 'deltaRevocationList': X500ATTR+'53', + 'norEduPersonLIN': NOREDUPERSON_OID+'4', + 'supportedApplicationContext': X500ATTR+'30', + 'eduPersonEntitlement': EDUPERSON_OID+'7', + 'generationQualifier': X500ATTR+'44', + 'eduPersonAffiliation': EDUPERSON_OID+'1', + 'eduPersonPrincipalName': EDUPERSON_OID+'6', + 'localityName': X500ATTR+'7', + 'owner': X500ATTR+'32', + 'norEduOrgUnitUniqueNumber': NOREDUPERSON_OID+'2', + 'searchGuide': X500ATTR+'14', + 'certificateRevocationList': X500ATTR+'39', + 'organizationalUnitName': X500ATTR+'11', + 'userCertificate': X500ATTR+'36', + 'preferredDeliveryMethod': X500ATTR+'28', + 'internationaliSDNNumber': X500ATTR+'25', + 'uniqueMember': X500ATTR+'50', + 'departmentNumber': NETSCAPE_LDAP+'2', + 'enhancedSearchGuide': X500ATTR+'47', + 'userPKCS12': NETSCAPE_LDAP+'216', + 'eduPersonTargetedID': EDUPERSON_OID+'10', + 'norEduOrgUniqueNumber': NOREDUPERSON_OID+'1', + 'x121Address': X500ATTR+'24', + 'destinationIndicator': X500ATTR+'27', + 'eduPersonPrimaryAffiliation': EDUPERSON_OID+'5', + 'surname': X500ATTR+'4', + 'jpegPhoto': UCL_DIR_PILOT+'60', + 'eduPersonScopedAffiliation': EDUPERSON_OID+'9', + 'protocolInformation': X500ATTR+'48', + 'knowledgeInformation': X500ATTR+'2', + 'employeeType': NETSCAPE_LDAP+'4', + 'userSMIMECertificate': NETSCAPE_LDAP+'40', + 'member': X500ATTR+'31', + 'streetAddress': X500ATTR+'9', + 'dmdName': X500ATTR+'54', + 'postalCode': X500ATTR+'17', + 'pseudonym': X500ATTR+'65', + 'dnQualifier': X500ATTR+'46', + 'crossCertificatePair': X500ATTR+'40', + 'eduPersonOrgDN': EDUPERSON_OID+'3', + 'authorityRevocationList': X500ATTR+'38', + 'displayName': NETSCAPE_LDAP+'241', + 'businessCategory': X500ATTR+'15', + 'serialNumber': X500ATTR+'5', + 'norEduOrgUniqueIdentifier': NOREDUPERSON_OID+'7', + 'st': X500ATTR+'8', + 'carLicense': NETSCAPE_LDAP+'1', + 'presentationAddress': X500ATTR+'29', + 'sn': X500ATTR+'4', + 'domainComponent': UCL_DIR_PILOT+'25', + } +} \ No newline at end of file diff --git a/example_sp/sp-repoze/sp.py b/example_sp/pysaml2/sp-repoze/sp.py similarity index 100% rename from example_sp/sp-repoze/sp.py rename to example_sp/pysaml2/sp-repoze/sp.py diff --git a/example_sp/sp-repoze/sp_conf.py b/example_sp/pysaml2/sp-repoze/sp_conf.py similarity index 100% rename from example_sp/sp-repoze/sp_conf.py rename to example_sp/pysaml2/sp-repoze/sp_conf.py diff --git a/example_sp/sp-repoze/sp_conf.py.example b/example_sp/pysaml2/sp-repoze/sp_conf.py.example similarity index 100% rename from example_sp/sp-repoze/sp_conf.py.example rename to example_sp/pysaml2/sp-repoze/sp_conf.py.example diff --git a/example_sp/sp-repoze/who.ini b/example_sp/pysaml2/sp-repoze/who.ini similarity index 100% rename from example_sp/sp-repoze/who.ini rename to example_sp/pysaml2/sp-repoze/who.ini diff --git a/example_sp/pysaml2/sp-wsgi/metadata.xml b/example_sp/pysaml2/sp-wsgi/metadata.xml new file mode 100644 index 00000000..e69de29b diff --git a/example_sp/sp-wsgi/service_conf.py b/example_sp/pysaml2/sp-wsgi/service_conf.py similarity index 100% rename from example_sp/sp-wsgi/service_conf.py rename to example_sp/pysaml2/sp-wsgi/service_conf.py diff --git a/example_sp/sp-wsgi/service_conf.py.example b/example_sp/pysaml2/sp-wsgi/service_conf.py.example similarity index 100% rename from example_sp/sp-wsgi/service_conf.py.example rename to example_sp/pysaml2/sp-wsgi/service_conf.py.example diff --git a/example_sp/sp-wsgi/sp.py b/example_sp/pysaml2/sp-wsgi/sp.py similarity index 100% rename from example_sp/sp-wsgi/sp.py rename to example_sp/pysaml2/sp-wsgi/sp.py diff --git a/example_sp/pysaml2/sp-wsgi/sp.xml b/example_sp/pysaml2/sp-wsgi/sp.xml new file mode 100644 index 00000000..e69de29b diff --git a/example_sp/sp-wsgi/sp_conf.py b/example_sp/pysaml2/sp-wsgi/sp_conf.py similarity index 100% rename from example_sp/sp-wsgi/sp_conf.py rename to example_sp/pysaml2/sp-wsgi/sp_conf.py diff --git a/example_sp/sp-wsgi/sp_conf.py.example b/example_sp/pysaml2/sp-wsgi/sp_conf.py.example similarity index 100% rename from example_sp/sp-wsgi/sp_conf.py.example rename to example_sp/pysaml2/sp-wsgi/sp_conf.py.example diff --git a/example_sp/start.sh b/example_sp/pysaml2/start.sh similarity index 100% rename from example_sp/start.sh rename to example_sp/pysaml2/start.sh diff --git a/requirements.txt b/requirements.txt index 6456a12e..f3d487e1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -28,7 +28,7 @@ pycparser==2.19 pycryptodomex==3.9.7 pyjwkest==1.4.2 pymongo==3.10.1 -pyop==3.0.1 +pyop>=3.2.0 pyOpenSSL==19.1.0 pyparsing==2.4.6 pystache==0.5.4