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
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
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
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
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
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)
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
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
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")
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
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
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
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)
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)
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
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
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
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
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
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