Skip to content

Commit

Permalink
Promote conf superusers during bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
ljdelight committed Nov 20, 2023
1 parent 23fe642 commit 4a6dfe4
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 23 deletions.
10 changes: 10 additions & 0 deletions app/org/maproulette/framework/repository/UserRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,16 @@ class UserRepository @Inject() (
}
}

def getSuperUserIdsFromDatabase(): List[Long] = {
db.withConnection { implicit c =>
// Search the grants table for grantee_id (eg the user's maproulette id) where the role is -1 (superuser)
// and the grantee_type is 5 (user).
anorm
.SQL("SELECT grantee_id AS id FROM grants WHERE role = -1 AND grantee_type = 5")
.as(SqlParser.scalar[Long].*)
}
}

def getUserTaskCounts(userId: Long, dateFilter: DateParameter)(
implicit c: Option[Connection] = None
): Map[String, Int] = {
Expand Down
41 changes: 20 additions & 21 deletions app/org/maproulette/framework/service/UserService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

package org.maproulette.framework.service

import anorm.SqlParser

import java.util.UUID
import javax.inject.{Inject, Singleton}
import org.apache.commons.lang3.StringUtils
Expand All @@ -26,15 +24,13 @@ import org.maproulette.permissions.Permission
import org.maproulette.session.SearchParameters
import org.maproulette.utils.{Crypto, Utils, Writers}
import org.slf4j.LoggerFactory
import play.api.db.Database
import play.api.libs.json.{JsString, JsValue, Json}

/**
* @author mcuthbert
*/
@Singleton
class UserService @Inject() (
db: Database,
repository: UserRepository,
savedObjectsRepository: UserSavedObjectsRepository,
serviceManager: ServiceManager,
Expand All @@ -54,7 +50,7 @@ class UserService @Inject() (

// On startup, seed the super user ids that exist in the database
seedSuperUserIds()
promoteSuperUsersInConfig()
//promoteSuperUsersInConfig()

/**
* Check if a given maproulette user id is a superuser
Expand All @@ -68,21 +64,31 @@ class UserService @Inject() (
def promoteUserToSuperUser(user: User, grantor: User): Boolean = {
if (isSuperUser(user.id)) {
logger.info(
s"Skipping superuser promotion, MapRoulette user id=${user.id} (osm_id=${user.osmProfile.id}) is already a superuser"
s"MapRoulette uid=${user.id} (osm_id=${user.osmProfile.id}) is already a superuser, skipping role promotion"
)
return true
}

logger.warn(s"Adding superuser role to user id=${user.id} (osm_id=${user.osmProfile.id})")
val grantName = s"User ${user.id} has Superuser"
logger.warn(s"Adding superuser role to uid=${user.id} (osm_id=${user.osmProfile.id})")
val grantName =
s"Grant superuser role on uid=${user.id} (osm_id=${user.osmProfile.id}), requested by uid=${grantor.id}"
val superUserGrant =
new Grant(-1, grantName, Grantee.user(user.id), Grant.ROLE_SUPER_USER, GrantTarget.project(0))
serviceManager.grant.createGrant(superUserGrant, grantor)
superUsers += user.id
true

serviceManager.grant.createGrant(superUserGrant, grantor) match {
case Some(grantedUser) =>
superUsers += grantedUser.id
true
case _ =>
// The grant.createGrant function will throw an exception if it fails, so we should never get here. But just in case...
logger.warn(
s"Failed to add superuser role to uid=${user.id} requested by uid=${grantor.id}"
)
false
}
}

private def promoteSuperUsersInConfig(): Unit = {
def promoteSuperUsersInConfig(): Unit = {
val usersToPromote: List[User] = config.superAccounts
.flatMap { osmId =>
retrieveByOSMId(osmId.toLong) match {
Expand All @@ -97,7 +103,7 @@ class UserService @Inject() (
.flatMap { user =>
if (isSuperUser(user.id)) {
logger.info(
s"Skipping superuser promotion, MapRoulette user id=${user.id} is already a superuser"
s"MapRoulette uid=${user.id} (osm_id=${user.osmProfile.id}) is already a superuser, skipping role promotion"
)
None
} else {
Expand All @@ -111,14 +117,7 @@ class UserService @Inject() (
}

private def seedSuperUserIds(): Unit = {
db.withConnection { implicit c =>
// Search the grants table for grantee_id (eg the user's maproulette id) where the role is -1 (superuser)
// and the grantee_type is 5 (user).
val superIds = anorm
.SQL("SELECT grantee_id AS id FROM grants WHERE role = -1 AND grantee_type = 5")
.as(SqlParser.scalar[Long].*)
superUsers ++= superIds
}
superUsers ++= repository.getSuperUserIdsFromDatabase()
}

/**
Expand Down
12 changes: 10 additions & 2 deletions app/org/maproulette/jobs/Bootstrap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
*/
package org.maproulette.jobs

import javax.inject.{Inject, Singleton}
import javax.inject.{Inject, Provider, Singleton}
import org.maproulette.Config
import org.maproulette.framework.service.UserService
import org.slf4j.LoggerFactory
import play.api.db.Database
import play.api.inject.ApplicationLifecycle
Expand All @@ -16,7 +17,12 @@ import scala.concurrent.Future
* @author mcuthbert
*/
@Singleton
class Bootstrap @Inject() (appLifeCycle: ApplicationLifecycle, db: Database, config: Config) {
class Bootstrap @Inject() (
appLifeCycle: ApplicationLifecycle,
db: Database,
config: Config,
userService: Provider[UserService]
) {

private val logger = LoggerFactory.getLogger(this.getClass)

Expand All @@ -35,6 +41,8 @@ class Bootstrap @Inject() (appLifeCycle: ApplicationLifecycle, db: Database, con
case _ => // do nothing
}
}

userService.get().promoteSuperUsersInConfig()
}

appLifeCycle.addStopHook { () =>
Expand Down

0 comments on commit 4a6dfe4

Please sign in to comment.