def check_permissions(cls, request: Request, user: AbstractUser, with_permissions: List[str] = None): """ Check if user having permissions in provided list If user has `manage_{resource_name}`, assume he can do all actions: `view, edit, change, delete` :param request: request instance :param user: normally a reference to request.user :param with_permissions: list of permissions for checking :return: True if all permission checked successfully, else False """ app_label = "crm" app_permissions_to_check = dict() for permission in with_permissions: try: permission_parts = permission.split("_") action_name = permission_parts[0] resource_name = permission_parts[1] app_permission = f"{app_label}.{permission}" if user.has_perm(f"{app_label}.manage_{resource_name}"): app_permissions_to_check[permission] = True else: app_permissions_to_check[permission] = user.has_perm( app_permission) except IndexError: continue return all([v for _, v in app_permissions_to_check.items()])
def revoke_stale_memberships(user: AbstractUser, group_paths: Iterable[str]): """Remove user from django groups that are not specified in keycloak""" logger.debug("Revoking stale memberships for user {}...".format(user)) allowed_group_names = [path.rpartition("/")[-1] for path in group_paths] for group in user.groups.exclude(name__in=allowed_group_names): logger.debug("removing user {} from group {}...".format(user, group)) user.groups.remove(group) user.save()
def create_django_memberships(user: AbstractUser, group_paths: Iterable[str]): """Add user to django groups that are specified in keycloak This function will create new django groups if they do not exist yet """ logger.debug("Creating new django memberships for user {}...".format(user)) allowed_group_names = [path.rpartition("/")[-1] for path in group_paths] for group_name in allowed_group_names: group = Group.objects.get_or_create(name=group_name)[0] logger.debug("adding user {} to group {}".format(user, group)) user.groups.add(group) user.save()
def enforce_staff_role(user: AbstractUser, roles: list) -> list: """Synchronize django ``staff`` role from the keycloak roles The returned list of roles does not contain the staff role anymore. """ logger.debug("Enforcing staff role for user {}...".format(user)) result = roles[:] try: result.remove(settings.KEYCLOAK.get("staff_role")) user.is_staff = True except ValueError: user.is_staff = False user.save() return result
def has_perm(self, perm, obj=None): if self.employee_id is not None and perm in ['c.scheduling.view_customer', 'c.scheduling.view_service', 'c.scheduling.view_appointment', 'c.scheduling.view_schedule']: return True if perm.startswith('c.'): perm = perm[2:] return AbstractUser.has_perm(self, perm, obj)
class Player(AbstractUser): objects = PlayerManager user = AbstractUser() active = models.BooleanField(default=True) is_referee = models.BooleanField(default=False) wins = models.IntegerField(default=0, ) losses = models.IntegerField(default=0, ) player_bio = models.TextField( blank=True, default='', max_length=280, ) player_ranking = models.ForeignKey( 'ranking.Ranking', on_delete=models.CASCADE, null=True, blank=True, related_name='player_ranking', ) def __str__(self): return self.user.get_username()
def update_translation_string(cls, user: AbstractUser, translation_id: int, key: str, value: str): """ create/update a single translation :param user: the user calling the service :param translation_id: the translation_id this string is related to :param key: the translation key :param value: the translation value :return: the newly created translation object """ translation = FormTranslation.objects.get(pk=translation_id) if not user.has_perm(CanAddFormTranslationPermission): raise PermissionError( "You are not allowed to change a translation for this form") try: trans_key = TranslationKey.objects.get(key=key, translation=translation.pk) trans_key = TranslationKeyService._update(trans_key.pk, { "value": value, "key": key }) except TranslationKey.DoesNotExist: trans_key = TranslationKeyService._create({ "translation": translation_id, "key": key, "value": value, }) return trans_key
def remove_member(cls, user: AbstractUser, team_id: int, affected_user_id: int) -> bool: """ update a team member :param user: user calling the service :param team_id: id of the team the user should be removed from :param affected_user_id: the user that should be removed :return: True if user has been sucessfully removed """ team = TeamService.retrieve(user, team_id) if not team.members.filter( user=user, role=TeamRoleChoices.ADMIN).exists( ) and not user.has_perm(CanRemoveTeamMemberPermission): raise TeamServiceException( "You don't have the permission to remove a team member." "You must be either team admin or have the permission 'CanRemoveTeamMemberPermission'." ) membership = team.members.filter(user=affected_user_id).get() if (team.members.filter(role=TeamRoleChoices.ADMIN).count() == 1 and membership.role == TeamRoleChoices.ADMIN): raise TeamServiceException( "This user can't be removed because every team needs at least one admin." ) return cls._delete(membership.id)
def create_form_translation(cls, user: AbstractUser, form_id: int, language: str, region: str): """create a new translation for the given form :param user: the user calling the service :param form_id: the form_id the translation is for :param language: the language the strings should be translated to :param region: the region of the language the strings should be translated to """ form = FormService.retrieve_form(form_id) if not user.has_perm(CanAddFormTranslationPermission): raise PermissionError( "You are not allowed to add a translation to this form") if f"{language}-{region}" not in [ a["iso_code"] for a in cls.get_available_languages() ]: raise FormServiceException( f"{language}-{region} is not configured as a supported language" ) translation = cls._create({ "form": form.id, "language": language, "region": region }) return translation
def activate_key(cls, user: AbstractUser, public_key_id: int, keys: Dict[int, str]) -> EncryptionKey: """ activate a submitted public key that is used to share form keys between users :param user: the user calling the service :param keys: the encrypted keys to access teams :param public_key_id: id the of the public key that should be activated :return: the activated key object """ if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError( "You are not allowed to activate this form key") public_key = EncryptionKey.objects.get(id=public_key_id) if public_key.active == True: raise FormServiceException("This public key is already active.") public_key.active = True public_key.save() for membership_id, key in keys.items(): TeamMembershipAccessKeyService.add_membership_key( membership=membership_id, encryption_key=public_key_id, key=key) return public_key
def create(cls, user: AbstractUser, name: str, keys: Dict[int, str]) -> Team: """ creates a new user and makes them admin :param user: user calling the service (needs CanCreateTeamPermission permission) :param name: name of the Team :param keys: the newly generated public key :return: the newly generated team """ if not user.has_perm(CanCreateTeamPermission): raise TeamServiceException( "You don't have the permission to create a new team") TeamMembershipService._validate_keys_provided(user, keys) team = cls._create({"name": name}) TeamMembershipService.add_member( user=user, team_id=team.id, keys=keys, invited_user_id=user.pk, role=TeamRoleChoices.ADMIN, ) return team
def update_form_(cls, user: AbstractUser, form_id: int, name: str = NotPassed, description: str = NotPassed, xml_code: str = NotPassed, js_code: str = NotPassed, active: bool = NotPassed) -> Form: """ update an exsisting form :param user: the user calling the service :param form_id: id of the form that should be updated :param name: name of the form :param description: description (legal information, …) :param xml_code: xml code for the visual editor :param js_code: javascript code to render the form :param active: if the form is active or inactive :return: the updated form instance """ # TODO: implement updated note if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError("You are not allowed to create this form.") form = cls._update(form_id, { 'name': name, 'description': description, 'xml_code': xml_code, 'js_code': js_code, 'active': active, }) form.refresh_from_db() return form
def force_login(self, user: AbstractUser, base_url: str) -> None: """ Sets selenium to appear as if a user has successfully signed in. The user will have its backend attribute set to the value of the backend argument (which should be a dotted Python path string), or to settings.AUTHENTICATION_BACKENDS[0] if a value isn't provided. The authenticate() function called by login() normally annotates the user like this. The code is based on https://github.com/feffe/django-selenium-login/blob/master/seleniumlogin/__init__.py. """ # The original code was licensed under: # # # MIT License # # Copyright (c) 2016 Fredrik Westermark # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # from django.conf import settings SessionStore = import_module(settings.SESSION_ENGINE).SessionStore selenium_login_start_page = getattr( settings, "SELENIUM_LOGIN_START_PAGE", "/page_404/" ) self.driver.get("{}{}".format(base_url, selenium_login_start_page)) session = SessionStore() session[SESSION_KEY] = user.id session[BACKEND_SESSION_KEY] = settings.AUTHENTICATION_BACKENDS[0] session[HASH_SESSION_KEY] = user.get_session_auth_hash() session.save() cookie = { "name": settings.SESSION_COOKIE_NAME, "value": session.session_key, "path": "/", } self.driver.add_cookie(cookie) self.driver.refresh()
def get_view_permissions(user: AbstractUser) -> Set[str]: """ Get model names based on a users view/change permissions """ lower_perms = map(lambda x: x.lower(), user.get_all_permissions()) return { x.replace("view_", "") for x in lower_perms if "view" in x or "change" in x }
def add_key(cls, user: AbstractUser, public_key: str) -> EncryptionKey: """ submit a generated key for a user :param user: the user calling the service :param public_key: their public key :return: id/information about key creation """ if not user.has_perm(CanAddEncryptionKeyPermission): raise PermissionError("You are not allowed to add a form key") return EncryptionKey.objects.create(user=user, public_key=public_key, active=False)
def get_view_permissions(user: AbstractUser) -> Set[str]: """ Get model names based on a users view/change permissions """ perms = user.get_all_permissions() # the perm codenames should always be lower case lower_perms = [] for perm in perms: app, perm_codename = perm.split(".") lower_perms.append("{app}.{perm_codename}".format(app=app, perm_codename=perm_codename.lower())) return {x.replace("view_", "") for x in lower_perms if "view" in x or "change" in x}
def test_email_user(self): # valid send_mail parameters kwargs = { "fail_silently": False, "auth_user": None, "auth_password": None, "connection": None, "html_message": None, } abstract_user = AbstractUser(email='*****@*****.**') abstract_user.email_user(subject="Subject here", message="This is a message", from_email="*****@*****.**", **kwargs) # Test that one message has been sent. self.assertEqual(len(mail.outbox), 1) # Verify that test email contains the correct attributes: message = mail.outbox[0] self.assertEqual(message.subject, "Subject here") self.assertEqual(message.body, "This is a message") self.assertEqual(message.from_email, "*****@*****.**") self.assertEqual(message.to, [abstract_user.email])
def test_email_user(self): # valid send_mail parameters kwargs = { "fail_silently": False, "auth_user": None, "auth_password": None, "connection": None, "html_message": None, } abstract_user = AbstractUser(email='*****@*****.**') abstract_user.email_user(subject="Subject here", message="This is a message", from_email="*****@*****.**", **kwargs) self.assertEqual(len(mail.outbox), 1) message = mail.outbox[0] self.assertEqual(message.subject, "Subject here") self.assertEqual(message.body, "This is a message") self.assertEqual(message.from_email, "*****@*****.**") self.assertEqual(message.to, [abstract_user.email])
def update(self, instance, validated_data): get_user_model() if 'email' in validated_data: validated_data['email'] = BaseUserManager.normalize_email(validated_data['email']) if 'username' in validated_data: validated_data['username'] = AbstractUser.normalize_username(validated_data['username']) user = super(CreateUpdateUserSerializer, self).update(instance, validated_data) if 'password' in validated_data: user.set_password(validated_data['password']) user.save() return user
def remove_key(cls, user: AbstractUser, public_key_id: int) -> bool: """ remove a submitted public key that is used to share form keys between users :param user: the user calling the service :param public_key_id: id the of the public key that should be activated :return: the activated key object """ if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError( "You are not allowed to activate this form key") public_key = EncryptionKey.objects.get(id=public_key_id) public_key.delete() return True
def create_form_(cls, user: AbstractUser, name: str, description: str) -> Form: """ Create a new form :param user: the user calling the service :param name: name of the form :param description: description (legal information, …) :return: the newly created form instance """ if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError("You are not allowed to create this form.") form = cls._create({"name": name, "description": description}) return form
def create_form_schema(cls, user: AbstractUser, key: str, form_id: int, schema: str) -> FormSchema: """ create a new form section/schema :param user: the user calling the service :param key: the key this schema uses :param form_id: id of the form that uses this schema :param schema: the schema object itself :return: the newly created schema object """ if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError("You are not allowed to create this form schema.") form = Form.objects.get(pk=form_id) cls._validate_json_schema(schema) schema = FormSchema.objects.create(key=key, form=form, schema=schema) schema.save() return schema
def update_form_schema(cls, user: AbstractUser, schema_id: int, schema: str) -> FormSchema: """ :param user: the user calling the service :param schema_id: id of the schema that should be updated :param schema: the schema object itself :return: the updated schema object """ if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError("You are not allowed to create this form schema.") cls._validate_json_schema(schema) form_schema = FormSchema.objects.get(pk=schema_id) form_schema.schema = schema form_schema.save() return form_schema
def activate_key(cls, user: AbstractUser, public_key_id) -> EncryptionKey: """ activate a submitted public key, so that newly generated forms use this key for encryption :param user: the user calling the service :param public_key_id: id the of the public key that should be activated :return: the activated key object """ if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError("You are not allowed to activate this form key") public_key = EncryptionKey.objects.get(id=public_key_id) if public_key.active == True: raise FormServiceException("This public key is already active.") public_key.active = True public_key.save() return public_key
def create_or_update_form_schema(cls, user: AbstractUser, key: str, form_id: int, schema: str) -> FormSchema: """ create or update a form section/schema :param user: the user calling the service :param key: the key this schema uses :param form_id: id of the form that uses this schema :param schema: the schema object itself :return: the newly created schema object """ if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError("You are not allowed to create this form schema.") try: schemaobj = FormSchema.objects.get(key=key, form__id=form_id) schemaobj = cls.update_form_schema(user, schemaobj.pk, schema) except FormSchema.DoesNotExist: schemaobj = cls.create_form_schema(user, key, form_id, schema) return schemaobj
def add_csr(cls, user: AbstractUser, team_id: int, csr: str, public_key: str): """ add the signed certificate to the team :param user: user calling the service :param team_id: id of the team :param csr: the certificate request :param public_key: the public_key :return: team object """ if not user.has_perm(CanCreateTeamPermission): raise TeamServiceException( "You don't have the permission to create a new team") team = cls.retrieve(user, team_id) TeamCertificateService.create_certificate(team, csr, public_key, user.email) return team
def add_key(cls, user: AbstractUser, public_key: str, key_name: str = NotPassed) -> EncryptionKey: """ submit a generated key for a user :param key_name: name/description of the encryption key :param user: the user calling the service :param public_key: their public key :return: id/information about key creation """ if not user.has_perm(CanAddEncryptionKeyPermission): raise PermissionError("You are not allowed to add a form key") return cls._create({ "user": user.pk, "public_key": public_key, "key_name": key_name, })
def update_form_translation( cls, user: AbstractUser, translation_id: int, language: str = NotPassed, region: str = NotPassed, active: bool = NotPassed, ): """updates a translation for the given form :param language: the language the strings should be translated to :param region: the region of the language the strings should be translated to :param translation_id: id of the translation object :param active: is the translation active? :param user: the user calling the service """ translation = FormTranslation.objects.get(pk=translation_id) # if a language was configured when it was still available we should still support updating if (f"{language}-{region}" not in [a["iso_code"] for a in cls.get_available_languages()] and language != translation.language): raise FormServiceException( f"{language}-{region} is not configured as a supported language" ) if not user.has_perm(CanAddFormTranslationPermission): raise PermissionError( "You are not allowed to change a translation for this form") translation = cls._update( translation.id, { "language": language, "region": region, "active": active, }, ) return translation
def save(self, force_insert=False, force_update=False, using=None, update_fields=None): ''' Overwritten predefined save method to assign permission after save. ''' if not self.username: self.set_random_username(length=10) response = AbstractUser.save(self, force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields) if not self.has_usable_password(): self.save_password() self.save() return response
def update_form_groups(cls, user: AbstractUser, form_id: int, groups: List[int]) -> Form: """ update the user-groups that receive the form submissions :param user: the user calling the service :param form_id: the id of the form affected :param groups: a list of groups that should be able to receive submissions :return: the updated form instance """ if not user.has_perm(CanActivateEncryptionKeyPermission): raise PermissionError("You are not allowed to create this form.") form = FormService.retrieve_form(form_id) form.teams.clear() for grp in groups: #TODO check team type form.teams.add(Group.objects.get(pk=grp)) form.save() return form
def add_member( cls, user: AbstractUser, team_id: int, keys: Dict[int, str], invited_user_id: int, role: TeamRoleChoices = TeamRoleChoices.MEMBER, ) -> TeamMembership: """ creates a new user and makes them admin :param invited_user_id: the user that sould be added :param role: the role the newly created Member should have (Admin or Member) :param team_id: the id of the team the user should be added to :param user: user calling the services (needs CanCreateTeamPermission permission) :param keys: the encrypted keys for this member :return: the newly generated team """ team = TeamService.retrieve(user, team_id) if (not (user.has_perm(CanCreateTeamPermission) and team.members.count() == 0 and invited_user_id == user.pk) and not team.members.filter( user=user, role=TeamRoleChoices.ADMIN).exists()): raise TeamServiceException( "You don't have the permission to add a new team member") invited_user = User.objects.filter(pk=invited_user_id).get() TeamMembershipService._validate_keys_provided(invited_user, keys) team_membership = cls._create({ "team": team_id, "user": invited_user_id, "role": role, }) TeamMembershipService._add_keys_to_membership(invited_user, team_membership, keys) return team_membership
def email_user(self, subject, message, from_email=None, ignore_confirmed=False): if not (ignore_confirmed or self.email_confirmed): return False AbstractUser.email_user(self, subject, message, from_email) return True