Browse Source

[django] Upgraded djangosaml2 to 1.9.3

We earlier had djangosaml2-0.18 in ext-py3 with three commits on
top of it.
1. Fix SAML TemplateDoesNotExist (fa1b914)
2. SAML login issues with csp enabled (864283c)
3. Fix for removal of django.conf.urls.url in Django4 (e22fab5)

Commit 2 and 3 are not needed as the fixes are already there in the
newer version.

I did not run into any issues yet regarding `TemplateDoesNotExist`.
So, I am assuming that the fix might no longer be needed on our
upgraded django4+djangosaml2v1.9.3 combination.
But, if we see the `TemplateDoesNotExist` error ever, then we can
consider bringing djangosaml2 again in our repo and applying this fix.
Amit Srivastava 8 months ago
parent
commit
285de32986
50 changed files with 32 additions and 4539 deletions
  1. 1 1
      desktop/core/base_requirements.txt
  2. 0 256
      desktop/core/ext-py3/djangosaml2-0.18.0/CHANGES
  3. 0 202
      desktop/core/ext-py3/djangosaml2-0.18.0/COPYING
  4. 0 6
      desktop/core/ext-py3/djangosaml2-0.18.0/MANIFEST.in
  5. 0 584
      desktop/core/ext-py3/djangosaml2-0.18.0/PKG-INFO
  6. 0 545
      desktop/core/ext-py3/djangosaml2-0.18.0/README.rst
  7. 0 0
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/__init__.py
  8. 0 22
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/acs_failures.py
  9. 0 278
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/backends.py
  10. 0 89
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/cache.py
  11. 0 70
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/conf.py
  12. 0 2
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/exceptions.py
  13. 0 1
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/models.py
  14. 0 24
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/overrides.py
  15. 0 20
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/signals.py
  16. 0 16
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/auth_error.html
  17. 0 18
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/echo_attributes.html
  18. 0 15
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/example_post_binding_form.html
  19. 0 13
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/login_error.html
  20. 0 17
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/logout_error.html
  21. 0 16
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/wayf.html
  22. 0 0
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templatetags/__init__.py
  23. 0 45
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templatetags/idplist.py
  24. 0 567
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/__init__.py
  25. 0 243
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/attribute-maps/saml_uri.py
  26. 0 103
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/auth_response.py
  27. 0 104
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/conf.py
  28. 0 17
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/idpcert.csr
  29. 0 27
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/idpcert.key
  30. 0 20
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/idpcert.pem
  31. 0 17
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/mycert.csr
  32. 0 27
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/mycert.key
  33. 0 20
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/mycert.pem
  34. 0 123
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/remote_metadata.xml
  35. 0 33
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/remote_metadata_one_idp.xml
  36. 0 93
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/remote_metadata_three_idps.xml
  37. 0 42
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/sp_metadata.xml
  38. 0 16
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/spcert.csr
  39. 0 27
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/spcert.key
  40. 0 19
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/spcert.pem
  41. 0 31
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/urls.py
  42. 0 27
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/urls.py
  43. 0 90
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/utils.py
  44. 0 536
      desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/views.py
  45. 0 7
      desktop/core/ext-py3/djangosaml2-0.18.0/setup.cfg
  46. 0 80
      desktop/core/ext-py3/djangosaml2-0.18.0/setup.py
  47. 1 1
      desktop/core/generate_requirements.py
  48. 2 2
      desktop/libs/libsaml/src/libsaml/backend.py
  49. 7 7
      desktop/libs/libsaml/src/libsaml/urls.py
  50. 21 20
      desktop/libs/libsaml/src/libsaml/views.py

+ 1 - 1
desktop/core/base_requirements.txt

@@ -26,6 +26,7 @@ django-webpack-loader==1.0.0
 djangomako==1.3.2
 djangorestframework-simplejwt==5.2.1
 djangorestframework==3.14.0
+djangosaml2==1.9.3
 future==0.18.3
 gcs-oauth2-boto-plugin==3.0
 greenlet==3.1.1
@@ -72,7 +73,6 @@ psutil==5.8.0
 drf-spectacular[sidecar]==0.27.2
 -e file://${ROOT}/desktop/core/ext-py3/boto-2.49.0
 -e file://${ROOT}/desktop/core/ext-py3/django-axes-5.13.0
--e file://${ROOT}/desktop/core/ext-py3/djangosaml2-0.18.0
 -e file://${ROOT}/desktop/core/ext-py3/pysaml2-7.3.1
 -e file://${ROOT}/desktop/core/ext-py3/python-sasl-0.3.1
 -e file://${ROOT}/desktop/core/ext-py3/django-babel

+ 0 - 256
desktop/core/ext-py3/djangosaml2-0.18.0/CHANGES

@@ -1,256 +0,0 @@
-Changes
-=======
-0.18.0 (2020-02-14)
-----------
-- Django 3.0 support. Thanks to OskarPersson
-- forceauthn and allowcreate support. Thanks to peppelinux
-- Dropped support for Python 3.4
-- Also thanks to WebSpider, mhindery, DylannCordel, habi3000 for various fixes and improvements
-
-Thanks to plumdog
-
-0.17.2 (2018-08-29)
-----------
-- Upgraded pysaml2 dependency to version 4.6.0 which fixes security issue.
-
-Thanks to plumdog
-
-0.17.1 (2018-07-16)
-----------
-- A 403 (permission denied) is now raised if a SAMLResponse is replayed, instead of 500.
-- Dropped support for Python 3.3
-- Upgraded pysaml2 dependency to version 4.5.0
-
-Thanks to francoisfreitag, mhindery, vkurup, peppelinux
-
-0.16.11 (2017-12-25)
-----------
-- Dropped compatibility for Python < 2.7 and Django < 1.8.
-- Added a clean_attributes hook allowing backends to restructure attributes extracted from SAML response.
-- Log when fields are missing in a SAML response.
-- Log when attribute_mapping maps to nonexistent User fields.
-- Multiple compatibility fixes and other minor improvements and code cleanups
-
-Thanks to francoisfreitag, mhindery, charn, jdufresne
-
-0.16.10 (2017-10-02)
--------------------
-- Bugfixes and internal refactorings.
-- Added support for custom USERNAME_FIELD on custom User models. Many thanks to francoisfreitag.
-
-0.16.9 (2017-09-19)
--------------------
-- Bugfixes and minor improvements. Thanks to goetzk and AmbientLighter.
-- Added option SAML_LOGOUT_REQUEST_PREFERRED_BINDING
-- Added Django 1.11 to tox.
-
-0.16.4 (2017-09-11)
--------------------
-- Added support for SHA-256 signing. Thanks to WebSpider.
-- Bugfixes. Thanks to justinsg and charn.
-- Error handling made more extensible. This will be further improved in next versions.
-
-0.16.1 (2017-07-15)
--------------------
-- Bugfixes. Thanks to canni, AmbientLighter, cranti and logston.
-- request is now passed to authentication backend (introduced in Django 1.11). Thanks to terite.
-
-0.16.0 (2017-04-14)
--------------------
-- Upgrade pysaml2 dependency to version 4.4.0 which fixes some serialization issues. Thanks to nakato for the report.
-- Added support for HTTP Redirect binding with signed authentication requests. Many thanks to liquidpele for this feature and other related refactorings.
-- The custom permission_denied.html template was removed in favor of standard PermissionDenied exception. Thanks to mhindery.
-
-0.15.0 (2016-12-18)
--------------------
-- Python 3.5 support. Thanks to timheap.
-- Added support for callable user attributes. Thanks to andy-miracl and joetsoi.
-- Security improvement: "next" URL is now checked. thanks to flupzor.
-- Improved testability. Thanks to flupzor.
-- Other bugfixes and minor improvements. Thanks to jamaalscarlett, ws0w, jaywink and liquidpele.
-
-0.14.5 (2016-09-19)
--------------------
-- Django 1.10 support. Thanks to inducer.
-- Various fixes and minor improvements. Thanks to ajsmilutin, ganiserb, inducer, grunichev, liquidpele and darbula
-
-0.14.4 (2016-03-29)
--------------------
-- Fix compatibility issue with pysaml2-4.0.3+. Thanks to jimr and astoltz.
-- Fix Django 1.9 compatibility issue in templates. Thanks to nikoskal.
-
-0.14.3 (2016-03-18)
--------------------
-- Upgraded to pysaml2-4.0.5.
-- Added 'ACS_DEFAULT_REDIRECT_URL' setting for default redirection after successful authentication. Thanks to ganiserb.
-
-0.14.2 (2016-03-11)
--------------------
-- Released under the original 'djangosaml2' package name; abandoning the djangosaml2-knaperek fork.
-
-0.14.1 (2016-03-09)
--------------------
-- Upgraded to pysaml2-4.0.4.
-
-0.14.0 (2016-01-28)
--------------------
-- Upgrade to pysaml2-4.0.2. Thanks to kviktor
-- Django 1.9 support. Thanks to Jordi Gutiérrez Hermoso
-
-0.13.2 (2015-06-24)
--------------------
-- Improved usage of standard Python logging.
-
-0.13.1 (2015-06-05)
--------------------
-- Added support for djangosaml2 specific user model defined by SAML_USER_MODEL setting
-
-0.13.0 (2015-02-12)
--------------------
-- Django 1.7 support. Thanks to Kamei Toshimitsu
-
-0.12.0 (2014-11-18)
--------------------
-- Pysaml2 2.2.0 support. Thanks to Erick Tryzelaar
-
-0.11.0 (2014-06-15)
--------------------
-- Django 1.5 custom user model support. Thanks to Jos van Velzen
-- Django 1.5 compatibility url template tag. Thanks to bula
-- Support Django 1.5 and 1.6. Thanks to David Evans and Justin Quick
-
-0.10.0 (2013-05-05)
--------------------
-- Check that RelayState is not empty before redirecting into a loop. Thanks
-  to Sam Bull for reporting this issue.
-- In the global logout process, when the session is lost, report an error
-  message to the user and perform a local logout.
-
-0.9.2 (2013-04-19)
-------------------
-- Upgrade to pysaml2-0.4.3.
-
-0.9.1 (2013-01-29)
-------------------
-- Add a method to the authentication backend so it is possible
-  to customize the authorization based on SAML attributes.
-
-0.9.0 (2012-10-30)
-------------------
-- Add a signal for modifying the user just before saving it on
-  the update_user method of the authentication backend.
-
-0.8.1 (2012-10-29)
-------------------
-- Trim the SAML attributes before setting them to the Django objects
-  if they are too long. This fixes a crash with MySQL.
-
-0.8.0 (2012-10-25)
-------------------
-- Allow to use different attributes besides 'username' to look for
-  existing users.
-
-0.7.0 (2012-10-19)
-------------------
-- Add a setting to decide if the user should be redirected to the
-  next view or shown an authorization error when the user tries to
-  login twice.
-
-0.6.1 (2012-09-03)
-------------------
-- Remove Django from our dependencies
-- Restore support for Django 1.3
-
-0.6.0 (2012-08-29)
-------------------
-- Add tox support configured to run the tests with Python 2.6 and 2.7
-- Fix some dependencies and sdist generation. Lorenzo Gil
-- Allow defining a logout redirect url in the settings. Lorenzo Gil
-- Add some logging calls to improve debugging. Lorenzo Gil
-- Add support for custom conf loading function. Sam Bull.
-- Make the tests more robust and easier to run when djangosaml2 is
-  included in a Django project. Sam Bull.
-- Make sure the profile is not None before saving it. Bug reported by
-  Leif Johansson
-
-0.5.0 (2012-05-22)
-------------------
-- Allow defining custom config loaders. They can be dynamic depending on
-  the request.
-- Do not automatically add the authentication backend. This way
-  we allow other people to add their own backends.
-- Support for additional attributes other than the ones that get mapped
-  into the User model. Those attributes get stored in the UserProfile model.
-
-0.4.2 (2012-03-23)
-------------------
-- Fix a crash in the idplist templatetag about using an old pysaml2 function
-- Added a test for the previous crash
-
-0.4.1 (2012-03-19)
-------------------
-- Upgrade pysaml2 dependency to version 0.4.1
-
-0.4.0 (2012-03-18)
-------------------
-- Upgrade pysaml2 dependency to version 0.4.0 (update our tests as a result
-  of this)
-- Add logging calls to make debugging easier
-- Use the Django configured logger in pysaml2
-
-0.3.3 (2012-02-14)
-------------------
-- Freeze the version of pysaml2 since we are not (yet!) compatible with
-  version 0.4.0
-
-0.3.2 (2011-12-13)
-------------------
-- Avoid a crash when reading the SAML attribute that maps to the Django
-  username
-
-0.3.1 (2011-12-01)
-------------------
-- Load the config in the render method of the idplist templatetag to
-  make it more flexible and reentrant.
-
-0.3.0 (2011-11-30)
-------------------
-- Templatetag to get the list of available idps.
-- Allow to map the same SAML attribute into several Django field.
-
-0.2.4 (2011-11-29)
-------------------
-- Fix restructured text bugs that made pypi page looks bad.
-
-0.2.3 (2011-06-14)
-------------------
-- Set a unusable password when the user is created for the first time
-
-0.2.2 (2011-06-07)
-------------------
-- Prevent infinite loop when going to the /saml2/login/ endpoint and the user
-  is already logged in and the settings.LOGIN_REDIRECT_URL is (badly) pointing
-  to /saml2/login.
-
-0.2.1 (2011-05-09)
-------------------
-- If no next parameter is supplied to the login view, use the
-  settings.LOGIN_REDIRECT_URL as default
-
-0.2.0 (2011-04-26)
-------------------
-- Python 2.4 compatible if the elementtree library is installed
-- Allow post processing after the authentication phase by using
-  Django signals.
-
-0.1.1 (2011-04-18)
-------------------
-- Simple view to echo SAML attributes
-- Improve documentation
-- Change default behaviour when a new user is created. Now their attributes
-  are filled this first time
-- Allow to set a next page after the logout
-
-0.1.0 (2011-03-16)
-------------------
-- Emancipation from the pysaml package

+ 0 - 202
desktop/core/ext-py3/djangosaml2-0.18.0/COPYING

@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.

+ 0 - 6
desktop/core/ext-py3/djangosaml2-0.18.0/MANIFEST.in

