def disable_user(session, user): """Disables an enabled user""" get_plugin_proxy().will_disable_user(session, user) user.enabled = False Counter.incr(session, "updates")
def post(self, group_id=None, name=None, account_id=None, accountname=None, mapping_id=None): group = Group.get(self.session, group_id, name) if not group: return self.notfound() service_account = ServiceAccount.get(self.session, account_id, accountname) if not service_account: return self.notfound() if not self.check_access(self.session, self.current_user, service_account): return self.forbidden() mapping = ServiceAccountPermissionMap.get(self.session, mapping_id) if not mapping: return self.notfound() permission = mapping.permission argument = mapping.argument mapping.delete(self.session) Counter.incr(self.session, "updates") self.session.commit() AuditLog.log( self.session, self.current_user.id, "revoke_permission", "Revoked permission with argument: {}".format(argument), on_permission_id=permission.id, on_group_id=group.id, on_user_id=service_account.user.id, ) return self.redirect( "/groups/{}/service/{}?refresh=yes".format(group.name, service_account.user.username) )
def update_status(self, requester, status, reason): now = datetime.utcnow() current_status = self.status self.status = status request_status_change = RequestStatusChange( request=self, user_id=requester.id, from_status=current_status, to_status=status, change_at=now ).add(self.session) self.session.flush() Comment( obj_type=OBJ_TYPES_IDX.index("RequestStatusChange"), obj_pk=request_status_change.id, user_id=requester.id, comment=reason, created_on=now ).add(self.session) if status == "actioned": edge = self.session.query(GroupEdge).filter_by( id=self.edge_id ).one() edge.apply_changes(self) Counter.incr(self.session, "updates")
def set_metadata(self, key, value): if not re.match(PERMISSION_VALIDATION, key): raise ValueError('Metadata key does not match regex.') row = None for try_row in self.my_metadata(): if try_row.data_key == key: row = try_row break if row: if value is None: row.delete(self.session) else: row.data_value = value else: if value is None: # Do nothing, a delete on a key that's not set return else: row = UserMetadata(user_id=self.id, data_key=key, data_value=value) row.add(self.session) Counter.incr(self.session, "updates") self.session.commit()
def post(self, tag_id=None, name=None): tag = PublicKeyTag.get(self.session, tag_id, name) if not tag: return self.notfound() if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name): return self.forbidden() form = TagEditForm(self.request.arguments, obj=tag) if not form.validate(): return self.render( "tag-edit.html", tag=tag, form=form, alerts=self.get_form_alerts(form.errors) ) tag.description = form.data["description"] tag.enabled = form.data["enabled"] Counter.incr(self.session, "updates") try: self.session.commit() except IntegrityError: self.session.rollback() form.tagname.errors.append( "{} already exists".format(form.data["tagname"]) ) return self.render( "tag-edit.html", tag=tag, form=form, alerts=self.get_form_alerts(form.errors) ) AuditLog.log(self.session, self.current_user.id, 'edit_tag', 'Edited tag.', on_tag_id=tag.id) return self.redirect("/tags/{}".format(tag.name))
def add_public_key(session, user, public_key_str): """Add a public key for a particular user. Args: session: db session user: User model of user in question public_key_str: public key to add Return created PublicKey model or raises DuplicateKey if key is already in use. """ pubkey = sshpubkey.PublicKey.from_str(public_key_str) db_pubkey = PublicKey( user=user, public_key='%s %s %s' % (pubkey.key_type, pubkey.key, pubkey.comment), fingerprint=pubkey.fingerprint, key_size=pubkey.key_size, key_type=pubkey.key_type, ) try: db_pubkey.add(session) Counter.incr(session, "updates") except IntegrityError: session.rollback() raise DuplicateKey() session.commit() return db_pubkey
def post(self, name=None, mapping_id=None): grantable = self.current_user.my_grantable_permissions() if not grantable: return self.forbidden() mapping = PermissionMap.get(self.session, id=mapping_id) if not mapping: return self.notfound() allowed = False for perm in grantable: if perm[0].name == mapping.permission.name: if matches_glob(perm[1], mapping.argument): allowed = True if not allowed: return self.forbidden() permission = mapping.permission group = mapping.group mapping.delete(self.session) Counter.incr(self.session, "updates") self.session.commit() AuditLog.log(self.session, self.current_user.id, 'revoke_permission', 'Revoked permission with argument: {}'.format(mapping.argument), on_group_id=group.id, on_permission_id=permission.id) return self.redirect('/groups/{}?refresh=yes'.format(group.name))
def disable_permission_auditing(session, permission_name, actor_user_id): """Set a permission as audited. Args: session(models.base.session.Session): database session permission_name(str): name of permission in question actor_user_id(int): id of user who is disabling auditing """ permission = get_permission(session, permission_name) if not permission: raise NoSuchPermission(name=permission_name) permission.audited = False AuditLog.log( session, actor_user_id, "disable_auditing", "Disabled auditing.", on_permission_id=permission.id, ) Counter.incr(session, "updates") session.commit()
def post(self): form = TagCreateForm(self.request.arguments) if not form.validate(): return self.render( "tag-create.html", form=form, alerts=self.get_form_alerts(form.errors) ) tag = PublicKeyTag( name=form.data["tagname"], description=form.data["description"], ) try: tag.add(self.session) self.session.flush() except IntegrityError: self.session.rollback() form.tagname.errors.append( "{} already exists".format(form.data["tagname"]) ) return self.render( "tag-create.html", form=form, alerts=self.get_form_alerts(form.errors) ) Counter.incr(self.session, "updates") self.session.commit() AuditLog.log(self.session, self.current_user.id, 'create_tag', 'Created new tag.', on_tag_id=tag.id) return self.redirect("/tags/{}?refresh=yes".format(tag.name))
def grant_permission_to_tag(session, tag_id, permission_id, argument=''): # type: (Session, int, int, str) -> bool """ Grant a permission to this tag. This will fail if the (permission, argument) has already been granted to this tag. Args: session(models.base.session.Sessioan): database session tag_id(int): the id of the tag we're granting the permission to permission_id(int): the id of the permission to be granted argument(str): must match constants.ARGUMENT_VALIDATION Throws: AssertError if argument does not match ARGUMENT_VALIDATION regex Returns: bool indicating whether the function succeeded or not """ assert re.match(ARGUMENT_VALIDATION + r"$", argument), \ 'Permission argument does not match regex.' try: mapping = TagPermissionMap(permission_id=permission_id, tag_id=tag_id, argument=argument) mapping.add(session) Counter.incr(session, "updates") except IntegrityError: session.rollback() return False session.commit() return True
def grant_permission_to_service_account(session, account, permission, argument=""): """ Grant a permission to this service account. This will fail if the (permission, argument) has already been granted to this group. Args: session(models.base.session.Session): database session account(ServiceAccount): a ServiceAccount object being granted a permission permission(Permission): a Permission object being granted argument(str): must match constants.ARGUMENT_VALIDATION Throws: AssertError if argument does not match ARGUMENT_VALIDATION regex """ assert re.match( ARGUMENT_VALIDATION + r"$", argument ), "Permission argument does not match regex." mapping = ServiceAccountPermissionMap( permission_id=permission.id, service_account_id=account.id, argument=argument ) mapping.add(session) Counter.incr(session, "updates") session.commit()
def add_service_account(session, group, service_account): # type: (Session, Group, ServiceAccount) -> None """Add a service account to a group.""" logging.debug("Adding service account %s to %s", service_account.user.username, group.groupname) GroupServiceAccount(group_id=group.id, service_account=service_account).add(session) Counter.incr(session, "updates") session.commit()
def revoke_member(self, requester, user_or_group, reason): """ Revoke a member (User or Group) from this group. Arguments: requester: A User object of the person requesting the addition user_or_group: A User/Group object of the member reason: A comment on why this member should exist """ now = datetime.utcnow() logging.debug( "Revoking member (%s) from %s", user_or_group.name, self.groupname ) # Create the edge even if it doesn't exist so that we can explicitly # disable it. edge, new = GroupEdge.get_or_create( self.session, group_id=self.id, member_type=user_or_group.member_type, member_pk=user_or_group.id, ) self.session.flush() request = Request( requester_id=requester.id, requesting_id=self.id, on_behalf_obj_type=user_or_group.member_type, on_behalf_obj_pk=user_or_group.id, requested_at=now, edge_id=edge.id, status="actioned", changes=build_changes( edge, role="member", expiration=None, active=False ) ).add(self.session) self.session.flush() request_status_change = RequestStatusChange( request=request, user_id=requester.id, to_status="actioned", change_at=now ).add(self.session) self.session.flush() Comment( obj_type=OBJ_TYPES_IDX.index("RequestStatusChange"), obj_pk=request_status_change.id, user_id=requester.id, comment=reason, created_on=now ).add(self.session) edge.apply_changes(request) self.session.flush() Counter.incr(self.session, "updates")
def disable_user_token(session, user_token): """Disable specified user token. Args: session(grouper.models.base.session.Session): database session user_token(grouper.models.user_token.UserToken): token to disable """ user_token.disabled_at = datetime.utcnow() Counter.incr(session, "updates")
def persist_group_member_changes(session, group, requester, member, status, reason, create_edge=False, **updates): requested_at = datetime.utcnow() if "role" in updates: role = updates["role"] _validate_role(member.member_type, role) get_plugin_proxy().will_update_group_membership(session, group, member, **updates) if create_edge: edge = _create_edge(session, group, member, updates.get("role", "member")) else: edge = _get_edge(session, group, member) if not edge: raise MemberNotFound() changes = _serialize_changes(edge, **updates) request = Request( requester_id=requester.id, requesting_id=group.id, on_behalf_obj_type=member.member_type, on_behalf_obj_pk=member.id, requested_at=requested_at, edge_id=edge.id, status=status, changes=changes, ).add(session) session.flush() request_status_change = RequestStatusChange( request=request, user_id=requester.id, to_status=status, change_at=requested_at, ).add(session) session.flush() Comment( obj_type=OBJ_TYPES["RequestStatusChange"], obj_pk=request_status_change.id, user_id=requester.id, comment=reason, created_on=requested_at, ).add(session) session.flush() if status == "actioned": edge.apply_changes(request.changes) session.flush() Counter.incr(session, "updates") return request
def enable_service_account(session, actor, service_account, owner): # type: (Session, User, ServiceAccount, Group) -> None """Enables a service account and sets a new owner.""" enable_user(session, service_account.user, actor, preserve_membership=False) add_service_account(session, owner, service_account) AuditLog.log(session, actor.id, "enable_service_account", "Enabled service account.", on_group_id=owner.id, on_user_id=service_account.user_id) Counter.incr(session, "updates") session.commit()
def test_groups_email(groups, session, graph, http_client, base_url): # noqa: F811 expected_address = "*****@*****.**" sad = groups["sad-team"] sad.email_address = expected_address session.commit() Counter.incr(session, "updates") graph.update_from_db(session) api_url = url(base_url, "/groups/{}".format(sad.name)) resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert body["data"]["group"]["contacts"]["email"] == expected_address
def delete_public_key(session, user_id, key_id): """Delete a particular user's public key. Args: session(models.base.session.Session): database session user_id(int): id of user in question key_id(int): id of the user's key we want to delete Throws: KeyNotFound if specified key wasn't found """ pkey = get_public_key(session, user_id, key_id) pkey.delete(session) Counter.incr(session, "updates") session.commit()
def delete_user_password(session, password_name, user_id): # type: (Session, str, int) -> None """Delete the specified UserPassword. Args: session(grouper.models.base.session.Session): database session password_name: the name of the password to delete user_id: the user whose password is being deleted """ p = session.query(UserPassword).filter_by(name=password_name, user_id=user_id).scalar() if not p: raise PasswordDoesNotExist() p.delete(session) Counter.incr(session, "updates") session.commit()
def add_public_key(session, user, public_key_str): """Add a public key for a particular user. Args: session: db session user: User model of user in question public_key_str: public key to add Throws: DuplicateKey if key is already in use PublicKeyParseError if key can't be parsed BadPublicKey if a plugin rejects the key Returns: PublicKey model object representing the key """ pubkey = sshpubkeys.SSHKey(public_key_str, strict=True) try: pubkey.parse() except sshpubkeys.InvalidKeyException as e: raise PublicKeyParseError(str(e)) try: get_plugin_proxy().will_add_public_key(pubkey) except PluginRejectedPublicKey as e: raise BadPublicKey(str(e)) db_pubkey = PublicKey( user=user, public_key=pubkey.keydata.strip(), fingerprint=pubkey.hash_md5().replace("MD5:", ""), fingerprint_sha256=pubkey.hash_sha256().replace("SHA256:", ""), key_size=pubkey.bits, key_type=pubkey.key_type, comment=pubkey.comment, ) try: db_pubkey.add(session) Counter.incr(session, "updates") except IntegrityError: session.rollback() raise DuplicateKey() session.commit() return db_pubkey
def disable_service_account(session, actor, service_account): # type: (Session, User, ServiceAccount) -> None """Disables a service account and deletes the association with a Group.""" disable_user(session, service_account.user) owner_id = service_account.owner.group.id service_account.owner.delete(session) permissions = session.query(ServiceAccountPermissionMap).filter_by( service_account_id=service_account.id) for permission in permissions: permission.delete(session) AuditLog.log(session, actor.id, "disable_service_account", "Disabled service account.", on_group_id=owner_id, on_user_id=service_account.user_id) Counter.incr(session, "updates") session.commit()
def post(self, group_id=None, name=None): group = Group.get(self.session, group_id, name) if not group: return self.notfound() if not user_can_manage_group(self.session, group, self.current_user): return self.forbidden() form = GroupEditForm(self.request.arguments, obj=group) if not form.validate(): return self.render( "group-edit.html", group=group, form=form, alerts=self.get_form_alerts(form.errors) ) if (group.groupname != form.data["groupname"] and is_service_account(self.session, group=group)): form.groupname.errors.append("You cannot change the name of service account groups") return self.render( "group-edit.html", group=group, form=form, alerts=self.get_form_alerts(form.errors) ) group.groupname = form.data["groupname"] group.description = form.data["description"] group.canjoin = form.data["canjoin"] group.auto_expire = form.data["auto_expire"] Counter.incr(self.session, "updates") try: self.session.commit() except IntegrityError: self.session.rollback() form.groupname.errors.append( "{} already exists".format(form.data["groupname"]) ) return self.render( "group-edit.html", group=group, form=form, alerts=self.get_form_alerts(form.errors) ) AuditLog.log(self.session, self.current_user.id, 'edit_group', 'Edited group.', on_group_id=group.id) return self.redirect("/groups/{}".format(group.name))
def add_new_user_password(session, password_name, password, user_id): # type: (Session, str, str, int) -> None """Add the new user password specified. Args: session(grouper.models.base.session.Session): database session password_name(str): name of the password to be added password(str): the (plaintext) password to be added user_id(int): the id of the user to add this password to """ p = UserPassword(name=password_name, user_id=user_id) p.set_password(password) Counter.incr(session, "updates") p.add(session) try: session.commit() except IntegrityError: raise PasswordAlreadyExists()
def edit_service_account(session, actor, service_account, description, machine_set): # type: (Session, User, ServiceAccount, str, str) -> None """Update the description and machine set of a service account. Raises: PluginRejectedMachineSet: if some plugin rejected the machine set """ if machine_set is not None: _check_machine_set(service_account, machine_set) service_account.description = description service_account.machine_set = machine_set Counter.incr(session, "updates") session.commit() AuditLog.log(session, actor.id, "edit_service_account", "Edited service account.", on_user_id=service_account.user.id)
def add_new_user_token(session, user_token): """Add the new user token specified. If user token doesn't contain a secret, create one. Args: session(grouper.models.base.session.Session): database session user_token(grouper.models.user_token.UserToken): token to create Returns: 2-tuple of the created UserToken and the secret """ secret = None if user_token.hashed_secret is None: secret = user_token._set_secret() user_token.add(session) Counter.incr(session, "updates") return user_token, secret
def test_users_aliased_permissions( mocker, session, standard_graph, http_client, base_url # noqa: F811 ): proxy = PluginProxy([PermissionAliasesPlugin()]) mocker.patch("grouper.graph.get_plugin_proxy", return_value=proxy) # Force graph update Counter.incr(session, "updates") standard_graph.update_from_db(session) api_url = url(base_url, "/users/[email protected]") resp = yield http_client.fetch(api_url) body = json.loads(resp.body) perms = [(p["permission"], p["argument"]) for p in body["data"]["permissions"]] assert ("owner", "sad-team") in perms assert ("ssh", "owner=sad-team") in perms assert ("sudo", "sad-team") in perms
def test_permissions_aliased_permissions(mocker, session, standard_graph, http_client, base_url): proxy = PluginProxy([PermissionAliasesPlugin()]) mocker.patch('grouper.graph.get_plugin_proxy', return_value=proxy) # Force graph update Counter.incr(session, "updates") standard_graph.update_from_db(session) api_url = url(base_url, '/permissions/ssh') resp = yield http_client.fetch(api_url) body = json.loads(resp.body) permissions = [ (group, p['argument']) for group, g in body['data']['groups'].iteritems() for p in g['permissions'] ] assert ('sad-team', 'owner=sad-team') in permissions
def enable_permission_auditing(session, permission_name, actor_user_id): """Set a permission as audited. Args: session(models.base.session.Session): database session permission_name(str): name of permission in question actor_user_id(int): id of user who is enabling auditing """ permission = Permission.get(session, permission_name) if not permission: raise NoSuchPermission(name=permission_name) permission._audited = True AuditLog.log(session, actor_user_id, 'enable_auditing', 'Enabled auditing.', on_permission_id=permission.id) Counter.incr(session, "updates") session.commit()
def add_tag_to_public_key(session, public_key, tag): # type: (Session, PublicKey, PublicKeyTag) -> None """Assigns the tag to the given public key. Args: session(models.base.session.Session): database session public_key(models.public_key.PublicKey): the public key to be tagged tag(models.public_key_tag.PublicKeyTag): the tag to be assigned to the public key Throws: DuplicateTag if the tag was already assigned to the public key """ mapping = PublicKeyTagMap(tag_id=tag.id, key_id=public_key.id) try: mapping.add(session) Counter.incr(session, "updates") session.commit() except IntegrityError: session.rollback() raise DuplicateTag()
def remove_tag_from_public_key(session, public_key, tag): # type: (Session, PublicKey, PublicKeyTag) -> None """Removes the tag from the given public key. Args: session(models.base.session.Session): database session public_key(models.public_key.PublicKey): the public key to be tagged tag(models.public_key_tag.PublicKeyTag): the tag to be removed from the public key Throws: TagNotOnKey if the tag was already assigned to the public key """ mapping = session.query(PublicKeyTagMap).filter_by(tag_id=tag.id, key_id=public_key.id).scalar() if not mapping: raise TagNotOnKey() mapping.delete(session) Counter.incr(session, "updates") session.commit()
def set_user_metadata(session, user_id, data_key, data_value): # type: (Session, int, str, str) -> Optional[UserMetadata] """Set a single piece of user metadata. Args: session(models.base.session.Session): database session user_id(int): id of user in question data_key(str): the metadata key (limited to 64 character by db schema) data_value(str): the metadata value (limited to 64 character by db schema) if this is None, the metadata entry is deleted. Returns: the UserMetadata object or None if entry was deleted """ assert re.match(PERMISSION_VALIDATION, data_key), "proposed metadata key is valid" user_md = get_user_metadata_by_key(session, user_id, data_key) if user_md: if data_value is None: user_md.delete(session) user_md = None else: user_md.data_value = data_value user_md.add(session) else: if data_value is None: # do nothing, a delete on a key that's not set return else: user_md = UserMetadata(user_id=user_id, data_key=data_key, data_value=data_value) user_md.add(session) Counter.incr(session, "updates") session.commit() return user_md
def disable_service_account(session, actor, service_account): # type: (Session, User, ServiceAccount) -> None """Disables a service account and deletes the association with a Group.""" disable_user(session, service_account.user) owner_id = service_account.owner.group.id service_account.owner.delete(session) permissions = session.query(ServiceAccountPermissionMap).filter_by( service_account_id=service_account.id) for permission in permissions: permission.delete(session) AuditLog.log( session, actor.id, "disable_service_account", "Disabled service account.", on_group_id=owner_id, on_user_id=service_account.user_id, ) Counter.incr(session, "updates") session.commit()
def remove_tag_from_public_key(session, public_key, tag): # type: (Session, PublicKey, PublicKeyTag) -> None """Removes the tag from the given public key. Args: session(models.base.session.Session): database session public_key(models.public_key.PublicKey): the public key to be tagged tag(models.public_key_tag.PublicKeyTag): the tag to be removed from the public key Throws: TagNotOnKey if the tag was already assigned to the public key """ mapping = ( session.query(PublicKeyTagMap).filter_by(tag_id=tag.id, key_id=public_key.id).scalar() ) if not mapping: raise TagNotOnKey() mapping.delete(session) Counter.incr(session, "updates") session.commit()
def post(self, *args: Any, **kwargs: Any) -> None: name = self.get_path_argument("name") accountname = self.get_path_argument("accountname") mapping_id = int(self.get_path_argument("mapping_id")) group = Group.get(self.session, name=name) if not group: return self.notfound() service_account = ServiceAccount.get(self.session, name=accountname) if not service_account: return self.notfound() if not self.check_access(self.session, self.current_user, service_account): return self.forbidden() mapping = ServiceAccountPermissionMap.get(self.session, mapping_id) if not mapping: return self.notfound() permission = mapping.permission argument = mapping.argument mapping.delete(self.session) Counter.incr(self.session, "updates") self.session.commit() AuditLog.log( self.session, self.current_user.id, "revoke_permission", "Revoked permission with argument: {}".format(argument), on_permission_id=permission.id, on_group_id=group.id, on_user_id=service_account.user.id, ) return self.redirect( "/groups/{}/service/{}?refresh=yes".format(group.name, service_account.user.username) )
def post(self, tag_id=None, name=None): tag = PublicKeyTag.get(self.session, tag_id, name) if not tag: return self.notfound() if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name): return self.forbidden() form = TagEditForm(self.request.arguments, obj=tag) if not form.validate(): return self.render("tag-edit.html", tag=tag, form=form, alerts=self.get_form_alerts(form.errors)) tag.description = form.data["description"] tag.enabled = form.data["enabled"] Counter.incr(self.session, "updates") try: self.session.commit() except IntegrityError: self.session.rollback() form.tagname.errors.append("{} already exists".format( form.data["tagname"])) return self.render("tag-edit.html", tag=tag, form=form, alerts=self.get_form_alerts(form.errors)) AuditLog.log(self.session, self.current_user.id, "edit_tag", "Edited tag.", on_tag_id=tag.id) return self.redirect("/tags/{}".format(tag.name))
def test_permissions_aliased_permissions( mocker, session, standard_graph, http_client, base_url # noqa: F811 ): proxy = PluginProxy([PermissionAliasesPlugin()]) mocker.patch("grouper.graph.get_plugin_proxy", return_value=proxy) # Force graph update Counter.incr(session, "updates") standard_graph.update_from_db(session) api_url = url(base_url, "/permissions/ssh") resp = yield http_client.fetch(api_url) body = json.loads(resp.body) perms = [(group, p["argument"]) for group, g in iteritems(body["data"]["groups"]) for p in g["permissions"]] assert ("sad-team", "owner=sad-team") in perms
def grant_permission(session, group_id, permission_id, argument=""): """ Grant a permission to this group. This will fail if the (permission, argument) has already been granted to this group. Args: session(models.base.session.Session): database session permission(Permission): a Permission object being granted argument(str): must match constants.ARGUMENT_VALIDATION Throws: AssertError if argument does not match ARGUMENT_VALIDATION regex """ assert re.match( ARGUMENT_VALIDATION + r"$", argument ), "Permission argument does not match regex." mapping = PermissionMap(permission_id=permission_id, group_id=group_id, argument=argument) mapping.add(session) Counter.incr(session, "updates") session.commit()
def disable_permission_auditing(session, permission_name, actor_user_id): """Set a permission as audited. Args: session(models.base.session.Session): database session permission_name(str): name of permission in question actor_user_id(int): id of user who is disabling auditing """ permission = Permission.get(session, permission_name) if not permission: raise NoSuchPermission(name=permission_name) permission._audited = False AuditLog.log(session, actor_user_id, 'disable_auditing', 'Disabled auditing.', on_permission_id=permission.id) Counter.incr(session, "updates") session.commit()
def grant_permission_to_service_account(session, account, permission, argument=''): """ Grant a permission to this service account. This will fail if the (permission, argument) has already been granted to this group. Args: session(models.base.session.Session): database session account(ServiceAccount): a ServiceAccount object being granted a permission permission(Permission): a Permission object being granted argument(str): must match constants.ARGUMENT_VALIDATION Throws: AssertError if argument does not match ARGUMENT_VALIDATION regex """ assert re.match(ARGUMENT_VALIDATION, argument), 'Permission argument does not match regex.' mapping = ServiceAccountPermissionMap( permission_id=permission.id, service_account_id=account.id, argument=argument) mapping.add(session) Counter.incr(session, "updates") session.commit()
def disable_permission(session, permission_name, actor_user_id): """Set a permission as disabled. Args: session(models.base.session.Session): database session permission_name(str): name of permission in question actor_user_id(int): id of user who is disabling the permission """ if permission_name in (entry[0] for entry in SYSTEM_PERMISSIONS): raise CannotDisableASystemPermission(permission_name) permission = get_permission(session, permission_name) if not permission: raise NoSuchPermission(name=permission_name) permission.enabled = False AuditLog.log( session, actor_user_id, "disable_permission", "Disabled permission.", on_permission_id=permission.id, ) Counter.incr(session, "updates") session.commit()
def delete_public_key(session, user_id, key_id): """Delete a particular user's public key. This will remove all tags from the public key prior to deletion. Args: session(models.base.session.Session): database session user_id(int): id of user in question key_id(int): id of the user's key we want to delete Throws: KeyNotFound if specified key wasn't found """ pkey = get_public_key(session, user_id, key_id) tag_mappings = session.query(PublicKeyTagMap).filter_by(key_id=key_id).all() for mapping in tag_mappings: remove_tag_from_public_key(session, pkey, mapping.tag) pkey.delete(session) Counter.incr(session, "updates") session.commit()
def grant_permission( session: Session, group_id: int, permission_id: int, argument: str = "" ) -> None: """Grant a permission to this group. This will fail if the (permission, argument) has already been granted to this group. Args: session: Database session group_id: ID of group to which to grant the permission permission_id: ID of permission to grant argument: Must match constants.ARGUMENT_VALIDATION Throws: AssertError if argument does not match ARGUMENT_VALIDATION regex """ assert re.match(ARGUMENT_VALIDATION + r"$", argument), "Invalid permission argument" mapping = PermissionMap(permission_id=permission_id, group_id=group_id, argument=argument) mapping.add(session) Counter.incr(session, "updates") session.commit()
def add(self, session): # type: (Session) -> ServiceAccount super().add(session) Counter.incr(session, "updates") return self
def persist_group_member_changes( session, # type: Session group, # type: Group requester, # type: User member, # type: Union[User, Group] status, # type: str reason, # type: str create_edge=False, # type: bool **updates # type: Any ): # type: (...) -> Request requested_at = datetime.utcnow() if "role" in updates: role = updates["role"] _validate_role(member.member_type, role) get_plugin_proxy().will_update_group_membership(session, group, member, **updates) if create_edge: edge = _create_edge(session, group, member, updates.get("role", "member")) else: edge = _get_edge(session, group, member) if not edge: raise MemberNotFound() changes = _serialize_changes(edge, **updates) request = Request( requester_id=requester.id, requesting_id=group.id, on_behalf_obj_type=member.member_type, on_behalf_obj_pk=member.id, requested_at=requested_at, edge_id=edge.id, status=status, changes=changes, ).add(session) session.flush() request_status_change = RequestStatusChange( request=request, user_id=requester.id, to_status=status, change_at=requested_at).add(session) session.flush() Comment( obj_type=OBJ_TYPES["RequestStatusChange"], obj_pk=request_status_change.id, user_id=requester.id, comment=reason, created_on=requested_at, ).add(session) session.flush() if status == "actioned": edge.apply_changes(request.changes) session.flush() Counter.incr(session, "updates") return request
def add(self, session): super().add(session) Counter.incr(session, "updates") return self
def disable(self): self.enabled = False Counter.incr(self.session, "updates")
def enable(self): self.enabled = True Counter.incr(self.session, "updates")
def disable_user(session, user): """Disables an enabled user""" user.enabled = False Counter.incr(session, "updates")
def add(self, session): # type: (Session) -> User super().add(session) Counter.incr(session, "updates") return self
def add_member(self, requester, user_or_group, reason, status="pending", expiration=None, role="member"): """ Add a member (User or Group) to this group. Arguments: requester: A User object of the person requesting the addition user_or_group: A User/Group object of the member reason: A comment on why this member should exist status: pending/actioned, whether the request needs approval or should be immediate expiration: datetime object when membership should expire. role: member/manager/owner/np-owner of the Group. """ now = datetime.utcnow() member_type = user_or_group.member_type if member_type == 1 and role != "member": raise InvalidRoleForMember("Groups can only have the role of 'member'") logging.debug( "Adding member (%s) to %s", user_or_group.name, self.groupname ) edge, new = GroupEdge.get_or_create( self.session, group_id=self.id, member_type=member_type, member_pk=user_or_group.id, ) # TODO(herb): this means all requests by this user to this group will # have the same role. we should probably record the role specifically # on the request and use that as the source on the UI edge._role = GROUP_EDGE_ROLES.index(role) self.session.flush() request = Request( requester_id=requester.id, requesting_id=self.id, on_behalf_obj_type=member_type, on_behalf_obj_pk=user_or_group.id, requested_at=now, edge_id=edge.id, status=status, changes=build_changes( edge, role=role, expiration=expiration, active=True ) ).add(self.session) self.session.flush() request_status_change = RequestStatusChange( request=request, user_id=requester.id, to_status=status, change_at=now ).add(self.session) self.session.flush() Comment( obj_type=3, obj_pk=request_status_change.id, user_id=requester.id, comment=reason, created_on=now ).add(self.session) if status == "actioned": edge.apply_changes(request) self.session.flush() Counter.incr(self.session, "updates") return request.id
def edit_member(self, requester, user_or_group, reason, **kwargs): """ Edit an existing member (User or Group) of a group. This takes the same parameters as add_member, except that we do not allow you to set a status: this only works on existing members. Any option that is not passed is not updated, and instead, the existing value for this user is kept. """ now = datetime.utcnow() member_type = user_or_group.member_type if member_type == 1 and "role" in kwargs and kwargs["role"] != "member": raise InvalidRoleForMember("Groups can only have the role of 'member'") logging.debug( "Editing member (%s) in %s", user_or_group.name, self.groupname ) edge = GroupEdge.get( self.session, group_id=self.id, member_type=member_type, member_pk=user_or_group.id, ) self.session.flush() if not edge: raise MemberNotFound() request = Request( requester_id=requester.id, requesting_id=self.id, on_behalf_obj_type=member_type, on_behalf_obj_pk=user_or_group.id, requested_at=now, edge_id=edge.id, status="actioned", changes=build_changes( edge, **kwargs ), ).add(self.session) self.session.flush() request_status_change = RequestStatusChange( request=request, user_id=requester.id, to_status="actioned", change_at=now, ).add(self.session) self.session.flush() Comment( obj_type=OBJ_TYPES_IDX.index("RequestStatusChange"), obj_pk=request_status_change.id, user_id=requester.id, comment=reason, created_on=now, ).add(self.session) edge.apply_changes(request) self.session.flush() message = "Edit member {} {}: {}".format( OBJ_TYPES_IDX[member_type].lower(), user_or_group.name, reason) AuditLog.log(self.session, requester.id, 'edit_member', message, on_group_id=self.id) Counter.incr(self.session, "updates")