diff --git a/mellon/adapters.py b/mellon/adapters.py index c11b679..09f569e 100644 --- a/mellon/adapters.py +++ b/mellon/adapters.py @@ -4,7 +4,7 @@ from django.core.exceptions import PermissionDenied from django.contrib import auth from django.contrib.auth.models import Group -from . import utils, app_settings +from . import utils, app_settings, models log = logging.getLogger(__name__) @@ -47,17 +47,20 @@ class DefaultAdapter(object): def lookup_user(self, idp, saml_attributes): User = auth.get_user_model() - username = self.format_username(idp, saml_attributes) - if not username: - return None - provision = utils.get_setting(idp, 'PROVISION') - if provision: - user, created = User.objects.get_or_create(username=username) - else: - try: - user = User.objects.get(username=username) - except User.DoesNotExist: - return + name_id = saml_attributes['name_id_content'] + issuer = saml_attributes['issuer'] + try: + return User.objects.get(saml_identifiers__name_id=name_id, + saml_identifiers__issuer=issuer) + except User.DoesNotExist: + if not utils.get_setting(idp, 'PROVISION'): + return None + username = self.format_username(idp, saml_attributes) + if not username: + return None + user = User(username=username) + user.save() + self.provision_name_id(user, idp, saml_attributes) return user def provision(self, user, idp, saml_attributes): @@ -65,6 +68,12 @@ class DefaultAdapter(object): self.provision_superuser(user, idp, saml_attributes) self.provision_groups(user, idp, saml_attributes) + def provision_name_id(self, user, idp, saml_attributes): + models.UserSAMLIdentifier.objects.get_or_create( + user=user, + issuer=saml_attributes['issuer'], + name_id=saml_attributes['name_id_content']) + def provision_attribute(self, user, idp, saml_attributes): realm = utils.get_setting(idp, 'REALM') attribute_mapping = utils.get_setting(idp, 'ATTRIBUTE_MAPPING') diff --git a/mellon/migrations/0001_initial.py b/mellon/migrations/0001_initial.py new file mode 100644 index 0000000..eca7a91 --- /dev/null +++ b/mellon/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='UserSAMLIdentifier', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('issuer', models.TextField(verbose_name='Issuer')), + ('name_id', models.TextField(verbose_name='SAML identifier')), + ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), + ('user', models.ForeignKey(related_name='saml_identifiers', verbose_name='user', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'user SAML identifier', + 'verbose_name_plural': 'users SAML identifiers', + }, + bases=(models.Model,), + ), + migrations.AlterUniqueTogether( + name='usersamlidentifier', + unique_together=set([('issuer', 'name_id')]), + ), + ] diff --git a/mellon/models.py b/mellon/models.py index 71a8362..7dfa1fa 100644 --- a/mellon/models.py +++ b/mellon/models.py @@ -1,3 +1,21 @@ from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.conf import settings -# Create your models here. +class UserSAMLIdentifier(models.Model): + user = models.ForeignKey( + verbose_name=_('user'), + to=settings.AUTH_USER_MODEL, + related_name='saml_identifiers') + issuer = models.TextField( + verbose_name=_('Issuer')) + name_id = models.TextField( + verbose_name=_('SAML identifier')) + created = models.DateTimeField( + verbose_name=_('created'), + auto_now_add=True) + + class Meta: + verbose_name = _('user SAML identifier') + verbose_name_plural = _('users SAML identifiers') + unique_together = (('issuer', 'name_id'),)