Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Prevent illegal updates with KnoraUserService #3098

Merged
merged 8 commits into from
Mar 6, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import org.knora.webapi.slice.admin.domain.service.KnoraUserToUserConverter
import org.knora.webapi.slice.admin.domain.service.PasswordService
import org.knora.webapi.slice.admin.domain.service.ProjectADMService
import org.knora.webapi.slice.admin.domain.service.UserChangeRequest
import org.knora.webapi.slice.admin.domain.service.UserService
import org.knora.webapi.slice.common.api.AuthorizationRestService
import org.knora.webapi.slice.common.api.KnoraResponseRenderer
Expand Down Expand Up @@ -135,14 +134,14 @@
_ <- ensureNotABuiltInUser(userIri)
_ <- ensureSelfUpdateOrSystemAdmin(userIri, requestingUser)
user <- getKnoraUserOrNotFound(userIri)
theChange = UserChangeRequest(
username = changeRequest.username,
email = changeRequest.email,
givenName = changeRequest.givenName,
familyName = changeRequest.familyName,
lang = changeRequest.lang,
)
updated <- knoraUserService.updateUser(user, theChange)
updated <- knoraUserService.updateUser(

Check warning on line 137 in webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/UsersRestService.scala

View check run for this annotation

Codecov / codecov/patch

webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/UsersRestService.scala#L137

Added line #L137 was not covered by tests
user,
changeRequest.username,
changeRequest.email,
changeRequest.givenName,
changeRequest.familyName,
changeRequest.lang,

Check warning on line 143 in webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/UsersRestService.scala

View check run for this annotation

Codecov / codecov/patch

webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/UsersRestService.scala#L139-L143

Added lines #L139 - L143 were not covered by tests
)
response <- asExternalUserResponseADM(requestingUser, updated)
} yield response

Expand Down Expand Up @@ -177,7 +176,7 @@
_ <- ensureNotABuiltInUser(userIri)
_ <- ensureSelfUpdateOrSystemAdmin(userIri, requestingUser)
user <- getKnoraUserOrNotFound(userIri)
updated <- knoraUserService.updateUser(user, UserChangeRequest(status = Some(changeRequest.status)))
updated <- knoraUserService.updateUserStatus(user, changeRequest.status)

Check warning on line 179 in webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/UsersRestService.scala

View check run for this annotation

Codecov / codecov/patch

webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/UsersRestService.scala#L179

Added line #L179 was not covered by tests
response <- asExternalUserResponseADM(requestingUser, updated)
} yield response

Expand All @@ -190,8 +189,7 @@
_ <- ensureNotABuiltInUser(userIri)
_ <- auth.ensureSystemAdmin(requestingUser)
user <- getKnoraUserOrNotFound(userIri)
theUpdate = UserChangeRequest(systemAdmin = Some(changeRequest.systemAdmin))
updated <- knoraUserService.updateUser(user, theUpdate)
updated <- knoraUserService.updateSystemAdminStatus(user, changeRequest.systemAdmin)

Check warning on line 192 in webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/UsersRestService.scala

View check run for this annotation

Codecov / codecov/patch

webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/UsersRestService.scala#L192

Added line #L192 was not covered by tests
response <- asExternalUserResponseADM(requestingUser, updated)
} yield response

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,36 @@
import org.knora.webapi.slice.admin.domain.model.UserStatus
import org.knora.webapi.slice.admin.domain.model.Username
import org.knora.webapi.slice.admin.domain.service.KnoraUserService.Errors.UserServiceError
import org.knora.webapi.slice.admin.domain.service.KnoraUserService.UserChangeRequest
import org.knora.webapi.store.cache.CacheService

final case class UserChangeRequest(
username: Option[Username] = None,
email: Option[Email] = None,
givenName: Option[GivenName] = None,
familyName: Option[FamilyName] = None,
status: Option[UserStatus] = None,
lang: Option[LanguageCode] = None,
passwordHash: Option[PasswordHash] = None,
projects: Option[Chunk[ProjectIri]] = None,
projectsAdmin: Option[Chunk[ProjectIri]] = None,
groups: Option[Chunk[GroupIri]] = None,
systemAdmin: Option[SystemAdmin] = None,
)

case class KnoraUserService(
private val userRepo: KnoraUserRepo,
private val iriService: IriService,
private val passwordService: PasswordService,
private val cacheService: CacheService,
) {

def updateUser(kUser: KnoraUser, update: UserChangeRequest): Task[KnoraUser] = {
def updateSystemAdminStatus(knoraUser: KnoraUser, status: SystemAdmin): Task[KnoraUser] =
updateUser(knoraUser, UserChangeRequest(systemAdmin = Some(status)))

Check warning on line 45 in webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala

View check run for this annotation

Codecov / codecov/patch

webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala#L45

Added line #L45 was not covered by tests

def updateUserStatus(knoraUser: KnoraUser, status: UserStatus): Task[KnoraUser] =
updateUser(knoraUser, UserChangeRequest(status = Some(status)))

Check warning on line 48 in webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala

View check run for this annotation

Codecov / codecov/patch

webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala#L48

Added line #L48 was not covered by tests

def updateUser(
knoraUser: KnoraUser,
username: Option[Username] = None,
email: Option[Email],
givenName: Option[GivenName] = None,
familyName: Option[FamilyName] = None,
lang: Option[LanguageCode] = None,
): Task[KnoraUser] = {
val theUpdate =
UserChangeRequest(username = username, email = email, givenName = givenName, familyName = familyName, lang = lang)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
UserChangeRequest(username = username, email = email, givenName = givenName, familyName = familyName, lang = lang)
UserChangeRequest(username, email, givenName, familyName, lang)

updateUser(knoraUser, theUpdate)

Check warning on line 60 in webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala

View check run for this annotation

Codecov / codecov/patch

webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala#L59-L60

Added lines #L59 - L60 were not covered by tests
}

private def updateUser(kUser: KnoraUser, update: UserChangeRequest): Task[KnoraUser] = {
val updatedUser = kUser.copy(
username = update.username.getOrElse(kUser.username),
email = update.email.getOrElse(kUser.email),
Expand Down Expand Up @@ -210,6 +216,20 @@
}

object KnoraUserService {
private final case class UserChangeRequest(
username: Option[Username] = None,
email: Option[Email] = None,
givenName: Option[GivenName] = None,
familyName: Option[FamilyName] = None,
status: Option[UserStatus] = None,
lang: Option[LanguageCode] = None,
passwordHash: Option[PasswordHash] = None,
projects: Option[Chunk[ProjectIri]] = None,
projectsAdmin: Option[Chunk[ProjectIri]] = None,
groups: Option[Chunk[GroupIri]] = None,
systemAdmin: Option[SystemAdmin] = None,
)

object Errors {
final case class UserServiceError(message: String)
}
Expand Down
Loading