Skip to content

Commit

Permalink
Docs updated for new release
Browse files Browse the repository at this point in the history
  • Loading branch information
mhindery committed Apr 11, 2020
1 parent 99fb188 commit 2164277
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 38 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,4 @@ jobs:
run: tox -e py${{ matrix.python-version }}-django${{ matrix.django-version }}
- uses: codecov/codecov-action@v1
with:
# token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
file: ./cov.xml # optional
# flags: unittests # optional
# name: codecov-umbrella # optional
# fail_ci_if_error: true # optional (default = false)
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## [0.7.0] - 2020-04-xx

*In development, *

Many thanks for major contributions (especially on the testing front where the project was lacking) from [Amertz08](https://github.com/Amertz08) and [askvortsov1](https://github.com/askvortsov1)

### Added
- Major and breaking change: Service Providers are now backed by the database instead of being configured via the settings: [#51](https://github.com/OTA-Insight/djangosaml2idp/pull/51)
- Test coverage has been improved significantly. CI was added to run tests, linting and report code coverage which will improve stability of development.
- Django 3.0 is added to the tests matrix. We currently are doing Python 3.6, 3.7, 3.8 and Django 2.2, 3.0.

### Removed
- Python 3.5
- Django 2.0 and 2.1 as they are no longer officially supported Django versions.


## [0.6.3] - 2020-02-10

Bugfix release, thanks to contributions from [pix666](https://github.com/pix666) in [#61](https://github.com/OTA-Insight/djangosaml2idp/pull/61/files)
Expand Down
49 changes: 16 additions & 33 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ you will need to set the full path to it in the configuration stage. XmlSec is a

Now you can install the djangosaml2idp package using pip. This will also install PySAML2 and its dependencies automatically::

.. code-block:: shell
pip install djangosaml2idp


Expand All @@ -57,6 +58,7 @@ Configuration & Usage

The first thing you need to do is add ``djangosaml2idp`` to the list of installed apps::

.. code-block:: python
INSTALLED_APPS = (
'django.contrib.admin',
'djangosaml2idp',
Expand All @@ -65,6 +67,7 @@ The first thing you need to do is add ``djangosaml2idp`` to the list of installe

Now include ``djangosaml2idp`` in your project by adding it in the url config::

.. code-block:: python
from django.conf.urls import url, include
from django.contrib import admin

Expand All @@ -76,7 +79,7 @@ Now include ``djangosaml2idp`` in your project by adding it in the url config::

In your Django settings, configure your IdP. Configuration follows the `PySAML2 configuration <https://github.com/IdentityPython/pysaml2/blob/master/docs/howto/config.rst>`_. The IdP from the example project looks like this::

...
.. code-block:: python
import saml2
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED
from saml2.sigver import get_xmlsec_binary
Expand Down Expand Up @@ -122,38 +125,14 @@ In your Django settings, configure your IdP. Configuration follows the `PySAML2

Notice the configuration requires a private key and public certificate to be available on the filesystem in order to sign and encrypt messages.

Next the Service Providers need to be added, this is done via the Django admin interface. Add the necessary configuration for each SP.
Upload a copy of the local metadata, or set a remote metadata url. Add an attribute mapping for user attributes to SAML fields in the configuration, as a dict of strings (with double quotes for the strings):

You also have to define a mapping for each SP you talk to. An example SP config::

...
SAML_IDP_SPCONFIG = {
'http://localhost:8000/saml2/metadata/': {
'processor': 'djangosaml2idp.processors.BaseProcessor',
'nameid_field': 'staffID'
'sign_response': False,
'sign_assertion': False,
'attribute_mapping': {
# DJANGO: SAML
'email': 'email',
'first_name': 'first_name',
'last_name': 'last_name',
'is_staff': 'is_staff',
'is_superuser': 'is_superuser',
'callable_to_get_id': 'calculate_id', # assuming <user_instance>.calculate_id() is a method
}
},
# ...
# config of additional Service Providers
# ...
}
attribute_mapping = {'email': 'email', 'first_name': 'first_name', 'last_name': 'last_name', 'is_staff': 'is_staff', 'is_superuser': 'is_superuser'}

Please note that the only required field for each SP is the Entity ID, which is the key for each individual SP config dict. The bare minimum is setting ``SAML_IDP_CONFIG[Your Entity Id] = {}``.
Also, ``attribute_mapping`` will default to ``{'username': 'username'}``.
If you would like to not send any attributes to the SP, set ``attribute_mapping`` to an empty dict (``{}``).
You can provide object attributes or callables names on the Django side in the attribute mapping. The callable needs to be a method on the object accepts 1 parameter (self), don't put parentheses in the attribute mapping.

If you want to override ``sign_assertion`` and/or ``sign_response`` for individual SPs, you can do so in ``SAML_IDP_SPCONFIG``, as seen above. If unset, these will default to the values set in ``SAML_IDP_CONFIG``.

Several attributes can be overriden per SP, but will fall back the defaults set in the application settings if not overriden explicitly, and if they haven't been set some sane settings are used.
The resulting configuration of a SP, with merged settings of its own and the defaults, is shown in the admin.

The last step is configuring metadata.
Download a copy of the IdP's metadata from <YOUR_SERVER_URL>/idp/metadata (assuming that's how you set up your urls.py). Use it to configure your SPs as required by them.
Expand All @@ -172,7 +151,8 @@ Use this metadata xml to configure your SP. Place the metadata xml from that SP

Without custom setting, users will be identified by the ``USERNAME_FIELD`` property on the user Model you use. By Django defaults this will be the username.
You can customize which field is used for the identifier by adding ``SAML_IDP_DJANGO_USERNAME_FIELD`` to your settings with as value the attribute to use on your user instance.
You can also override this per SP by setting ``nameid_field`` in the SP config, as seen in the sample ``SAML_IDP_SPCONFIG`` above.

Other settings you can set as defaults to be used if not overriden by an SP are `SAML_AUTHN_SIGN_ALG`, `SAML_AUTHN_DIGEST_ALG`, and `SAML_ENCRYPT_AUTHN_RESPONSE`.

Customizing error handling
==========================
Expand Down Expand Up @@ -220,10 +200,13 @@ Install the dev dependencies in ``requirements-dev.txt``::

pip install -r requirements-dev.txt

Run ``py.test`` from the project root::
Run the test suite from the project root::

py.test
tox -e format # to run linting
tox -e py3.7-django3.0 # to run the tests
tox -e typing # to run typechecking, this is allowed to fail

Tests will be ran using CI when opening a merge request as well.


Example project
Expand Down
11 changes: 10 additions & 1 deletion djangosaml2idp/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib import admin

from .forms import ServiceProviderAdminForm
from .models import ServiceProvider
from .models import PersistentId, ServiceProvider


@admin.register(ServiceProvider)
Expand All @@ -25,3 +25,12 @@ class ServiceProviderAdmin(admin.ModelAdmin):
'fields': ('dt_created', 'dt_updated', 'resulting_config')
})
)


@admin.register(PersistentId)
class PersistentIdAdmin(admin.ModelAdmin):
list_filter = ['sp', ]
list_display = ['user', 'sp', 'persistent_id']

def get_queryset(self, request):
return super().get_queryset(request).select_related('user', 'sp')

0 comments on commit 2164277

Please sign in to comment.