コード例 #1
0
ファイル: backends.py プロジェクト: ucdavis/dlc-placement
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None
        try:
            user = User.objects.get(**{User.USERNAME_FIELD: username})
            created = False
        except User.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            if not settings.CAS_CREATE_USER:
                return None
            # user will have an "unusable" password
            user = User.objects.create_user(username, '')
            user.save()
            created = True

        if pgtiou and settings.CAS_PROXY_CALLBACK:
            request.session['pgtiou'] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #2
0
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        username, attributes = _verify(ticket, service)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None
        try:
            user = User.objects.get(username=username)
            created = False
        except User.DoesNotExist:
            # user will have an "unusable" password
            user = User.objects.create_user(username, '')
            user.save()
            created = True

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #3
0
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        #username, attributes = _verify(ticket, service)
        username, attributes = _verify_cas3_saml(ticket, service)

        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None
        try:
            user = User.objects.get(username=username)
            created = False
        except User.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            create = getattr(settings, 'CAS_CREATE_USER', True)
            if not create:
                return None
            # user will have an "unusable" password
            user = User.objects.create_user(username, attributes["email"], '')
            user.first_name = attributes["personName"]
            user.last_name = attributes["idPessoa"]
            user.is_staff = True
            user.save()
            created = True

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #4
0
    def authenticate(self, request, ticket, service):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes and request:
            request.session['attributes'] = attributes
            # Attributes
            # {
            #     'username': String
            #     'first_name': String
            #     'last_name': String
            #     'email': String
            #     'is_active': Bool
            #     'station_code': Int or None
            #     'profile_image': String or None
            #     'permissions': String
            # }
            print(attributes)

        if not username:
            return None

        user = None

        UserModel = get_user_model()
        user, created = UserModel._default_manager.get_or_create(
            **{UserModel.USERNAME_FIELD: username})

        if created:
            # If devs want to do something with new user
            pass

        if attributes:
            user.username = attributes['username']
            user.first_name = attributes['first_name']
            user.last_name = attributes['last_name']
            user.email = attributes['email']
            user.is_active = attributes['is_active']
            user.cas_permissions = attributes['permissions']
            if attributes['profile_image'] and \
               attributes['profile_image'] != 'None':
                user.profile_image = attributes['profile_image']

            user.save()

        if not self.user_can_authenticate(user):
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK and request:
            request.session['pgtiou'] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(sender=self,
                                    user=user,
                                    created=created,
                                    attributes=attributes,
                                    ticket=ticket,
                                    service=service,
                                    request=request)
        return user
コード例 #5
0
ファイル: backends.py プロジェクト: quinox/django-cas-ng
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes:
            request.session["attributes"] = attributes
        if not username:
            return None
        try:
            user = User.objects.get(**{User.USERNAME_FIELD: username})
            created = False
        except User.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            create = getattr(settings, "CAS_CREATE_USER", True)
            if not create:
                return None
            # user will have an "unusable" password
            user = User.objects.create_user(username, "")
            user.save()
            created = True

        if pgtiou and settings.CAS_PROXY_CALLBACK:
            request.session["pgtiou"] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self, user=user, created=created, attributes=attributes, ticket=ticket, service=service
        )
        return user
コード例 #6
0
 def test_profile_url_show_data_authenticated(self):
     """Test if profile url shows data in the page for an authenticated user."""
     cas_user_authenticated.send(
         sender=self,
         user=self.user,
         created=False,
         attributes=SSOUITest.ATTRIBUTES
     )
     self.client.login(username='******', password='******')
     response = self.client.get(reverse('sso_ui:profile'))
     self.assertEqual(response.status_code, 200)
     content = response.content.decode('utf-8')
     attributes = [
         self.user.get_full_name(),
         self.user.username,
         self.user.email,
         self.user.profile.org_code,
         self.user.profile.role,
         self.user.profile.npm,
         self.user.profile.faculty,
         self.user.profile.study_program,
         self.user.profile.educational_program
     ]
     for attr in attributes:
         self.assertIn(attr, content)
