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

Prevent Deactivating Organization Owner #6816

Merged
merged 1 commit into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions app/controllers/UserController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,15 @@ class UserController @Inject()(userService: UserService,
adminCount <- userDAO.countAdminsForOrganization(user._organization)
_ <- bool2Fox(adminCount > 1) ?~> "user.lastAdmin"
} yield ()
} else {
Fox.successful(())
}
} else Fox.successful(())

private def preventZeroOwners(user: User, isActive: Boolean) =
if (user.isOrganizationOwner && !user.isDeactivated && !isActive) {
for {
ownerCount <- userDAO.countOwnersForOrganization(user._organization)
_ <- bool2Fox(ownerCount > 1) ?~> "user.lastOwner"
} yield ()
} else Fox.successful(())

@ApiOperation(hidden = true, value = "")
def update(userId: String): Action[JsValue] = sil.SecuredAction.async(parse.json) { implicit request =>
Expand Down Expand Up @@ -387,6 +393,7 @@ class UserController @Inject()(userService: UserService,
_ <- checkNoActivateBeyondLimit(user, isActive)
_ <- checkSuperUserOnlyUpdates(user, oldEmail, email)(issuingUser)
_ <- preventZeroAdmins(user, isAdmin)
_ <- preventZeroOwners(user, isActive)
teams <- Fox.combined(assignedMemberships.map(t =>
teamDAO.findOne(t.teamId)(GlobalAccessContext) ?~> "team.notFound" ~> NOT_FOUND))
oldTeamMemberships <- userService.teamMembershipsFor(user._id)
Expand Down
24 changes: 17 additions & 7 deletions app/models/user/User.scala
Original file line number Diff line number Diff line change
Expand Up @@ -184,32 +184,42 @@ class UserDAO @Inject()(sqlClient: SqlClient)(implicit ec: ExecutionContext)
def findContributorsForAnnotation(annotationId: ObjectId)(implicit ctx: DBAccessContext): Fox[List[User]] =
for {
accessQuery <- accessQueryFromAccessQ(listAccessQ)
result <- run(
q"""select $columns from $existingCollectionName
where _id in (select _user from webknossos.annotation_contributors where _annotation = $annotationId) and $accessQuery"""
.as[UsersRow])
result <- run(q"""SELECT $columns
FROM $existingCollectionName
WHERE _id in
(SELECT _user FROM webknossos.annotation_contributors WHERE _annotation = $annotationId)
AND NOT isUnlisted
AND $accessQuery""".as[UsersRow])
parsed <- parseAll(result)
} yield parsed

def countAllForOrganization(organizationId: ObjectId): Fox[Int] =
for {
resultList <- run(
q"select count(_id) from $existingCollectionName where _organization = $organizationId and not isDeactivated and not isUnlisted"
q"select count(*) from $existingCollectionName where _organization = $organizationId and not isDeactivated and not isUnlisted"
.as[Int])
result <- resultList.headOption
} yield result

def countAdminsForOrganization(organizationId: ObjectId): Fox[Int] =
for {
resultList <- run(
q"select count(_id) from $existingCollectionName where _organization = $organizationId and isAdmin and not isUnlisted"
q"select count(*) from $existingCollectionName where _organization = $organizationId and isAdmin and not isUnlisted"
.as[Int])
result <- resultList.headOption
} yield result

def countOwnersForOrganization(organizationId: ObjectId): Fox[Int] =
for {
resultList <- run(
q"select count(*) from $existingCollectionName where _organization = $organizationId and isOrganizationOwner and not isUnlisted"
.as[Int])
result <- resultList.headOption
} yield result

def countIdentitiesForMultiUser(multiUserId: ObjectId): Fox[Int] =
for {
resultList <- run(q"select count(_id) from $existingCollectionName where _multiUser = $multiUserId".as[Int])
resultList <- run(q"select count(*) from $existingCollectionName where _multiUser = $multiUserId".as[Int])
result <- resultList.headOption
} yield result

Expand Down
5 changes: 3 additions & 2 deletions conf/messages
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ organization.list.failed=Failed to retrieve list of organizations.
organization.name.invalid=This organization name contains illegal characters. Please only use letters and numbers.
organization.name.alreadyInUse=This name is already claimed by a different organization and not available anymore. Please choose a different name.
organization.alreadyJoined=Your account is already associated with the selected organization.
organization.users.userLimitReached=Cannot add new user to this organization because it would exceed the organization’s user limit. Please ask the organization owner to upgrade.
organization.users.userLimitReached=Cannot add new user to this organization because it would exceed the organization’s user limit. Please ask the organization owner to upgrade.
organization.pricingUpgrades.notAuthorized=You are not authorized to request any changes to your organization WEBKNOSSOS plan. Please ask the organization owner for permission.

termsOfService.versionMismatch=Terms of service version mismatch. Current version is {0}, received acceptance for {1}
Expand All @@ -46,7 +46,8 @@ user.notFound=User not found
user.noAdmin=Access denied. Only admin users can execute this operation.
user.deactivated=Your account has not been activated by an admin yet. Please contact your organization’s admin for help.
user.noSelfDeactivate=You cannot deactivate yourself. Please contact an admin to do it for you.
user.lastAdmin=Your account is the last remaining admin in your organzation. You cannot remove admin privileges from your account.
user.lastAdmin=This user is the last remaining admin in your organzation. You cannot remove admin privileges from this account.
user.lastOwner=Cannot deactivate the organization owner. Please talk to the WEBKNOSSOS team to transfer organization ownership.

user.email.alreadyInUse=This email address is already in use
user.email.onlySuperUserCanChange=Only super users can change emails of users with multiple organization accounts
Expand Down