def delete(self, name): """ --- summary: Delete group description: | Remove group from database. Requires `manage_users` capability. security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name responses: 200: description: When group was removed successfully content: application/json: schema: GroupSuccessResponseSchema 403: description: When user doesn't have `manage_users` capability. 404: description: When group doesn't exist 503: description: | Request canceled due to database statement timeout. """ group = (db.session.query(Group).filter(Group.name == name)).first() if group is None: raise NotFound("No such group") if group.immutable is True: raise Forbidden( f"Group '{name}' is immutable and can't be removed.") db.session.delete(group) db.session.commit() hooks.on_removed_group(group) logger.info("Group was deleted", extra={"group": name}) schema = GroupSuccessResponseSchema() return schema.dump({"name": name})
def post(self, name): """ --- summary: Create a new group description: | Creates a new group. Requires `manage_users` capability. security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name requestBody: description: Group information content: application/json: schema: GroupCreateRequestSchema responses: 200: description: When group was created successfully content: application/json: schema: GroupSuccessResponseSchema 400: description: When group name or request body is invalid 403: description: When user doesn't have `manage_users` capability 409: description: When group exists yet """ schema = GroupCreateRequestSchema() obj = loads_schema(request.get_data(as_text=True), schema) group_name_obj = load_schema({"name": name}, GroupNameSchemaBase()) if db.session.query( exists().where(Group.name == group_name_obj["name"])).scalar(): raise Conflict("Group exists yet") group = Group(name=group_name_obj["name"], capabilities=obj["capabilities"]) db.session.add(group) db.session.commit() logger.info( "Group created", extra={ "group": group.name, "capabilities": group.capabilities }, ) schema = GroupSuccessResponseSchema() return schema.dump({"name": name})
def delete(self, name, login): """ --- summary: Delete member from group description: | Removes member from existing group. Works only for user-defined groups (excluding private and 'public') Requires `manage_users` capability. security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name - in: path name: login schema: type: string description: Member login responses: 200: description: When member was removed successfully content: application/json: schema: GroupSuccessResponseSchema 400: description: When request body is invalid 403: description: When user doesn't have `manage_users` capability, group is immutable or user is pending 404: description: When user or group doesn't exist """ group_name_obj = load_schema({"name": name}, GroupNameSchemaBase()) user_login_obj = load_schema({"login": login}, UserLoginSchemaBase()) member = db.session.query(User).filter(User.login == login).first() if member is None: raise NotFound("No such user") if member.pending: raise Forbidden("User is pending and need to be accepted first") group = db.session.query(Group).options(joinedload( Group.users)).filter(Group.name == name).first() if group is None: raise NotFound("No such group") if group.immutable: raise Forbidden( "Removing members from private or public group is not allowed") group.users.remove(member) member.reset_sessions() db.session.commit() logger.info('Group member deleted', extra={ 'user': member.login, 'group': group.name }) schema = GroupSuccessResponseSchema() return schema.dump({"name": name})
def put(self, name): """ --- summary: Update group name and capabilities description: | Updates group name and capabilities. Works only for user-defined groups (excluding private and 'public') Requires `manage_users` capability. security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name requestBody: description: Group information content: application/json: schema: GroupUpdateRequestSchema responses: 200: description: When group was updated successfully content: application/json: schema: GroupSuccessResponseSchema 400: description: When group name or request body is invalid 403: description: When user doesn't have `manage_users` capability or group is immutable 404: description: When group doesn't exist """ schema = GroupUpdateRequestSchema() obj = loads_schema(request.get_data(as_text=True), schema) group_name_obj = load_schema({"name": name}, GroupNameSchemaBase()) group = db.session.query(Group).filter(Group.name == name).first() if group is None: raise NotFound("No such group") if obj["name"] is not None: if obj["name"] != name and group.immutable: raise Forbidden( "Renaming group not allowed - group is immutable") group.name = obj["name"] if obj["capabilities"] is not None: group.capabilities = obj["capabilities"] # Invalidate all sessions due to potentially changed capabilities for member in group.users: member.reset_sessions() db.session.commit() logger.info('Group updated', extra={ "group": group.name, "capabilities": group.capabilities }) schema = GroupSuccessResponseSchema() return schema.dump({"name": group.name})
def delete(self, name, login): """ --- summary: Delete member from group description: | Removes member from existing group. Works only for user-defined groups (excluding private and 'public') Requires `manage_users` capability or group_admin membership. security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name - in: path name: login schema: type: string description: Member login responses: 200: description: When member was removed successfully content: application/json: schema: GroupSuccessResponseSchema 400: description: When request body is invalid 403: description: | When user doesn't have `manage_users` capability, group is immutable or user is pending 404: description: When user or group doesn't exist 409: description: When member is already removed """ group_name_obj = load_schema({"name": name}, GroupNameSchemaBase()) user_login_obj = load_schema({"login": login}, UserLoginSchemaBase()) group = (db.session.query(Group).options( joinedload(Group.members), joinedload(Group.members, Member.user)).filter( Group.name == group_name_obj["name"])).first() if not (g.auth_user.has_rights(Capabilities.manage_users) or g.auth_user.is_group_admin(group.id)): raise Forbidden("You are not permitted to manage this group") if group is None: raise NotFound("No such group") if group.immutable: raise Forbidden( "Removing members from immutable group is not allowed") member = (db.session.query(User).filter( User.login == user_login_obj["login"]).first()) if g.auth_user.login == member.login: raise Forbidden("You can't remove yourself from the group, " "only system admin can remove group admins.") if member is None: raise NotFound("No such user") if member.pending: raise Forbidden("User is pending and need to be accepted first") if not group.remove_member(member): raise Conflict("Member is already removed") db.session.commit() logger.info("Group member deleted", extra={ "user": member.login, "group": group.name }) schema = GroupSuccessResponseSchema() return schema.dump({"name": name})
def put(self, name, login): """ --- summary: Update group membership description: | Updates group membership for specific member e.g. to set admin role. Works only for user-defined groups (excluding private and 'public') Requires `manage_users` capability security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name - in: path name: login schema: type: string description: Member login requestBody: description: Group membership information content: application/json: schema: GroupMemberUpdateRequestSchema responses: 200: description: When member was added successfully content: application/json: schema: GroupSuccessResponseSchema 400: description: When request body is invalid 403: description: | When user doesn't have `manage_users` capability, group is immutable or user is pending 404: description: When user or group doesn't exist 409: description: When member is already added """ group_name_obj = load_schema({"name": name}, GroupNameSchemaBase()) user_login_obj = load_schema({"login": login}, UserLoginSchemaBase()) membership = loads_schema(request.get_data(as_text=True), GroupMemberUpdateRequestSchema()) group = (db.session.query(Group).options( joinedload(Group.members), joinedload(Group.members, Member.user)).filter( Group.name == group_name_obj["name"])).first() if group is None: raise NotFound("No such group") if group.immutable: raise Forbidden( "Change membership in immutable group is not allowed") member = (db.session.query(User).filter( User.login == user_login_obj["login"]).first()) if member is None: raise NotFound("No such user") if member.pending: raise Forbidden("User is pending and need to be accepted first") member.set_group_admin(group.id, membership["group_admin"]) db.session.commit() logger.info("Group member updated", extra={ "user": member.login, "group": group.name }) schema = GroupSuccessResponseSchema() return schema.dump({"name": name})
def post(self, name, login): """ --- summary: Add a member to the specific group description: | Adds new member to existing group Works only for user-defined groups (excluding private and 'public') Requires `manage_users` capability security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name - in: path name: login schema: type: string description: Member login responses: 200: description: When member was added successfully content: application/json: schema: GroupSuccessResponseSchema 400: description: When request body is invalid 403: description: | When user doesn't have `manage_users` capability, group is immutable or user is pending 404: description: When user or group doesn't exist """ group_name_obj = load_schema({"name": name}, GroupNameSchemaBase()) user_login_obj = load_schema({"login": login}, UserLoginSchemaBase()) group = (db.session.query(Group).options( joinedload(Group.members), joinedload(Group.members, Member.user)).filter( Group.name == group_name_obj["name"])).first() if group is None: raise NotFound("No such group") if group.immutable: raise Forbidden("Adding members to immutable group is not allowed") member = (db.session.query(User).filter( User.login == user_login_obj["login"]).first()) if member is None: raise NotFound("No such user") if member.pending: raise Forbidden("User is pending and need to be accepted first") if not group.add_member(member): raise Conflict("Member is already added") db.session.commit() logger.info("Group member added", extra={ "user": member.login, "group": group.name }) schema = GroupSuccessResponseSchema() return schema.dump({"name": name})
def put(self, name): """ --- summary: Update group attributes description: | Updates group attributes. If the group is immutable, you can only change capabilities. Requires `manage_users` capability. security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name requestBody: description: Group information content: application/json: schema: GroupUpdateRequestSchema responses: 200: description: When group was updated successfully content: application/json: schema: GroupSuccessResponseSchema 400: description: When group name or request body is invalid 403: description: | When user doesn't have `manage_users` capability or group is immutable 404: description: When group doesn't exist """ schema = GroupUpdateRequestSchema() obj = loads_schema(request.get_data(as_text=True), schema) group_name_obj = load_schema({"name": name}, GroupNameSchemaBase()) group = (db.session.query(Group).filter( Group.name == group_name_obj["name"]).first()) if group is None: raise NotFound("No such group") immutable_fields = ["name", "default", "workspace"] if group.immutable: for field in immutable_fields: if obj[field] is not None: raise Forbidden( f"Can't change '{field}', group is immutable") if obj["name"] is not None: group.name = obj["name"] if obj["capabilities"] is not None: group.capabilities = obj["capabilities"] if obj["default"] is not None: group.default = obj["default"] if obj["workspace"] is not None: group.default = obj["workspace"] db.session.commit() logger.info( "Group updated", extra={ "group": group.name, "capabilities": group.capabilities }, ) schema = GroupSuccessResponseSchema() return schema.dump({"name": group.name})