コード例 #7
0
ファイル: backends.py プロジェクト: Rayco/patrimonioULL
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        username, attributes = _verify(ticket, service)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None
        try:
            user = User.objects.get(**{User.USERNAME_FIELD: username})
            created = False
        except User.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            create = getattr(settings, 'CAS_CREATE_USER', True)
            if not create:
                return None
            # user will have an "unusable" password
            user = User.objects.create_user(username, '')
            user.save()
            created = True

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #8
0
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None
        created, user = client.get_or_create_user(username, attributes)

        if user is None:
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK:
            request.session['pgtiou'] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #9
0
 def test_profile_can_save_attributes(self):
     """Test if Profile model can save the attributes from CAS."""
     cas_user_authenticated.send(
         sender=self,
         user=self.user,
         created=False,
         attributes=SSOUITest.ATTRIBUTES
     )
     self.assertJSONEqual(
         json.dumps({
             "nama": self.user.get_full_name(),
             "peran_user": self.user.profile.role,
             "npm": self.user.profile.npm,
             "kd_org": self.user.profile.org_code
         }),
         SSOUITest.ATTRIBUTES
     )
     self.assertJSONEqual(
         json.dumps({
             "faculty": self.user.profile.faculty,
             "study_program": self.user.profile.study_program,
             "educational_program": self.user.profile.educational_program
         }),
         ORG_CODE['id'][SSOUITest.ATTRIBUTES['kd_org']]
     )
     self.assertEqual(self.user.email, f"{self.user.username}@ui.ac.id")
     self.assertEqual(self.user.first_name, "Ice")
     self.assertEqual(self.user.last_name, "Bear")
コード例 #10
0
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None
        created, user = client.get_or_create_user(username, attributes)

        if user is None:
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK:
            request.session['pgtiou'] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #11
0
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        username, attributes = _verify(ticket, service)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None
        try:
            user = User.objects.get(username=username)
            created = False
        except User.DoesNotExist:
            # user will have an "unusable" password
            user = User.objects.create_user(username, '')
            user.save()
            created = True

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #12
0
    def authenticate(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""
        username, attributes = _verify(ticket, service)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None
        try:
            user = User.objects.get(**{User.USERNAME_FIELD: username})
            created = False
        except User.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            create = getattr(settings, 'CAS_CREATE_USER', True)
            if not create:
                return None
            # user will have an "unusable" password
            user = User.create_user(username, None)
            user.save()
            created = True

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #13
0
    def authenticate(self, request, ticket, service):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        from django.contrib.auth.models import User
        try:
            User.objects.get(username=username)
        except User.DoesNotExist:

            user = User.objects.create_user(username=username,
                                 email=username+"@seuemail.com.br",
                                 password='')
            user.save()
        if attributes and request:
            request.session['attributes'] = attributes

        if not username:
            return None
        user = None
        username = self.clean_username(username)

        UserModel = get_user_model()

        # 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.
        if settings.CAS_CREATE_USER:
            user, created = UserModel._default_manager.get_or_create(**{
                UserModel.USERNAME_FIELD: username
            })
            if created:
                user = self.configure_user(user)
        else:
            created = False
            try:
                user = UserModel._default_manager.get_by_natural_key(username)
            except UserModel.DoesNotExist:
                pass

        if not self.user_can_authenticate(user):
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK and request:
            request.session['pgtiou'] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
            request=request
        )
        return user
コード例 #14
0
    def authenticate(self, ticket, service, request, proxy=False):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        if proxy:
            client.url_suffix = 'proxyValidate'
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None

        username_case = settings.CAS_FORCE_CHANGE_USERNAME_CASE
        if username_case == 'lower':
            username = username.lower()
        elif username_case == 'upper':
            username = username.upper()

        try:
            user = User.objects.get(**{User.USERNAME_FIELD: username})
            created = False
        except User.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            if not settings.CAS_CREATE_USER:
                return None
            # user will have an "unusable" password
            user = User.objects.create_user(username, '')
            created = True

        if attributes:
            for attr, value in attributes.iteritems():
                if value is None:
                    value = ''
                elif value == 'True':
                    value = True
                elif value == 'False':
                    value = False
                setattr(user, attr, value)
        user.save()

        if pgtiou and settings.CAS_PROXY_CALLBACK:
            request.session['pgtiou'] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #15
