Decider admin access to deciders by steam id
This commit is contained in:
@@ -25,6 +25,27 @@ class AdminController @Inject()(
|
||||
implicit val ec: ExecutionContext = cc.executionContext
|
||||
private val logger = org.slf4j.LoggerFactory.getLogger("controllers.AdminController")
|
||||
|
||||
// ---------- Ownership ----------
|
||||
|
||||
private def currentSteamId[A](request: Request[A]): String =
|
||||
SecuredActions.steamIdOrUnknown(request)
|
||||
|
||||
/** Редактировать и удалять десайдера может только его владелец. */
|
||||
private def owns[A](decider: repository.Decider, request: Request[A]): Boolean =
|
||||
decider.ownerSteamId.contains(currentSteamId(request))
|
||||
|
||||
private def deciderJson(d: repository.Decider): JsObject = Json.obj(
|
||||
"key" -> d.key,
|
||||
"name" -> d.name,
|
||||
"rules" -> d.rules,
|
||||
"raceCount" -> d.raceCount,
|
||||
"existAdditionalRaces" -> d.existAdditionalRaces,
|
||||
"existTextFieldRaces" -> d.existTextFieldRaces,
|
||||
"description" -> d.description,
|
||||
"ownerSteamId" -> d.ownerSteamId,
|
||||
"maps" -> d.maps.map(m => Json.obj("map" -> m.map, "description" -> m.description))
|
||||
)
|
||||
|
||||
// ---------- Steam OpenID ----------
|
||||
|
||||
private val SteamLoginUrl = "https://steamcommunity.com/openid/login"
|
||||
@@ -89,7 +110,7 @@ class AdminController @Inject()(
|
||||
|
||||
def index() = Secured { implicit request =>
|
||||
implicit val messages: Messages = messagesApi.preferred(request)
|
||||
Ok(views.html.admin(DeciderRepository.all))
|
||||
Ok(views.html.admin(DeciderRepository.all.filter(d => owns(d, request))))
|
||||
}
|
||||
|
||||
// ---------- API: list map images ----------
|
||||
@@ -130,16 +151,7 @@ class AdminController @Inject()(
|
||||
// ---------- API: list all deciders ----------
|
||||
|
||||
def decidersList() = Secured { implicit request =>
|
||||
val list = DeciderRepository.all.map(d => Json.obj(
|
||||
"key" -> d.key,
|
||||
"name" -> d.name,
|
||||
"rules" -> d.rules,
|
||||
"raceCount" -> d.raceCount,
|
||||
"existAdditionalRaces" -> d.existAdditionalRaces,
|
||||
"existTextFieldRaces" -> d.existTextFieldRaces,
|
||||
"description" -> d.description,
|
||||
"maps" -> d.maps.map(m => Json.obj("map" -> m.map, "description" -> m.description))
|
||||
))
|
||||
val list = DeciderRepository.all.filter(d => owns(d, request)).map(deciderJson)
|
||||
Ok(Json.toJson(list))
|
||||
}
|
||||
|
||||
@@ -147,17 +159,10 @@ class AdminController @Inject()(
|
||||
|
||||
def deciderGet(key: String) = Secured { implicit request =>
|
||||
DeciderRepository.get(key) match {
|
||||
case Some(d) =>
|
||||
Ok(Json.obj(
|
||||
"key" -> d.key,
|
||||
"name" -> d.name,
|
||||
"rules" -> d.rules,
|
||||
"raceCount" -> d.raceCount,
|
||||
"existAdditionalRaces" -> d.existAdditionalRaces,
|
||||
"existTextFieldRaces" -> d.existTextFieldRaces,
|
||||
"description" -> d.description,
|
||||
"maps" -> d.maps.map(m => Json.obj("map" -> m.map, "description" -> m.description))
|
||||
))
|
||||
case Some(d) if owns(d, request) =>
|
||||
Ok(deciderJson(d))
|
||||
case Some(_) =>
|
||||
Forbidden(Json.obj("error" -> "You don't own this decider"))
|
||||
case None =>
|
||||
NotFound(Json.obj("error" -> s"Decider $key not found"))
|
||||
}
|
||||
@@ -167,49 +172,59 @@ class AdminController @Inject()(
|
||||
|
||||
def deciderSave() = SecuredJson { implicit request =>
|
||||
val json = request.body
|
||||
val steamId = currentSteamId(request)
|
||||
|
||||
(json \ "key").asOpt[String] match {
|
||||
case None =>
|
||||
BadRequest(Json.obj("error" -> "Missing key"))
|
||||
|
||||
case Some(key) =>
|
||||
Try {
|
||||
val maps = (json \ "maps").as[List[JsValue]].map { m =>
|
||||
repository.DeciderMapConfig(
|
||||
map = (m \ "map").as[String],
|
||||
description = (m \ "description").asOpt[String]
|
||||
)
|
||||
}
|
||||
repository.Decider(
|
||||
key = key,
|
||||
name = (json \ "name").as[String],
|
||||
rules = (json \ "rules").as[String],
|
||||
raceCount = (json \ "raceCount").as[Int],
|
||||
existAdditionalRaces = (json \ "existAdditionalRaces").as[Boolean],
|
||||
existTextFieldRaces = (json \ "existTextFieldRaces").as[Boolean],
|
||||
description = (json \ "description").as[Boolean],
|
||||
maps = maps
|
||||
)
|
||||
}.toEither match {
|
||||
case Right(decider) =>
|
||||
val existed = DeciderRepository.get(decider.key).isDefined
|
||||
DeciderRepository.save(decider)
|
||||
DeciderRepository.reload()
|
||||
if (existed) {
|
||||
logger.info(
|
||||
s"Admin ${SecuredActions.steamIdOrUnknown(request)} updated decider '${decider.key}' " +
|
||||
s"(name='${decider.name}', maps=${decider.maps.size})"
|
||||
val existing = DeciderRepository.get(key)
|
||||
if (existing.exists(d => !owns(d, request))) {
|
||||
Forbidden(Json.obj("error" -> "You don't own this decider"))
|
||||
} else {
|
||||
val name = (json \ "name").asOpt[String].map(_.trim).getOrElse("")
|
||||
val duplicateName = existing.isEmpty && name.nonEmpty &&
|
||||
DeciderRepository.all.exists(_.name.trim.equalsIgnoreCase(name))
|
||||
if (duplicateName) {
|
||||
Conflict(Json.obj("error" -> s"A decider named '$name' already exists"))
|
||||
} else {
|
||||
Try {
|
||||
val maps = (json \ "maps").as[List[JsValue]].map { m =>
|
||||
repository.DeciderMapConfig(
|
||||
map = (m \ "map").as[String],
|
||||
description = (m \ "description").asOpt[String]
|
||||
)
|
||||
}
|
||||
repository.Decider(
|
||||
key = key,
|
||||
name = (json \ "name").as[String],
|
||||
rules = (json \ "rules").as[String],
|
||||
raceCount = (json \ "raceCount").as[Int],
|
||||
existAdditionalRaces = (json \ "existAdditionalRaces").as[Boolean],
|
||||
existTextFieldRaces = (json \ "existTextFieldRaces").as[Boolean],
|
||||
description = (json \ "description").as[Boolean],
|
||||
maps = maps,
|
||||
// Владельца из запроса игнорируем: он либо уже назначен, либо
|
||||
// им становится автор нового десайдера.
|
||||
ownerSteamId = existing.flatMap(_.ownerSteamId).orElse(Some(steamId))
|
||||
)
|
||||
} else {
|
||||
logger.info(
|
||||
s"Admin ${SecuredActions.steamIdOrUnknown(request)} created decider '${decider.key}' " +
|
||||
s"(name='${decider.name}', maps=${decider.maps.size})"
|
||||
)
|
||||
}
|
||||
Ok(Json.obj("ok" -> true))
|
||||
}.toEither match {
|
||||
case Right(decider) =>
|
||||
DeciderRepository.save(decider)
|
||||
DeciderRepository.reload()
|
||||
val action = if (existing.isDefined) "updated" else "created"
|
||||
logger.info(
|
||||
s"Admin $steamId $action decider '${decider.key}' " +
|
||||
s"(name='${decider.name}', maps=${decider.maps.size}, " +
|
||||
s"owner=${decider.ownerSteamId.getOrElse("-")})"
|
||||
)
|
||||
Ok(Json.obj("ok" -> true))
|
||||
|
||||
case Left(error) =>
|
||||
BadRequest(Json.obj("error" -> s"$error"))
|
||||
case Left(error) =>
|
||||
BadRequest(Json.obj("error" -> s"$error"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,12 +232,17 @@ class AdminController @Inject()(
|
||||
// ---------- API: delete decider ----------
|
||||
|
||||
def deciderDelete(key: String) = SecuredApi { implicit request =>
|
||||
if (DeciderRepository.delete(key)) {
|
||||
DeciderRepository.reload()
|
||||
logger.info(s"Admin ${SecuredActions.steamIdOrUnknown(request)} deleted decider '$key'")
|
||||
Ok(Json.obj("ok" -> true))
|
||||
} else {
|
||||
NotFound(Json.obj("error" -> s"Decider $key not found"))
|
||||
DeciderRepository.get(key) match {
|
||||
case Some(d) if !owns(d, request) =>
|
||||
Forbidden(Json.obj("error" -> "You don't own this decider"))
|
||||
case _ =>
|
||||
if (DeciderRepository.delete(key)) {
|
||||
DeciderRepository.reload()
|
||||
logger.info(s"Admin ${currentSteamId(request)} deleted decider '$key'")
|
||||
Ok(Json.obj("ok" -> true))
|
||||
} else {
|
||||
NotFound(Json.obj("error" -> s"Decider $key not found"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user