Skip to content

Commit

Permalink
refactor: Migrate GET /admin/users/<iri|email|name> to Tapir (#3020)
Browse files Browse the repository at this point in the history
  • Loading branch information
seakayone authored Feb 6, 2024
1 parent 35ff4ed commit 4b25387
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 274 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import java.util.UUID
import dsp.errors.BadRequestException
import dsp.errors.DuplicateValueException
import dsp.errors.ForbiddenException
import dsp.errors.NotFoundException
import dsp.valueobjects.LanguageCode
import org.knora.webapi.*
import org.knora.webapi.messages.StringFormatter
Expand Down Expand Up @@ -87,79 +86,73 @@ class UsersResponderADMSpec extends CoreSpec with ImplicitSender {

"asked about an user identified by 'iri' " should {
"return a profile if the user (root user) is known" in {
appActor ! UserGetByIriADM(
identifier = UserIri.unsafeFrom(rootUser.id),
userInformationTypeADM = UserInformationTypeADM.Full,
requestingUser = KnoraSystemInstances.Users.SystemUser
val actual = UnsafeZioRun.runOrThrow(
UsersResponderADM.findUserByIri(
UserIri.unsafeFrom(rootUser.id),
UserInformationTypeADM.Full,
KnoraSystemInstances.Users.SystemUser
)
)
expectMsg(Some(rootUser.ofType(UserInformationTypeADM.Full)))
actual shouldBe Some(rootUser.ofType(UserInformationTypeADM.Full))
}

"return 'None' when the user is unknown" in {
appActor ! UserGetByIriADM(
identifier = UserIri.unsafeFrom("http://rdfh.ch/users/notexisting"),
userInformationTypeADM = UserInformationTypeADM.Full,
requestingUser = KnoraSystemInstances.Users.SystemUser
val actual = UnsafeZioRun.runOrThrow(
UsersResponderADM.findUserByIri(
UserIri.unsafeFrom("http://rdfh.ch/users/notexisting"),
UserInformationTypeADM.Full,
KnoraSystemInstances.Users.SystemUser
)
)
expectMsg(None)
actual shouldBe None
}
}

"asked about an user identified by 'email'" should {
"return a profile if the user (root user) is known" in {
appActor ! UserGetByEmailADM(
email = Email.unsafeFrom(rootUser.email),
userInformationTypeADM = UserInformationTypeADM.Full,
requestingUser = KnoraSystemInstances.Users.SystemUser
)
expectMsg(Some(rootUser.ofType(UserInformationTypeADM.Full)))
}

"return 'NotFoundException' when the user is unknown" in {
appActor ! UserGetByEmailRequestADM(
email = Email.unsafeFrom("[email protected]"),
userInformationTypeADM = UserInformationTypeADM.Full,
requestingUser = KnoraSystemInstances.Users.SystemUser
val actual = UnsafeZioRun.runOrThrow(
UsersResponderADM.findUserByEmail(
Email.unsafeFrom(rootUser.email),
UserInformationTypeADM.Full,
KnoraSystemInstances.Users.SystemUser
)
)
expectMsg(Failure(NotFoundException(s"User '[email protected]' not found")))
actual shouldBe Some(rootUser.ofType(UserInformationTypeADM.Full))
}

"return 'None' when the user is unknown" in {
appActor ! UserGetByEmailADM(
email = Email.unsafeFrom("[email protected]"),
userInformationTypeADM = UserInformationTypeADM.Full,
requestingUser = KnoraSystemInstances.Users.SystemUser
val actual = UnsafeZioRun.runOrThrow(
UsersResponderADM.findUserByEmail(
Email.unsafeFrom("[email protected]"),
UserInformationTypeADM.Full,
KnoraSystemInstances.Users.SystemUser
)
)
expectMsg(None)
actual shouldBe None
}
}

"asked about an user identified by 'username'" should {
"return a profile if the user (root user) is known" in {
appActor ! UserGetByUsernameADM(
username = Username.unsafeFrom(rootUser.username),
userInformationTypeADM = UserInformationTypeADM.Full,
requestingUser = KnoraSystemInstances.Users.SystemUser
)
expectMsg(Some(rootUser.ofType(UserInformationTypeADM.Full)))
}

"return 'NotFoundException' when the user is unknown" in {
appActor ! UserGetByUsernameRequestADM(
username = Username.unsafeFrom("userwrong"),
userInformationTypeADM = UserInformationTypeADM.Full,
requestingUser = KnoraSystemInstances.Users.SystemUser
val actual = UnsafeZioRun.runOrThrow(
UsersResponderADM.findUserByUsername(
Username.unsafeFrom(rootUser.username),
UserInformationTypeADM.Full,
KnoraSystemInstances.Users.SystemUser
)
)
expectMsg(Failure(NotFoundException(s"User 'userwrong' not found")))
actual shouldBe Some(rootUser.ofType(UserInformationTypeADM.Full))
}

"return 'None' when the user is unknown" in {
appActor ! UserGetByUsernameADM(
username = Username.unsafeFrom("userwrong"),
userInformationTypeADM = UserInformationTypeADM.Full,
requestingUser = KnoraSystemInstances.Users.SystemUser
val actual = UnsafeZioRun.runOrThrow(
UsersResponderADM.findUserByUsername(
Username.unsafeFrom("userwrong"),
UserInformationTypeADM.Full,
KnoraSystemInstances.Users.SystemUser
)
)
expectMsg(None)
actual shouldBe None
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import org.knora.webapi.messages.admin.responder.permissionsmessages.Permissions
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectADM
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectsADMJsonProtocol
import org.knora.webapi.slice.admin.domain.model.*
import org.knora.webapi.slice.common.ToValidation.validateOneWithFrom
import org.knora.webapi.slice.common.ToValidation.validateOptionWithFrom

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// API requests
Expand Down Expand Up @@ -159,58 +161,6 @@ case class UserGetByIriADM(
requestingUser: User
) extends UsersResponderRequestADM

/**
* A message that requests a user's profile by username. A successful response will be a [[User]].
*
* @param username the username of the user to be queried.
* @param userInformationTypeADM the extent of the information returned.
* @param requestingUser the user initiating the request.
*/
case class UserGetByUsernameADM(
username: Username,
userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.Short,
requestingUser: User
) extends UsersResponderRequestADM

/**
* A message that requests a user's profile by email. A successful response will be a [[User]].
*
* @param email the email of the user to be queried.
* @param userInformationTypeADM the extent of the information returned.
* @param requestingUser the user initiating the request.
*/
case class UserGetByEmailADM(
email: Email,
userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.Short,
requestingUser: User
) extends UsersResponderRequestADM

/**
* A message that requests a user's profile by email. A successful response will be a [[UserResponseADM]].
*
* @param email the email of the user to be queried.
* @param userInformationTypeADM the extent of the information returned.
* @param requestingUser the user initiating the request.
*/
case class UserGetByEmailRequestADM(
email: Email,
userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.Short,
requestingUser: User
) extends UsersResponderRequestADM

/**
* A message that requests a user's profile by username. A successful response will be a [[UserResponseADM]].
*
* @param username the username of the user to be queried.
* @param userInformationTypeADM the extent of the information returned.
* @param requestingUser the user initiating the request.
*/
case class UserGetByUsernameRequestADM(
username: Username,
userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.Short,
requestingUser: User
) extends UsersResponderRequestADM

/**
* Requests the creation of a new user.
*
Expand Down Expand Up @@ -594,10 +544,10 @@ object UserUpdateBasicInformationPayloadADM {

def make(req: ChangeUserApiRequestADM): Validation[ValidationException, UserUpdateBasicInformationPayloadADM] =
Validation.validateWith(
validateWithOptionOrNone(req.username, Username.validationFrom).mapError(ValidationException(_)),
validateWithOptionOrNone(req.email, Email.validationFrom).mapError(ValidationException(_)),
validateWithOptionOrNone(req.givenName, GivenName.validationFrom).mapError(ValidationException(_)),
validateWithOptionOrNone(req.familyName, FamilyName.validationFrom).mapError(ValidationException(_)),
validateOptionWithFrom(req.username, Username.from, ValidationException.apply),
validateOptionWithFrom(req.email, Email.from, ValidationException.apply),
validateOptionWithFrom(req.givenName, GivenName.from, ValidationException.apply),
validateOptionWithFrom(req.familyName, FamilyName.from, ValidationException.apply),
validateWithOptionOrNone(req.lang, LanguageCode.make)
)(UserUpdateBasicInformationPayloadADM.apply)
}
Expand All @@ -606,11 +556,12 @@ case class UserUpdatePasswordPayloadADM(requesterPassword: Password, newPassword
object UserUpdatePasswordPayloadADM {
def make(apiRequest: ChangeUserPasswordApiRequestADM): Validation[String, UserUpdatePasswordPayloadADM] = {
val requesterPasswordValidation = apiRequest.requesterPassword
.map(Password.validationFrom)
.map(validateOneWithFrom(_, Password.from, a => a))
.getOrElse(Validation.fail("The requester's password is missing."))
val newPasswordValidation = apiRequest.newPassword
.map(Password.validationFrom)
.getOrElse(Validation.fail("The new password is missing."))
val newPasswordValidation =
apiRequest.newPassword
.map(validateOneWithFrom(_, Password.from, a => a))
.getOrElse(Validation.fail("The new password is missing."))
Validation.validateWith(requesterPasswordValidation, newPasswordValidation)(UserUpdatePasswordPayloadADM.apply)
}
}
Expand Down Expand Up @@ -640,19 +591,16 @@ object UserCreatePayloadADM {
def make(apiRequest: CreateUserApiRequestADM): Validation[String, UserCreatePayloadADM] =
Validation
.validateWith(
apiRequest.id
.map(UserIri.validationFrom(_).map(Some(_)).mapError(ValidationException(_)))
.getOrElse(Validation.succeed(None)),
Username.validationFrom(apiRequest.username).mapError(ValidationException(_)),
Email.validationFrom(apiRequest.email).mapError(ValidationException(_)),
GivenName.validationFrom(apiRequest.givenName).mapError(ValidationException(_)),
FamilyName.validationFrom(apiRequest.familyName).mapError(ValidationException(_)),
Password.validationFrom(apiRequest.password).mapError(ValidationException(_)),
validateOptionWithFrom(apiRequest.id, UserIri.from, a => a),
validateOneWithFrom(apiRequest.username, Username.from, a => a),
validateOneWithFrom(apiRequest.email, Email.from, a => a),
validateOneWithFrom(apiRequest.givenName, GivenName.from, a => a),
validateOneWithFrom(apiRequest.familyName, FamilyName.from, a => a),
validateOneWithFrom(apiRequest.password, Password.from, a => a),
Validation.succeed(UserStatus.from(apiRequest.status)),
LanguageCode.make(apiRequest.lang),
LanguageCode.make(apiRequest.lang).mapError(_.getMessage),
Validation.succeed(SystemAdmin.from(apiRequest.systemAdmin))
)(UserCreatePayloadADM.apply)
.mapError(_.getMessage)
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit 4b25387

Please sign in to comment.