@@ -1,6 +0,0 @@
-include README
-include CHANGES
-include COPYING
-global-include *.html *.csr *.key *.pem *.xml
-include djangosaml2/tests/attribute-maps/*.py
-global-exclude *.pyc

+ 0 - 584
desktop/core/ext-py3/djangosaml2-0.18.0/PKG-INFO

@@ -1,584 +0,0 @@
-Metadata-Version: 2.1
-Name: djangosaml2
-Version: 0.18.0
-Summary: pysaml2 integration for Django
-Home-page: https://github.com/knaperek/djangosaml2
-Author: Yaco Sistemas and independent contributors
-Author-email: lgs@yaco.es
-Maintainer: Jozef Knaperek
-License: Apache 2.0
-Download-URL: https://pypi.org/project/djangosaml2/
-Description: ===========
-        djangosaml2
-        ===========
-        
-        .. image:: https://travis-ci.org/knaperek/djangosaml2.svg?branch=master
-            :target: https://travis-ci.org/knaperek/djangosaml2
-            :align: left
-        
-        
-        djangosaml2 is a Django application that integrates the PySAML2 library
-        into your project. This mean that you can protect your Django based project
-        with a service provider based on PySAML. This way it will talk SAML2 with
-        your Identity Provider allowing you to use this authentication mechanism.
-        This document will guide you through a few simple steps to accomplish
-        such goal.
-        
-        .. contents::
-        
-        Installation
-        ============
-        
-        PySAML2 uses xmlsec1_ binary to sign SAML assertions so you need to install
-        it either through your operating system package or by compiling the source
-        code. It doesn't matter where the final executable is installed because
-        you will need to set the full path to it in the configuration stage.
-        
-        .. _xmlsec1: http://www.aleksey.com/xmlsec/
-        
-        Now you can install the djangosaml2 package using easy_install or pip. This
-        will also install PySAML2 and its dependencies automatically.
-        
-        
-        Configuration
-        =============
-        
-        There are three things you need to setup to make djangosaml2 work in your
-        Django project:
-        
-        1. **settings.py** as you may already know, it is the main Django
-           configuration file.
-        2. **urls.py** is the file where you will include djangosaml2 urls.
-        3. **pysaml2** specific files such as an attribute map directory and a
-           certificate.
-        
-        
-        Changes in the settings.py file
-        -------------------------------
-        The first thing you need to do is add ``djangosaml2`` to the list of
-        installed apps::
-        
-          INSTALLED_APPS = (
-              'django.contrib.auth',
-              'django.contrib.contenttypes',
-              'django.contrib.sessions',
-              'django.contrib.sites',
-              'django.contrib.messages',
-              'django.contrib.admin',
-              'djangosaml2',  # new application
-          )
-        
-        Actually this is not really required since djangosaml2 does not include
-        any data model. The only reason we include it is to be able to run
-        djangosaml2 test suite from our project, something you should always
-        do to make sure it is compatible with your Django version and environment.
-        
-        .. note::
-        
-          When you finish the configuration you can run the djangosaml2 test suite as
-          you run any other Django application test suite. Just type ``python manage.py
-          test djangosaml2``.
-        
-          Python 2 users need to ``pip install djangosaml2[test]`` in order to run the
-          tests.
-        
-        Then you have to add the ``djangosaml2.backends.Saml2Backend``
-        authentication backend to the list of authentications backends.
-        By default only the ModelBackend included in Django is configured.
-        A typical configuration would look like this::
-        
-          AUTHENTICATION_BACKENDS = (
-              'django.contrib.auth.backends.ModelBackend',
-              'djangosaml2.backends.Saml2Backend',
-          )
-        
-        .. note::
-        
-          Before djangosaml2 0.5.0 this authentication backend was
-          automatically added by djangosaml2. This turned out to be
-          a bad idea since some applications want to use their own
-          custom policies for authorization and the authentication
-          backend is a good place to define that. Starting from
-          djangosaml2 0.5.0 it is now possible to define such
-          backends.
-        
-        Finally we have to tell Django what the new login url we want to use is::
-        
-          LOGIN_URL = '/saml2/login/'
-          SESSION_EXPIRE_AT_BROWSER_CLOSE = True
-        
-        Here we are telling Django that any view that requires an authenticated
-        user should redirect the user browser to that url if the user has not
-        been authenticated before. We are also telling that when the user closes
-        his browser, the session should be terminated. This is useful in SAML2
-        federations where the logout protocol is not always available.
-        
-        .. note::
-        
-          The login url starts with ``/saml2/`` as an example but you can change that
-          if you want. Check the section about changes in the ``urls.py``
-          file for more information.
-        
-        If you want to allow several authentication mechanisms in your project
-        you should set the LOGIN_URL option to another view and put a link in such
-        view to the ``/saml2/login/`` view.
-        
-        Preferred Logout binding
-        ------------------------
-        Use the following setting to choose your preferred binding for SP initiated logout requests::
-        
-          SAML_LOGOUT_REQUEST_PREFERRED_BINDING
-        
-        For example::
-        
-          import saml2
-          SAML_LOGOUT_REQUEST_PREFERRED_BINDING = saml2.BINDING_HTTP_POST
-        
-        Changes in the urls.py file
-        ---------------------------
-        
-        The next thing you need to do is to include ``djangosaml2.urls`` module in your
-        main ``urls.py`` module::
-        
-          urlpatterns = patterns(
-              '',
-              #  lots of url definitions here
-        
-              (r'^saml2/', include('djangosaml2.urls')),
-        
-              #  more url definitions
-          )
-        
-        As you can see we are including ``djangosaml2.urls`` under the *saml2*
-        prefix. Feel free to use your own prefix but be consistent with what
-        you have put in the ``settings.py`` file in the LOGIN_URL parameter.
-        
-        
-        PySAML2 specific files and configuration
-        ----------------------------------------
-        Once you have finished configuring your Django project you have to
-        start configuring PySAML. If you use just that library you have to
-        put your configuration options in a file and initialize PySAML2 with
-        the path to that file.
-        
-        In djangosaml2 you just put the same information in the Django
-        settings.py file under the SAML_CONFIG option.
-        
-        We will see a typical configuration for protecting a Django project::
-        
-          from os import path
-          import saml2
-          import saml2.saml
-          BASEDIR = path.dirname(path.abspath(__file__))
-          SAML_CONFIG = {
-            # full path to the xmlsec1 binary programm
-            'xmlsec_binary': '/usr/bin/xmlsec1',
-        
-            # your entity id, usually your subdomain plus the url to the metadata view
-            'entityid': 'http://localhost:8000/saml2/metadata/',
-        
-            # directory with attribute mapping
-            'attribute_map_dir': path.join(BASEDIR, 'attribute-maps'),
-        
-            # this block states what services we provide
-            'service': {
-                # we are just a lonely SP
-                'sp' : {
-                    'name': 'Federated Django sample SP',
-                    'name_id_format': saml2.saml.NAMEID_FORMAT_PERSISTENT,
-                    'endpoints': {
-                        # url and binding to the assetion consumer service view
-                        # do not change the binding or service name
-                        'assertion_consumer_service': [
-                            ('http://localhost:8000/saml2/acs/',
-                             saml2.BINDING_HTTP_POST),
-                            ],
-                        # url and binding to the single logout service view
-                        # do not change the binding or service name
-                        'single_logout_service': [
-                            ('http://localhost:8000/saml2/ls/',
-                             saml2.BINDING_HTTP_REDIRECT),
-                            ('http://localhost:8000/saml2/ls/post',
-                             saml2.BINDING_HTTP_POST),
-                            ],
-                        },
-                     # Mandates that the identity provider MUST authenticate the
-                     # presenter directly rather than rely on a previous security context.
-                    'force_authn': False, 
-                    
-                     # Enable AllowCreate in NameIDPolicy.
-                    'name_id_format_allow_create': False,
-                    
-                     # attributes that this project need to identify a user
-                    'required_attributes': ['uid'],
-        
-                     # attributes that may be useful to have but not required
-                    'optional_attributes': ['eduPersonAffiliation'],
-        
-                    # in this section the list of IdPs we talk to are defined
-                    'idp': {
-                        # we do not need a WAYF service since there is
-                        # only an IdP defined here. This IdP should be
-                        # present in our metadata
-        
-                        # the keys of this dictionary are entity ids
-                        'https://localhost/simplesaml/saml2/idp/metadata.php': {
-                            'single_sign_on_service': {
-                                saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SSOService.php',
-                                },
-                            'single_logout_service': {
-                                saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SingleLogoutService.php',
-                                },
-                            },
-                        },
-                    },
-                },
-        
-            # where the remote metadata is stored
-            'metadata': {
-                'local': [path.join(BASEDIR, 'remote_metadata.xml')],
-                },
-        
-            # set to 1 to output debugging information
-            'debug': 1,
-        
-            # Signing
-            'key_file': path.join(BASEDIR, 'mycert.key'),  # private part
-            'cert_file': path.join(BASEDIR, 'mycert.pem'),  # public part
-        
-            # Encryption
-            'encryption_keypairs': [{
-                'key_file': path.join(BASEDIR, 'my_encryption_key.key'),  # private part
-                'cert_file': path.join(BASEDIR, 'my_encryption_cert.pem'),  # public part
-            }],
-        
-            # own metadata settings
-            'contact_person': [
-                {'given_name': 'Lorenzo',
-                 'sur_name': 'Gil',
-                 'company': 'Yaco Sistemas',
-                 'email_address': 'lgs@yaco.es',
-                 'contact_type': 'technical'},
-                {'given_name': 'Angel',
-                 'sur_name': 'Fernandez',
-                 'company': 'Yaco Sistemas',
-                 'email_address': 'angel@yaco.es',
-                 'contact_type': 'administrative'},
-                ],
-            # you can set multilanguage information here
-            'organization': {
-                'name': [('Yaco Sistemas', 'es'), ('Yaco Systems', 'en')],
-                'display_name': [('Yaco', 'es'), ('Yaco', 'en')],
-                'url': [('http://www.yaco.es', 'es'), ('http://www.yaco.com', 'en')],
-                },
-            'valid_for': 24,  # how long is our metadata valid
-            }
-        
-        .. note::
-        
-          Please check the `PySAML2 documentation`_ for more information about
-          these and other configuration options.
-        
-        .. _`PySAML2 documentation`: http://pysaml2.readthedocs.io/en/latest/
-        
-        There are several external files and directories you have to create according
-        to this configuration.
-        
-        The xmlsec1 binary was mentioned in the installation section. Here, in the
-        configuration part you just need to put the full path to xmlsec1 so PySAML2
-        can call it as it needs.
-        
-        The ``attribute_map_dir`` points to a directory with attribute mappings that
-        are used to translate user attribute names from several standards. It's usually
-        safe to just copy the default PySAML2 attribute maps that you can find in the
-        ``tests/attributemaps`` directory of the source distribution.
-        
-        The ``metadata`` option is a dictionary where you can define several types of
-        metadata for remote entities. Usually the easiest type is the ``local`` where
-        you just put the name of a local XML file with the contents of the remote
-        entities metadata. This XML file should be in the SAML2 metadata format.
-        
-        The ``key_file`` and ``cert_file`` options reference the two parts of a
-        standard x509 certificate. You need it to sign your metadata. For assertion
-        encryption/decryption support please configure another set of ``key_file`` and
-        ``cert_file``, but as inner attributes of ``encryption_keypairs`` option.
-        
-        .. note::
-        
-          Check your openssl documentation to generate a test certificate but don't
-          forget to order a real one when you go into production.
-        
-        
-        Custom and dynamic configuration loading
-        ........................................
-        
-        By default, djangosaml2 reads the pysaml2 configuration options from the
-        SAML_CONFIG setting but sometimes you want to read this information from
-        another place, like a file or a database. Sometimes you even want this
-        configuration to be different depending on the request.
-        
-        Starting from djangosaml2 0.5.0 you can define your own configuration
-        loader which is a callable that accepts a request parameter and returns
-        a saml2.config.SPConfig object. In order to do so you set the following
-        setting::
-        
-          SAML_CONFIG_LOADER = 'python.path.to.your.callable'
-        
-        
-        User attributes
-        ---------------
-        
-        In the SAML 2.0 authentication process the Identity Provider (IdP) will
-        send a security assertion to the Service Provider (SP) upon a successful
-        authentication. This assertion contains attributes about the user that
-        was authenticated. It depends on the IdP configuration what exact
-        attributes are sent to each SP it can talk to.
-        
-        When such assertion is received on the Django side it is used to find a Django
-        user and create a session for it. By default djangosaml2 will do a query on the
-        User model with the USERNAME_FIELD_ attribute but you can change it to any
-        other attribute of the User model. For example, you can do this lookup using
-        the 'email' attribute. In order to do so you should set the following setting::
-        
-          SAML_DJANGO_USER_MAIN_ATTRIBUTE = 'email'
-        
-        .. _USERNAME_FIELD: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.CustomUser.USERNAME_FIELD
-        
-        Please, use an unique attribute when setting this option. Otherwise
-        the authentication process may fail because djangosaml2 will not know
-        which Django user it should pick.
-        
-        If your main attribute is something inherently case-insensitive (such as
-        an email address), you may set::
-        
-          SAML_DJANGO_USER_MAIN_ATTRIBUTE_LOOKUP = '__iexact'
-        
-        (This is simply appended to the main attribute name to form a Django
-        query. Your main attribute must be unique even given this lookup.)
-        
-        Another option is to use the SAML2 name id as the username by setting::
-        
-          SAML_USE_NAME_ID_AS_USERNAME = True
-        
-        You can configure djangosaml2 to create such user if it is not already in
-        the Django database or maybe you don't want to allow users that are not
-        in your database already. For this purpose there is another option you
-        can set in the settings.py file::
-        
-          SAML_CREATE_UNKNOWN_USER = True
-        
-        This setting is True by default.
-        
-          ACS_DEFAULT_REDIRECT_URL = reverse_lazy('some_url_name')
-        
-        This setting lets you specify a URL for redirection after a successful
-        authentication. Particularly useful when you only plan to use
-        IdP initiated login and the IdP does not have a configured RelayState
-        parameter. The default is ``/``.
-        
-        The other thing you will probably want to configure is the mapping of
-        SAML2 user attributes to Django user attributes. By default only the
-        User.username attribute is mapped but you can add more attributes or
-        change that one. In order to do so you need to change the
-        SAML_ATTRIBUTE_MAPPING option in your settings.py::
-        
-          SAML_ATTRIBUTE_MAPPING = {
-              'uid': ('username', ),
-              'mail': ('email', ),
-              'cn': ('first_name', ),
-              'sn': ('last_name', ),
-          }
-        
-        where the keys of this dictionary are SAML user attributes and the values
-        are Django User attributes.
-        
-        If you are using Django user profile objects to store extra attributes
-        about your user you can add those attributes to the SAML_ATTRIBUTE_MAPPING
-        dictionary. For each (key, value) pair, djangosaml2 will try to store the
-        attribute in the User model if there is a matching field in that model.
-        Otherwise it will try to do the same with your profile custom model. For
-        multi-valued attributes only the first value is assigned to the destination field.
-        
-        Alternatively, custom processing of attributes can be achieved by setting the
-        value(s) in the SAML_ATTRIBUTE_MAPPING, to name(s) of method(s) defined on a
-        custom django User object. In this case, each method is called by djangosaml2,
-        passing the full list of attribute values extracted from the <saml:AttributeValue>
-        elements of the <saml:Attribute>. Among other uses, this is a useful way to process
-        multi-valued attributes such as lists of user group names.
-        
-        For example:
-        
-        Saml assertion snippet::
-        
-          <saml:Attribute Name="groups" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
-                <saml:AttributeValue>group1</saml:AttributeValue>
-                <saml:AttributeValue>group2</saml:AttributeValue>
-                <saml:AttributeValue>group3</saml:AttributeValue>
-          </saml:Attribute>
-        
-        Custom User object::
-        
-          from django.contrib.auth.models import AbstractUser
-        
-          class User(AbstractUser):
-        
-            def process_groups(self, groups):
-              // process list of group names in argument 'groups'
-              pass;
-        
-        settings.py::
-        
-          SAML_ATTRIBUTE_MAPPING = {
-              'groups': ('process_groups', ),
-          }
-        
-        
-        Learn more about Django profile models at:
-        
-        https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model
-        
-        
-        Sometimes you need to use special logic to update the user object
-        depending on the SAML2 attributes and the mapping described above
-        is simply not enough. For these cases djangosaml2 provides a Django
-        signal that you can listen to. In order to do so you can add the
-        following code to your app::
-        
-          from djangosaml2.signals import pre_user_save
-        
-          def custom_update_user(sender=User, instance, attributes, user_modified, **kargs)
-             ...
-             return True  # I modified the user object
-        
-        
-        Your handler will receive the user object, the list of SAML attributes
-        and a flag telling you if the user is already modified and need
-        to be saved after your handler is executed. If your handler
-        modifies the user object it should return True. Otherwise it should
-        return False. This way djangosaml2 will know if it should save
-        the user object so you don't need to do it and no more calls to
-        the save method are issued.
-        
-        
-        IdP setup
-        =========
-        Congratulations, you have finished configuring the SP side of the federation.
-        Now you need to send the entity id and the metadata of this new SP to the
-        IdP administrators so they can add it to their list of trusted services.
-        
-        You can get this information starting your Django development server and
-        going to the http://localhost:8000/saml2/metadata url. If you have included
-        the djangosaml2 urls under a different url prefix you need to correct this
-        url.
-        
-        SimpleSAMLphp issues
-        --------------------
-        As of SimpleSAMLphp 1.8.2 there is a problem if you specify attributes in
-        the SP configuration. When the SimpleSAMLphp metadata parser converts the
-        XML into its custom php format it puts the following option::
-        
-          'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'
-        
-        But it need to be replaced by this one::
-        
-          'AttributeNameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'
-        
-        Otherwise the Assertions sent from the IdP to the SP will have a wrong
-        Attribute Name Format and pysaml2 will be confused.
-        
-        Furthermore if you have a AttributeLimit filter in your SimpleSAMLphp
-        configuration  you will need to enable another attribute filter just
-        before to make sure that the AttributeLimit does not remove the attributes
-        from the authentication source. The filter you need to add is an AttributeMap
-        filter like this::
-        
-          10 => array(
-                     'class' => 'core:AttributeMap', 'name2oid'
-                ),
-        
-        Testing
-        =======
-        
-        One way to check if everything is working as expected is to enable the
-        following url::
-        
-          urlpatterns = patterns(
-              '',
-              #  lots of url definitions here
-        
-              (r'^saml2/', include('djangosaml2.urls')),
-              (r'^test/', 'djangosaml2.views.echo_attributes'),
-        
-              #  more url definitions
-          )
-        
-        
-        Now if you go to the /test/ url you will see your SAML attributes and also
-        a link to do a global logout.
-        
-        You can also run the unit tests with the following command::
-        
-          python tests/run_tests.py
-        
-        If you have `tox`_ installed you can simply call tox inside the root directory
-        and it will run the tests in multiple versions of Python.
-        
-        .. _`tox`: http://pypi.python.org/pypi/tox
-        
-        FAQ
-        ===
-        
-        **Why can't SAML be implemented as an Django Authentication Backend?**
-        
-        well SAML authentication is not that simple as a set of credentials you can
-        put on a login form and get a response back. Actually the user password is
-        not given to the service provider at all. This is by design. You have to
-        delegate the task of authentication to the IdP and then get an asynchronous
-        response from it.
-        
-        Given said that, djangosaml2 does use a Django Authentication Backend to
-        transform the SAML assertion about the user into a Django user object.
-        
-        **Why not put everything in a Django middleware class and make our lifes
-        easier?**
-        
-        Yes, that was an option I did evaluate but at the end the current design
-        won. In my opinion putting this logic into a middleware has the advantage
-        of making it easier to configure but has a couple of disadvantages: first,
-        the middleware would need to check if the request path is one of the
-        SAML endpoints for every request. Second, it would be too magical and in
-        case of a problem, much harder to debug.
-        
-        **Why not call this package django-saml as many other Django applications?**
-        
-        Following that pattern then I should import the application with
-        import saml but unfortunately that module name is already used in pysaml2.
-        
-Keywords: django,pysaml2,sso,saml2,federated authentication,authentication
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: Environment :: Web Environment
-Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.8
-Classifier: Framework :: Django :: 1.9
-Classifier: Framework :: Django :: 1.10
-Classifier: Framework :: Django :: 1.11
-Classifier: Framework :: Django :: 2.0
-Classifier: Framework :: Django :: 2.1
-Classifier: Framework :: Django :: 2.2
-Classifier: Framework :: Django :: 3.0
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Topic :: Internet :: WWW/HTTP
-Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
-Classifier: Topic :: Security
-Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
-Provides-Extra: test

+ 0 - 545
desktop/core/ext-py3/djangosaml2-0.18.0/README.rst

@@ -1,545 +0,0 @@
-===========
-djangosaml2
-===========
-
-.. image:: https://travis-ci.org/knaperek/djangosaml2.svg?branch=master
-    :target: https://travis-ci.org/knaperek/djangosaml2
-    :align: left
-
-
-djangosaml2 is a Django application that integrates the PySAML2 library
-into your project. This mean that you can protect your Django based project
-with a service provider based on PySAML. This way it will talk SAML2 with
-your Identity Provider allowing you to use this authentication mechanism.
-This document will guide you through a few simple steps to accomplish
-such goal.
-
-.. contents::
-
-Installation
-============
-
-PySAML2 uses xmlsec1_ binary to sign SAML assertions so you need to install
-it either through your operating system package or by compiling the source
-code. It doesn't matter where the final executable is installed because
-you will need to set the full path to it in the configuration stage.
-
-.. _xmlsec1: http://www.aleksey.com/xmlsec/
-
-Now you can install the djangosaml2 package using easy_install or pip. This
-will also install PySAML2 and its dependencies automatically.
-
-
-Configuration
-=============
-
-There are three things you need to setup to make djangosaml2 work in your
-Django project:
-
-1. **settings.py** as you may already know, it is the main Django
-   configuration file.
-2. **urls.py** is the file where you will include djangosaml2 urls.
-3. **pysaml2** specific files such as an attribute map directory and a
-   certificate.
-
-
-Changes in the settings.py file
--------------------------------
-The first thing you need to do is add ``djangosaml2`` to the list of
-installed apps::
-
-  INSTALLED_APPS = (
-      'django.contrib.auth',
-      'django.contrib.contenttypes',
-      'django.contrib.sessions',
-      'django.contrib.sites',
-      'django.contrib.messages',
-      'django.contrib.admin',
-      'djangosaml2',  # new application
-  )
-
-Actually this is not really required since djangosaml2 does not include
-any data model. The only reason we include it is to be able to run
-djangosaml2 test suite from our project, something you should always
-do to make sure it is compatible with your Django version and environment.
-
-.. note::
-
-  When you finish the configuration you can run the djangosaml2 test suite as
-  you run any other Django application test suite. Just type ``python manage.py
-  test djangosaml2``.
-
-  Python 2 users need to ``pip install djangosaml2[test]`` in order to run the
-  tests.
-
-Then you have to add the ``djangosaml2.backends.Saml2Backend``
-authentication backend to the list of authentications backends.
-By default only the ModelBackend included in Django is configured.
-A typical configuration would look like this::
-
-  AUTHENTICATION_BACKENDS = (
-      'django.contrib.auth.backends.ModelBackend',
-      'djangosaml2.backends.Saml2Backend',
-  )
-
-.. note::
-
-  Before djangosaml2 0.5.0 this authentication backend was
-  automatically added by djangosaml2. This turned out to be
-  a bad idea since some applications want to use their own
-  custom policies for authorization and the authentication
-  backend is a good place to define that. Starting from
-  djangosaml2 0.5.0 it is now possible to define such
-  backends.
-
-Finally we have to tell Django what the new login url we want to use is::
-
-  LOGIN_URL = '/saml2/login/'
-  SESSION_EXPIRE_AT_BROWSER_CLOSE = True
-
-Here we are telling Django that any view that requires an authenticated
-user should redirect the user browser to that url if the user has not
-been authenticated before. We are also telling that when the user closes
-his browser, the session should be terminated. This is useful in SAML2
-federations where the logout protocol is not always available.
-
-.. note::
-
-  The login url starts with ``/saml2/`` as an example but you can change that
-  if you want. Check the section about changes in the ``urls.py``
-  file for more information.
-
-If you want to allow several authentication mechanisms in your project
-you should set the LOGIN_URL option to another view and put a link in such
-view to the ``/saml2/login/`` view.
-
-Preferred Logout binding
-------------------------
-Use the following setting to choose your preferred binding for SP initiated logout requests::
-
-  SAML_LOGOUT_REQUEST_PREFERRED_BINDING
-
-For example::
-
-  import saml2
-  SAML_LOGOUT_REQUEST_PREFERRED_BINDING = saml2.BINDING_HTTP_POST
-
-Changes in the urls.py file
----------------------------
-
-The next thing you need to do is to include ``djangosaml2.urls`` module in your
-main ``urls.py`` module::
-
-  urlpatterns = patterns(
-      '',
-      #  lots of url definitions here
-
-      (r'^saml2/', include('djangosaml2.urls')),
-
-      #  more url definitions
-  )
-
-As you can see we are including ``djangosaml2.urls`` under the *saml2*
-prefix. Feel free to use your own prefix but be consistent with what
-you have put in the ``settings.py`` file in the LOGIN_URL parameter.
-
-
-PySAML2 specific files and configuration
-----------------------------------------
-Once you have finished configuring your Django project you have to
-start configuring PySAML. If you use just that library you have to
-put your configuration options in a file and initialize PySAML2 with
-the path to that file.
-
-In djangosaml2 you just put the same information in the Django
-settings.py file under the SAML_CONFIG option.
-
-We will see a typical configuration for protecting a Django project::
-
-  from os import path
-  import saml2
-  import saml2.saml
-  BASEDIR = path.dirname(path.abspath(__file__))
-  SAML_CONFIG = {
-    # full path to the xmlsec1 binary programm
-    'xmlsec_binary': '/usr/bin/xmlsec1',
-
-    # your entity id, usually your subdomain plus the url to the metadata view
-    'entityid': 'http://localhost:8000/saml2/metadata/',
-
-    # directory with attribute mapping
-    'attribute_map_dir': path.join(BASEDIR, 'attribute-maps'),
-
-    # this block states what services we provide
-    'service': {
-        # we are just a lonely SP
-        'sp' : {
-            'name': 'Federated Django sample SP',
-            'name_id_format': saml2.saml.NAMEID_FORMAT_PERSISTENT,
-            'endpoints': {
-                # url and binding to the assetion consumer service view
-                # do not change the binding or service name
-                'assertion_consumer_service': [
-                    ('http://localhost:8000/saml2/acs/',
-                     saml2.BINDING_HTTP_POST),
-                    ],
-                # url and binding to the single logout service view
-                # do not change the binding or service name
-                'single_logout_service': [
-                    ('http://localhost:8000/saml2/ls/',
-                     saml2.BINDING_HTTP_REDIRECT),
-                    ('http://localhost:8000/saml2/ls/post',
-                     saml2.BINDING_HTTP_POST),
-                    ],
-                },
-             # Mandates that the identity provider MUST authenticate the
-             # presenter directly rather than rely on a previous security context.
-            'force_authn': False, 
-            
-             # Enable AllowCreate in NameIDPolicy.
-            'name_id_format_allow_create': False,
-            
-             # attributes that this project need to identify a user
-            'required_attributes': ['uid'],
-
-             # attributes that may be useful to have but not required
-            'optional_attributes': ['eduPersonAffiliation'],
-
-            # in this section the list of IdPs we talk to are defined
-            'idp': {
-                # we do not need a WAYF service since there is
-                # only an IdP defined here. This IdP should be
-                # present in our metadata
-
-                # the keys of this dictionary are entity ids
-                'https://localhost/simplesaml/saml2/idp/metadata.php': {
-                    'single_sign_on_service': {
-                        saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SSOService.php',
-                        },
-                    'single_logout_service': {
-                        saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SingleLogoutService.php',
-                        },
-                    },
-                },
-            },
-        },
-
-    # where the remote metadata is stored
-    'metadata': {
-        'local': [path.join(BASEDIR, 'remote_metadata.xml')],
-        },
-
-    # set to 1 to output debugging information
-    'debug': 1,
-
-    # Signing
-    'key_file': path.join(BASEDIR, 'mycert.key'),  # private part
-    'cert_file': path.join(BASEDIR, 'mycert.pem'),  # public part
-
-    # Encryption
-    'encryption_keypairs': [{
-        'key_file': path.join(BASEDIR, 'my_encryption_key.key'),  # private part
-        'cert_file': path.join(BASEDIR, 'my_encryption_cert.pem'),  # public part
-    }],
-
-    # own metadata settings
-    'contact_person': [
-        {'given_name': 'Lorenzo',
-         'sur_name': 'Gil',
-         'company': 'Yaco Sistemas',
-         'email_address': 'lgs@yaco.es',
-         'contact_type': 'technical'},
-        {'given_name': 'Angel',
-         'sur_name': 'Fernandez',
-         'company': 'Yaco Sistemas',
-         'email_address': 'angel@yaco.es',
-         'contact_type': 'administrative'},
-        ],
-    # you can set multilanguage information here
-    'organization': {
-        'name': [('Yaco Sistemas', 'es'), ('Yaco Systems', 'en')],
-        'display_name': [('Yaco', 'es'), ('Yaco', 'en')],
-        'url': [('http://www.yaco.es', 'es'), ('http://www.yaco.com', 'en')],
-        },
-    'valid_for': 24,  # how long is our metadata valid
-    }
-
-.. note::
-
-  Please check the `PySAML2 documentation`_ for more information about
-  these and other configuration options.
-
-.. _`PySAML2 documentation`: http://pysaml2.readthedocs.io/en/latest/
-
-There are several external files and directories you have to create according
-to this configuration.
-
-The xmlsec1 binary was mentioned in the installation section. Here, in the
-configuration part you just need to put the full path to xmlsec1 so PySAML2
-can call it as it needs.
-
-The ``attribute_map_dir`` points to a directory with attribute mappings that
-are used to translate user attribute names from several standards. It's usually
-safe to just copy the default PySAML2 attribute maps that you can find in the
-``tests/attributemaps`` directory of the source distribution.
-
-The ``metadata`` option is a dictionary where you can define several types of
-metadata for remote entities. Usually the easiest type is the ``local`` where
-you just put the name of a local XML file with the contents of the remote
-entities metadata. This XML file should be in the SAML2 metadata format.
-
-The ``key_file`` and ``cert_file`` options reference the two parts of a
-standard x509 certificate. You need it to sign your metadata. For assertion
-encryption/decryption support please configure another set of ``key_file`` and
-``cert_file``, but as inner attributes of ``encryption_keypairs`` option.
-
-.. note::
-
-  Check your openssl documentation to generate a test certificate but don't
-  forget to order a real one when you go into production.
-
-
-Custom and dynamic configuration loading
-........................................
-
-By default, djangosaml2 reads the pysaml2 configuration options from the
-SAML_CONFIG setting but sometimes you want to read this information from
-another place, like a file or a database. Sometimes you even want this
-configuration to be different depending on the request.
-
-Starting from djangosaml2 0.5.0 you can define your own configuration
-loader which is a callable that accepts a request parameter and returns
-a saml2.config.SPConfig object. In order to do so you set the following
-setting::
-
-  SAML_CONFIG_LOADER = 'python.path.to.your.callable'
-
-
-User attributes
----------------
-
-In the SAML 2.0 authentication process the Identity Provider (IdP) will
-send a security assertion to the Service Provider (SP) upon a successful
-authentication. This assertion contains attributes about the user that
-was authenticated. It depends on the IdP configuration what exact
-attributes are sent to each SP it can talk to.
-
-When such assertion is received on the Django side it is used to find a Django
-user and create a session for it. By default djangosaml2 will do a query on the
-User model with the USERNAME_FIELD_ attribute but you can change it to any
-other attribute of the User model. For example, you can do this lookup using
-the 'email' attribute. In order to do so you should set the following setting::
-
-  SAML_DJANGO_USER_MAIN_ATTRIBUTE = 'email'
-
-.. _USERNAME_FIELD: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.CustomUser.USERNAME_FIELD
-
-Please, use an unique attribute when setting this option. Otherwise
-the authentication process may fail because djangosaml2 will not know
-which Django user it should pick.
-
-If your main attribute is something inherently case-insensitive (such as
-an email address), you may set::
-
-  SAML_DJANGO_USER_MAIN_ATTRIBUTE_LOOKUP = '__iexact'
-
-(This is simply appended to the main attribute name to form a Django
-query. Your main attribute must be unique even given this lookup.)
-
-Another option is to use the SAML2 name id as the username by setting::
-
-  SAML_USE_NAME_ID_AS_USERNAME = True
-
-You can configure djangosaml2 to create such user if it is not already in
-the Django database or maybe you don't want to allow users that are not
-in your database already. For this purpose there is another option you
-can set in the settings.py file::
-
-  SAML_CREATE_UNKNOWN_USER = True
-
-This setting is True by default.
-
-  ACS_DEFAULT_REDIRECT_URL = reverse_lazy('some_url_name')
-
-This setting lets you specify a URL for redirection after a successful
-authentication. Particularly useful when you only plan to use
-IdP initiated login and the IdP does not have a configured RelayState
-parameter. The default is ``/``.
-
-The other thing you will probably want to configure is the mapping of
-SAML2 user attributes to Django user attributes. By default only the
-User.username attribute is mapped but you can add more attributes or
-change that one. In order to do so you need to change the
-SAML_ATTRIBUTE_MAPPING option in your settings.py::
-
-  SAML_ATTRIBUTE_MAPPING = {
-      'uid': ('username', ),
-      'mail': ('email', ),
-      'cn': ('first_name', ),
-      'sn': ('last_name', ),
-  }
-
-where the keys of this dictionary are SAML user attributes and the values
-are Django User attributes.
-
-If you are using Django user profile objects to store extra attributes
-about your user you can add those attributes to the SAML_ATTRIBUTE_MAPPING
-dictionary. For each (key, value) pair, djangosaml2 will try to store the
-attribute in the User model if there is a matching field in that model.
-Otherwise it will try to do the same with your profile custom model. For
-multi-valued attributes only the first value is assigned to the destination field.
-
-Alternatively, custom processing of attributes can be achieved by setting the
-value(s) in the SAML_ATTRIBUTE_MAPPING, to name(s) of method(s) defined on a
-custom django User object. In this case, each method is called by djangosaml2,
-passing the full list of attribute values extracted from the <saml:AttributeValue>
-elements of the <saml:Attribute>. Among other uses, this is a useful way to process
-multi-valued attributes such as lists of user group names.
-
-For example:
-
-Saml assertion snippet::
-
-  <saml:Attribute Name="groups" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
-        <saml:AttributeValue>group1</saml:AttributeValue>
-        <saml:AttributeValue>group2</saml:AttributeValue>
-        <saml:AttributeValue>group3</saml:AttributeValue>
-  </saml:Attribute>
-
-Custom User object::
-
-  from django.contrib.auth.models import AbstractUser
-
-  class User(AbstractUser):
-
-    def process_groups(self, groups):
-      // process list of group names in argument 'groups'
-      pass;
-
-settings.py::
-
-  SAML_ATTRIBUTE_MAPPING = {
-      'groups': ('process_groups', ),
-  }
-
-
-Learn more about Django profile models at:
-
-https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model
-
-
-Sometimes you need to use special logic to update the user object
-depending on the SAML2 attributes and the mapping described above
-is simply not enough. For these cases djangosaml2 provides a Django
-signal that you can listen to. In order to do so you can add the
-following code to your app::
-
-  from djangosaml2.signals import pre_user_save
-
-  def custom_update_user(sender=User, instance, attributes, user_modified, **kargs)
-     ...
-     return True  # I modified the user object
-
-
-Your handler will receive the user object, the list of SAML attributes
-and a flag telling you if the user is already modified and need
-to be saved after your handler is executed. If your handler
-modifies the user object it should return True. Otherwise it should
-return False. This way djangosaml2 will know if it should save
-the user object so you don't need to do it and no more calls to
-the save method are issued.
-
-
-IdP setup
-=========
-Congratulations, you have finished configuring the SP side of the federation.
-Now you need to send the entity id and the metadata of this new SP to the
-IdP administrators so they can add it to their list of trusted services.
-
-You can get this information starting your Django development server and
-going to the http://localhost:8000/saml2/metadata url. If you have included
-the djangosaml2 urls under a different url prefix you need to correct this
-url.
-
-SimpleSAMLphp issues
---------------------
-As of SimpleSAMLphp 1.8.2 there is a problem if you specify attributes in
-the SP configuration. When the SimpleSAMLphp metadata parser converts the
-XML into its custom php format it puts the following option::
-
-  'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'
-
-But it need to be replaced by this one::
-
-  'AttributeNameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'
-
-Otherwise the Assertions sent from the IdP to the SP will have a wrong
-Attribute Name Format and pysaml2 will be confused.
-
-Furthermore if you have a AttributeLimit filter in your SimpleSAMLphp
-configuration  you will need to enable another attribute filter just
-before to make sure that the AttributeLimit does not remove the attributes
-from the authentication source. The filter you need to add is an AttributeMap
-filter like this::
-
-  10 => array(
-             'class' => 'core:AttributeMap', 'name2oid'
-        ),
-
-Testing
-=======
-
-One way to check if everything is working as expected is to enable the
-following url::
-
-  urlpatterns = patterns(
-      '',
-      #  lots of url definitions here
-
-      (r'^saml2/', include('djangosaml2.urls')),
-      (r'^test/', 'djangosaml2.views.echo_attributes'),
-
-      #  more url definitions
-  )
-
-
-Now if you go to the /test/ url you will see your SAML attributes and also
-a link to do a global logout.
-
-You can also run the unit tests with the following command::
-
-  python tests/run_tests.py
-
-If you have `tox`_ installed you can simply call tox inside the root directory
-and it will run the tests in multiple versions of Python.
-
-.. _`tox`: http://pypi.python.org/pypi/tox
-
-FAQ
-===
-
-**Why can't SAML be implemented as an Django Authentication Backend?**
-
-well SAML authentication is not that simple as a set of credentials you can
-put on a login form and get a response back. Actually the user password is
-not given to the service provider at all. This is by design. You have to
-delegate the task of authentication to the IdP and then get an asynchronous
-response from it.
-
-Given said that, djangosaml2 does use a Django Authentication Backend to
-transform the SAML assertion about the user into a Django user object.
-
-**Why not put everything in a Django middleware class and make our lifes
-easier?**
-
-Yes, that was an option I did evaluate but at the end the current design
-won. In my opinion putting this logic into a middleware has the advantage
-of making it easier to configure but has a couple of disadvantages: first,
-the middleware would need to check if the request path is one of the
-SAML endpoints for every request. Second, it would be too magical and in
-case of a problem, much harder to debug.
-
-**Why not call this package django-saml as many other Django applications?**
-
-Following that pattern then I should import the application with
-import saml but unfortunately that module name is already used in pysaml2.

+ 0 - 0
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/__init__.py


+ 0 - 22
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/acs_failures.py

@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# This module defines a set of useful ACS failure functions that are used to
-# produce an output suitable for end user in case of SAML failure.
-#
-from __future__ import unicode_literals
-
-from django.core.exceptions import PermissionDenied
-from django.shortcuts import render
-
-
-def template_failure(request, status=403, **kwargs):
-    """ Renders a SAML-specific template with general authentication error description. """
-    return render(request, 'djangosaml2/login_error.html', status=status, using='django')
-
-
-def exception_failure(request, exc_class=PermissionDenied, **kwargs):
-    """ Rather than using a custom SAML specific template that is rendered on failure,
-    this makes use of a standard exception handling machinery present in Django
-    and thus ends up rendering a project-wide error page for Permission Denied exceptions.
-    """
-    raise exc_class

+ 0 - 278
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/backends.py

@@ -1,278 +0,0 @@
-# Copyright (C) 2010-2012 Yaco Sistemas (http://www.yaco.es)
-# Copyright (C) 2009 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import logging
-
-from django.conf import settings
-from django.contrib import auth
-from django.contrib.auth.backends import ModelBackend
-from django.core.exceptions import (
-    MultipleObjectsReturned, ImproperlyConfigured,
-)
-
-from djangosaml2.signals import pre_user_save
-
-
-logger = logging.getLogger('djangosaml2')
-
-
-def get_model(model_path):
-    try:
-        from django.apps import apps
-        return apps.get_model(model_path)
-    except ImportError:
-        # Django < 1.7 (cannot use the new app loader)
-        from django.db.models import get_model as django_get_model
-        try:
-            app_label, model_name = model_path.split('.')
-        except ValueError:
-            raise ImproperlyConfigured("SAML_USER_MODEL must be of the form "
-                "'app_label.model_name'")
-        user_model = django_get_model(app_label, model_name)
-        if user_model is None:
-            raise ImproperlyConfigured("SAML_USER_MODEL refers to model '%s' "
-                "that has not been installed" % model_path)
-        return user_model
-
-
-def get_saml_user_model():
-    try:
-        # djangosaml2 custom user model
-        return get_model(settings.SAML_USER_MODEL)
-    except AttributeError:
-        try:
-            # Django 1.5 Custom user model
-            return auth.get_user_model()
-        except AttributeError:
-            return auth.models.User
-
-
-class Saml2Backend(ModelBackend):
-
-    def authenticate(self, request, session_info=None, attribute_mapping=None,
-                     create_unknown_user=True, **kwargs):
-        if session_info is None or attribute_mapping is None:
-            logger.info('Session info or attribute mapping are None')
-            return None
-
-        if 'ava' not in session_info:
-            logger.error('"ava" key not found in session_info')
-            return None
-
-        attributes = self.clean_attributes(session_info['ava'])
-        if not attributes:
-            logger.error('The attributes dictionary is empty')
-
-        use_name_id_as_username = getattr(
-            settings, 'SAML_USE_NAME_ID_AS_USERNAME', False)
-
-        django_user_main_attribute = self.get_django_user_main_attribute()
-
-        logger.debug('attributes: %s', attributes)
-        saml_user = None
-        if use_name_id_as_username:
-            if 'name_id' in session_info:
-                logger.debug('name_id: %s', session_info['name_id'])
-                saml_user = session_info['name_id'].text
-            else:
-                logger.error('The nameid is not available. Cannot find user without a nameid.')
-        else:
-            saml_user = self.get_attribute_value(django_user_main_attribute,
-                                                 attributes,
-                                                 attribute_mapping)
-
-        if saml_user is None:
-            logger.error('Could not find saml_user value')
-            return None
-
-        if not self.is_authorized(attributes, attribute_mapping):
-            return None
-
-        main_attribute = self.clean_user_main_attribute(saml_user)
-
-        # Note that this could be accomplished in one try-except clause, but
-        # instead we use get_or_create when creating unknown users since it has
-        # built-in safeguards for multiple threads.
-        return self.get_saml2_user(
-            create_unknown_user, main_attribute, attributes, attribute_mapping)
-
-    def get_attribute_value(self, django_field, attributes, attribute_mapping):
-        saml_user = None
-        logger.debug('attribute_mapping: %s', attribute_mapping)
-        for saml_attr, django_fields in attribute_mapping.items():
-            if django_field in django_fields and saml_attr in attributes:
-                saml_user = attributes.get('saml_attr', [None])[0]
-                if not saml_user:
-                    logger.error('attributes[saml_attr] attribute '
-                                 'value is missing. Probably the user '
-                                 'session is expired.')
-        return saml_user
-
-    def is_authorized(self, attributes, attribute_mapping):
-        """Hook to allow custom authorization policies based on
-        SAML attributes.
-        """
-        return True
-
-    def clean_attributes(self, attributes):
-        """Hook to clean attributes from the SAML response."""
-        return attributes
-
-    def clean_user_main_attribute(self, main_attribute):
-        """Performs any cleaning on the user main attribute (which
-        usually is "username") prior to using it to get or
-        create the user object.  Returns the cleaned attribute.
-
-        By default, returns the attribute unchanged.
-        """
-        return main_attribute
-
-    def get_django_user_main_attribute(self):
-        return getattr(
-            settings,
-            'SAML_DJANGO_USER_MAIN_ATTRIBUTE',
-            getattr(get_saml_user_model(), 'USERNAME_FIELD', 'username'))
-
-    def get_django_user_main_attribute_lookup(self):
-        return getattr(settings, 'SAML_DJANGO_USER_MAIN_ATTRIBUTE_LOOKUP', '')
-
-    def get_user_query_args(self, main_attribute):
-        lookup = (self.get_django_user_main_attribute() +
-                  self.get_django_user_main_attribute_lookup())
-        return {lookup: main_attribute}
-
-    def get_saml2_user(self, create, main_attribute, attributes, attribute_mapping):
-        if create:
-            return self._get_or_create_saml2_user(main_attribute, attributes, attribute_mapping)
-
-        return self._get_saml2_user(main_attribute, attributes, attribute_mapping)
-
-    def _get_or_create_saml2_user(self, main_attribute, attributes, attribute_mapping):
-        logger.debug('Check if the user "%s" exists or create otherwise',
-                     main_attribute)
-        django_user_main_attribute = self.get_django_user_main_attribute()
-        user_query_args = self.get_user_query_args(main_attribute)
-        user_create_defaults = {django_user_main_attribute: main_attribute}
-
-        User = get_saml_user_model()
-        try:
-            user, created = User.objects.get_or_create(
-                defaults=user_create_defaults, **user_query_args)
-        except MultipleObjectsReturned:
-            logger.error("There are more than one user with %s = %s",
-                         django_user_main_attribute, main_attribute)
-            return None
-
-        if created:
-            logger.debug('New user created')
-            user = self.configure_user(user, attributes, attribute_mapping)
-        else:
-            logger.debug('User updated')
-            user = self.update_user(user, attributes, attribute_mapping)
-        return user
-
-    def _get_saml2_user(self, main_attribute, attributes, attribute_mapping):
-        User = get_saml_user_model()
-        django_user_main_attribute = self.get_django_user_main_attribute()
-        user_query_args = self.get_user_query_args(main_attribute)
-
-        logger.debug('Retrieving existing user "%s"', main_attribute)
-        try:
-            user = User.objects.get(**user_query_args)
-            user = self.update_user(user, attributes, attribute_mapping)
-        except User.DoesNotExist:
-            logger.error('The user "%s" does not exist, searched %s', main_attribute, django_user_main_attribute)
-            return None
-        except MultipleObjectsReturned:
-            logger.error("There are more than one user with %s = %s",
-                         django_user_main_attribute, main_attribute)
-            return None
-        return user
-
-    def configure_user(self, user, attributes, attribute_mapping):
-        """Configures a user after creation and returns the updated user.
-
-        By default, returns the user with his attributes updated.
-        """
-        user.set_unusable_password()
-        return self.update_user(user, attributes, attribute_mapping,
-                                force_save=True)
-
-    def update_user(self, user, attributes, attribute_mapping,
-                    force_save=False):
-        """Update a user with a set of attributes and returns the updated user.
-
-        By default it uses a mapping defined in the settings constant
-        SAML_ATTRIBUTE_MAPPING. For each attribute, if the user object has
-        that field defined it will be set.
-        """
-        if not attribute_mapping:
-            return user
-
-        user_modified = False
-        for saml_attr, django_attrs in attribute_mapping.items():
-            attr_value_list = attributes.get(saml_attr)
-            if not attr_value_list:
-                logger.debug(
-                    'Could not find value for "%s", not updating fields "%s"',
-                    saml_attr, django_attrs)
-                continue
-
-            for attr in django_attrs:
-                if hasattr(user, attr):
-                    user_attr = getattr(user, attr)
-                    if callable(user_attr):
-                        modified = user_attr(attr_value_list)
-                    else:
-                        modified = self._set_attribute(user, attr, attr_value_list[0])
-
-                    user_modified = user_modified or modified
-                else:
-                    logger.debug(
-                        'Could not find attribute "%s" on user "%s"', attr, user)
-
-        logger.debug('Sending the pre_save signal')
-        signal_modified = any(
-            [response for receiver, response
-             in pre_user_save.send_robust(sender=user.__class__,
-                                          instance=user,
-                                          attributes=attributes,
-                                          user_modified=user_modified)]
-            )
-
-        if user_modified or signal_modified or force_save:
-            user.save()
-
-        return user
-
-    def _set_attribute(self, obj, attr, value):
-        """Set an attribute of an object to a specific value.
-
-        Return True if the attribute was changed and False otherwise.
-        """
-        field = obj._meta.get_field(attr)
-        if field.max_length is not None and len(value) > field.max_length:
-            cleaned_value = value[:field.max_length]
-            logger.warn('The attribute "%s" was trimmed from "%s" to "%s"',
-                        attr, value, cleaned_value)
-        else:
-            cleaned_value = value
-
-        old_value = getattr(obj, attr)
-        if cleaned_value != old_value:
-            setattr(obj, attr, cleaned_value)
-            return True
-
-        return False

+ 0 - 89
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/cache.py

@@ -1,89 +0,0 @@
-# Copyright (C) 2011-2012 Yaco Sistemas (http://www.yaco.es)
-# Copyright (C) 2010 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from saml2.cache import Cache
-
-
-class DjangoSessionCacheAdapter(dict):
-    """A cache of things that are stored in the Django Session"""
-
-    key_prefix = '_saml2'
-
-    def __init__(self, django_session, key_suffix):
-        self.session = django_session
-        self.key = self.key_prefix + key_suffix
-
-        super(DjangoSessionCacheAdapter, self).__init__(self._get_objects())
-
-    def _get_objects(self):
-        return self.session.get(self.key, {})
-
-    def _set_objects(self, objects):
-        self.session[self.key] = objects
-
-    def sync(self):
-        # Changes in inner objects do not cause session invalidation
-        # https://docs.djangoproject.com/en/1.9/topics/http/sessions/#when-sessions-are-saved
-
-        #add objects to session
-        self._set_objects(dict(self))
-        #invalidate session
-        self.session.modified = True
-
-
-class OutstandingQueriesCache(object):
-    """Handles the queries that have been sent to the IdP and have not
-    been replied yet.
-    """
-
-    def __init__(self, django_session):
-        self._db = DjangoSessionCacheAdapter(django_session,
-                                             '_outstanding_queries')
-
-    def outstanding_queries(self):
-        return self._db._get_objects()
-
-    def set(self, saml2_session_id, came_from):
-        self._db[saml2_session_id] = came_from
-        self._db.sync()
-
-    def delete(self, saml2_session_id):
-        if saml2_session_id in self._db:
-            del self._db[saml2_session_id]
-            self._db.sync()
-
-
-class IdentityCache(Cache):
-    """Handles information about the users that have been succesfully
-    logged in.
-
-    This information is useful because when the user logs out we must
-    know where does he come from in order to notify such IdP/AA.
-
-    The current implementation stores this information in the Django session.
-    """
-
-    def __init__(self, django_session):
-        self._db = DjangoSessionCacheAdapter(django_session, '_identities')
-        self._sync = True
-
-
-class StateCache(DjangoSessionCacheAdapter):
-    """Store state information that is needed to associate a logout
-    request with its response.
-    """
-
-    def __init__(self, django_session):
-        super(StateCache, self).__init__(django_session, '_state')

+ 0 - 70
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/conf.py

@@ -1,70 +0,0 @@
-# Copyright (C) 2010-2012 Yaco Sistemas (http://www.yaco.es)
-# Copyright (C) 2009 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import copy
-from importlib import import_module
-
-from django.conf import settings
-from django.core.exceptions import ImproperlyConfigured
-
-from saml2.config import SPConfig
-
-from djangosaml2.utils import get_custom_setting
-
-
-def get_config_loader(path, request=None):
-    i = path.rfind('.')
-    module, attr = path[:i], path[i + 1:]
-    try:
-        mod = import_module(module)
-    except ImportError as e:
-        raise ImproperlyConfigured(
-            'Error importing SAML config loader %s: "%s"' % (path, e))
-    except ValueError as e:
-        raise ImproperlyConfigured(
-            'Error importing SAML config loader. Is SAML_CONFIG_LOADER '
-            'a correctly string with a callable path?'
-            )
-    try:
-        config_loader = getattr(mod, attr)
-    except AttributeError:
-        raise ImproperlyConfigured(
-            'Module "%s" does not define a "%s" config loader' %
-            (module, attr)
-            )
-
-    if not hasattr(config_loader, '__call__'):
-        raise ImproperlyConfigured(
-            "SAML config loader must be a callable object.")
-
-    return config_loader
-
-
-def config_settings_loader(request=None):
-    """Utility function to load the pysaml2 configuration.
-
-    This is also the default config loader.
-    """
-    conf = SPConfig()
-    conf.load(copy.deepcopy(settings.SAML_CONFIG))
-    return conf
-
-
-def get_config(config_loader_path=None, request=None):
-    config_loader_path = config_loader_path or get_custom_setting(
-        'SAML_CONFIG_LOADER', 'djangosaml2.conf.config_settings_loader')
-
-    config_loader = get_config_loader(config_loader_path)
-    return config_loader(request)

+ 0 - 2
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/exceptions.py

@@ -1,2 +0,0 @@
-class IdPConfigurationMissing(Exception):
-    pass

+ 0 - 1
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/models.py

@@ -1 +0,0 @@
-# nothing here, just an empty file to avoid Django complaints

+ 0 - 24
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/overrides.py

@@ -1,24 +0,0 @@
-import logging
-
-import saml2.client
-from django.conf import settings
-
-logger = logging.getLogger('djangosaml2')
-
-
-class Saml2Client(saml2.client.Saml2Client):
-    """
-    Custom Saml2Client that adds a choice of preference for binding used with
-    SAML Logout Requests. The preferred binding can be configured via
-    SAML_LOGOUT_REQUEST_PREFERRED_BINDING settings variable.
-    (Original Saml2Client always prefers SOAP, so it is always used if declared
-    in remote metadata); but doesn't actually work and causes crashes.
-    """
-    def do_logout(self, *args, **kwargs):
-        if not kwargs.get('expected_binding'):
-            try:
-                kwargs['expected_binding'] = settings.SAML_LOGOUT_REQUEST_PREFERRED_BINDING
-            except AttributeError:
-                logger.warning('SAML_LOGOUT_REQUEST_PREFERRED_BINDING setting is'
-                    ' not defined. Default binding will be used.')
-        return super(Saml2Client, self).do_logout(*args, **kwargs)

+ 0 - 20
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/signals.py

@@ -1,20 +0,0 @@
-# Copyright (C) 2011-2012 Yaco Sistemas (http://www.yaco.es)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import django.dispatch
-
-
-pre_user_save = django.dispatch.Signal(providing_args=['attributes',
-                                                       'user_modified'])
-post_authenticated = django.dispatch.Signal(providing_args=['session_info'])

+ 0 - 16
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/auth_error.html

@@ -1,16 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-  </head>
-  <body>
-    <h1>Authorization error</h1>
-    <p>You are already logged in and you are trying to go to the login page again.</p>
-
-    <p>You may have been redirected here when trying to access some content
-      that required extra privileges that you do not have.</p>
-
-    <p>Please <a href="{% url 'saml2_logout' %}">logout</a> and login as a different user</p>
-  </body>
-</html>

+ 0 - 18
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/echo_attributes.html

@@ -1,18 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-  </head>
-  <body>
-    <h1>SAML attributes</h1>
-    <dl>
-      {% for attribute, value in attributes.items %}
-      <dt>{{ attribute }}:</dt>
-      <dd>{{ value|join:", " }}</dd>
-      {% endfor %}
-    </dl>
-
-    <p><a href="{% url 'saml2_logout' %}">Log out</a></p>
-  </body>
-</html>

+ 0 - 15
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/example_post_binding_form.html

@@ -1,15 +0,0 @@
-<script type="text/javascript">
-	window.onload = function(){
-		document.SSO_Login.submit();
-	};
-</script>
-<p>
-You're being redirected to a SSO login page.
-Please click the button below if you're not redirected automatically within a few seconds.
-</p>
-<form method="post" action="{{ target_url }}" name="SSO_Login">
-	{% for key, value in params.items %}
-	    <input type="hidden" name="{{ key|safe }}" value="{{ value|safe }}" />
-	{% endfor %}
-    <input type="submit" value="Log in" />
-</form>

+ 0 - 13
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/login_error.html

@@ -1,13 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-  </head>
-  <body>
-    <h1>Authentication Error.</h1>
-
-    <h2>Access Denied.</h2>
-
-  </body>
-</html>

+ 0 - 17
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/logout_error.html

@@ -1,17 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-  </head>
-  <body>
-    <h1>Logout error</h1>
-    <p>Your Identity Provider ask this system to do a global logout but your federated session is lost.</p>
-
-    <p>Even if your local session in this system has been closed, you have probably open sessions in other systems.</p>
-
-    <p>In order to prevent illicit use of your personal information, please close your browser window and/or remove your cookies from your browser.</p>
-
-    <p>Sorry for this inconvenience.</p>
-  </body>
-</html>

+ 0 - 16
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templates/djangosaml2/wayf.html

@@ -1,16 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-  </head>
-  <body>
-    <h1>Where are you from?</h1>
-    <p>Please select your <strong>Identity Provider</strong> from the following list:</p>
-    <ul>
-      {% for url, name in available_idps %}
-      <li><a href="{% url 'saml2_login' %}?idp={{ url }}{% if came_from %}&next={{ came_from }}{% endif %}">{{ name }}</a></li>
-      {% endfor %}
-    </ul>
-  </body>
-</html>

+ 0 - 0
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templatetags/__init__.py


+ 0 - 45
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/templatetags/idplist.py

@@ -1,45 +0,0 @@
-# Copyright (C) 2011-2012 Yaco Sistemas (http://www.yaco.es)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from django import template
-
-from djangosaml2.conf import config_settings_loader
-from djangosaml2.utils import available_idps
-
-register = template.Library()
-
-
-class IdPListNode(template.Node):
-
-    def __init__(self, variable_name):
-        self.variable_name = variable_name
-
-    def render(self, context):
-        conf = config_settings_loader()
-        context[self.variable_name] = available_idps(conf)
-        return ''
-
-
-@register.tag
-def idplist(parser, token):
-    try:
-        tag_name, as_part, variable = token.split_contents()
-    except ValueError:
-        raise template.TemplateSyntaxError(
-            '%r tag requires two arguments' % token.contents.split()[0])
-    if not as_part == 'as':
-        raise template.TemplateSyntaxError(
-            '%r tag first argument must be the literal "as"' % tag_name)
-
-    return IdPListNode(variable)

+ 0 - 567
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/__init__.py

@@ -1,567 +0,0 @@
-# Copyright (C) 2012 Sam Bull (lsb@pocketuniverse.ca)
-# Copyright (C) 2011-2012 Yaco Sistemas (http://www.yaco.es)
-# Copyright (C) 2010 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import datetime
-import base64
-import re
-from unittest import skip
-import sys
-
-from django.conf import settings
-from django.contrib.auth import SESSION_KEY, get_user_model
-from django.contrib.auth.models import AnonymousUser
-from django.contrib.sessions.middleware import SessionMiddleware
-try:
-    from django.urls import reverse
-except ImportError:
-    from django.core.urlresolvers import reverse
-from django.template import Template, Context
-from django.test import TestCase
-from django.test.client import RequestFactory
-try:
-    from django.utils.encoding import force_text
-except ImportError:
-    from django.utils.text import force_text
-try:
-    from django.utils.six.moves.urllib.parse import urlparse, parse_qs
-except ImportError:
-    from urllib.parse import urlparse, parse_qs
-
-from saml2.config import SPConfig
-from saml2.s_utils import decode_base64_and_inflate, deflate_and_base64_encode
-
-from djangosaml2 import views
-from djangosaml2.cache import OutstandingQueriesCache
-from djangosaml2.conf import get_config
-from djangosaml2.tests import conf
-from djangosaml2.tests.auth_response import auth_response
-from djangosaml2.signals import post_authenticated
-from djangosaml2.views import finish_logout
-
-User = get_user_model()
-
-PY_VERSION = sys.version_info[:2]
-
-
-class SAML2Tests(TestCase):
-
-    urls = 'djangosaml2.tests.urls'
-
-    def setUp(self):
-        if hasattr(settings, 'SAML_ATTRIBUTE_MAPPING'):
-            self.actual_attribute_mapping = settings.SAML_ATTRIBUTE_MAPPING
-            del settings.SAML_ATTRIBUTE_MAPPING
-        if hasattr(settings, 'SAML_CONFIG_LOADER'):
-            self.actual_conf_loader = settings.SAML_CONFIG_LOADER
-            del settings.SAML_CONFIG_LOADER
-
-    def tearDown(self):
-        if hasattr(self, 'actual_attribute_mapping'):
-            settings.SAML_ATTRIBUTE_MAPPING = self.actual_attribute_mapping
-        if hasattr(self, 'actual_conf_loader'):
-            settings.SAML_CONFIG_LOADER = self.actual_conf_loader
-
-    def assertSAMLRequestsEquals(self, real_xml, expected_xmls):
-
-        def remove_variable_attributes(xml_string):
-            xml_string = re.sub(r' ID=".*?" ', ' ', xml_string)
-            xml_string = re.sub(r' IssueInstant=".*?" ', ' ', xml_string)
-            xml_string = re.sub(
-                r'<saml:NameID(.*)>.*</saml:NameID>',
-                r'<saml:NameID\1></saml:NameID>',
-                xml_string)
-
-            return xml_string
-
-        self.assertEqual(remove_variable_attributes(real_xml),
-                         remove_variable_attributes(expected_xmls))
-
-    def init_cookies(self):
-        self.client.cookies[settings.SESSION_COOKIE_NAME] = 'testing'
-
-    def add_outstanding_query(self, session_id, came_from):
-        session = self.client.session
-        oq_cache = OutstandingQueriesCache(session)
-        oq_cache.set(session_id, came_from)
-        session.save()
-        self.client.cookies[settings.SESSION_COOKIE_NAME] = session.session_key
-
-    def render_template(self, text):
-        return Template(text).render(Context())
-
-    def b64_for_post(self, xml_text, encoding='utf-8'):
-        return base64.b64encode(xml_text.encode(encoding)).decode('ascii')
-
-    def test_login_evil_redirect(self):
-        """
-        Make sure that if we give an URL other than our own host as the next
-        parameter, it is replaced with the default LOGIN_REDIRECT_URL.
-        """
-
-        # monkey patch SAML configuration
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp.example.com'],
-            metadata_file='remote_metadata_one_idp.xml',
-        )
-        response = self.client.get(reverse('saml2_login') + '?next=http://evil.com')
-        url = urlparse(response['Location'])
-        params = parse_qs(url.query)
-
-        self.assertEqual(params['RelayState'], [settings.LOGIN_REDIRECT_URL, ])
-
-    def test_login_one_idp(self):
-        # monkey patch SAML configuration
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp.example.com'],
-            metadata_file='remote_metadata_one_idp.xml',
-        )
-
-        response = self.client.get(reverse('saml2_login'))
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-
-        url = urlparse(location)
-        self.assertEqual(url.hostname, 'idp.example.com')
-        self.assertEqual(url.path, '/simplesaml/saml2/idp/SSOService.php')
-
-        params = parse_qs(url.query)
-        self.assertIn('SAMLRequest', params)
-        self.assertIn('RelayState', params)
-
-        saml_request = params['SAMLRequest'][0]
-        if PY_VERSION < (3,):
-            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
-<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
-        else:
-            expected_request = """<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
-
-        self.assertSAMLRequestsEquals(
-            decode_base64_and_inflate(saml_request).decode('utf-8'),
-            expected_request)
-
-        # if we set a next arg in the login view, it is preserverd
-        # in the RelayState argument
-        next = '/another-view/'
-        response = self.client.get(reverse('saml2_login'), {'next': next})
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-
-        url = urlparse(location)
-        self.assertEqual(url.hostname, 'idp.example.com')
-        self.assertEqual(url.path, '/simplesaml/saml2/idp/SSOService.php')
-
-        params = parse_qs(url.query)
-        self.assertIn('SAMLRequest', params)
-        self.assertIn('RelayState', params)
-        self.assertEqual(params['RelayState'][0], next)
-
-    def test_login_several_idps(self):
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp1.example.com',
-                       'idp2.example.com',
-                       'idp3.example.com'],
-            metadata_file='remote_metadata_three_idps.xml',
-        )
-        response = self.client.get(reverse('saml2_login'))
-        # a WAYF page should be displayed
-        self.assertContains(response, 'Where are you from?', status_code=200)
-        for i in range(1, 4):
-            link = '/login/?idp=https://idp%d.example.com/simplesaml/saml2/idp/metadata.php&next=/'
-            self.assertContains(response, link % i)
-
-        # click on the second idp
-        response = self.client.get(reverse('saml2_login'), {
-                'idp': 'https://idp2.example.com/simplesaml/saml2/idp/metadata.php',
-                'next': '/',
-                })
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-
-        url = urlparse(location)
-        self.assertEqual(url.hostname, 'idp2.example.com')
-        self.assertEqual(url.path, '/simplesaml/saml2/idp/SSOService.php')
-
-        params = parse_qs(url.query)
-        self.assertIn('SAMLRequest', params)
-        self.assertIn('RelayState', params)
-
-        saml_request = params['SAMLRequest'][0]
-        if PY_VERSION < (3,):
-            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
-<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp2.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
-        else:
-            expected_request = """<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp2.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
-
-        self.assertSAMLRequestsEquals(decode_base64_and_inflate(saml_request).decode('utf-8'),
-                                      expected_request)
-
-    def test_assertion_consumer_service(self):
-        # Get initial number of users
-        initial_user_count = User.objects.count()
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp.example.com'],
-            metadata_file='remote_metadata_one_idp.xml',
-        )
-
-        # session_id should start with a letter since it is a NCName
-        session_id = "a0123456789abcdef0123456789abcdef"
-        came_from = '/another-view/'
-        self.add_outstanding_query(session_id, came_from)
-
-        # this will create a user
-        saml_response = auth_response(session_id, 'student')
-        response = self.client.post(reverse('saml2_acs'), {
-                'SAMLResponse': self.b64_for_post(saml_response),
-                'RelayState': came_from,
-                })
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-        url = urlparse(location)
-        self.assertEqual(url.path, came_from)
-
-        self.assertEqual(User.objects.count(), initial_user_count + 1)
-        user_id = self.client.session[SESSION_KEY]
-        user = User.objects.get(id=user_id)
-        self.assertEqual(user.username, 'student')
-
-        # let's create another user and log in with that one
-        new_user = User.objects.create(username='teacher', password='not-used')
-
-        session_id = "a1111111111111111111111111111111"
-        came_from = ''  # bad, let's see if we can deal with this
-        saml_response = auth_response(session_id, 'teacher')
-        self.add_outstanding_query(session_id, '/')
-        response = self.client.post(reverse('saml2_acs'), {
-                'SAMLResponse': self.b64_for_post(saml_response),
-                'RelayState': came_from,
-                })
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-
-        url = urlparse(location)
-        # as the RelayState is empty we have redirect to LOGIN_REDIRECT_URL
-        self.assertEqual(url.path, settings.LOGIN_REDIRECT_URL)
-        self.assertEqual(force_text(new_user.id), self.client.session[SESSION_KEY])
-
-    def test_assertion_consumer_service_no_session(self):
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp.example.com'],
-            metadata_file='remote_metadata_one_idp.xml',
-        )
-
-        # session_id should start with a letter since it is a NCName
-        session_id = "a0123456789abcdef0123456789abcdef"
-        came_from = '/another-view/'
-        self.add_outstanding_query(session_id, came_from)
-
-        # Authentication is confirmed.
-        saml_response = auth_response(session_id, 'student')
-        response = self.client.post(reverse('saml2_acs'), {
-            'SAMLResponse': self.b64_for_post(saml_response),
-            'RelayState': came_from,
-        })
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-        url = urlparse(location)
-        self.assertEqual(url.path, came_from)
-
-        # Session should no longer be in outstanding queries.
-        saml_response = auth_response(session_id, 'student')
-        response = self.client.post(reverse('saml2_acs'), {
-            'SAMLResponse': self.b64_for_post(saml_response),
-            'RelayState': came_from,
-        })
-        self.assertEqual(response.status_code, 403)
-
-    def test_missing_param_to_assertion_consumer_service_request(self):
-        # Send request without SAML2Response parameter
-        response = self.client.post(reverse('saml2_acs'))
-        # Assert that view responded with "Bad Request" error
-        self.assertEqual(response.status_code, 400)
-
-    def test_bad_request_method_to_assertion_consumer_service(self):
-        # Send request with non-POST method.
-        response = self.client.get(reverse('saml2_acs'))
-        # Assert that view responded with method not allowed status
-        self.assertEqual(response.status_code, 405)
-
-    def do_login(self):
-        """Auxiliary method used in several tests (mainly logout tests)"""
-        self.init_cookies()
-
-        session_id = "a0123456789abcdef0123456789abcdef"
-        came_from = '/another-view/'
-        self.add_outstanding_query(session_id, came_from)
-
-        saml_response = auth_response(session_id, 'student')
-
-        # this will create a user
-        response = self.client.post(reverse('saml2_acs'), {
-                'SAMLResponse': self.b64_for_post(saml_response),
-                'RelayState': came_from,
-                })
-        self.assertEqual(response.status_code, 302)
-
-    @skip("This is a known issue caused by pysaml2. Needs more investigation. Fixes are welcome.")
-    def test_logout(self):
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp.example.com'],
-            metadata_file='remote_metadata_one_idp.xml',
-        )
-        self.do_login()
-
-        response = self.client.get(reverse('saml2_logout'))
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-
-        url = urlparse(location)
-        self.assertEqual(url.hostname, 'idp.example.com')
-        self.assertEqual(url.path,
-                         '/simplesaml/saml2/idp/SingleLogoutService.php')
-
-        params = parse_qs(url.query)
-        self.assertIn('SAMLRequest', params)
-
-        saml_request = params['SAMLRequest'][0]
-        if PY_VERSION < (3,):
-            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
-<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
-        else:
-            expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
-        self.assertSAMLRequestsEquals(decode_base64_and_inflate(saml_request).decode('utf-8'),
-                                      expected_request)
-
-    def test_logout_service_local(self):
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp.example.com'],
-            metadata_file='remote_metadata_one_idp.xml',
-        )
-
-        self.do_login()
-
-        response = self.client.get(reverse('saml2_logout'))
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-
-        url = urlparse(location)
-        self.assertEqual(url.hostname, 'idp.example.com')
-        self.assertEqual(url.path,
-                         '/simplesaml/saml2/idp/SingleLogoutService.php')
-
-        params = parse_qs(url.query)
-        self.assertIn('SAMLRequest', params)
-
-        saml_request = params['SAMLRequest'][0]
-        if PY_VERSION < (3,):
-            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
-<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
-        else:
-            expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
-        self.assertSAMLRequestsEquals(decode_base64_and_inflate(saml_request).decode('utf-8'),
-                                      expected_request)
-
-        # now simulate a logout response sent by the idp
-        request_id = re.findall(r' ID="(.*?)" ', expected_request)[0]
-        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
-
-        saml_response = """<?xml version='1.0' encoding='UTF-8'?>
-<samlp:LogoutResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://sp.example.com/saml2/ls/" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="%s" IssueInstant="%s" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>""" % (
-            request_id, instant)
-
-        response = self.client.get(reverse('saml2_ls'), {
-                'SAMLResponse': deflate_and_base64_encode(saml_response),
-                })
-        self.assertContains(response, "Logged out", status_code=200)
-        self.assertListEqual(list(self.client.session.keys()), [])
-
-    def test_logout_service_global(self):
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp.example.com'],
-            metadata_file='remote_metadata_one_idp.xml',
-        )
-
-        self.do_login()
-
-        # now simulate a global logout process initiated by another SP
-        subject_id = views._get_subject_id(self.client.session)
-        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
-        saml_request = """<?xml version='1.0' encoding='UTF-8'?>
-<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/"><saml:Issuer>https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>""" % (instant, subject_id.text)
-
-        response = self.client.get(reverse('saml2_ls'), {
-                'SAMLRequest': deflate_and_base64_encode(saml_request),
-                })
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-
-        url = urlparse(location)
-        self.assertEqual(url.hostname, 'idp.example.com')
-        self.assertEqual(url.path,
-                         '/simplesaml/saml2/idp/SingleLogoutService.php')
-
-        params = parse_qs(url.query)
-        self.assertIn('SAMLResponse', params)
-
-        saml_response = params['SAMLResponse'][0]
-        if PY_VERSION < (3,):
-            expected_response = """<?xml version='1.0' encoding='UTF-8'?>
-<samlp:LogoutResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="_9961abbaae6d06d251226cb25e38bf8f468036e57e" IssueInstant="2010-09-05T09:10:12Z" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>"""
-        else:
-            expected_response = """<samlp:LogoutResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="_9961abbaae6d06d251226cb25e38bf8f468036e57e" IssueInstant="2010-09-05T09:10:12Z" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>"""
-        self.assertSAMLRequestsEquals(decode_base64_and_inflate(saml_response).decode('utf-8'),
-                                      expected_response)
-
-    def test_incomplete_logout(self):
-        settings.SAML_CONFIG = conf.create_conf(sp_host='sp.example.com',
-                                                idp_hosts=['idp.example.com'])
-
-        # don't do a login
-
-        # now simulate a global logout process initiated by another SP
-        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
-        saml_request = '<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/"><saml:Issuer>https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>' % (
-            instant, 'invalid-subject-id')
-
-        response = self.client.get(reverse('saml2_ls'), {
-                'SAMLRequest': deflate_and_base64_encode(saml_request),
-                })
-        self.assertContains(response, 'Logout error', status_code=403)
-
-    def test_finish_logout_renders_error_template(self):
-        request = RequestFactory().get('/bar/foo')
-        response = finish_logout(request, None)
-        self.assertContains(response, "<h1>Logout error</h1>", status_code=200)
-
-    def _test_metadata(self):
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp.example.com'],
-            metadata_file='remote_metadata_one_idp.xml',
-        )
-        valid_until = datetime.datetime.utcnow() + datetime.timedelta(hours=24)
-        valid_until = valid_until.strftime("%Y-%m-%dT%H:%M:%SZ")
-        expected_metadata = """<?xml version='1.0' encoding='UTF-8'?>
-<md:EntityDescriptor entityID="http://sp.example.com/saml2/metadata/" validUntil="%s" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>MIIDPjCCAiYCCQCkHjPQlll+mzANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJF
-UzEQMA4GA1UECBMHU2V2aWxsYTEbMBkGA1UEChMSWWFjbyBTaXN0ZW1hcyBTLkwu
-MRAwDgYDVQQHEwdTZXZpbGxhMREwDwYDVQQDEwh0aWNvdGljbzAeFw0wOTEyMDQx
-OTQzNTJaFw0xMDEyMDQxOTQzNTJaMGExCzAJBgNVBAYTAkVTMRAwDgYDVQQIEwdT
-ZXZpbGxhMRswGQYDVQQKExJZYWNvIFNpc3RlbWFzIFMuTC4xEDAOBgNVBAcTB1Nl
-dmlsbGExETAPBgNVBAMTCHRpY290aWNvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEA7rMOMOaIZ/YYD5hYS6Hpjpovcu4k8gaIY+om9zCxLV5F8BLEfkxo
-Pk9IA3cRQNRxf7AXCFxEOH3nKy56AIi1gU7X6fCT30JBT8NQlYdgOVMLlR+tjy1b
-YV07tDa9U8gzjTyKQHgVwH0436+rmSPnacGj3fMwfySTMhtmrJmax0bIa8EB+gY1
-77DBtvf8dIZIXLlGMQFloZeUspvHOrgNoEA9xU4E9AanGnV9HeV37zv3mLDUOQLx
-4tk9sMQmylCpij7WZmcOV07DyJ/cEmnvHSalBTcyIgkcwlhmjtSgfCy6o5zuWxYd
-T9ia80SZbWzn8N6B0q+nq23+Oee9H0lvcwIDAQABMA0GCSqGSIb3DQEBBQUAA4IB
-AQCQBhKOqucJZAqGHx4ybDXNzpPethszonLNVg5deISSpWagy55KlGCi5laio/xq
-hHRx18eTzeCeLHQYvTQxw0IjZOezJ1X30DD9lEqPr6C+IrmZc6bn/pF76xsvdaRS
-gduNQPT1B25SV2HrEmbf8wafSlRARmBsyUHh860TqX7yFVjhYIAUF/El9rLca51j
-ljCIqqvT+klPdjQoZwODWPFHgute2oNRmoIcMjSnoy1+mxOC2Q/j7kcD8/etulg2
-XDxB3zD81gfdtT8VBFP+G4UrBa+5zFk6fT6U8a7ZqVsyH+rCXAdCyVlEC4Y5fZri
-ID4zT0FcZASGuthM56rRJJSx
-</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://sp.example.com/saml2/ls/" /><md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://sp.example.com/saml2/acs/" index="1" /><md:AttributeConsumingService index="1"><md:ServiceName xml:lang="en">Test SP</md:ServiceName><md:RequestedAttribute FriendlyName="uid" Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /><md:RequestedAttribute FriendlyName="eduPersonAffiliation" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false" /></md:AttributeConsumingService></md:SPSSODescriptor><md:Organization><md:OrganizationName xml:lang="es">Ejemplo S.A.</md:OrganizationName><md:OrganizationName xml:lang="en">Example Inc.</md:OrganizationName><md:OrganizationDisplayName xml:lang="es">Ejemplo</md:OrganizationDisplayName><md:OrganizationDisplayName xml:lang="en">Example</md:OrganizationDisplayName><md:OrganizationURL xml:lang="es">http://www.example.es</md:OrganizationURL><md:OrganizationURL xml:lang="en">http://www.example.com</md:OrganizationURL></md:Organization><md:ContactPerson contactType="technical"><md:Company>Example Inc.</md:Company><md:GivenName>Technical givenname</md:GivenName><md:SurName>Technical surname</md:SurName><md:EmailAddress>technical@sp.example.com</md:EmailAddress></md:ContactPerson><md:ContactPerson contactType="administrative"><md:Company>Example Inc.</md:Company><md:GivenName>Administrative givenname</md:GivenName><md:SurName>Administrative surname</md:SurName><md:EmailAddress>administrative@sp.example.ccom</md:EmailAddress></md:ContactPerson></md:EntityDescriptor>"""
-
-        expected_metadata = expected_metadata % valid_until
-
-        response = self.client.get('/metadata/')
-        self.assertEqual(response['Content-type'], 'text/xml; charset=utf8')
-        self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, expected_metadata)
-
-    def test_post_authenticated_signal(self):
-
-        def signal_handler(signal, user, session_info):
-            self.assertEqual(isinstance(user, User), True)
-
-        post_authenticated.connect(signal_handler, dispatch_uid='test_signal')
-
-        self.do_login()
-
-        post_authenticated.disconnect(dispatch_uid='test_signal')
-
-    def test_idplist_templatetag(self):
-        settings.SAML_CONFIG = conf.create_conf(
-            sp_host='sp.example.com',
-            idp_hosts=['idp1.example.com',
-                       'idp2.example.com',
-                       'idp3.example.com'],
-            metadata_file='remote_metadata_three_idps.xml',
-        )
-        rendered = self.render_template(
-            '{% load idplist %}'
-            '{% idplist as idps %}'
-            '{% for url, name in idps.items %}'
-            '{{ url }} - {{ name }}; '
-            '{% endfor %}'
-            )
-
-        # the idplist is unordered, so convert the result into a set.
-        rendered = set(rendered.split('; '))
-        expected = set([
-            u'https://idp1.example.com/simplesaml/saml2/idp/metadata.php - idp1.example.com IdP',
-            u'https://idp2.example.com/simplesaml/saml2/idp/metadata.php - idp2.example.com IdP',
-            u'https://idp3.example.com/simplesaml/saml2/idp/metadata.php - idp3.example.com IdP',
-            u'',
-        ])
-
-        self.assertEqual(rendered, expected)
-
-
-def test_config_loader(request):
-    config = SPConfig()
-    config.load({'entityid': 'testentity'})
-    return config
-
-
-def test_config_loader_with_real_conf(request):
-    config = SPConfig()
-    config.load(conf.create_conf(sp_host='sp.example.com',
-                                 idp_hosts=['idp.example.com'],
-                                 metadata_file='remote_metadata_one_idp.xml'))
-    return config
-
-
-class ConfTests(TestCase):
-
-    def test_custom_conf_loader(self):
-        config_loader_path = 'djangosaml2.tests.test_config_loader'
-        request = RequestFactory().get('/bar/foo')
-        conf = get_config(config_loader_path, request)
-
-        self.assertEqual(conf.entityid, 'testentity')
-
-    def test_custom_conf_loader_from_view(self):
-        config_loader_path = 'djangosaml2.tests.test_config_loader_with_real_conf'
-        request = RequestFactory().get('/login/')
-        request.user = AnonymousUser()
-        middleware = SessionMiddleware()
-        middleware.process_request(request)
-        request.session.save()
-        response = views.login(request, config_loader_path)
-        self.assertEqual(response.status_code, 302)
-        location = response['Location']
-
-        url = urlparse(location)
-        self.assertEqual(url.hostname, 'idp.example.com')
-        self.assertEqual(url.path, '/simplesaml/saml2/idp/SSOService.php')

+ 0 - 243
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/attribute-maps/saml_uri.py

@@ -1,243 +0,0 @@
-__author__ = 'rolandh'
-
-EDUPERSON_OID = "urn:oid:1.3.6.1.4.1.5923.1.1.1."
-X500ATTR_OID = "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.1."
-UMICH = "urn:oid:1.3.6.1.4.1.250.1.57."
-SCHAC = "urn:oid:1.3.6.1.4.1.25178.1.2."
-
-MAP = {
-    "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format: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_OID+'53': 'deltaRevocationList',
-        X500ATTR_OID+'52': 'supportedAlgorithms',
-        X500ATTR_OID+'51': 'houseIdentifier',
-        X500ATTR_OID+'50': 'uniqueMember',
-        X500ATTR_OID+'19': 'physicalDeliveryOfficeName',
-        X500ATTR_OID+'18': 'postOfficeBox',
-        X500ATTR_OID+'17': 'postalCode',
-        X500ATTR_OID+'16': 'postalAddress',
-        X500ATTR_OID+'15': 'businessCategory',
-        X500ATTR_OID+'14': 'searchGuide',
-        EDUPERSON_OID+'5': 'eduPersonPrimaryAffiliation',
-        X500ATTR_OID+'12': 'title',
-        X500ATTR_OID+'11': 'ou',
-        X500ATTR_OID+'10': 'o',
-        X500ATTR_OID+'37': 'cACertificate',
-        X500ATTR_OID+'36': 'userCertificate',
-        X500ATTR_OID+'31': 'member',
-        X500ATTR_OID+'30': 'supportedApplicationContext',
-        X500ATTR_OID+'33': 'roleOccupant',
-        X500ATTR_OID+'32': 'owner',
-        NETSCAPE_LDAP+'1': 'carLicense',
-        PKCS_9+'1': 'email',
-        NETSCAPE_LDAP+'3': 'employeeNumber',
-        NETSCAPE_LDAP+'2': 'departmentNumber',
-        X500ATTR_OID+'39': 'certificateRevocationList',
-        X500ATTR_OID+'38': 'authorityRevocationList',
-        NETSCAPE_LDAP+'216': 'userPKCS12',
-        EDUPERSON_OID+'8': 'eduPersonPrimaryOrgUnitDN',
-        X500ATTR_OID+'9': 'street',
-        X500ATTR_OID+'8': 'st',
-        NETSCAPE_LDAP+'39': 'preferredLanguage',
-        EDUPERSON_OID+'7': 'eduPersonEntitlement',
-        X500ATTR_OID+'2': 'knowledgeInformation',
-        X500ATTR_OID+'7': 'l',
-        X500ATTR_OID+'6': 'c',
-        X500ATTR_OID+'5': 'serialNumber',
-        X500ATTR_OID+'4': 'sn',
-        X500ATTR_OID+'3': 'cn',
-        UCL_DIR_PILOT+'60': 'jpegPhoto',
-        X500ATTR_OID+'65': 'pseudonym',
-        NOREDUPERSON_OID+'5': 'norEduPersonNIN',
-        UCL_DIR_PILOT+'3': 'mail',
-        UCL_DIR_PILOT+'25': 'dc',
-        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+'54': 'dmdName',
-        NETSCAPE_LDAP+'4': 'employeeType',
-        X500ATTR_OID+'22': 'teletexTerminalIdentifier',
-        X500ATTR_OID+'23': 'facsimileTelephoneNumber',
-        X500ATTR_OID+'20': 'telephoneNumber',
-        X500ATTR_OID+'21': 'telexNumber',
-        X500ATTR_OID+'26': 'registeredAddress',
-        X500ATTR_OID+'27': 'destinationIndicator',
-        X500ATTR_OID+'24': 'x121Address',
-        X500ATTR_OID+'25': 'internationaliSDNNumber',
-        X500ATTR_OID+'28': 'preferredDeliveryMethod',
-        X500ATTR_OID+'29': 'presentationAddress',
-        EDUPERSON_OID+'3': 'eduPersonOrgDN',
-        NOREDUPERSON_OID+'3': 'norEduPersonBirthDate',
-        UMICH+'57': 'labeledURI',
-        UCL_DIR_PILOT+'1': 'uid',
-        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',
-    },
-    "to": {
-        'roleOccupant': X500ATTR_OID+'33',
-        'gn': X500ATTR_OID+'42',
-        'norEduPersonNIN': NOREDUPERSON_OID+'5',
-        'title': X500ATTR_OID+'12',
-        'facsimileTelephoneNumber': X500ATTR_OID+'23',
-        'mail': UCL_DIR_PILOT+'3',
-        'postOfficeBox': X500ATTR_OID+'18',
-        'fax': X500ATTR_OID+'23',
-        'telephoneNumber': X500ATTR_OID+'20',
-        'norEduPersonBirthDate': NOREDUPERSON_OID+'3',
-        'rfc822Mailbox': UCL_DIR_PILOT+'3',
-        'dc': UCL_DIR_PILOT+'25',
-        'countryName': X500ATTR_OID+'6',
-        'emailAddress': PKCS_9+'1',
-        'employeeNumber': NETSCAPE_LDAP+'3',
-        'organizationName': X500ATTR_OID+'10',
-        'eduPersonAssurance': EDUPERSON_OID+'11',
-        'norEduOrgAcronym': NOREDUPERSON_OID+'6',
-        'registeredAddress': X500ATTR_OID+'26',
-        'physicalDeliveryOfficeName': X500ATTR_OID+'19',
-        'associatedDomain': UCL_DIR_PILOT+'37',
-        'l': X500ATTR_OID+'7',
-        'stateOrProvinceName': X500ATTR_OID+'8',
-        'federationFeideSchemaVersion': NOREDUPERSON_OID+'9',
-        'pkcs9email': PKCS_9+'1',
-        'givenName': X500ATTR_OID+'42',
-        'givenname': X500ATTR_OID+'42',
-        'x500UniqueIdentifier': X500ATTR_OID+'45',
-        'eduPersonNickname': EDUPERSON_OID+'2',
-        'houseIdentifier': X500ATTR_OID+'51',
-        'street': X500ATTR_OID+'9',
-        'supportedAlgorithms': X500ATTR_OID+'52',
-        'preferredLanguage': NETSCAPE_LDAP+'39',
-        'postalAddress': X500ATTR_OID+'16',
-        'email': PKCS_9+'1',
-        'norEduOrgUnitUniqueIdentifier': NOREDUPERSON_OID+'8',
-        'eduPersonPrimaryOrgUnitDN': EDUPERSON_OID+'8',
-        'c': X500ATTR_OID+'6',
-        'teletexTerminalIdentifier': X500ATTR_OID+'22',
-        'o': X500ATTR_OID+'10',
-        'cACertificate': X500ATTR_OID+'37',
-        'telexNumber': X500ATTR_OID+'21',
-        'ou': X500ATTR_OID+'11',
-        'initials': X500ATTR_OID+'43',
-        'eduPersonOrgUnitDN': EDUPERSON_OID+'4',
-        'deltaRevocationList': X500ATTR_OID+'53',
-        'norEduPersonLIN': NOREDUPERSON_OID+'4',
-        'supportedApplicationContext': X500ATTR_OID+'30',
-        'eduPersonEntitlement': EDUPERSON_OID+'7',
-        'generationQualifier': X500ATTR_OID+'44',
-        'eduPersonAffiliation': EDUPERSON_OID+'1',
-        'edupersonaffiliation': EDUPERSON_OID+'1',
-        'eduPersonPrincipalName': EDUPERSON_OID+'6',
-        'edupersonprincipalname': EDUPERSON_OID+'6',
-        'localityName': X500ATTR_OID+'7',
-        'owner': X500ATTR_OID+'32',
-        'norEduOrgUnitUniqueNumber': NOREDUPERSON_OID+'2',
-        'searchGuide': X500ATTR_OID+'14',
-        'certificateRevocationList': X500ATTR_OID+'39',
-        'organizationalUnitName': X500ATTR_OID+'11',
-        'userCertificate': X500ATTR_OID+'36',
-        'preferredDeliveryMethod': X500ATTR_OID+'28',
-        'internationaliSDNNumber': X500ATTR_OID+'25',
-        'uniqueMember': X500ATTR_OID+'50',
-        'departmentNumber': NETSCAPE_LDAP+'2',
-        'enhancedSearchGuide': X500ATTR_OID+'47',
-        'userPKCS12': NETSCAPE_LDAP+'216',
-        'eduPersonTargetedID': EDUPERSON_OID+'10',
-        'norEduOrgUniqueNumber': NOREDUPERSON_OID+'1',
-        'x121Address': X500ATTR_OID+'24',
-        'destinationIndicator': X500ATTR_OID+'27',
-        'eduPersonPrimaryAffiliation': EDUPERSON_OID+'5',
-        'surname': X500ATTR_OID+'4',
-        'jpegPhoto': UCL_DIR_PILOT+'60',
-        'eduPersonScopedAffiliation': EDUPERSON_OID+'9',
-        'edupersonscopedaffiliation': EDUPERSON_OID+'9',
-        'protocolInformation': X500ATTR_OID+'48',
-        'knowledgeInformation': X500ATTR_OID+'2',
-        'employeeType': NETSCAPE_LDAP+'4',
-        'userSMIMECertificate': NETSCAPE_LDAP+'40',
-        'member': X500ATTR_OID+'31',
-        'streetAddress': X500ATTR_OID+'9',
-        'dmdName': X500ATTR_OID+'54',
-        'postalCode': X500ATTR_OID+'17',
-        'pseudonym': X500ATTR_OID+'65',
-        'dnQualifier': X500ATTR_OID+'46',
-        'crossCertificatePair': X500ATTR_OID+'40',
-        'eduPersonOrgDN': EDUPERSON_OID+'3',
-        'authorityRevocationList': X500ATTR_OID+'38',
-        'displayName': NETSCAPE_LDAP+'241',
-        'businessCategory': X500ATTR_OID+'15',
-        'serialNumber': X500ATTR_OID+'5',
-        'norEduOrgUniqueIdentifier': NOREDUPERSON_OID+'7',
-        'st': X500ATTR_OID+'8',
-        'carLicense': NETSCAPE_LDAP+'1',
-        'presentationAddress': X500ATTR_OID+'29',
-        'sn': X500ATTR_OID+'4',
-        'cn': X500ATTR_OID+'3',
-        'domainComponent': UCL_DIR_PILOT+'25',
-        'labeledURI': UMICH+'57',
-        'uid': UCL_DIR_PILOT+'1',
-        'schacMotherTongue':SCHAC+'1',
-        'schacGender': SCHAC+'2',
-        'schacDateOfBirth':SCHAC+'3',
-        'schacPlaceOfBirth': SCHAC+'4',
-        'schacCountryOfCitizenship':SCHAC+'5',
-        'schacSn1': SCHAC+'6',
-        'schacSn2': SCHAC+'7',
-        'schacPersonalTitle':SCHAC+'8',
-        'schacHomeOrganization': SCHAC+'9',
-        'schacHomeOrganizationType': SCHAC+'10',
-        'schacCountryOfResidence': SCHAC+'11',
-        'schacUserPresenceID': SCHAC+'12',
-        'schacPersonalPosition': SCHAC+'13',
-        'schacPersonalUniqueCode': SCHAC+'14',
-        'schacPersonalUniqueID': SCHAC+'15',
-        'schacExpiryDate': SCHAC+'17',
-        'schacUserPrivateAttribute': SCHAC+'18',
-        'schacUserStatus': SCHAC+'19',
-        'schacProjectMembership': SCHAC+'20',
-        'schacProjectSpecificRole': SCHAC+'21',
-    }
-}

+ 0 - 103
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/auth_response.py

@@ -1,103 +0,0 @@
-# Copyright (C) 2011-2012 Yaco Sistemas (http://www.yaco.es)
-# Copyright (C) 2010 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import datetime
-
-
-def auth_response(session_id,
-                  uid,
-                  audience='http://sp.example.com/saml2/metadata/',
-                  acs_url='http://sp.example.com/saml2/acs/',
-                  metadata_url='http://sp.example.com/saml2/metadata/',
-                  attribute_statements=None):
-    """Generates a fresh signed authentication response
-
-    Params:
-        session_id: The session ID to generate the reponse for. Login set an
-            outstanding session ID, i.e. djangosaml2 waits for a response for
-            that session.
-        uid: Unique identifier for a User (will be present as an attribute in
-            the answer). Ignored when attribute_statements is not ``None``.
-        audience: SP entityid (used when PySAML validates the response
-            audience).
-        acs_url: URL where the response has been posted back.
-        metadata_url: URL where the SP metadata can be queried.
-        attribute_statements: An alternative XML AttributeStatement to use in
-            lieu of the default (uid). The uid argument is ignored when
-            attribute_statements is not ``None``.
-    """
-    timestamp = datetime.datetime.now() - datetime.timedelta(seconds=10)
-    tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
-    yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
-
-    if attribute_statements is None:
-        attribute_statements = (
-            '<saml:AttributeStatement>'
-                '<saml:Attribute FriendlyName="uid" Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">'
-                    '<saml:AttributeValue xsi:nil="true" xsi:type="xs:string">'
-                        '%(uid)s'
-                    '</saml:AttributeValue>'
-                '</saml:Attribute>'
-            '</saml:AttributeStatement>'
-        ) % {'uid': uid}
-
-    saml_response_tpl = (
-        "<?xml version='1.0' encoding='UTF-8'?>"
-        '<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Destination="%(acs_url)s" ID="id-88b9f586a2a3a639f9327485cc37c40a" InResponseTo="%(session_id)s" IssueInstant="%(timestamp)s" Version="2.0">'
-            '<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">'
-                'https://idp.example.com/simplesaml/saml2/idp/metadata.php'
-            '</saml:Issuer>'
-            '<samlp:Status>'
-                '<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />'
-            '</samlp:Status>'
-            '<saml:Assertion ID="id-093952102ceb73436e49cb91c58b0578" IssueInstant="%(timestamp)s" Version="2.0">'
-                '<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">'
-                    'https://idp.example.com/simplesaml/saml2/idp/metadata.php'
-                '</saml:Issuer>'
-                '<saml:Subject>'
-                    '<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" NameQualifier="" SPNameQualifier="%(metadata_url)s">'
-                        '1f87035b4c1325b296a53d92097e6b3fa36d7e30ee82e3fcb0680d60243c1f03'
-                    '</saml:NameID>'
-                    '<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">'
-                        '<saml:SubjectConfirmationData InResponseTo="%(session_id)s" NotOnOrAfter="%(tomorrow)s" Recipient="%(acs_url)s" />'
-                    '</saml:SubjectConfirmation>'
-                '</saml:Subject>'
-                '<saml:Conditions NotBefore="%(yesterday)s" NotOnOrAfter="%(tomorrow)s">'
-                    '<saml:AudienceRestriction>'
-                        '<saml:Audience>'
-                            '%(audience)s'
-                        '</saml:Audience>'
-                    '</saml:AudienceRestriction>'
-                '</saml:Conditions>'
-                '<saml:AuthnStatement AuthnInstant="%(timestamp)s" SessionIndex="%(session_id)s">'
-                    '<saml:AuthnContext>'
-                        '<saml:AuthnContextClassRef>'
-                            'urn:oasis:names:tc:SAML:2.0:ac:classes:Password'
-                        '</saml:AuthnContextClassRef>'
-                    '</saml:AuthnContext>'
-                '</saml:AuthnStatement>'
-                '%(attribute_statements)s'
-            '</saml:Assertion>'
-        '</samlp:Response>')
-    return saml_response_tpl % {
-        'session_id': session_id,
-        'audience': audience,
-        'acs_url': acs_url,
-        'metadata_url': metadata_url,
-        'attribute_statements': attribute_statements,
-        'timestamp': timestamp.strftime('%Y-%m-%dT%H:%M:%SZ'),
-        'tomorrow': tomorrow.strftime('%Y-%m-%dT%H:%M:%SZ'),
-        'yesterday': yesterday.strftime('%Y-%m-%dT%H:%M:%SZ'),
-    }

+ 0 - 104
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/conf.py

@@ -1,104 +0,0 @@
-# Copyright (C) 2011-2012 Yaco Sistemas (http://www.yaco.es)
-# Copyright (C) 2010 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os.path
-
-import saml2
-
-
-def create_conf(sp_host='sp.example.com', idp_hosts=['idp.example.com'],
-                metadata_file='remote_metadata.xml'):
-
-    try:
-        from saml2.sigver import get_xmlsec_binary
-    except ImportError:
-        get_xmlsec_binary = None
-
-    if get_xmlsec_binary:
-        xmlsec_path = get_xmlsec_binary(["/opt/local/bin"])
-    else:
-        xmlsec_path = '/usr/bin/xmlsec1'
-
-    BASEDIR = os.path.dirname(os.path.abspath(__file__))
-    config = {
-        'xmlsec_binary': xmlsec_path,
-        'entityid': 'http://%s/saml2/metadata/' % sp_host,
-        'attribute_map_dir': os.path.join(BASEDIR, 'attribute-maps'),
-
-        'service': {
-            'sp': {
-                'name': 'Test SP',
-                'name_id_format': saml2.saml.NAMEID_FORMAT_PERSISTENT,
-                'endpoints': {
-                    'assertion_consumer_service': [
-                        ('http://%s/saml2/acs/' % sp_host,
-                         saml2.BINDING_HTTP_POST),
-                        ],
-                    'single_logout_service': [
-                        ('http://%s/saml2/ls/' % sp_host,
-                         saml2.BINDING_HTTP_REDIRECT),
-                        ],
-                    },
-                'required_attributes': ['uid'],
-                'optional_attributes': ['eduPersonAffiliation'],
-                'idp': {},  # this is filled later
-                'want_response_signed': False,
-                },
-            },
-
-        'metadata': {
-            'local': [os.path.join(BASEDIR, metadata_file)],
-            },
-
-        'debug': 1,
-
-        # certificates
-        'key_file': os.path.join(BASEDIR, 'mycert.key'),
-        'cert_file': os.path.join(BASEDIR, 'mycert.pem'),
-
-        # These fields are only used when generating the metadata
-        'contact_person': [
-            {'given_name': 'Technical givenname',
-             'sur_name': 'Technical surname',
-             'company': 'Example Inc.',
-             'email_address': 'technical@sp.example.com',
-             'contact_type': 'technical'},
-            {'given_name': 'Administrative givenname',
-             'sur_name': 'Administrative surname',
-             'company': 'Example Inc.',
-             'email_address': 'administrative@sp.example.ccom',
-             'contact_type': 'administrative'},
-            ],
-        'organization': {
-            'name': [('Ejemplo S.A.', 'es'), ('Example Inc.', 'en')],
-            'display_name': [('Ejemplo', 'es'), ('Example', 'en')],
-            'url': [('http://www.example.es', 'es'),
-                    ('http://www.example.com', 'en')],
-            },
-        'valid_for': 24,
-        }
-
-    for idp in idp_hosts:
-        entity_id = 'https://%s/simplesaml/saml2/idp/metadata.php' % idp
-        config['service']['sp']['idp'][entity_id] = {
-            'single_sign_on_service': {
-                saml2.BINDING_HTTP_REDIRECT: 'https://%s/simplesaml/saml2/idp/SSOService.php' % idp,
-                },
-            'single_logout_service': {
-                saml2.BINDING_HTTP_REDIRECT: 'https://%s/simplesaml/saml2/idp/SingleLogoutService.php' % idp,
-                },
-            }
-
-    return config

+ 0 - 17
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/idpcert.csr

@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE REQUEST-----
-MIICrTCCAZUCAQAwaDELMAkGA1UEBhMCRVMxEDAOBgNVBAgMB1NldmlsbGExGzAZ
-BgNVBAoMEllhY28gU2lzdGVtYXMgUy5MLjEQMA4GA1UEBwwHU2V2aWxsYTEYMBYG
-A1UEAwwPaWRwLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAsUBPANpwZb1MUmRsEKMsb+v5eHNih8J/fU7g6iUtvBHacjuQeZEVye/K
-qxMOGC+wKW53xUDeITSs91w79eztm+QwdpZPzfjuKH4q5LNeMj6E8YwGw9vymF4b
-gsZfZ7iKY+RkqubH7bzYtPSeTtqDkNPlJy6qjpuFMaEkbjAaSAm0KW84/NpMnZn6
-HRATWs0noqNDo7yHafTRvtCbJbFp6cCbkTd4h0WeolQBmRisg7pMAmC8uuA06CX2
-hU8Ej5/unGw/hCMsF5ysPDYUzLwI18m+kZSgE+Yw2pkVdJcEtmJjw/HqbzJJ+rH4
-E8TdWHK7mMi13EwbyEav5d1shN7erwIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEB
-AJIrkVa22Yoi5TBIq5grZhDkyCFkxLn8xIGbr3eS4VSq6osgqsALCuxGAioXGoR7
-QkczLXz4rWVGCZBF8yGZ3/zujSW8ajqjLqnwgu4hK8TlgtBiIWG7kq+1/yTWD0zl
-kSts9WGKWKdSYHGAX8vTAFpYGVnw76H6Fd+cJwnuk0Zym6I9Vr4lTWtBQeVLrMxM
-8AlBYMAgJS3JGgsqAhcxv4oNdMKec6nJmJPSggWUmdNQN8Cluq30kJj3GGtuRd0c
-Z0qgTvBQzlSty63nqS76EFNdQiaIKfwvracqoDFIFkqvZgznQih40jzqhRpQ6E/Y
-jwz0DPWrG/7E5c/ga9yUt3U=
------END CERTIFICATE REQUEST-----

+ 0 - 27
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/idpcert.key

@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEAsUBPANpwZb1MUmRsEKMsb+v5eHNih8J/fU7g6iUtvBHacjuQ
-eZEVye/KqxMOGC+wKW53xUDeITSs91w79eztm+QwdpZPzfjuKH4q5LNeMj6E8YwG
-w9vymF4bgsZfZ7iKY+RkqubH7bzYtPSeTtqDkNPlJy6qjpuFMaEkbjAaSAm0KW84
-/NpMnZn6HRATWs0noqNDo7yHafTRvtCbJbFp6cCbkTd4h0WeolQBmRisg7pMAmC8
-uuA06CX2hU8Ej5/unGw/hCMsF5ysPDYUzLwI18m+kZSgE+Yw2pkVdJcEtmJjw/Hq
-bzJJ+rH4E8TdWHK7mMi13EwbyEav5d1shN7erwIDAQABAoIBAQCFkQk3gmOaNvhR
-Sf0o2Fz/Bdnai1BfLxB088CGkHeTNfzfgcUP5mV94yVcnqJLVXww7F5ylLwOV6xT
-RfylB+HRTDW81u3SL1f/yXs3FXbQ882oWzUp2A9KA/hFJoj0FtqqBYxaQEe9/UVr
-rr2we/cSZqpSSVca2VSYHm7eXX8gcnZa42jKrLLKFfybq4Pw/917tvKnWnES7MV1
-2jt2+ZeS/Q5GqqJR7hhyVwim10ifO2Lh9c0TB9e/U7ddyTIt6VfKusW7YiOrkRwx
-ZM1NpZly1IAxK55ceV6w7IX9y1FM6A8ZvV7bqfVn13S5Zdyjr5XkiU10WXBsHodx
-ZndU2SFRAoGBANqvzFjEcWkaDIYnV/vSPmDMrgMA5FL1cUN3if5+LRatiXeQKbnv
-nVA5edGnB8LlkMDD4oDjCqx0xVbxaWqS4X8WEPa1/xss34y1MRg6yMZgu60mkzPM
-pj+i5mk1Kvsjm6uYz6XPtm7//GWl2y+zgAl8+bgzeUFD5HKV4B+8iZPnAoGBAM9+
-nSZDTFrbA5z5vGLXJlOdAx38ffQTfC1isb+M5I8NhE4CctaYcXcgMbhl+avfEsK9
-Wgpivmd7KTnhTujnf4WaIoe655TpnXJJ6dCdXDWktWZTErfqAXTTl945BLrQuGbe
-EIAN+1bYqGmk73U/Uw28c8hbTmY6GHTEyQSWMYX5AoGBAKxcfw0/17tlApYCEIC0
-VuHosQZA/7S7KwhoAWWKgXMsV/rar2iTiUQf6PnrUly0n4CvY6j+Sf1fE+LQ56tO
-FVkbRUeOboE2vwOiFA3q1zA0MffpPYBIPohNlpk5hKTojduT16XyrvGR5ZcgQD+6
-lKHl1NTwDRP5tObzZfDdovnlAoGBAIXpeRKQrF6WqqZMpsBDioC7/J8FrWQwjxvb
-bkvpajjIyHJwMh09FT2EkZIofhHmTf1QpyO8xpWSbvDj8EFv5mUbLN3cSklY3Dw+
-Z6AzbqdQPaJkSthXNcloJcNNmTfYLKp29r8uRt+txEMqJ0DMNZXP4gmUo+xl4hK6
-TeGf7SZBAoGAdTfeG5EmOoTVITw3imvoyETtbXO309YeUhk14p0OELK25w8Dnh70
-OLTaY5o4zfUh0noKQSTM9sgxkBCFhwYPxw2CoIWikc1+izAiFesWpgVp8rkFPWuI
-B7+5OACkAYK2DGzdlwwVti3LkrvW8gOZ7CUS5W7XzhmpcH6/+mHaKEY=
------END RSA PRIVATE KEY-----

+ 0 - 20
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/idpcert.pem

@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDTDCCAjQCCQDs8RuyGDEFWTANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF
-UzEQMA4GA1UECAwHU2V2aWxsYTEbMBkGA1UECgwSWWFjbyBTaXN0ZW1hcyBTLkwu
-MRAwDgYDVQQHDAdTZXZpbGxhMRgwFgYDVQQDDA9pZHAuZXhhbXBsZS5jb20wHhcN
-MTAwODI4MTAyNjQ1WhcNMTEwODI4MTAyNjQ1WjBoMQswCQYDVQQGEwJFUzEQMA4G
-A1UECAwHU2V2aWxsYTEbMBkGA1UECgwSWWFjbyBTaXN0ZW1hcyBTLkwuMRAwDgYD
-VQQHDAdTZXZpbGxhMRgwFgYDVQQDDA9pZHAuZXhhbXBsZS5jb20wggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxQE8A2nBlvUxSZGwQoyxv6/l4c2KHwn99
-TuDqJS28EdpyO5B5kRXJ78qrEw4YL7ApbnfFQN4hNKz3XDv17O2b5DB2lk/N+O4o
-firks14yPoTxjAbD2/KYXhuCxl9nuIpj5GSq5sftvNi09J5O2oOQ0+UnLqqOm4Ux
-oSRuMBpICbQpbzj82kydmfodEBNazSeio0OjvIdp9NG+0JslsWnpwJuRN3iHRZ6i
-VAGZGKyDukwCYLy64DToJfaFTwSPn+6cbD+EIywXnKw8NhTMvAjXyb6RlKAT5jDa
-mRV0lwS2YmPD8epvMkn6sfgTxN1YcruYyLXcTBvIRq/l3WyE3t6vAgMBAAEwDQYJ
-KoZIhvcNAQEFBQADggEBAHLT+SirLvjzGb1kPJZq5hDhYAMIrUFSgU/ghNRd3tDw
-ryOHh9nHgjDq4siy9cRL19LRgly1wspErUTmL/cD6A6L7t6CFUXgXEzshJ+RsZz7
-Nbg+61pfK+4+OyO2I3pzGXAHsqLuUpUQFpwHBLu9YiHzY+uiKLgODZl5B3A8nqLN
-2NJ9uH9+YWgquxB6KQLW8cx9kC3AWAsEWihYFb22Uc6I8qFngmDldeHPgVFbt6nV
-74F28qlbWr69NvGMGHZdfL2Ts+KC/yer88+tNrUrJ1tV1jmaMglfWoVTIVMI0Agl
-/jPhsxhx0+HHOuIfcD6b334mi/UZz91y/d7poiiiMtY=
------END CERTIFICATE-----

+ 0 - 17
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/mycert.csr

@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE REQUEST-----
-MIICpjCCAY4CAQAwYTELMAkGA1UEBhMCRVMxEDAOBgNVBAgTB1NldmlsbGExGzAZ
-BgNVBAoTEllhY28gU2lzdGVtYXMgUy5MLjEQMA4GA1UEBxMHU2V2aWxsYTERMA8G
-A1UEAxMIdGljb3RpY28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDu
-sw4w5ohn9hgPmFhLoemOmi9y7iTyBohj6ib3MLEtXkXwEsR+TGg+T0gDdxFA1HF/
-sBcIXEQ4fecrLnoAiLWBTtfp8JPfQkFPw1CVh2A5UwuVH62PLVthXTu0Nr1TyDON
-PIpAeBXAfTjfr6uZI+dpwaPd8zB/JJMyG2asmZrHRshrwQH6BjXvsMG29/x0hkhc
-uUYxAWWhl5Sym8c6uA2gQD3FTgT0BqcadX0d5XfvO/eYsNQ5AvHi2T2wxCbKUKmK
-PtZmZw5XTsPIn9wSae8dJqUFNzIiCRzCWGaO1KB8LLqjnO5bFh1P2JrzRJltbOfw
-3oHSr6erbf45570fSW9zAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAQEAoK9viSij
-kqOwofEUvoJTMdcONm/Ext1yHIilsC3h5ZU451u0kurg4uuwpAOoZDOXtmZHfGOE
-/WQ0Juojpwco/SF1I+QGr7coq26xNQldsHlKBuO/wIrgVdtVfjOc+TxS/szMTZv5
-whZoZe6HEdxFBvVVedtOMiXONZzzzK3cycSgaQz7BglYgfbFuwB3hdV1Y+iMfQfq
-PoIxWrjeDJa1LgFBDkklpgWYLFiaMVvhhdZVFXs/E66OdFwZg+OEplb97bLVba8T
-BxDqu6yhNlDlnhaLBd5lIfDCqy5OXa65MqS3vIR9k5CCAwwtaPPxQ2ChUXYhwj0n
-aW9RyTsESl7Z+Q==
------END CERTIFICATE REQUEST-----

+ 0 - 27
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/mycert.key

@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA7rMOMOaIZ/YYD5hYS6Hpjpovcu4k8gaIY+om9zCxLV5F8BLE
-fkxoPk9IA3cRQNRxf7AXCFxEOH3nKy56AIi1gU7X6fCT30JBT8NQlYdgOVMLlR+t
-jy1bYV07tDa9U8gzjTyKQHgVwH0436+rmSPnacGj3fMwfySTMhtmrJmax0bIa8EB
-+gY177DBtvf8dIZIXLlGMQFloZeUspvHOrgNoEA9xU4E9AanGnV9HeV37zv3mLDU
-OQLx4tk9sMQmylCpij7WZmcOV07DyJ/cEmnvHSalBTcyIgkcwlhmjtSgfCy6o5zu
-WxYdT9ia80SZbWzn8N6B0q+nq23+Oee9H0lvcwIDAQABAoIBAEXolw1nVyfrgVx/
-58wu3XJwYdktOhDQLP3mRAc9cYayB5WqSXYb9qPZIGQzaRAtqBgXgIdoTmqlJSEW
-eZDSeSYn60COvyAyDWLI9z7z6RCg69F+95vpUswPPD8pkQWKqt6AjpUXFnfLtO5+
-SqmNRGdK2S1V3iw+kAWq1MVUL2qRFaC6izY3eln/C27mqVDLwb/SWGfl90S+/cNB
-4AyI5LaTT6fwTxjkxlJFIWF9qWjzXM2skRzb/V2QzCF+RiS27maNDnVJMGHWacmo
-2idxOyU+Q0VXmY0ycKkIOrSqoq+F168VxfZNMqUN9fyLu+AjEJmIZWC3jRX9P2NX
-ILQjMkECgYEA/sXSyjj05+oFCr/XSvBDy1/JnB2tOTTk/lFXe2IQpJpEb0RqNmYf
-vk/5OteMsDcxf13c4Gk7xJXkkgZutXa66PSL4h8DzBAwvl9R0YuWHhDyj4oeYCXl
-VsmIjtaUoPS297jckpQMXsuT7YSZpuycJmUGJ0WVq4wuuATIPIxIA9ECgYEA79lp
-N46rWGfel2+ruHxt/OZ5fbYzj6VnuwcwrDe2CcYmZ07SRH7AlnwRdPLyY7TGt+p2
-7RjhJ8jpjReJK5yNrnq2D82KgJOwysCGCNDHWf2llEW8Pv66MhDqCn86RYyFbiGn
-4jEb7IcWdmUfMPpOu3TWhxVl/AxUhA8asz1oJAMCgYEAtdoIgrWzAhLFdI3Io8Hp
-8jG2G4wHSC0cQvdWpUgzLvq6XF2OHrQ4dkRpVnni/yj2WL5r2Xbj5YdEdoLG5RoR
-ghSEAGw47qCj2k75fMPQ7DcWnCRvWBvUnmUN5z79KgJi02GNd8bbKZLQTRp3/nEn
-aDR19vQxSBiwhENNlgJfqPECgYAMdTJt3E8yDFMXcolsz6m21RHCYdBTybeVk04H
-4+zknRIpk4KAZEUEi/UsKeJFI4Ke0uLSddRcCKd42JwbU8pYIa+LKpXjD8jC/zT3
-CEESf4Y2KVkZvIlXSGGfofQY4K+dhMn/iaV1p56XD7GLDbVBL1RlN8tQSCOrqE0u
-uiXKmQKBgQCrBHEns8QMjWsMRfh+5ebSQNRY1XVtIWV10MMsA3zZqRLUwC0XcU2Z
-FEF0FvXgWGC/MQOxXA5ACnToEC7PTfg5WPHxvf0dFi8sGr6nE6yWIzvNJKdp4rz3
-q+99h7P2j25C2CmXJ2uS4zhXzaNbZ+UpyDDIzi7Ndw40A3wuh9U7Qw==
------END RSA PRIVATE KEY-----

+ 0 - 20
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/mycert.pem

@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDPjCCAiYCCQCkHjPQlll+mzANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJF
-UzEQMA4GA1UECBMHU2V2aWxsYTEbMBkGA1UEChMSWWFjbyBTaXN0ZW1hcyBTLkwu
-MRAwDgYDVQQHEwdTZXZpbGxhMREwDwYDVQQDEwh0aWNvdGljbzAeFw0wOTEyMDQx
-OTQzNTJaFw0xMDEyMDQxOTQzNTJaMGExCzAJBgNVBAYTAkVTMRAwDgYDVQQIEwdT
-ZXZpbGxhMRswGQYDVQQKExJZYWNvIFNpc3RlbWFzIFMuTC4xEDAOBgNVBAcTB1Nl
-dmlsbGExETAPBgNVBAMTCHRpY290aWNvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEA7rMOMOaIZ/YYD5hYS6Hpjpovcu4k8gaIY+om9zCxLV5F8BLEfkxo
-Pk9IA3cRQNRxf7AXCFxEOH3nKy56AIi1gU7X6fCT30JBT8NQlYdgOVMLlR+tjy1b
-YV07tDa9U8gzjTyKQHgVwH0436+rmSPnacGj3fMwfySTMhtmrJmax0bIa8EB+gY1
-77DBtvf8dIZIXLlGMQFloZeUspvHOrgNoEA9xU4E9AanGnV9HeV37zv3mLDUOQLx
-4tk9sMQmylCpij7WZmcOV07DyJ/cEmnvHSalBTcyIgkcwlhmjtSgfCy6o5zuWxYd
-T9ia80SZbWzn8N6B0q+nq23+Oee9H0lvcwIDAQABMA0GCSqGSIb3DQEBBQUAA4IB
-AQCQBhKOqucJZAqGHx4ybDXNzpPethszonLNVg5deISSpWagy55KlGCi5laio/xq
-hHRx18eTzeCeLHQYvTQxw0IjZOezJ1X30DD9lEqPr6C+IrmZc6bn/pF76xsvdaRS
-gduNQPT1B25SV2HrEmbf8wafSlRARmBsyUHh860TqX7yFVjhYIAUF/El9rLca51j
-ljCIqqvT+klPdjQoZwODWPFHgute2oNRmoIcMjSnoy1+mxOC2Q/j7kcD8/etulg2
-XDxB3zD81gfdtT8VBFP+G4UrBa+5zFk6fT6U8a7ZqVsyH+rCXAdCyVlEC4Y5fZri
-ID4zT0FcZASGuthM56rRJJSx
------END CERTIFICATE-----

+ 0 - 123
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/remote_metadata.xml

@@ -1,123 +0,0 @@
-<?xml version="1.0"?>
-<md:EntitiesDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-  <md:EntityDescriptor entityID="https://idp.example.com/simplesaml/saml2/idp/metadata.php">
-    <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor use="signing">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:KeyDescriptor use="encryption">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php"/>
-      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
-      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.example.com/simplesaml/saml2/idp/SSOService.php"/>
-    </md:IDPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationName xml:lang="en">Lorenzo's test IdP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">idp.example.com IdP</md:OrganizationDisplayName>
-      <md:OrganizationURL xml:lang="en">http://idp.example.com/</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-  <md:EntityDescriptor entityID="https://idp1.example.com/simplesaml/saml2/idp/metadata.php">
-    <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor use="signing">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:KeyDescriptor use="encryption">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp1.example.com/simplesaml/saml2/idp/SingleLogoutService.php"/>
-      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
-      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp1.example.com/simplesaml/saml2/idp/SSOService.php"/>
-    </md:IDPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationName xml:lang="en">Lorenzo's test IdP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">idp1.example.com IdP</md:OrganizationDisplayName>
-      <md:OrganizationURL xml:lang="en">http://idp1.example.com/</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-  <md:EntityDescriptor entityID="https://idp2.example.com/simplesaml/saml2/idp/metadata.php">
-    <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor use="signing">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:KeyDescriptor use="encryption">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp2.example.com/simplesaml/saml2/idp/SingleLogoutService.php"/>
-      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
-      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp2.example.com/simplesaml/saml2/idp/SSOService.php"/>
-    </md:IDPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationName xml:lang="en">Lorenzo's test IdP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">idp2.example.com IdP</md:OrganizationDisplayName>
-      <md:OrganizationURL xml:lang="en">http://idp2.example.com/</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-  <md:EntityDescriptor entityID="https://idp3.example.com/simplesaml/saml2/idp/metadata.php">
-    <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor use="signing">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:KeyDescriptor use="encryption">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp3.example.com/simplesaml/saml2/idp/SingleLogoutService.php"/>
-      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
-      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp3.example.com/simplesaml/saml2/idp/SSOService.php"/>
-    </md:IDPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationName xml:lang="en">Lorenzo's test IdP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">idp3.example.com IdP</md:OrganizationDisplayName>
-      <md:OrganizationURL xml:lang="en">http://idp3.example.com/</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-</md:EntitiesDescriptor>

+ 0 - 33
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/remote_metadata_one_idp.xml

@@ -1,33 +0,0 @@
-<?xml version="1.0"?>
-<md:EntitiesDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-  <md:EntityDescriptor entityID="https://idp.example.com/simplesaml/saml2/idp/metadata.php">
-    <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor use="signing">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:KeyDescriptor use="encryption">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php"/>
-      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
-      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.example.com/simplesaml/saml2/idp/SSOService.php"/>
-    </md:IDPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationName xml:lang="en">Lorenzo's test IdP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">idp.example.com IdP</md:OrganizationDisplayName>
-      <md:OrganizationURL xml:lang="en">http://idp.example.com/</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-</md:EntitiesDescriptor>

+ 0 - 93
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/remote_metadata_three_idps.xml

@@ -1,93 +0,0 @@
-<?xml version="1.0"?>
-<md:EntitiesDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-  <md:EntityDescriptor entityID="https://idp1.example.com/simplesaml/saml2/idp/metadata.php">
-    <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor use="signing">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:KeyDescriptor use="encryption">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp1.example.com/simplesaml/saml2/idp/SingleLogoutService.php"/>
-      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
-      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp1.example.com/simplesaml/saml2/idp/SSOService.php"/>
-    </md:IDPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationName xml:lang="en">Lorenzo's test IdP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">idp1.example.com IdP</md:OrganizationDisplayName>
-      <md:OrganizationURL xml:lang="en">http://idp1.example.com/</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-  <md:EntityDescriptor entityID="https://idp2.example.com/simplesaml/saml2/idp/metadata.php">
-    <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor use="signing">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:KeyDescriptor use="encryption">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp2.example.com/simplesaml/saml2/idp/SingleLogoutService.php"/>
-      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
-      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp2.example.com/simplesaml/saml2/idp/SSOService.php"/>
-    </md:IDPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationName xml:lang="en">Lorenzo's test IdP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">idp2.example.com IdP</md:OrganizationDisplayName>
-      <md:OrganizationURL xml:lang="en">http://idp2.example.com/</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-  <md:EntityDescriptor entityID="https://idp3.example.com/simplesaml/saml2/idp/metadata.php">
-    <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor use="signing">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:KeyDescriptor use="encryption">
-        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-          <ds:X509Data>
-            <ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
-          </ds:X509Data>
-        </ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp3.example.com/simplesaml/saml2/idp/SingleLogoutService.php"/>
-      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
-      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp3.example.com/simplesaml/saml2/idp/SSOService.php"/>
-    </md:IDPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationName xml:lang="en">Lorenzo's test IdP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">idp3.example.com IdP</md:OrganizationDisplayName>
-      <md:OrganizationURL xml:lang="en">http://idp3.example.com/</md:OrganizationURL>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-</md:EntitiesDescriptor>

+ 0 - 42
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/sp_metadata.xml

@@ -1,42 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<md:EntitiesDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
-  <md:EntityDescriptor entityID="http://sp.example.com/saml2/metadata/">
-    <md:SPSSODescriptor AuthnRequestsSigned="False" WantAssertionsSigned="True" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
-      <md:KeyDescriptor>
-	<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
-	  <ds:X509Data>
-	    <ds:X509Certificate>MIIDFjCCAf4CCQCzHO9MprkomDANBgkqhkiG9w0BAQUFADBNMQswCQYDVQQGEwJl
-czEQMA4GA1UECAwHU2V2aWxsYTENMAsGA1UECgwEWWFjbzEQMA4GA1UEBwwHU2V2
-aWxsYTELMAkGA1UEAwwCU1AwHhcNMTIwMzE1MjA1MjA1WhcNMTMwMzE1MjA1MjA1
-WjBNMQswCQYDVQQGEwJlczEQMA4GA1UECAwHU2V2aWxsYTENMAsGA1UECgwEWWFj
-bzEQMA4GA1UEBwwHU2V2aWxsYTELMAkGA1UEAwwCU1AwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQCeOJEVPpGZMDm3nZsJkl/jH8lEmhA4OWgILP3XzdYL
-rc/fuKR66XYapGied+Pe+PldqyfLpkojUuRDwAXHTprr1HKlUkKvt4Lk0mqH9Z3/
-mZgj1NkKQBkGRLU0miFK93+m1B/Zlg4K1ycRV7111l5NvT9EVDAnyRU0RVjTrifp
-duy85vz9BnRusaR1YKc3NfwC1BiRUAAqhbuSYa0ALwVVri7mNob+/lYmbqrWScpA
-QFHy4VjSricjR8WvFjC3eBJbV7LIzdtd19cD+yDX2cDgXXR+QFxLUhHEhVrF+wvT
-QGcaZPYFiujcY/3FveRoRwdp6e03sUH/eqJksgR5ylJfAgMBAAEwDQYJKoZIhvcN
-AQEFBQADggEBAAu0rKFYHr6pi3yqIIc8EE6NnngqyZEnnDRPWuUK3WKcDI5rOmy9
-8pPE+6sj2NBJyyPu/bsiaCOZBOPywh/AZymO6q3iJRB3pmllH7zYp0LW10HI3NRw
-0T5BJ1ecudM5oitzE7EeMAT6+PogB9i+wxbf/p2YUYsbyiD/JPcrbt5h22sLGxTZ
-ovbOVacQF9es/YenvgmFGY42yea6fO33jZyBTiY69Tmjt+sv1nQJTUIyGeb1bVvF
-JMCJ3g73lNb3DTDS0UO+zLTlTHb1M/uJJnGY/CCb4kmoPRpxgMbybOh2TVfx9RHm
-45W7GtDf4fZ+LqdZC0JVAZQ7a28L5df0TwQ=
-</ds:X509Certificate>
-	  </ds:X509Data>
-	</ds:KeyInfo>
-      </md:KeyDescriptor>
-      <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://sp.example.com/saml2/acs/" index="0" />
-      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://sp.example.com/saml2/ls/"/>
-    </md:SPSSODescriptor>
-    <md:Organization>
-      <md:OrganizationURL xml:lang="en">http://sp.example.com/</md:OrganizationURL>
-      <md:OrganizationName xml:lang="en">Lorenzo's test SP</md:OrganizationName>
-      <md:OrganizationDisplayName xml:lang="en">sp.example.com</md:OrganizationDisplayName>
-    </md:Organization>
-    <md:ContactPerson contactType="technical">
-      <md:SurName>Administrator</md:SurName>
-      <md:EmailAddress>lgs@yaco.es</md:EmailAddress>
-    </md:ContactPerson>
-  </md:EntityDescriptor>
-</md:EntitiesDescriptor>

+ 0 - 16
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/spcert.csr

@@ -1,16 +0,0 @@
------BEGIN CERTIFICATE REQUEST-----
-MIICkjCCAXoCAQAwTTELMAkGA1UEBhMCZXMxEDAOBgNVBAgMB1NldmlsbGExDTAL
-BgNVBAoMBFlhY28xEDAOBgNVBAcMB1NldmlsbGExCzAJBgNVBAMMAlNQMIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnjiRFT6RmTA5t52bCZJf4x/JRJoQ
-ODloCCz9183WC63P37ikeul2GqRonnfj3vj5Xasny6ZKI1LkQ8AFx06a69RypVJC
-r7eC5NJqh/Wd/5mYI9TZCkAZBkS1NJohSvd/ptQf2ZYOCtcnEVe9ddZeTb0/RFQw
-J8kVNEVY064n6XbsvOb8/QZ0brGkdWCnNzX8AtQYkVAAKoW7kmGtAC8FVa4u5jaG
-/v5WJm6q1knKQEBR8uFY0q4nI0fFrxYwt3gSW1eyyM3bXdfXA/sg19nA4F10fkBc
-S1IRxIVaxfsL00BnGmT2BYro3GP9xb3kaEcHaentN7FB/3qiZLIEecpSXwIDAQAB
-oAAwDQYJKoZIhvcNAQEFBQADggEBAIKJqu8OspbEUBizU9XJBUsdIgFaSurC2QxX
-Z/E1bVsg5NLlWYk3Hq8Vec6jCRluasOtqyTqCt9KH+RP+6Q4PXKf0OM5AQ/wLS4R
-4tj2wISEUeuIawwZ64hu8ICEHEoQrRpFos0MWGNXFG5uCxApy7wtpoZsaG8/Lrlw
-5+NVqR3PfC64e4LMVWO60g4OqLzda/XwIrkQszPL5q8zvlTc8ra4d0XEklrmgj2f
-I0U0CaImxEVjBXphRUK/RKOFo97mrzw/I9J2oNgJXr0M079m4tnC7kMZgBao39l5
-buzpclosi0oznSJWwyV9i/KiIBDqr9iF8l9qCyyVv/CwHGVQW3k=
------END CERTIFICATE REQUEST-----

+ 0 - 27
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/spcert.key

@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAnjiRFT6RmTA5t52bCZJf4x/JRJoQODloCCz9183WC63P37ik
-eul2GqRonnfj3vj5Xasny6ZKI1LkQ8AFx06a69RypVJCr7eC5NJqh/Wd/5mYI9TZ
-CkAZBkS1NJohSvd/ptQf2ZYOCtcnEVe9ddZeTb0/RFQwJ8kVNEVY064n6XbsvOb8
-/QZ0brGkdWCnNzX8AtQYkVAAKoW7kmGtAC8FVa4u5jaG/v5WJm6q1knKQEBR8uFY
-0q4nI0fFrxYwt3gSW1eyyM3bXdfXA/sg19nA4F10fkBcS1IRxIVaxfsL00BnGmT2
-BYro3GP9xb3kaEcHaentN7FB/3qiZLIEecpSXwIDAQABAoIBAFtwT5Cah2SjtUeD
-gx0mBdpp/VRzQRptOs02y0ETyTcYrUEbIZuTHtlI2Nl0ajHra5oRlz8fjEsb1aW9
-7NkBeZD/R355quaIRNJfNIf8j+Iu7vkOQpyk7JFt1ddfmAwOOyy7/Ogvy0/CheaE
-8Y6PZBLDYzPm/6mOkX2S8kHrrU9DrdOWNzcJNhOV1UbPpo/e4S2rHHQzx71GU/50
-HKdKVv5WX+A9vqIzugvXlN0BpGtW4vAOwnXLg5rTg2RLAeCNdBsKUbFPqVaA6xSC
-+bgCpR+UC2MWmDBGlIMMTr4Yytuv0n+EkF590N/VqlF5coWTbBjAMogs1t8WxEuQ
-d3Caj5ECgYEAz4qum5tkPMZEvLIXABWb26ZBhTSqsyWt4uLuEJb66Q0PRE7yYtxh
-8XL0b2WFfia5dQJGFBTeQATa5VFejMXbxtKWjbdhX8d5mefWZ6xMsgxssx4kBwmp
-fsvd1wdFRZEJZE6VLnm/WGRd1SETYFUuzpyLwLypnqkjTdw8Gl9htqcCgYEAwyna
-Kr7+b/8F9y0Ka09WdgJIagqi4aoFX63ZV1LfIiqPiAFu/N9BGMr2BRfy+PoKfMdk
-R6oVIiFKVE5KWgy++K9TXZ3zBkhRwDFKzyTbaIF8P9mxbEBxhB/G8GF/sEnVo2/R
-+F3TUIRO8/ZIk7HU9uubIcdIgSuuJ5pthsO5NYkCgYBfOnwJzFA/Dp6FkpW5JTEh
-pPSVYWgd0WErJQMlO5Gfk614o1zWfda3Cg8cehG5o50fEk8DcdvUtiWWaTKgFz1T
-ylboacdVQlsKgnU/lrCOVeMegOr5C7bpBjQhMSXY2Mbdbq1G6PgiX9MqMwYIAq36
-gZwicK7HrUYUuMQfObrFKwKBgFBZnM7Yj5zAnE4lpxKDOY+gZPvzoRfTjh7UTpUb
-M263oxxVqsJFkGGKvjtentRO7Z5t4SV4KvdASX/oM8hbUwzD8kiqzPGbOL0uDiS2
-gfbGyMbo85kj9xh0lM1G9vE3lNOTKBlfV67gqjja/wp/vrRiUB5aE8nKmAsKE2nW
-jxwxAoGAXBVVaHMA5vVmCZLwuKQxfFfCfd8K7GDeEwXVh0dAv1aglfHk4wSKiKJB
-K2OEyYusUQX2hFKzAPWY3nReH+nrgXOBzFXlk6S8pJlXLiDFaDac/DCi0u2dQa4w
-vYKXdYMo+cuVYtf1zuUlzlkWprL6Tk04T3AFbcf4nX8dvtf6Iwc=
------END RSA PRIVATE KEY-----

+ 0 - 19
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/spcert.pem

@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDFjCCAf4CCQCzHO9MprkomDANBgkqhkiG9w0BAQUFADBNMQswCQYDVQQGEwJl
-czEQMA4GA1UECAwHU2V2aWxsYTENMAsGA1UECgwEWWFjbzEQMA4GA1UEBwwHU2V2
-aWxsYTELMAkGA1UEAwwCU1AwHhcNMTIwMzE1MjA1MjA1WhcNMTMwMzE1MjA1MjA1
-WjBNMQswCQYDVQQGEwJlczEQMA4GA1UECAwHU2V2aWxsYTENMAsGA1UECgwEWWFj
-bzEQMA4GA1UEBwwHU2V2aWxsYTELMAkGA1UEAwwCU1AwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQCeOJEVPpGZMDm3nZsJkl/jH8lEmhA4OWgILP3XzdYL
-rc/fuKR66XYapGied+Pe+PldqyfLpkojUuRDwAXHTprr1HKlUkKvt4Lk0mqH9Z3/
-mZgj1NkKQBkGRLU0miFK93+m1B/Zlg4K1ycRV7111l5NvT9EVDAnyRU0RVjTrifp
-duy85vz9BnRusaR1YKc3NfwC1BiRUAAqhbuSYa0ALwVVri7mNob+/lYmbqrWScpA
-QFHy4VjSricjR8WvFjC3eBJbV7LIzdtd19cD+yDX2cDgXXR+QFxLUhHEhVrF+wvT
-QGcaZPYFiujcY/3FveRoRwdp6e03sUH/eqJksgR5ylJfAgMBAAEwDQYJKoZIhvcN
-AQEFBQADggEBAAu0rKFYHr6pi3yqIIc8EE6NnngqyZEnnDRPWuUK3WKcDI5rOmy9
-8pPE+6sj2NBJyyPu/bsiaCOZBOPywh/AZymO6q3iJRB3pmllH7zYp0LW10HI3NRw
-0T5BJ1ecudM5oitzE7EeMAT6+PogB9i+wxbf/p2YUYsbyiD/JPcrbt5h22sLGxTZ
-ovbOVacQF9es/YenvgmFGY42yea6fO33jZyBTiY69Tmjt+sv1nQJTUIyGeb1bVvF
-JMCJ3g73lNb3DTDS0UO+zLTlTHb1M/uJJnGY/CCb4kmoPRpxgMbybOh2TVfx9RHm
-45W7GtDf4fZ+LqdZC0JVAZQ7a28L5df0TwQ=
------END CERTIFICATE-----

+ 0 - 31
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/tests/urls.py

@@ -1,31 +0,0 @@
-# Copyright (C) 2012 Yaco Sistemas (http://www.yaco.es)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from django.conf.urls import include, url
-from django.contrib import admin
-
-from djangosaml2 import views
-
-
-urlpatterns = [
-    url(r'^login/$', views.login, name='saml2_login'),
-    url(r'^acs/$', views.assertion_consumer_service, name='saml2_acs'),
-    url(r'^logout/$', views.logout, name='saml2_logout'),
-    url(r'^ls/$', views.logout_service, name='saml2_ls'),
-    url(r'^ls/post/$', views.logout_service_post, name='saml2_ls_post'),
-    url(r'^metadata/$', views.metadata, name='saml2_metadata'),
-
-    # this is needed for the tests
-    url(r'^admin/', include(admin.site.urls)),
-]

+ 0 - 27
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/urls.py

@@ -1,27 +0,0 @@
-# Copyright (C) 2010-2012 Yaco Sistemas (http://www.yaco.es)
-# Copyright (C) 2009 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from django.urls import path
-
-from . import views
-
-urlpatterns = [
-    path('login/', views.login, name='saml2_login'),
-    path('acs/', views.assertion_consumer_service, name='saml2_acs'),
-    path('logout/', views.logout, name='saml2_logout'),
-    path('ls/', views.logout_service, name='saml2_ls'),
-    path('ls/post/', views.logout_service_post, name='saml2_ls_post'),
-    path('metadata/', views.metadata, name='saml2_metadata'),
-]

+ 0 - 90
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/utils.py

@@ -1,90 +0,0 @@
-# Copyright (C) 2012 Yaco Sistemas (http://www.yaco.es)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import django
-from django.conf import settings
-from django.core.exceptions import ImproperlyConfigured
-from django.utils.http import is_safe_url
-from django.utils.module_loading import import_string
-from saml2.s_utils import UnknownSystemEntity
-
-
-def get_custom_setting(name, default=None):
-    return getattr(settings, name, default)
-
-
-def available_idps(config, langpref=None):
-    if langpref is None:
-        langpref = "en"
-
-    idps = set()
-
-    for metadata_name, metadata in config.metadata.metadata.items():
-        result = metadata.any('idpsso_descriptor', 'single_sign_on_service')
-        if result:
-            idps = idps.union(set(result.keys()))
-
-    return dict([(idp, config.metadata.name(idp, langpref)) for idp in idps])
-
-
-def get_idp_sso_supported_bindings(idp_entity_id=None, config=None):
-    """Returns the list of bindings supported by an IDP
-    This is not clear in the pysaml2 code, so wrapping it in a util"""
-    if config is None:
-        # avoid circular import
-        from djangosaml2.conf import get_config
-        config = get_config()
-    # load metadata store from config
-    meta = getattr(config, 'metadata', {})
-    # if idp is None, assume only one exists so just use that
-    if idp_entity_id is None:
-        # .keys() returns dict_keys in python3.5+
-        try:
-            idp_entity_id = list(available_idps(config).keys())[0]
-        except IndexError:
-            raise ImproperlyConfigured("No IdP configured!")
-    try:
-        return meta.service(idp_entity_id, 'idpsso_descriptor', 'single_sign_on_service').keys()
-    except UnknownSystemEntity:
-        return []
-
-
-def get_location(http_info):
-    """Extract the redirect URL from a pysaml2 http_info object"""
-    try:
-        headers = dict(http_info['headers'])
-        return headers['Location']
-    except KeyError:
-        return http_info['url']
-
-
-def fail_acs_response(request, *args, **kwargs):
-    """ Serves as a common mechanism for ending ACS in case of any SAML related failure.
-    Handling can be configured by setting the SAML_ACS_FAILURE_RESPONSE_FUNCTION as
-    suitable for the project.
-
-    The default behavior uses SAML specific template that is rendered on any ACS error,
-    but this can be simply changed so that PermissionDenied exception is raised instead.
-    """
-    failure_function = import_string(get_custom_setting('SAML_ACS_FAILURE_RESPONSE_FUNCTION',
-                                                        'djangosaml2.acs_failures.template_failure'))
-    return failure_function(request, *args, **kwargs)
-
-
-def is_safe_url_compat(url, allowed_hosts=None, require_https=False):
-    if django.VERSION >= (1, 11):
-        return is_safe_url(url, allowed_hosts=allowed_hosts, require_https=require_https)
-    assert len(allowed_hosts) == 1
-    host = allowed_hosts.pop()
-    return is_safe_url(url, host=host)

+ 0 - 536
desktop/core/ext-py3/djangosaml2-0.18.0/djangosaml2/views.py

@@ -1,536 +0,0 @@
-# Copyright (C) 2010-2013 Yaco Sistemas (http://www.yaco.es)
-# Copyright (C) 2009 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import base64
-import logging
-
-from django.conf import settings
-from django.contrib import auth
-from django.contrib.auth.decorators import login_required
-try:
-    from django.contrib.auth.views import LogoutView
-    django_logout = LogoutView.as_view()
-except ImportError:
-    from django.contrib.auth.views import logout as django_logout
-from django.core.exceptions import PermissionDenied, SuspiciousOperation
-from django.http import Http404, HttpResponse
-from django.http import HttpResponseRedirect  # 30x
-from django.http import HttpResponseBadRequest  # 40x
-from django.http import HttpResponseServerError  # 50x
-from django.views.decorators.http import require_POST
-from django.shortcuts import render
-from django.template import TemplateDoesNotExist
-
-try:
-    from django.utils.six import text_type, binary_type, PY3
-except ImportError:
-    import sys
-    PY3 = sys.version_info[0] == 3
-    text_type = str
-    binary_type = bytes
-
-from django.views.decorators.csrf import csrf_exempt
-
-from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST
-from saml2.metadata import entity_descriptor
-from saml2.ident import code, decode
-from saml2.sigver import MissingKey
-from saml2.s_utils import UnsupportedBinding
-from saml2.response import (
-    StatusError, StatusAuthnFailed, SignatureError, StatusRequestDenied,
-    UnsolicitedResponse, StatusNoAuthnContext,
-)
-from saml2.validate import ResponseLifetimeExceed, ToEarly
-from saml2.xmldsig import SIG_RSA_SHA1, SIG_RSA_SHA256  # support for SHA1 is required by spec
-
-from djangosaml2.cache import IdentityCache, OutstandingQueriesCache
-from djangosaml2.cache import StateCache
-from djangosaml2.exceptions import IdPConfigurationMissing
-from djangosaml2.conf import get_config
-from djangosaml2.overrides import Saml2Client
-from djangosaml2.signals import post_authenticated
-from djangosaml2.utils import (
-    available_idps, fail_acs_response, get_custom_setting,
-    get_idp_sso_supported_bindings, get_location, is_safe_url_compat,
-)
-
-
-logger = logging.getLogger('djangosaml2')
-
-
-def _set_subject_id(session, subject_id):
-    session['_saml2_subject_id'] = code(subject_id)
-
-
-def _get_subject_id(session):
-    try:
-        return decode(session['_saml2_subject_id'])
-    except KeyError:
-        return None
-
-
-def callable_bool(value):
-    """ A compatibility wrapper for pre Django 1.10 User model API that used
-    is_authenticated() and is_anonymous() methods instead of attributes
-    """
-    if callable(value):
-        return value()
-    else:
-        return value
-
-
-def login(request,
-          config_loader_path=None,
-          wayf_template='djangosaml2/wayf.html',
-          authorization_error_template='djangosaml2/auth_error.html',
-          post_binding_form_template='djangosaml2/post_binding_form.html'):
-    """SAML Authorization Request initiator
-
-    This view initiates the SAML2 Authorization handshake
-    using the pysaml2 library to create the AuthnRequest.
-    It uses the SAML 2.0 Http Redirect protocol binding.
-
-    * post_binding_form_template - path to a template containing HTML form with
-    hidden input elements, used to send the SAML message data when HTTP POST
-    binding is being used. You can customize this template to include custom
-    branding and/or text explaining the automatic redirection process. Please
-    see the example template in
-    templates/djangosaml2/example_post_binding_form.html
-    If set to None or nonexistent template, default form from the saml2 library
-    will be rendered.
-    """
-    logger.debug('Login process started')
-
-    came_from = request.GET.get('next', settings.LOGIN_REDIRECT_URL)
-    if not came_from:
-        logger.warning('The next parameter exists but is empty')
-        came_from = settings.LOGIN_REDIRECT_URL
-
-    # Ensure the user-originating redirection url is safe.
-    if not is_safe_url_compat(url=came_from, allowed_hosts={request.get_host()}):
-        came_from = settings.LOGIN_REDIRECT_URL
-
-    # if the user is already authenticated that maybe because of two reasons:
-    # A) He has this URL in two browser windows and in the other one he
-    #    has already initiated the authenticated session.
-    # B) He comes from a view that (incorrectly) send him here because
-    #    he does not have enough permissions. That view should have shown
-    #    an authorization error in the first place.
-    # We can only make one thing here and that is configurable with the
-    # SAML_IGNORE_AUTHENTICATED_USERS_ON_LOGIN setting. If that setting
-    # is True (default value) we will redirect him to the came_from view.
-    # Otherwise, we will show an (configurable) authorization error.
-    if callable_bool(request.user.is_authenticated):
-        redirect_authenticated_user = getattr(settings, 'SAML_IGNORE_AUTHENTICATED_USERS_ON_LOGIN', True)
-        if redirect_authenticated_user:
-            return HttpResponseRedirect(came_from)
-        else:
-            logger.debug('User is already logged in')
-            return render(request, authorization_error_template, {
-                    'came_from': came_from,
-                    }, using='django')
-
-    selected_idp = request.GET.get('idp', None)
-    conf = get_config(config_loader_path, request)
-
-    kwargs = {}
-    # pysaml needs a string otherwise: "cannot serialize True (type bool)"
-    if getattr(conf, '_sp_force_authn', False):
-        kwargs['force_authn'] = "true"
-    if getattr(conf, '_sp_allow_create', False):
-        kwargs['allow_create'] = "true"
-
-    # is a embedded wayf needed?
-    idps = available_idps(conf)
-    if selected_idp is None and len(idps) > 1:
-        logger.debug('A discovery process is needed')
-        return render(request, wayf_template, {
-                'available_idps': idps.items(),
-                'came_from': came_from,
-                }, using='django')
-    else:
-        # is the first one, otherwise next logger message will print None
-        if not idps:
-            raise IdPConfigurationMissing(('IdP configuration is missing or '
-                                           'its metadata is expired.'))
-        if selected_idp is None:
-            selected_idp = list(idps.keys())[0]
-    
-    # choose a binding to try first
-    sign_requests = getattr(conf, '_sp_authn_requests_signed', False)
-    binding = BINDING_HTTP_POST if sign_requests else BINDING_HTTP_REDIRECT
-    logger.debug('Trying binding %s for IDP %s', binding, selected_idp)
-
-    # ensure our selected binding is supported by the IDP
-    supported_bindings = get_idp_sso_supported_bindings(selected_idp, config=conf)
-    if binding not in supported_bindings:
-        logger.debug('Binding %s not in IDP %s supported bindings: %s',
-                     binding, selected_idp, supported_bindings)
-        if binding == BINDING_HTTP_POST:
-            logger.warning('IDP %s does not support %s,  trying %s',
-                           selected_idp, binding, BINDING_HTTP_REDIRECT)
-            binding = BINDING_HTTP_REDIRECT
-        else:
-            logger.warning('IDP %s does not support %s,  trying %s',
-                           selected_idp, binding, BINDING_HTTP_POST)
-            binding = BINDING_HTTP_POST
-        # if switched binding still not supported, give up
-        if binding not in supported_bindings:
-            raise UnsupportedBinding('IDP %s does not support %s or %s',
-                                     selected_idp, BINDING_HTTP_POST, BINDING_HTTP_REDIRECT)
-
-    client = Saml2Client(conf)
-    http_response = None
-
-    logger.debug('Redirecting user to the IdP via %s binding.', binding)
-    if binding == BINDING_HTTP_REDIRECT:
-        try:
-            # do not sign the xml itself, instead use the sigalg to
-            # generate the signature as a URL param
-            sig_alg_option_map = {'sha1': SIG_RSA_SHA1,
-                                  'sha256': SIG_RSA_SHA256}
-            sig_alg_option = getattr(conf, '_sp_authn_requests_signed_alg', 'sha1')
-            sigalg = sig_alg_option_map[sig_alg_option] if sign_requests else None
-            nsprefix = get_namespace_prefixes()
-            session_id, result = client.prepare_for_authenticate(
-                entityid=selected_idp, relay_state=came_from,
-                binding=binding, sign=False, sigalg=sigalg,
-                nsprefix=nsprefix, **kwargs)
-        except TypeError as e:
-            logger.error('Unable to know which IdP to use')
-            return HttpResponse(text_type(e))
-        else:
-            http_response = HttpResponseRedirect(get_location(result))
-    elif binding == BINDING_HTTP_POST:
-        if post_binding_form_template:
-            # get request XML to build our own html based on the template
-            try:
-                location = client.sso_location(selected_idp, binding)
-            except TypeError as e:
-                logger.error('Unable to know which IdP to use')
-                return HttpResponse(text_type(e))
-            session_id, request_xml = client.create_authn_request(
-                location,
-                binding=binding,
-                **kwargs)
-            try:
-                if PY3:
-                    saml_request = base64.b64encode(binary_type(request_xml, 'UTF-8')).decode('utf-8')
-                else:
-                    saml_request = base64.b64encode(binary_type(request_xml))
-
-                http_response = render(request, post_binding_form_template, {
-                    'request': request,
-                    'target_url': location,
-                    'params': {
-                        'SAMLRequest': saml_request,
-                        'RelayState': came_from,
-                        },
-                    }, using='django')
-            except TemplateDoesNotExist:
-                pass
-
-        if not http_response:
-            # use the html provided by pysaml2 if no template was specified or it didn't exist
-            try:
-                session_id, result = client.prepare_for_authenticate(
-                    entityid=selected_idp, relay_state=came_from,
-                    binding=binding)
-            except TypeError as e:
-                logger.error('Unable to know which IdP to use')
-                return HttpResponse(text_type(e))
-            else:
-                http_response = HttpResponse(result['data'])
-    else:
-        raise UnsupportedBinding('Unsupported binding: %s', binding)
-
-    # success, so save the session ID and return our response
-    logger.debug('Saving the session_id in the OutstandingQueries cache')
-    oq_cache = OutstandingQueriesCache(request.session)
-    oq_cache.set(session_id, came_from)
-    return http_response
-
-
-@require_POST
-@csrf_exempt
-def assertion_consumer_service(request,
-                               config_loader_path=None,
-                               attribute_mapping=None,
-                               create_unknown_user=None):
-    """SAML Authorization Response endpoint
-
-    The IdP will send its response to this view, which
-    will process it with pysaml2 help and log the user
-    in using the custom Authorization backend
-    djangosaml2.backends.Saml2Backend that should be
-    enabled in the settings.py
-    """
-    attribute_mapping = attribute_mapping or get_custom_setting('SAML_ATTRIBUTE_MAPPING', {'uid': ('username', )})
-    create_unknown_user = create_unknown_user if create_unknown_user is not None else \
-                          get_custom_setting('SAML_CREATE_UNKNOWN_USER', True)
-    conf = get_config(config_loader_path, request)
-    try:
-        xmlstr = request.POST['SAMLResponse']
-    except KeyError:
-        logger.warning('Missing "SAMLResponse" parameter in POST data.')
-        raise SuspiciousOperation
-
-    client = Saml2Client(conf, identity_cache=IdentityCache(request.session))
-
-    oq_cache = OutstandingQueriesCache(request.session)
-    outstanding_queries = oq_cache.outstanding_queries()
-
-    try:
-        response = client.parse_authn_request_response(xmlstr, BINDING_HTTP_POST, outstanding_queries)
-    except (StatusError, ToEarly):
-        logger.exception("Error processing SAML Assertion.")
-        return fail_acs_response(request)
-    except ResponseLifetimeExceed:
-        logger.info("SAML Assertion is no longer valid. Possibly caused by network delay or replay attack.", exc_info=True)
-        return fail_acs_response(request)
-    except SignatureError:
-        logger.info("Invalid or malformed SAML Assertion.", exc_info=True)
-        return fail_acs_response(request)
-    except StatusAuthnFailed:
-        logger.info("Authentication denied for user by IdP.", exc_info=True)
-        return fail_acs_response(request)
-    except StatusRequestDenied:
-        logger.warning("Authentication interrupted at IdP.", exc_info=True)
-        return fail_acs_response(request)
-    except StatusNoAuthnContext:
-        logger.warning("Missing Authentication Context from IdP.", exc_info=True)
-        return fail_acs_response(request)
-    except MissingKey:
-        logger.exception("SAML Identity Provider is not configured correctly: certificate key is missing!")
-        return fail_acs_response(request)
-    except UnsolicitedResponse:
-        logger.exception("Received SAMLResponse when no request has been made.")
-        return fail_acs_response(request)
-
-    if response is None:
-        logger.warning("Invalid SAML Assertion received (unknown error).")
-        return fail_acs_response(request, status=400, exc_class=SuspiciousOperation)
-
-    session_id = response.session_id()
-    oq_cache.delete(session_id)
-
-    # authenticate the remote user
-    session_info = response.session_info()
-
-    if callable(attribute_mapping):
-        attribute_mapping = attribute_mapping()
-    if callable(create_unknown_user):
-        create_unknown_user = create_unknown_user()
-
-    logger.debug('Trying to authenticate the user. Session info: %s', session_info)
-    user = auth.authenticate(request=request,
-                             session_info=session_info,
-                             attribute_mapping=attribute_mapping,
-                             create_unknown_user=create_unknown_user)
-    if user is None:
-        logger.warning("Could not authenticate user received in SAML Assertion. Session info: %s", session_info)
-        raise PermissionDenied
-
-    auth.login(request, user)
-    _set_subject_id(request.session, session_info['name_id'])
-    logger.debug("User %s authenticated via SSO.", user)
-
-    logger.debug('Sending the post_authenticated signal')
-    post_authenticated.send_robust(sender=user, session_info=session_info)
-
-    # redirect the user to the view where he came from
-    default_relay_state = get_custom_setting('ACS_DEFAULT_REDIRECT_URL',
-                                             settings.LOGIN_REDIRECT_URL)
-    relay_state = request.POST.get('RelayState', default_relay_state)
-    if not relay_state:
-        logger.warning('The RelayState parameter exists but is empty')
-        relay_state = default_relay_state
-    if not is_safe_url_compat(url=relay_state, allowed_hosts={request.get_host()}):
-        relay_state = settings.LOGIN_REDIRECT_URL
-    logger.debug('Redirecting to the RelayState: %s', relay_state)
-    return HttpResponseRedirect(relay_state)
-
-
-@login_required
-def echo_attributes(request,
-                    config_loader_path=None,
-                    template='djangosaml2/echo_attributes.html'):
-    """Example view that echo the SAML attributes of an user"""
-    state = StateCache(request.session)
-    conf = get_config(config_loader_path, request)
-
-    client = Saml2Client(conf, state_cache=state,
-                         identity_cache=IdentityCache(request.session))
-    subject_id = _get_subject_id(request.session)
-    try:
-        identity = client.users.get_identity(subject_id,
-                                             check_not_on_or_after=False)
-    except AttributeError:
-        return HttpResponse("No active SAML identity found. Are you sure you have logged in via SAML?")
-
-    return render(request, template, {'attributes': identity[0]}, using='django')
-
-
-@login_required
-def logout(request, config_loader_path=None):
-    """SAML Logout Request initiator
-
-    This view initiates the SAML2 Logout request
-    using the pysaml2 library to create the LogoutRequest.
-    """
-    state = StateCache(request.session)
-    conf = get_config(config_loader_path, request)
-
-    client = Saml2Client(conf, state_cache=state,
-                         identity_cache=IdentityCache(request.session))
-    subject_id = _get_subject_id(request.session)
-    if subject_id is None:
-        logger.warning(
-            'The session does not contain the subject id for user %s',
-            request.user)
-
-    result = client.global_logout(subject_id)
-
-    state.sync()
-
-    if not result:
-        logger.error("Looks like the user %s is not logged in any IdP/AA", subject_id)
-        return HttpResponseBadRequest("You are not logged in any IdP/AA")
-
-    if len(result) > 1:
-        logger.error('Sorry, I do not know how to logout from several sources. I will logout just from the first one')
-
-    for entityid, logout_info in result.items():
-        if isinstance(logout_info, tuple):
-            binding, http_info = logout_info
-            if binding == BINDING_HTTP_POST:
-                logger.debug('Returning form to the IdP to continue the logout process')
-                body = ''.join(http_info['data'])
-                return HttpResponse(body)
-            elif binding == BINDING_HTTP_REDIRECT:
-                logger.debug('Redirecting to the IdP to continue the logout process')
-                return HttpResponseRedirect(get_location(http_info))
-            else:
-                logger.error('Unknown binding: %s', binding)
-                return HttpResponseServerError('Failed to log out')
-        else:
-            # We must have had a soap logout
-            return finish_logout(request, logout_info)
-
-    logger.error('Could not logout because there only the HTTP_REDIRECT is supported')
-    return HttpResponseServerError('Logout Binding not supported')
-
-
-def logout_service(request, *args, **kwargs):
-    return do_logout_service(request, request.GET, BINDING_HTTP_REDIRECT, *args, **kwargs)
-
-
-@csrf_exempt
-def logout_service_post(request, *args, **kwargs):
-    return do_logout_service(request, request.POST, BINDING_HTTP_POST, *args, **kwargs)
-
-
-def do_logout_service(request, data, binding, config_loader_path=None, next_page=None,
-                   logout_error_template='djangosaml2/logout_error.html'):
-    """SAML Logout Response endpoint
-
-    The IdP will send the logout response to this view,
-    which will process it with pysaml2 help and log the user
-    out.
-    Note that the IdP can request a logout even when
-    we didn't initiate the process as a single logout
-    request started by another SP.
-    """
-    logger.debug('Logout service started')
-    conf = get_config(config_loader_path, request)
-
-    state = StateCache(request.session)
-    client = Saml2Client(conf, state_cache=state,
-                         identity_cache=IdentityCache(request.session))
-
-    if 'SAMLResponse' in data:  # we started the logout
-        logger.debug('Receiving a logout response from the IdP')
-        response = client.parse_logout_request_response(data['SAMLResponse'], binding)
-        state.sync()
-        return finish_logout(request, response, next_page=next_page)
-
-    elif 'SAMLRequest' in data:  # logout started by the IdP
-        logger.debug('Receiving a logout request from the IdP')
-        subject_id = _get_subject_id(request.session)
-        if subject_id is None:
-            logger.warning(
-                'The session does not contain the subject id for user %s. Performing local logout',
-                request.user)
-            auth.logout(request)
-            return render(request, logout_error_template, status=403, using='django')
-        else:
-            http_info = client.handle_logout_request(
-                data['SAMLRequest'],
-                subject_id,
-                binding,
-                relay_state=data.get('RelayState', ''))
-            state.sync()
-            auth.logout(request)
-            if (
-                http_info.get('method', 'GET') == 'POST' and
-                'data' in http_info and
-                ('Content-type', 'text/html') in http_info.get('headers', [])
-            ):
-                # need to send back to the IDP a signed POST response with user session
-                # return HTML form content to browser with auto form validation
-                # to finally send request to the IDP
-                return HttpResponse(http_info['data'])
-            else:
-                return HttpResponseRedirect(get_location(http_info))
-    else:
-        logger.error('No SAMLResponse or SAMLRequest parameter found')
-        raise Http404('No SAMLResponse or SAMLRequest parameter found')
-
-
-def finish_logout(request, response, next_page=None):
-    if response and response.status_ok():
-        if next_page is None and hasattr(settings, 'LOGOUT_REDIRECT_URL'):
-            next_page = settings.LOGOUT_REDIRECT_URL
-        logger.debug('Performing django logout with a next_page of %s',
-                     next_page)
-        return django_logout(request, next_page=next_page)
-    else:
-        logger.error('Unknown error during the logout')
-        return render(request, "djangosaml2/logout_error.html", {}, using='django')
-
-
-def metadata(request, config_loader_path=None, valid_for=None):
-    """Returns an XML with the SAML 2.0 metadata for this
-    SP as configured in the settings.py file.
-    """
-    conf = get_config(config_loader_path, request)
-    metadata = entity_descriptor(conf)
-    return HttpResponse(content=text_type(metadata).encode('utf-8'),
-                        content_type="text/xml; charset=utf8")
-
-
-def get_namespace_prefixes():
-    from saml2 import md, saml, samlp
-    try:
-        from saml2 import xmlenc
-        from saml2 import xmldsig
-    except ImportError:
-        import xmlenc
-        import xmldsig
-    return {'saml': saml.NAMESPACE,
-            'samlp': samlp.NAMESPACE,
-            'md': md.NAMESPACE,
-            'ds': xmldsig.NAMESPACE,
-            'xenc': xmlenc.NAMESPACE}

+ 0 - 7
desktop/core/ext-py3/djangosaml2-0.18.0/setup.cfg

@@ -1,7 +0,0 @@
-[bdist_wheel]
-universal = 1
-
-[egg_info]
-tag_build = 
-tag_date = 0
-

+ 0 - 80
desktop/core/ext-py3/djangosaml2-0.18.0/setup.py

@@ -1,80 +0,0 @@
-# Copyright (C) 2011-2012 Yaco Sistemas <lgs@yaco.es>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import codecs
-import os
-import sys
-from setuptools import setup, find_packages
-
-
-def read(*rnames):
-    return codecs.open(os.path.join(os.path.dirname(__file__), *rnames), encoding='utf-8').read()
-
-
-extra = {'test': []}
-if sys.version_info < (3, 4):
-    # Necessary to use assertLogs in tests
-    extra['test'].append('unittest2')
-
-
-setup(
-    name='djangosaml2',
-    version='0.18.0',
-    description='pysaml2 integration for Django',
-    long_description=read('README.rst'),
-    classifiers=[
-        "Development Status :: 4 - Beta",
-        "Environment :: Web Environment",
-        "Framework :: Django",
-        "Framework :: Django :: 1.8",
-        "Framework :: Django :: 1.9",
-        "Framework :: Django :: 1.10",
-        "Framework :: Django :: 1.11",
-        "Framework :: Django :: 2.0",
-        "Framework :: Django :: 2.1",
-        "Framework :: Django :: 2.2",
-        "Framework :: Django :: 3.0",
-        "Intended Audience :: Developers",
-        "License :: OSI Approved :: Apache Software License",
-        "Operating System :: OS Independent",
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.5",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
-        "Topic :: Internet :: WWW/HTTP",
-        "Topic :: Internet :: WWW/HTTP :: WSGI",
-        "Topic :: Security",
-        "Topic :: Software Development :: Libraries :: Application Frameworks",
-        ],
-    keywords="django,pysaml2,sso,saml2,federated authentication,authentication",
-    author="Yaco Sistemas and independent contributors",
-    author_email="lgs@yaco.es",
-    maintainer="Jozef Knaperek",
-    url="https://github.com/knaperek/djangosaml2",
-    download_url="https://pypi.org/project/djangosaml2/",
-    license='Apache 2.0',
-    packages=find_packages(exclude=["tests", "tests.*"]),
-    include_package_data=True,
-    zip_safe=False,
-    install_requires=[
-        'defusedxml>=0.4.1',
-        'Django>=1.8',
-        'pysaml2>=4.6.0',
-        ],
-    extras_require=extra,
-    )

+ 1 - 1
desktop/core/generate_requirements.py

@@ -22,7 +22,6 @@ class RequirementsGenerator:
             "boto-2.49.0",
             "django-axes-5.13.0",
             "django-babel",
-            "djangosaml2-0.18.0",
             "pysaml2-7.3.1",
             "python-sasl-0.3.1",
         ]
@@ -58,6 +57,7 @@ class RequirementsGenerator:
             "djangomako==1.3.2",
             "djangorestframework-simplejwt==5.2.1",
             "djangorestframework==3.14.0",
+            "djangosaml2==1.9.3",
             "future==0.18.3",
             "gcs-oauth2-boto-plugin==3.0",
             "greenlet==3.1.1",

+ 2 - 2
desktop/libs/libsaml/src/libsaml/backend.py

@@ -26,7 +26,7 @@ import logging
 from django.contrib.auth import logout as auth_logout
 from django.http import HttpResponse
 from djangosaml2.backends import Saml2Backend as _Saml2Backend
-from djangosaml2.views import logout as saml_logout
+from djangosaml2.views import LogoutView
 
 from desktop.auth.backend import force_username_case, rewrite_user
 from desktop.conf import AUTH
@@ -111,7 +111,7 @@ class SAML2Backend(_Saml2Backend):
 
   def logout(self, request, next_page=None):
     if conf.LOGOUT_ENABLED.get():
-      response = saml_logout(request)
+      response = LogoutView.as_view()(request)
       auth_logout(request)
       return response
     elif conf.CDP_LOGOUT_URL.get():

+ 7 - 7
desktop/libs/libsaml/src/libsaml/urls.py

@@ -39,18 +39,18 @@ except ImportError:
 
 if djangosaml2_views is not None:
   urlpatterns = [
-    re_path(r'^logout/$', djangosaml2_views.logout, name='saml2_logout')
+    re_path(r'^logout/$', djangosaml2_views.LogoutView.as_view(), name='saml2_logout')
   ]
 
   urlpatterns += [
-    re_path(r'^ls/$', libsaml_views.logout_service, name='saml2_ls'),
-    re_path(r'^acs/$', libsaml_views.assertion_consumer_service, name='saml2_acs'),
-    re_path(r'^login/$', libsaml_views.login, name='saml2_login'),
-    re_path(r'^metadata/$', libsaml_views.metadata, name='saml2_metadata'),
-    re_path(r'^test/$', libsaml_views.echo_attributes)
+    re_path(r'^ls/$', libsaml_views.LogoutView.as_view(), name='saml2_ls'),
+    re_path(r'^acs/$', libsaml_views.CustomAssertionConsumerServiceView.as_view(), name='saml2_acs'),
+    re_path(r'^login/$', libsaml_views.LoginView.as_view(), name='saml2_login'),
+    re_path(r'^metadata/$', libsaml_views.MetadataView.as_view(), name='saml2_metadata'),
+    re_path(r'^test/$', libsaml_views.EchoAttributesView.as_view())
   ]
 
   if logout_service_post is not None:
     urlpatterns += [
-      re_path(r'^ls/post/$', libsaml_views.logout_service_post, name='saml2_ls_post')
+      re_path(r'^ls/post/$', libsaml_views.LogoutServicePostView.as_view(), name='saml2_ls_post')
     ]

+ 21 - 20
desktop/libs/libsaml/src/libsaml/views.py

@@ -16,37 +16,38 @@
 # limitations under the License.
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.http import require_POST
-
-from djangosaml2.views import login, echo_attributes, metadata,\
-                              assertion_consumer_service, logout_service
+from djangosaml2.views import AssertionConsumerServiceView, EchoAttributesView, LoginView, LogoutView, MetadataView
 
 try:
-  from djangosaml2.views import logout_service_post
+  from djangosaml2.views import LogoutServicePostView
 except ImportError:
   # We are on an older version of djangosaml2
-  logout_service_post = None
+  LogoutServicePostView = None
 
 import libsaml.conf
 
 
-__all__ = ['login', 'echo_attributes', 'assertion_consumer_service', 'metadata']
+# Customize AssertionConsumerServiceView
+class CustomAssertionConsumerServiceView(AssertionConsumerServiceView):
+  def dispatch(self, request, *args, **kwargs):
+    username_source = libsaml.conf.USERNAME_SOURCE.get().lower()
+    return super().dispatch(request, *args, **kwargs)
 
+# Expose the views
 
-if logout_service_post is None:
-  _assertion_consumer_service = assertion_consumer_service
 
-  @require_POST
-  @csrf_exempt
-  def assertion_consumer_service(request, config_loader_path=None, attribute_mapping=None, create_unknown_user=None):
-    username_source = libsaml.conf.USERNAME_SOURCE.get().lower()
-    return _assertion_consumer_service(request, config_loader_path, attribute_mapping, create_unknown_user, username_source)
+login = LoginView
+echo_attributes = EchoAttributesView
+metadata = MetadataView
+assertion_consumer_service = CustomAssertionConsumerServiceView
+logout_service = LogoutView
+logout_service_post = LogoutServicePostView
 
+__all__ = ['login', 'echo_attributes', 'assertion_consumer_service', 'metadata', 'logout_service', 'logout_service_post']
 
-setattr(logout_service, 'login_notrequired', True)
-setattr(login, 'login_notrequired', True)
-setattr(echo_attributes, 'login_notrequired', True)
-setattr(assertion_consumer_service, 'login_notrequired', True)
-setattr(metadata, 'login_notrequired', True)
+# Set login_notrequired attribute
+for view in [LogoutView, LoginView, EchoAttributesView, AssertionConsumerServiceView, MetadataView]:
+  setattr(view, 'login_notrequired', True)
 
-if logout_service_post is not None:
-  setattr(logout_service_post, 'login_notrequired', True)
+if LogoutServicePostView is not None:
+  setattr(LogoutServicePostView, 'login_notrequired', True)