0
ファイル: backends.py プロジェクト: simonehu/django-cas-ng
    def authenticate(self, ticket, service, request, proxy=False):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        if proxy:
            client.url_suffix = 'proxyValidate'
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None

        username_case = settings.CAS_FORCE_CHANGE_USERNAME_CASE
        if username_case == 'lower':
            username = username.lower()
        elif username_case == 'upper':
            username = username.upper()

        try:
            user = User.objects.get(**{User.USERNAME_FIELD: username})
            created = False
        except User.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            if not settings.CAS_CREATE_USER:
                return None
            # user will have an "unusable" password
            user = User.objects.create_user(username, '')
            created = True

        if attributes:
            for attr, value in attributes.iteritems():
                if value is None:
                    value = ''
                elif value == 'True':
                    value = True
                elif value == 'False':
                    value = False
                setattr(user, attr, value)
        user.save()

        if pgtiou and settings.CAS_PROXY_CALLBACK:
            request.session['pgtiou'] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #16
0
    def test_signal_assign_new_user_to_unit_notexists(self):
        """
        if new user's unit doesn't exist: no assignment
        """
        UnitFactory()
        user = UserFactory()

        cas_user_authenticated.send(
            sender="manual",
            user=user,
            created=True,
            username=user.username,
        )
        self.assertEqual(UnitMembership.objects.exists(), False)
コード例 #17
0
    def test_signal_assign_new_user_to_unit_member(self):
        """
        if unit membersip is no empty the new user is assigned as member
        """
        unit = UnitFactory()
        UnitMembershipFactory(role=UnitMembershipRole.OWNER, unit=unit)
        new_member = UserFactory(unit_name=unit.name)

        cas_user_authenticated.send(
            sender="manual",
            user=new_member,
            created=True,
            username=new_member.username,
        )
        membership = UnitMembership.objects.get(user=new_member, unit=unit)
        self.assertEqual(membership.role, UnitMembershipRole.MEMBER)
コード例 #18
0
    def authenticate(self, ticket, service, request=None):
        """Verifies CAS ticket and gets or creates user object"""
        client = get_cas_client(service_url=service)
        universal_id, attributes, pgtiou = client.verify_ticket(ticket)

        if attributes and request:
            request.session['attributes'] = attributes
        if not universal_id:
            return None

        try:
            user = CASUser.objects.get(universal_id=universal_id).user
            attributes['username'] = self.clean_username(
                user.username, attributes['username'])
            self.update_user_attributes(user, attributes)
            created = False
        except CASUser.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            if not settings.CAS_CREATE_USER:
                return None

            attributes['username'] = self.clean_username(
                None, attributes['username'])

            user = create_user_and_casuser(attributes['username'],
                                           attributes['email'], universal_id)
            user.save()
            created = True

        if not self.user_can_authenticate(user):
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK and request:
            request.session['pgtiou'] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
        )
        return user
