From 719cd0dbfc60aae1c80d3b0e4e4ae09febe37791 Mon Sep 17 00:00:00 2001 From: irinaschubert Date: Mon, 13 Sep 2021 16:38:23 +0200 Subject: [PATCH] docs: add username to changeable attributes (DSP-1895) (#1904) * add username to changeable attributes list in code documentation * add username to changeable attributes list in docstring --- docs/03-apis/api-admin/users.md | 2 +- .../usersmessages/UsersMessagesADM.scala | 967 +++++++++--------- 2 files changed, 493 insertions(+), 476 deletions(-) diff --git a/docs/03-apis/api-admin/users.md b/docs/03-apis/api-admin/users.md index 110532de22..a0394d580a 100644 --- a/docs/03-apis/api-admin/users.md +++ b/docs/03-apis/api-admin/users.md @@ -111,7 +111,7 @@ specified by the `id` in the request body as below: ### Update basic user information** - Required permission: SystemAdmin / self - - Changeable information: email, given name, family name, + - Changeable information: username, email, given name, family name, password, status, SystemAdmin membership - TypeScript Docs: userFormats - ChangeUserApiRequestADM - PUT: `/admin/users/iri//BasicUserInformation` diff --git a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala index 5537be27c8..5dd282cc91 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala @@ -39,27 +39,29 @@ import spray.json._ // API requests /** - * Represents an API request payload that asks the Knora API server to create a new user. - * - * @param id the optional IRI of the user to be created (unique). - * @param username the username of the user to be created (unique). - * @param email the email of the user to be created (unique). - * @param givenName the given name of the user to be created. - * @param familyName the family name of the user to be created - * @param password the password of the user to be created. - * @param status the status of the user to be created (active = true, inactive = false). - * @param lang the default language of the user to be created. - * @param systemAdmin the system admin membership. - */ -case class CreateUserApiRequestADM(id: Option[IRI] = None, - username: String, - email: String, - givenName: String, - familyName: String, - password: String, - status: Boolean, - lang: String, - systemAdmin: Boolean) { + * Represents an API request payload that asks the Knora API server to create a new user. + * + * @param id the optional IRI of the user to be created (unique). + * @param username the username of the user to be created (unique). + * @param email the email of the user to be created (unique). + * @param givenName the given name of the user to be created. + * @param familyName the family name of the user to be created + * @param password the password of the user to be created. + * @param status the status of the user to be created (active = true, inactive = false). + * @param lang the default language of the user to be created. + * @param systemAdmin the system admin membership. + */ +case class CreateUserApiRequestADM( + id: Option[IRI] = None, + username: String, + email: String, + givenName: String, + familyName: String, + password: String, + status: Boolean, + lang: String, + systemAdmin: Boolean +) { implicit protected val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance @@ -77,29 +79,31 @@ case class CreateUserApiRequestADM(id: Option[IRI] = None, } /** - * Represents an API request payload that asks the Knora API server to update an existing user. Information that can - * be changed include the user's email, given name, family name, language, password, user status, and system admin - * membership. - * - * @param username the new username. Needs to be unique on the server. - * @param email the new email address. Needs to be unique on the server. - * @param givenName the new given name. - * @param familyName the new family name. - * @param lang the new ISO 639-1 code of the new preferred language. - * @param requesterPassword the password of the user making the request. - * @param newPassword the new password. - * @param status the new user status (active = true, inactive = false). - * @param systemAdmin the new system admin membership status. - */ -case class ChangeUserApiRequestADM(username: Option[String] = None, - email: Option[String] = None, - givenName: Option[String] = None, - familyName: Option[String] = None, - lang: Option[String] = None, - requesterPassword: Option[String] = None, - newPassword: Option[String] = None, - status: Option[Boolean] = None, - systemAdmin: Option[Boolean] = None) { + * Represents an API request payload that asks the Knora API server to update an existing user. Information that can + * be changed include the user's username, email, given name, family name, language, password, user status, and system admin + * membership. + * + * @param username the new username. Needs to be unique on the server. + * @param email the new email address. Needs to be unique on the server. + * @param givenName the new given name. + * @param familyName the new family name. + * @param lang the new ISO 639-1 code of the new preferred language. + * @param requesterPassword the password of the user making the request. + * @param newPassword the new password. + * @param status the new user status (active = true, inactive = false). + * @param systemAdmin the new system admin membership status. + */ +case class ChangeUserApiRequestADM( + username: Option[String] = None, + email: Option[String] = None, + givenName: Option[String] = None, + familyName: Option[String] = None, + lang: Option[String] = None, + requesterPassword: Option[String] = None, + newPassword: Option[String] = None, + status: Option[Boolean] = None, + systemAdmin: Option[Boolean] = None +) { val parametersCount: Int = List( username, @@ -149,329 +153,347 @@ case class ChangeUserApiRequestADM(username: Option[String] = None, // Messages /** - * An abstract trait representing message that can be sent to `UsersResponderV1`. - */ + * An abstract trait representing message that can be sent to `UsersResponderV1`. + */ sealed trait UsersResponderRequestADM extends KnoraRequestADM /** - * Get all information about all users in form of a sequence of [[UserADM]]. Returns an empty sequence if - * no users are found. Administration permission checking is skipped. - * - * @param userInformationTypeADM the extent of the information returned. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user that is making the request. - */ -case class UsersGetADM(userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM) - extends UsersResponderRequestADM + * Get all information about all users in form of a sequence of [[UserADM]]. Returns an empty sequence if + * no users are found. Administration permission checking is skipped. + * + * @param userInformationTypeADM the extent of the information returned. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user that is making the request. + */ +case class UsersGetADM( + userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM +) extends UsersResponderRequestADM /** - * Get all information about all users in form of [[UsersGetResponseV1]]. The UsersGetRequestV1 returns either - * something or a NotFound exception if there are no users found. Administration permission checking is performed. - * - * @param userInformationTypeADM the extent of the information returned. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - */ -case class UsersGetRequestADM(userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM) - extends UsersResponderRequestADM + * Get all information about all users in form of [[UsersGetResponseV1]]. The UsersGetRequestV1 returns either + * something or a NotFound exception if there are no users found. Administration permission checking is performed. + * + * @param userInformationTypeADM the extent of the information returned. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + */ +case class UsersGetRequestADM( + userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM +) extends UsersResponderRequestADM /** - * A message that requests a user's profile either by IRI, username, or email. A successful response will be a [[UserADM]]. - * - * @param identifier the IRI, email, or username of the user to be queried. - * @param userInformationTypeADM the extent of the information returned. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - */ -case class UserGetADM(identifier: UserIdentifierADM, - userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM) - extends UsersResponderRequestADM {} + * A message that requests a user's profile either by IRI, username, or email. A successful response will be a [[UserADM]]. + * + * @param identifier the IRI, email, or username of the user to be queried. + * @param userInformationTypeADM the extent of the information returned. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + */ +case class UserGetADM( + identifier: UserIdentifierADM, + userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM +) extends UsersResponderRequestADM {} /** - * A message that requests a user's profile either by IRI, username, or email. A successful response will be a [[UserResponseADM]]. - * - * @param identifier the IRI, email, or username of the user to be queried. - * @param userInformationTypeADM the extent of the information returned. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - */ -case class UserGetRequestADM(identifier: UserIdentifierADM, - userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM) - extends UsersResponderRequestADM {} + * A message that requests a user's profile either by IRI, username, or email. A successful response will be a [[UserResponseADM]]. + * + * @param identifier the IRI, email, or username of the user to be queried. + * @param userInformationTypeADM the extent of the information returned. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + */ +case class UserGetRequestADM( + identifier: UserIdentifierADM, + userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM +) extends UsersResponderRequestADM {} /** - * Requests the creation of a new user. - * - * @param createRequest the [[CreateUserApiRequestADM]] information used for creating the new user. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user creating the new user. - * @param apiRequestID the ID of the API request. - */ -case class UserCreateRequestADM(createRequest: CreateUserApiRequestADM, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Requests the creation of a new user. + * + * @param createRequest the [[CreateUserApiRequestADM]] information used for creating the new user. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user creating the new user. + * @param apiRequestID the ID of the API request. + */ +case class UserCreateRequestADM( + createRequest: CreateUserApiRequestADM, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Request updating of an existing user. - * - * @param userIri the IRI of the user to be updated. - * @param changeUserRequest the data which needs to be update. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserChangeBasicUserInformationRequestADM(userIri: IRI, - changeUserRequest: ChangeUserApiRequestADM, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Request updating of an existing user. + * + * @param userIri the IRI of the user to be updated. + * @param changeUserRequest the data which needs to be update. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserChangeBasicUserInformationRequestADM( + userIri: IRI, + changeUserRequest: ChangeUserApiRequestADM, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Request updating the users password. - * - * @param userIri the IRI of the user to be updated. - * @param changeUserRequest the [[ChangeUserApiRequestADM]] object containing the old and new password. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserChangePasswordRequestADM(userIri: IRI, - changeUserRequest: ChangeUserApiRequestADM, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Request updating the users password. + * + * @param userIri the IRI of the user to be updated. + * @param changeUserRequest the [[ChangeUserApiRequestADM]] object containing the old and new password. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserChangePasswordRequestADM( + userIri: IRI, + changeUserRequest: ChangeUserApiRequestADM, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Request updating the users status ('knora-base:isActiveUser' property) - * - * @param userIri the IRI of the user to be updated. - * @param changeUserRequest the [[ChangeUserApiRequestADM]] containing the new status (true / false). - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserChangeStatusRequestADM(userIri: IRI, - changeUserRequest: ChangeUserApiRequestADM, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Request updating the users status ('knora-base:isActiveUser' property) + * + * @param userIri the IRI of the user to be updated. + * @param changeUserRequest the [[ChangeUserApiRequestADM]] containing the new status (true / false). + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserChangeStatusRequestADM( + userIri: IRI, + changeUserRequest: ChangeUserApiRequestADM, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Request updating the users system admin status ('knora-base:isInSystemAdminGroup' property) - * - * @param userIri the IRI of the user to be updated. - * @param changeUserRequest the [[ChangeUserApiRequestADM]] containing - * the new system admin membership status (true / false). - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserChangeSystemAdminMembershipStatusRequestADM(userIri: IRI, - changeUserRequest: ChangeUserApiRequestADM, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Request updating the users system admin status ('knora-base:isInSystemAdminGroup' property) + * + * @param userIri the IRI of the user to be updated. + * @param changeUserRequest the [[ChangeUserApiRequestADM]] containing + * the new system admin membership status (true / false). + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserChangeSystemAdminMembershipStatusRequestADM( + userIri: IRI, + changeUserRequest: ChangeUserApiRequestADM, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Requests user's project memberships. - * - * @param userIri the IRI of the user. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - */ -case class UserProjectMembershipsGetRequestADM(userIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM) - extends UsersResponderRequestADM + * Requests user's project memberships. + * + * @param userIri the IRI of the user. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + */ +case class UserProjectMembershipsGetRequestADM( + userIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM +) extends UsersResponderRequestADM /** - * Requests adding the user to a project. - * - * @param userIri the IRI of the user to be updated. - * @param projectIri the IRI of the project. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserProjectMembershipAddRequestADM(userIri: IRI, - projectIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Requests adding the user to a project. + * + * @param userIri the IRI of the user to be updated. + * @param projectIri the IRI of the project. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserProjectMembershipAddRequestADM( + userIri: IRI, + projectIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Requests removing the user from a project. - * - * @param userIri the IRI of the user to be updated. - * @param projectIri the IRI of the project. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserProjectMembershipRemoveRequestADM(userIri: IRI, - projectIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Requests removing the user from a project. + * + * @param userIri the IRI of the user to be updated. + * @param projectIri the IRI of the project. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserProjectMembershipRemoveRequestADM( + userIri: IRI, + projectIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Requests user's project admin memberships. - * - * @param userIri the IRI of the user. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserProjectAdminMembershipsGetRequestADM(userIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Requests user's project admin memberships. + * + * @param userIri the IRI of the user. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserProjectAdminMembershipsGetRequestADM( + userIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Requests adding the user to a project as project admin. - * - * @param userIri the IRI of the user to be updated. - * @param projectIri the IRI of the project. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserProjectAdminMembershipAddRequestADM(userIri: IRI, - projectIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Requests adding the user to a project as project admin. + * + * @param userIri the IRI of the user to be updated. + * @param projectIri the IRI of the project. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserProjectAdminMembershipAddRequestADM( + userIri: IRI, + projectIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Requests removing the user from a project as project admin. - * - * @param userIri the IRI of the user to be updated. - * @param projectIri the IRI of the project. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserProjectAdminMembershipRemoveRequestADM(userIri: IRI, - projectIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Requests removing the user from a project as project admin. + * + * @param userIri the IRI of the user to be updated. + * @param projectIri the IRI of the project. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserProjectAdminMembershipRemoveRequestADM( + userIri: IRI, + projectIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Requests user's group memberships. - * - * @param userIri the IRI of the user. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - */ -case class UserGroupMembershipsGetRequestADM(userIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM) - extends UsersResponderRequestADM + * Requests user's group memberships. + * + * @param userIri the IRI of the user. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + */ +case class UserGroupMembershipsGetRequestADM( + userIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM +) extends UsersResponderRequestADM /** - * Requests adding the user to a group. - * - * @param userIri the IRI of the user to be updated. - * @param groupIri the IRI of the group. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserGroupMembershipAddRequestADM(userIri: IRI, - groupIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Requests adding the user to a group. + * + * @param userIri the IRI of the user to be updated. + * @param groupIri the IRI of the group. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserGroupMembershipAddRequestADM( + userIri: IRI, + groupIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM /** - * Requests removing the user from a group. - * - * @param userIri the IRI of the user to be updated. - * @param groupIri the IRI of the group. - * @param featureFactoryConfig the feature factory configuration. - * @param requestingUser the user initiating the request. - * @param apiRequestID the ID of the API request. - */ -case class UserGroupMembershipRemoveRequestADM(userIri: IRI, - groupIri: IRI, - featureFactoryConfig: FeatureFactoryConfig, - requestingUser: UserADM, - apiRequestID: UUID) - extends UsersResponderRequestADM + * Requests removing the user from a group. + * + * @param userIri the IRI of the user to be updated. + * @param groupIri the IRI of the group. + * @param featureFactoryConfig the feature factory configuration. + * @param requestingUser the user initiating the request. + * @param apiRequestID the ID of the API request. + */ +case class UserGroupMembershipRemoveRequestADM( + userIri: IRI, + groupIri: IRI, + featureFactoryConfig: FeatureFactoryConfig, + requestingUser: UserADM, + apiRequestID: UUID +) extends UsersResponderRequestADM // Responses /** - * Represents an answer to a request for a list of all users. - * - * @param users a sequence of user profiles of the requested type. - */ + * Represents an answer to a request for a list of all users. + * + * @param users a sequence of user profiles of the requested type. + */ case class UsersGetResponseADM(users: Seq[UserADM]) extends KnoraResponseADM { def toJsValue = UsersADMJsonProtocol.usersGetResponseADMFormat.write(this) } /** - * Represents an answer to a user profile request. - * - * @param user the user's information of the requested type. - */ + * Represents an answer to a user profile request. + * + * @param user the user's information of the requested type. + */ case class UserResponseADM(user: UserADM) extends KnoraResponseADM { def toJsValue: JsValue = UsersADMJsonProtocol.userProfileResponseADMFormat.write(this) } /** - * Represents an answer to a request for a list of all projects the user is member of. - * - * @param projects a sequence of projects the user is member of. - */ + * Represents an answer to a request for a list of all projects the user is member of. + * + * @param projects a sequence of projects the user is member of. + */ case class UserProjectMembershipsGetResponseADM(projects: Seq[ProjectADM]) extends KnoraResponseADM { def toJsValue: JsValue = UsersADMJsonProtocol.userProjectMembershipsGetResponseADMFormat.write(this) } /** - * Represents an answer to a request for a list of all projects the user is member of the project admin group. - * - * @param projects a sequence of projects the user is member of the project admin group. - */ + * Represents an answer to a request for a list of all projects the user is member of the project admin group. + * + * @param projects a sequence of projects the user is member of the project admin group. + */ case class UserProjectAdminMembershipsGetResponseADM(projects: Seq[ProjectADM]) extends KnoraResponseADM { def toJsValue: JsValue = UsersADMJsonProtocol.userProjectAdminMembershipsGetResponseADMFormat.write(this) } /** - * Represents an answer to a request for a list of all groups the user is member of. - * - * @param groups a sequence of groups the user is member of. - */ + * Represents an answer to a request for a list of all groups the user is member of. + * + * @param groups a sequence of groups the user is member of. + */ case class UserGroupMembershipsGetResponseADM(groups: Seq[GroupADM]) extends KnoraResponseADM { def toJsValue: JsValue = UsersADMJsonProtocol.userGroupMembershipsGetResponseADMFormat.write(this) } /** - * Represents an answer to a user creating/modifying operation. - * - * @param user the new user profile of the created/modified user. - */ + * Represents an answer to a user creating/modifying operation. + * + * @param user the new user profile of the created/modified user. + */ case class UserOperationResponseADM(user: UserADM) extends KnoraResponseADM { def toJsValue: JsValue = UsersADMJsonProtocol.userOperationResponseADMFormat.write(this) } @@ -480,50 +502,51 @@ case class UserOperationResponseADM(user: UserADM) extends KnoraResponseADM { // Components of messages /** - * Represents a user's profile. - * - * @param id The user's IRI. - * @param username The user's username (unique). - * @param email The user's email address. - * @param password The user's hashed password. - * @param token The API token. Can be used instead of email/password for authentication. - * @param givenName The user's given name. - * @param familyName The user's surname. - * @param status The user's status. - * @param lang The ISO 639-1 code of the user's preferred language. - * @param groups The groups that the user belongs to. - * @param projects The projects that the user belongs to. - * @param sessionId The sessionId,. - * @param permissions The user's permissions. - */ -case class UserADM(id: IRI, - username: String, - email: String, - password: Option[String] = None, - token: Option[String] = None, - givenName: String, - familyName: String, - status: Boolean, - lang: String, - groups: Seq[GroupADM] = Vector.empty[GroupADM], - projects: Seq[ProjectADM] = Seq.empty[ProjectADM], - sessionId: Option[String] = None, - permissions: PermissionsDataADM = PermissionsDataADM()) - extends Ordered[UserADM] { + * Represents a user's profile. + * + * @param id The user's IRI. + * @param username The user's username (unique). + * @param email The user's email address. + * @param password The user's hashed password. + * @param token The API token. Can be used instead of email/password for authentication. + * @param givenName The user's given name. + * @param familyName The user's surname. + * @param status The user's status. + * @param lang The ISO 639-1 code of the user's preferred language. + * @param groups The groups that the user belongs to. + * @param projects The projects that the user belongs to. + * @param sessionId The sessionId,. + * @param permissions The user's permissions. + */ +case class UserADM( + id: IRI, + username: String, + email: String, + password: Option[String] = None, + token: Option[String] = None, + givenName: String, + familyName: String, + status: Boolean, + lang: String, + groups: Seq[GroupADM] = Vector.empty[GroupADM], + projects: Seq[ProjectADM] = Seq.empty[ProjectADM], + sessionId: Option[String] = None, + permissions: PermissionsDataADM = PermissionsDataADM() +) extends Ordered[UserADM] { /** - * Allows to sort collections of UserADM. Sorting is done by the id. - */ + * Allows to sort collections of UserADM. Sorting is done by the id. + */ def compare(that: UserADM): Int = this.id.compareTo(that.id) /** - * Check password (in clear text) using SCrypt. The password supplied in clear text is hashed and - * compared against the stored hash. - * - * @param password the password to check. - * @return true if password matches and false if password doesn't match. - */ - def passwordMatch(password: String): Boolean = { + * Check password (in clear text) using SCrypt. The password supplied in clear text is hashed and + * compared against the stored hash. + * + * @param password the password to check. + * @return true if password matches and false if password doesn't match. + */ + def passwordMatch(password: String): Boolean = this.password.exists { hashedPassword => // check which type of hash we have if (hashedPassword.startsWith("$e0801$")) { @@ -542,15 +565,13 @@ case class UserADM(id: IRI, md.digest(password.getBytes("UTF-8")).map("%02x".format(_)).mkString.equals(hashedPassword) } } - } /** - * Creating a [[UserADM]] of the requested type. - * - * @return a [[UserADM]] - */ - def ofType(userTemplateType: UserInformationTypeADM): UserADM = { - + * Creating a [[UserADM]] of the requested type. + * + * @return a [[UserADM]] + */ + def ofType(userTemplateType: UserInformationTypeADM): UserADM = userTemplateType match { case UserInformationTypeADM.PUBLIC => { UserADM( @@ -624,28 +645,26 @@ case class UserADM(id: IRI, } case _ => throw BadRequestException(s"The requested userTemplateType: $userTemplateType is invalid.") } - } /** - * Given an identifier, returns true if it is the same user, and false if not. - */ + * Given an identifier, returns true if it is the same user, and false if not. + */ def isSelf(identifier: UserIdentifierADM): Boolean = { - val iriEquals = identifier.toIriOption.contains(id) - val emailEquals = identifier.toEmailOption.contains(email) + val iriEquals = identifier.toIriOption.contains(id) + val emailEquals = identifier.toEmailOption.contains(email) val usernameEquals = identifier.toUsernameOption.contains(username) iriEquals || emailEquals || usernameEquals } /** - * Is the user a member of the SystemAdmin group - */ - def isSystemAdmin: Boolean = { + * Is the user a member of the SystemAdmin group + */ + def isSystemAdmin: Boolean = permissions.groupsPerProject .getOrElse(OntologyConstants.KnoraAdmin.SystemProject, List.empty[IRI]) .contains(OntologyConstants.KnoraAdmin.SystemAdmin) - } def isSystemUser: Boolean = id.equalsIgnoreCase(OntologyConstants.KnoraAdmin.SystemUser) @@ -654,13 +673,13 @@ case class UserADM(id: IRI, def fullname: String = givenName + " " + familyName def getDigest: String = { - val md = java.security.MessageDigest.getInstance("SHA-1") - val time = System.currentTimeMillis().toString + val md = java.security.MessageDigest.getInstance("SHA-1") + val time = System.currentTimeMillis().toString val value = (time + this.toString).getBytes("UTF-8") md.digest(value).map("%02x".format(_)).mkString } - def setSessionId(sessionId: String): UserADM = { + def setSessionId(sessionId: String): UserADM = UserADM( id = id, username = username, @@ -676,18 +695,15 @@ case class UserADM(id: IRI, sessionId = Some(sessionId), permissions = permissions ) - } - def isActive: Boolean = { + def isActive: Boolean = status - } def toJsValue: JsValue = UsersADMJsonProtocol.userADMFormat.write(this) // ToDo: Refactor by using implicit conversions (when I manage to understand them) // and probably value classes: https://docs.scala-lang.org/overviews/core/value-classes.html - def asUserProfileV1: UserProfileV1 = { - + def asUserProfileV1: UserProfileV1 = if (this.isAnonymousUser) { UserProfileV1() } else { @@ -712,9 +728,8 @@ case class UserADM(id: IRI, sessionId = sessionId ) } - } - def asUserDataV1: UserDataV1 = { + def asUserDataV1: UserDataV1 = UserDataV1( user_id = if (this.isAnonymousUser) { None @@ -729,67 +744,66 @@ case class UserADM(id: IRI, status = Some(status), lang = lang ) - } } /** - * UserInformationTypeADM types: - * full: everything - * restricted: everything without sensitive information, i.e. token, password, session. - * short: like restricted and additionally without groups, projects and permissions. - * public: temporary: givenName, familyName - * - * Mainly used in combination with the 'ofType' method, to make sure that a request receiving this information - * also returns the user profile of the correct type. Should be used in cases where we don't want to expose - * sensitive information to the outside world. Since in API Admin [[UserADM]] is returned with some responses, - * we use 'restricted' in those cases. - */ + * UserInformationTypeADM types: + * full: everything + * restricted: everything without sensitive information, i.e. token, password, session. + * short: like restricted and additionally without groups, projects and permissions. + * public: temporary: givenName, familyName + * + * Mainly used in combination with the 'ofType' method, to make sure that a request receiving this information + * also returns the user profile of the correct type. Should be used in cases where we don't want to expose + * sensitive information to the outside world. Since in API Admin [[UserADM]] is returned with some responses, + * we use 'restricted' in those cases. + */ object UserInformationTypeADM extends Enumeration { /* TODO: Extend to incorporate user privacy wishes */ type UserInformationTypeADM = Value - val PUBLIC = Value(0, "public") // a temporary type which only returns firstname and lastname - val SHORT = Value(1, "short") // only basic user information (restricted and additionally without groups + val PUBLIC = Value(0, "public") // a temporary type which only returns firstname and lastname + val SHORT = Value(1, "short") // only basic user information (restricted and additionally without groups val RESTRICTED = Value(2, "restricted") // without sensitive information - val FULL = Value(3, "full") // everything, including sensitive information + val FULL = Value(3, "full") // everything, including sensitive information val valueMap: Map[String, Value] = values.map(v => (v.toString, v)).toMap /** - * Given the name of a value in this enumeration, returns the value. If the value is not found, throws an - * [[InconsistentRepositoryDataException]]. - * - * @param name the name of the value. - * @return the requested value. - */ - def lookup(name: String): Value = { + * Given the name of a value in this enumeration, returns the value. If the value is not found, throws an + * [[InconsistentRepositoryDataException]]. + * + * @param name the name of the value. + * @return the requested value. + */ + def lookup(name: String): Value = valueMap.get(name) match { case Some(value) => value case None => throw InconsistentRepositoryDataException(s"User profile type not supported: $name") } - } } /** - * Represents the type of a user identifier. - */ + * Represents the type of a user identifier. + */ object UserIdentifierType extends Enumeration { type UserIdentifierType - val IRI = Value(0, "iri") - val EMAIL = Value(1, "email") + val IRI = Value(0, "iri") + val EMAIL = Value(1, "email") val USERNAME = Value(3, "username") } /** - * The UserIdentifierADM factory object, making sure that all necessary checks are performed and all inputs - * validated and escaped. - */ + * The UserIdentifierADM factory object, making sure that all necessary checks are performed and all inputs + * validated and escaped. + */ object UserIdentifierADM { def apply(maybeIri: Option[String] = None, maybeEmail: Option[String] = None, maybeUsername: Option[String] = None)( - implicit sf: StringFormatter): UserIdentifierADM = { + implicit sf: StringFormatter + ): UserIdentifierADM = { val parametersCount: Int = List( maybeIri, @@ -803,26 +817,30 @@ object UserIdentifierADM { if (parametersCount > 1) throw BadRequestException("Only one option allowed for user identifier.") new UserIdentifierADM( - maybeIri = sf.validateAndEscapeOptionalUserIri(maybeIri, throw BadRequestException(s"Invalid user IRI $maybeIri")), + maybeIri = + sf.validateAndEscapeOptionalUserIri(maybeIri, throw BadRequestException(s"Invalid user IRI $maybeIri")), maybeEmail = sf.validateAndEscapeOptionalEmail(maybeEmail, throw BadRequestException(s"Invalid email $maybeEmail")), - maybeUsername = - sf.validateAndEscapeOptionalUsername(maybeUsername, - throw BadRequestException(s"Invalid username $maybeUsername")) + maybeUsername = sf.validateAndEscapeOptionalUsername( + maybeUsername, + throw BadRequestException(s"Invalid username $maybeUsername") + ) ) } } /** - * Represents the user's identifier. It can be an IRI, email, or username. - * - * @param maybeIri the user's IRI. - * @param maybeEmail the user's email. - * @param maybeUsername the user's username. - */ -class UserIdentifierADM private (maybeIri: Option[IRI] = None, - maybeEmail: Option[String] = None, - maybeUsername: Option[String] = None) { + * Represents the user's identifier. It can be an IRI, email, or username. + * + * @param maybeIri the user's IRI. + * @param maybeEmail the user's email. + * @param maybeUsername the user's username. + */ +class UserIdentifierADM private ( + maybeIri: Option[IRI] = None, + maybeEmail: Option[String] = None, + maybeUsername: Option[String] = None +) { // squash and return value. val value: String = List( @@ -833,8 +851,7 @@ class UserIdentifierADM private (maybeIri: Option[IRI] = None, // validate and escape - def hasType: UserIdentifierType.Value = { - + def hasType: UserIdentifierType.Value = if (maybeIri.isDefined) { UserIdentifierType.IRI } else if (maybeEmail.isDefined) { @@ -842,88 +859,85 @@ class UserIdentifierADM private (maybeIri: Option[IRI] = None, } else { UserIdentifierType.USERNAME } - } /** - * Tries to return the value as an IRI. - */ - def toIri: IRI = { + * Tries to return the value as an IRI. + */ + def toIri: IRI = maybeIri.getOrElse( - throw DataConversionException(s"Identifier $value is not of the required 'UserIdentifierType.IRI' type.")) - } + throw DataConversionException(s"Identifier $value is not of the required 'UserIdentifierType.IRI' type.") + ) /** - * Returns an optional value of the identifier. - */ - def toIriOption: Option[IRI] = { + * Returns an optional value of the identifier. + */ + def toIriOption: Option[IRI] = maybeIri - } /** - * Tries to return the value as email. - */ - def toEmail: IRI = { + * Tries to return the value as email. + */ + def toEmail: IRI = maybeEmail.getOrElse( - throw DataConversionException(s"Identifier $value is not of the required 'UserIdentifierType.EMAIL' type.")) - } + throw DataConversionException(s"Identifier $value is not of the required 'UserIdentifierType.EMAIL' type.") + ) /** - * Returns an optional value of the identifier. - */ - def toEmailOption: Option[String] = { + * Returns an optional value of the identifier. + */ + def toEmailOption: Option[String] = maybeEmail - } /** - * Tries to return the value as username. - */ - def toUsername: IRI = { + * Tries to return the value as username. + */ + def toUsername: IRI = maybeUsername.getOrElse( - throw DataConversionException(s"Identifier $value is not of the required 'UserIdentifierType.USERNAME' type.")) - } + throw DataConversionException(s"Identifier $value is not of the required 'UserIdentifierType.USERNAME' type.") + ) /** - * Returns an optional value of the identifier. - */ - def toUsernameOption: Option[String] = { + * Returns an optional value of the identifier. + */ + def toUsernameOption: Option[String] = maybeUsername - } /** - * Returns the string representation - */ - override def toString: IRI = { + * Returns the string representation + */ + override def toString: IRI = s"UserIdentifierADM(${this.value})" - } } /** - * Payload used for updating of an existing user. - * - * @param email the new email address. Needs to be unique on the server. - * @param username the new username. - * @param givenName the new given name. - * @param familyName the new family name. - * @param password the new password. - * @param status the new status. - * @param lang the new language. - * @param projects the new project memberships list. - * @param projectsAdmin the new projects admin membership list. - * @param groups the new group memberships list. - * @param systemAdmin the new system admin membership - */ -case class UserUpdatePayloadADM(username: Option[String] = None, - email: Option[String] = None, - givenName: Option[String] = None, - familyName: Option[String] = None, - password: Option[String] = None, - status: Option[Boolean] = None, - lang: Option[String] = None, - projects: Option[Seq[IRI]] = None, - projectsAdmin: Option[Seq[IRI]] = None, - groups: Option[Seq[IRI]] = None, - systemAdmin: Option[Boolean] = None) { + * Payload used for updating of an existing user. + * + * @param email the new email address. Needs to be unique on the server. + * @param username the new username. + * @param givenName the new given name. + * @param familyName the new family name. + * @param password the new password. + * @param status the new status. + * @param lang the new language. + * @param projects the new project memberships list. + * @param projectsAdmin the new projects admin membership list. + * @param groups the new group memberships list. + * @param systemAdmin the new system admin membership + */ +case class UserUpdatePayloadADM( + username: Option[String] = None, + email: Option[String] = None, + givenName: Option[String] = None, + familyName: Option[String] = None, + password: Option[String] = None, + status: Option[Boolean] = None, + lang: Option[String] = None, + projects: Option[Seq[IRI]] = None, + projectsAdmin: Option[Seq[IRI]] = None, + groups: Option[Seq[IRI]] = None, + systemAdmin: Option[Boolean] = None +) { val parametersCount: Int = List( email, @@ -986,8 +1000,8 @@ case class UserUpdatePayloadADM(username: Option[String] = None, // JSON formatting /** - * A spray-json protocol for formatting objects as JSON. - */ + * A spray-json protocol for formatting objects as JSON. + */ object UsersADMJsonProtocol extends SprayJsonSupport with DefaultJsonProtocol @@ -1006,7 +1020,8 @@ object UsersADMJsonProtocol "password", "status", "lang", - "systemAdmin") + "systemAdmin" + ) implicit val changeUserApiRequestADMFormat: RootJsonFormat[ChangeUserApiRequestADM] = jsonFormat( ChangeUserApiRequestADM, "username", @@ -1017,9 +1032,10 @@ object UsersADMJsonProtocol "requesterPassword", "newPassword", "status", - "systemAdmin") + "systemAdmin" + ) implicit val usersGetResponseADMFormat: RootJsonFormat[UsersGetResponseADM] = jsonFormat1(UsersGetResponseADM) - implicit val userProfileResponseADMFormat: RootJsonFormat[UserResponseADM] = jsonFormat1(UserResponseADM) + implicit val userProfileResponseADMFormat: RootJsonFormat[UserResponseADM] = jsonFormat1(UserResponseADM) implicit val userProjectMembershipsGetResponseADMFormat: RootJsonFormat[UserProjectMembershipsGetResponseADM] = jsonFormat1(UserProjectMembershipsGetResponseADM) implicit val userProjectAdminMembershipsGetResponseADMFormat @@ -1027,5 +1043,6 @@ object UsersADMJsonProtocol implicit val userGroupMembershipsGetResponseADMFormat: RootJsonFormat[UserGroupMembershipsGetResponseADM] = jsonFormat1(UserGroupMembershipsGetResponseADM) implicit val userOperationResponseADMFormat: RootJsonFormat[UserOperationResponseADM] = jsonFormat1( - UserOperationResponseADM) + UserOperationResponseADM + ) }