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 @@
+yqmXnkQV7s7mz2bcIb4fLiTM/wwLaRmTTjJHW6lkafc=BLLJrRnwcYU2dobAKG9DfzyDlHkI7uLH9agT9TOkgwCXqOrhDeN/lFRrqy4gt7oii5uGlnuTmqGUW5hNGUkb6pzETu3WbTVTl8UjvdmsQcNzYNtZPhr00dawgb52j2pPt8KsJKgA4iv8Fl8ALQwVKBlJ2w20d9iWVMJLh/7CHjgzA1TfuGsaKe9vEzqXKDKRDlK614lCAGu/v0kektWtVGECT038dnAuN+KbWqCkojc3nrnAjCm3/pPQ3POzlBdKhRpN55SE29eSd49gm4rDsp9CkRDYYx3IG44ihmBNVONg8zZSp3Jc24TQ/dmS1jDK+LyJvxh6YHhs0I6ejQ6VlA==MIIEGDCCAwCgAwIBAgIJAOrYj9oLEJCwMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJdGFseTENMAsGA1UEBxMEUm9tZTENMAsGA1UEChMEQWdJRDESMBAGA1UECxMJQWdJRCBURVNUMRQwEgYDVQQDEwthZ2lkLmdvdi5pdDAeFw0xOTA0MTExMDAyMDhaFw0yNTAzMDgxMDAyMDhaMGUxCzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJdGFseTENMAsGA1UEBxMEUm9tZTENMAsGA1UEChMEQWdJRDESMBAGA1UECxMJQWdJRCBURVNUMRQwEgYDVQQDEwthZ2lkLmdvdi5pdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK8kJVo+ugRrbbv9xhXCuVrqi4B7/MQzQc62ocwlFFujJNd4m1mXkUHFbgvwhRkQqo2DAmFeHiwCkJT3K1eeXIFhNFFroEzGPzONyekLpjNvmYIs1CFvirGOj0bkEiGaKEs+/umzGjxIhy5JQlqXE96y1+Izp2QhJimDK0/KNij8I1bzxseP0Ygc4SFveKS+7QO+PrLzWklEWGMs4DM5Zc3VRK7g4LWPWZhKdImC1rnS+/lEmHSvHisdVp/DJtbSrZwSYTRvTTz5IZDSq4kAzrDfpj16h7b3t3nFGc8UoY2Ro4tRZ3ahJ2r3b79yK6C5phY7CAANuW3gDdhVjiBNYs0CAwEAAaOByjCBxzAdBgNVHQ4EFgQU3/7kV2tbdFtphbSA4LH7+w8SkcwwgZcGA1UdIwSBjzCBjIAU3/7kV2tbdFtphbSA4LH7+w8SkcyhaaRnMGUxCzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJdGFseTENMAsGA1UEBxMEUm9tZTENMAsGA1UEChMEQWdJRDESMBAGA1UECxMJQWdJRCBURVNUMRQwEgYDVQQDEwthZ2lkLmdvdi5pdIIJAOrYj9oLEJCwMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJNFqXg/V3aimJKUmUaqmQEEoSc3qvXFITvT5f5bKw9yk/NVhR6wndL+z/24h1OdRqs76blgH8k116qWNkkDtt0AlSjQOx5qvFYh1UviOjNdRI4WkYONSw+vuavcx+fB6O5JDHNmMhMySKTnmRqTkyhjrch7zaFIWUSV7hsBuxpqmrWDoLWdXbV3eFH3mINA5AoIY/m0bZtzZ7YNgiFWzxQgekpxd0vcTseMnCcXnsAlctdir0FoCZztxMuZjlBjwLTtM6Ry3/48LMM8Z+lw7NMciKLLTGQyU8XmKKSSOh0dGh5Lrlt5GxIIJkH81C0YimWebz8464QPL3RbLnTKg+c=MIIEGDCCAwCgAwIBAgIJAOrYj9oLEJCwMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJdGFseTENMAsGA1UEBxMEUm9tZTENMAsGA1UEChMEQWdJRDESMBAGA1UECxMJQWdJRCBURVNUMRQwEgYDVQQDEwthZ2lkLmdvdi5pdDAeFw0xOTA0MTExMDAyMDhaFw0yNTAzMDgxMDAyMDhaMGUxCzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJdGFseTENMAsGA1UEBxMEUm9tZTENMAsGA1UEChMEQWdJRDESMBAGA1UECxMJQWdJRCBURVNUMRQwEgYDVQQDEwthZ2lkLmdvdi5pdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK8kJVo+ugRrbbv9xhXCuVrqi4B7/MQzQc62ocwlFFujJNd4m1mXkUHFbgvwhRkQqo2DAmFeHiwCkJT3K1eeXIFhNFFroEzGPzONyekLpjNvmYIs1CFvirGOj0bkEiGaKEs+/umzGjxIhy5JQlqXE96y1+Izp2QhJimDK0/KNij8I1bzxseP0Ygc4SFveKS+7QO+PrLzWklEWGMs4DM5Zc3VRK7g4LWPWZhKdImC1rnS+/lEmHSvHisdVp/DJtbSrZwSYTRvTTz5IZDSq4kAzrDfpj16h7b3t3nFGc8UoY2Ro4tRZ3ahJ2r3b79yK6C5phY7CAANuW3gDdhVjiBNYs0CAwEAAaOByjCBxzAdBgNVHQ4EFgQU3/7kV2tbdFtphbSA4LH7+w8SkcwwgZcGA1UdIwSBjzCBjIAU3/7kV2tbdFtphbSA4LH7+w8SkcyhaaRnMGUxCzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJdGFseTENMAsGA1UEBxMEUm9tZTENMAsGA1UEChMEQWdJRDESMBAGA1UECxMJQWdJRCBURVNUMRQwEgYDVQQDEwthZ2lkLmdvdi5pdIIJAOrYj9oLEJCwMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJNFqXg/V3aimJKUmUaqmQEEoSc3qvXFITvT5f5bKw9yk/NVhR6wndL+z/24h1OdRqs76blgH8k116qWNkkDtt0AlSjQOx5qvFYh1UviOjNdRI4WkYONSw+vuavcx+fB6O5JDHNmMhMySKTnmRqTkyhjrch7zaFIWUSV7hsBuxpqmrWDoLWdXbV3eFH3mINA5AoIY/m0bZtzZ7YNgiFWzxQgekpxd0vcTseMnCcXnsAlctdir0FoCZztxMuZjlBjwLTtM6Ry3/48LMM8Z+lw7NMciKLLTGQyU8XmKKSSOh0dGh5Lrlt5GxIIJkH81C0YimWebz8464QPL3RbLnTKg+c=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