コード例 #19
0
    def authenticate(self, request, ticket, service):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes and request:
            request.session['attributes'] = attributes

        if not username:
            return None
        user = None
        username = self.clean_username(username)
        domain = username
        # Extra added line, to ensure it is not the full email address
        if "@" in username:
            domain = username.split('@')[1]
            username = username.split('@')[0]

        EXEMPT_USERS = []
        DISALLOWED_DOMAINS = []

        if hasattr(settings, 'EXEMPT_USERS'):
            EXEMPT_USERS += settings.EXEMPT_USERS

        if hasattr(settings, 'DISALLOWED_DOMAINS'):
            DISALLOWED_DOMAINS += settings.DISALLOWED_DOMAINS

        if domain in DISALLOWED_DOMAINS and username not in EXEMPT_USERS:
            return None

        UserModel = get_user_model()

        # Note that this could be accomplished in one try-except clause, but
        # instead we use get_or_create when creating unknown pble_users since it has
        # built-in safeguards for multiple threads.
        if settings.CAS_CREATE_USER:
            user, created = UserModel._default_manager.get_or_create(**{
                UserModel.USERNAME_FIELD: username
            })
            if created:
                # Extra parameter, attributes, added
                user = self.configure_user(user, attributes)
            else:
                self.fill_misc_info(user, attributes)
        else:
            created = False
            try:
                user = UserModel._default_manager.get_by_natural_key(username)
            except UserModel.DoesNotExist:
                pass

        if not self.user_can_authenticate(user):
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK and request:
            request.session['pgtiou'] = pgtiou

        if settings.CAS_APPLY_ATTRIBUTES_TO_USER and attributes:
            # If we are receiving None for any values which cannot be NULL
            # in the User model, set them to an empty string instead.
            # Possibly it would be desirable to let these throw an error
            # and push the responsibility to the CAS provider or remove
            # them from the dictionary entirely instead. Handling these
            # is a little ambiguous.
            user_model_fields = UserModel._meta.fields
            for field in user_model_fields:
                # Handle null -> '' conversions mentioned above
                if not field.null:
                    try:
                        if attributes[field.name] is None:
                            attributes[field.name] = ''
                    except KeyError:
                        continue
                # Coerce boolean strings into true booleans
                if field.get_internal_type() == 'BooleanField':
                    try:
                        boolean_value = attributes[field.name] == 'True'
                        attributes[field.name] = boolean_value
                    except KeyError:
                        continue

            user.__dict__.update(attributes)

            # If we are keeping a local copy of the user model we
            # should save these attributes which have a corresponding
            # instance in the DB.
            if settings.CAS_CREATE_USER:
                user.save()

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
            request=request
        )
        return user
コード例 #20
0
ファイル: backends.py プロジェクト: bgroff/django-cas-ng
    def authenticate(self, request, ticket, service):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service, request=request)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes and request:
            request.session['attributes'] = attributes

        if not username:
            return None
        user = None
        username = self.clean_username(username)

        if attributes:
            reject = self.bad_attributes_reject(request, username, attributes)
            if reject:
                return None

        UserModel = get_user_model()

        # 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.
        if settings.CAS_CREATE_USER:
            user_kwargs = {
                UserModel.USERNAME_FIELD: username
            }
            if settings.CAS_CREATE_USER_WITH_ID:
                user_kwargs['id'] = self.get_user_id(attributes)

            user, created = UserModel._default_manager.get_or_create(**user_kwargs)
            if created:
                user = self.configure_user(user)
        else:
            created = False
            try:
                user = UserModel._default_manager.get_by_natural_key(username)
            except UserModel.DoesNotExist:
                pass

        if not self.user_can_authenticate(user):
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK and request:
            request.session['pgtiou'] = pgtiou

        if settings.CAS_APPLY_ATTRIBUTES_TO_USER and attributes:
            # If we are receiving None for any values which cannot be NULL
            # in the User model, set them to an empty string instead.
            # Possibly it would be desirable to let these throw an error
            # and push the responsibility to the CAS provider or remove
            # them from the dictionary entirely instead. Handling these
            # is a little ambiguous.
            user_model_fields = UserModel._meta.fields
            for field in user_model_fields:
                # Handle null -> '' conversions mentioned above
                if not field.null:
                    try:
                        if attributes[field.name] is None:
                            attributes[field.name] = ''
                    except KeyError:
                        continue
                # Coerce boolean strings into true booleans
                if field.get_internal_type() == 'BooleanField':
                    try:
                        boolean_value = attributes[field.name] == 'True'
                        attributes[field.name] = boolean_value
                    except KeyError:
                        continue

            user.__dict__.update(attributes)

            # If we are keeping a local copy of the user model we
            # should save these attributes which have a corresponding
            # instance in the DB.
            if settings.CAS_CREATE_USER:
                user.save()

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            attributes=attributes,
            ticket=ticket,
            service=service,
            request=request
        )
        return user
コード例 #21
0
ファイル: backends.py プロジェクト: only-ove/django-cas-ng
    def authenticate(self, request, ticket, service):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service, request=request)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes and request:
            request.session['attributes'] = attributes

        if settings.CAS_USERNAME_ATTRIBUTE != 'uid' and settings.CAS_VERSION != 'CAS_2_SAML_1_0':
            if attributes:
                username = attributes.get(settings.CAS_USERNAME_ATTRIBUTE)
            else:
                return None

        if not username:
            return None
        user = None
        username = self.clean_username(username)

        if attributes:
            reject = self.bad_attributes_reject(request, username, attributes)
            if reject:
                return None

            # If we can, we rename the attributes as described in the settings file
            # Existing attributes will be overwritten
            for cas_attr_name, req_attr_name in settings.CAS_RENAME_ATTRIBUTES.items(
            ):
                if cas_attr_name in attributes and cas_attr_name is not req_attr_name:
                    attributes[req_attr_name] = attributes[cas_attr_name]
                    attributes.pop(cas_attr_name)

        UserModel = get_user_model()

        # 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.
        if settings.CAS_CREATE_USER:
            user_kwargs = {UserModel.USERNAME_FIELD: username}
            if settings.CAS_CREATE_USER_WITH_ID:
                user_kwargs['id'] = self.get_user_id(attributes)

            user, created = UserModel._default_manager.get_or_create(
                **user_kwargs)
            if created:
                user = self.configure_user(user)
        else:
            created = False
            try:
                if settings.CAS_LOCAL_NAME_FIELD:
                    user_kwargs = {settings.CAS_LOCAL_NAME_FIELD: username}
                    user = UserModel._default_manager.get(**user_kwargs)
                else:
                    user = UserModel._default_manager.get_by_natural_key(
                        username)
            except UserModel.DoesNotExist:
                pass

        if not self.user_can_authenticate(user):
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK and request:
            request.session['pgtiou'] = pgtiou

        if settings.CAS_APPLY_ATTRIBUTES_TO_USER and attributes:
            # If we are receiving None for any values which cannot be NULL
            # in the User model, set them to an empty string instead.
            # Possibly it would be desirable to let these throw an error
            # and push the responsibility to the CAS provider or remove
            # them from the dictionary entirely instead. Handling these
            # is a little ambiguous.
            user_model_fields = UserModel._meta.fields
            for field in user_model_fields:
                # Handle null -> '' conversions mentioned above
                if not field.null:
                    try:
                        if attributes[field.name] is None:
                            attributes[field.name] = ''
                    except KeyError:
                        continue
                # Coerce boolean strings into true booleans
                if field.get_internal_type() == 'BooleanField':
                    try:
                        boolean_value = attributes[field.name] == 'True'
                        attributes[field.name] = boolean_value
                    except KeyError:
                        continue

            user.__dict__.update(attributes)

            # If we are keeping a local copy of the user model we
            # should save these attributes which have a corresponding
            # instance in the DB.
            if settings.CAS_CREATE_USER:
                user.save()

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(sender=self,
                                    user=user,
                                    created=created,
                                    username=username,
                                    attributes=attributes,
                                    pgtiou=pgtiou,
                                    ticket=ticket,
                                    service=service,
                                    request=request)
        return user
コード例 #22
0
    def authenticate(self, request: HttpRequest, ticket: str,
                     service: str) -> Optional[User]:
        """
        Verifies CAS ticket and gets or creates User object

        :returns: [User] Authenticated User object or None if authenticate failed.
        """
        UserModel = get_user_model()

        client = get_cas_client(service_url=service, request=request)
        username, attributes, pgtiou = client.verify_ticket(ticket)

        # Get the user from a user mapping that links a user with their identity provider id
        try:
            user_mapping = UserMapping.objects.get(id=username)
        except UserMapping.DoesNotExist:
            user_mapping = None

        # Dictionary of fields to add to the user as we create or update it
        user_kwargs = {}

        if attributes and request:
            request.session["attributes"] = attributes

        if (settings.CAS_USERNAME_ATTRIBUTE != "uid"
                and settings.CAS_VERSION != "CAS_2_SAML_1_0"):
            if attributes:
                username = attributes.get(settings.CAS_USERNAME_ATTRIBUTE)
            else:
                return None

        if not username:
            return None
        user = None
        username = self.clean_username(username)

        if attributes:
            reject = self.bad_attributes_reject(request, username, attributes)
            if reject:
                return None

            # If we can, we rename the attributes as described in the settings file
            # Existing attributes will be overwritten
            for cas_attr_name, req_attr_name in settings.CAS_RENAME_ATTRIBUTES.items(
            ):
                if cas_attr_name in attributes and cas_attr_name is not req_attr_name:
                    attributes[req_attr_name] = attributes[cas_attr_name]
                    attributes.pop(cas_attr_name)

            if settings.CAS_APPLY_ATTRIBUTES_TO_USER:
                # If we are receiving None for any values which cannot be NULL
                # in the User model, set them to an empty string instead.
                # Possibly it would be desirable to let these throw an error
                # and push the responsibility to the CAS provider or remove
                # them from the dictionary entirely instead. Handling these
                # is a little ambiguous.
                user_model_fields = UserModel._meta.fields

                for field in user_model_fields:
                    # Handle null -> '' conversions mentioned above
                    if not field.null:
                        try:
                            if attributes[field.name] is None:
                                user_kwargs[field.name] = ""
                            else:
                                user_kwargs[field.name] = attributes[
                                    field.name]
                        except KeyError:
                            continue
                    # Coerce boolean strings into true booleans
                    elif field.get_internal_type() == "BooleanField":
                        try:
                            boolean_value = attributes[field.name] == "True"
                            user_kwargs[field.name] = boolean_value
                        except KeyError:
                            continue
                    else:
                        try:
                            user_kwargs[field.name] = attributes[field.name]
                        except KeyError:
                            continue

        if not user_mapping and not settings.CAS_CREATE_USER:
            return None

        if user_mapping:
            # If the user already exists in our mapping, we're not creating it
            created = False
            user = user_mapping.user
            if settings.CAS_APPLY_ATTRIBUTES_TO_USER:
                for field_name, value in user_kwargs.items():
                    setattr(user, field_name, value)
                user.save()
        else:
            # Apply attributes to our user as we create it, if appropriate
            user = UserModel.objects.create(**user_kwargs)
            # Create a mapping to associate the user with their CAS/SMAL provider id
            UserMapping.objects.create(id=username, user=user)
            created = True

        if not self.user_can_authenticate(user):
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK and request:
            request.session["pgtiou"] = pgtiou

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(
            sender=self,
            user=user,
            created=created,
            username=username,
            attributes=attributes,
            pgtiou=pgtiou,
            ticket=ticket,
            service=service,
            request=request,
        )
        return user
コード例 #23
0
    def authenticate(self, request, ticket, service):
        """Verifies CAS ticket and gets or creates User object"""
        client = get_cas_client(service_url=service)
        username, attributes, pgtiou = client.verify_ticket(ticket)
        if attributes and request:
            request.session['attributes'] = attributes

        if not username:
            return None
        user = None
        username = self.clean_username(username)

        UserModel = get_user_model()

        # 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.
        if settings.CAS_CREATE_USER:
            user, created = UserModel._default_manager.get_or_create(
                **{UserModel.USERNAME_FIELD: username})
            if created:
                user = self.configure_user(user)
        else:
            created = False
            try:
                user = UserModel._default_manager.get_by_natural_key(username)
            except UserModel.DoesNotExist:
                pass

        if not self.user_can_authenticate(user):
            return None

        if pgtiou and settings.CAS_PROXY_CALLBACK and request:
            request.session['pgtiou'] = pgtiou

        if settings.CAS_APPLY_ATTRIBUTES_TO_USER and attributes:
            # If we are receiving None for any values which cannot be NULL
            # in the User model, set them to an empty string instead.
            # Possibly it would be desirable to let these throw an error
            # and push the responsibility to the CAS provider or remove
            # them from the dictionary entirely instead. Handling these
            # is a little ambiguous.
            user_model_fields = UserModel._meta.fields
            for field in user_model_fields:
                if not field.null:
                    try:
                        if attributes[field.name] is None:
                            attributes[field.name] = ''
                    except KeyError:
                        continue

            user.__dict__.update(attributes)

            # If we are keeping a local copy of the user model we
            # should save these attributes which have a corresponding
            # instance in the DB.
            if settings.CAS_CREATE_USER:
                user.save()

        # send the `cas_user_authenticated` signal
        cas_user_authenticated.send(sender=self,
                                    user=user,
                                    created=created,
                                    attributes=attributes,
                                    ticket=ticket,
                                    service=service,
                                    request=request)
        return user