forked from SteamWar/SteamWar
Merge pull request 'Add AuditLog to Backend' (#244) from Backend/auditlog into main
Reviewed-on: SteamWar/SteamWar#244 Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
This commit is contained in:
@@ -20,12 +20,9 @@
|
||||
package de.steamwar
|
||||
|
||||
import de.steamwar.plugins.configurePlugins
|
||||
import de.steamwar.routes.ResponseUser
|
||||
import de.steamwar.routes.SchematicCode
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.engine.*
|
||||
import de.steamwar.routes.configureRoutes
|
||||
import de.steamwar.sql.SchematicType
|
||||
import de.steamwar.sql.SteamwarUser
|
||||
import io.ktor.server.netty.*
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
@@ -47,7 +44,6 @@ fun main() {
|
||||
Thread {
|
||||
while (true) {
|
||||
Thread.sleep(1000 * 10)
|
||||
ResponseUser.clearCache()
|
||||
SteamwarUser.clear()
|
||||
}
|
||||
}.start()
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.routes
|
||||
|
||||
import de.steamwar.plugins.SWPermissionCheck
|
||||
import de.steamwar.sql.AuditLog
|
||||
import de.steamwar.sql.AuditLogTable
|
||||
import de.steamwar.sql.SteamwarUserTable
|
||||
import de.steamwar.sql.UserPerm
|
||||
import de.steamwar.sql.internal.useDb
|
||||
import io.ktor.server.application.call
|
||||
import io.ktor.server.application.install
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.Route
|
||||
import io.ktor.server.routing.get
|
||||
import io.ktor.server.routing.route
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.jetbrains.exposed.v1.core.Alias
|
||||
import org.jetbrains.exposed.v1.core.JoinType
|
||||
import org.jetbrains.exposed.v1.core.SortOrder
|
||||
import org.jetbrains.exposed.v1.core.alias
|
||||
import org.jetbrains.exposed.v1.core.greater
|
||||
import org.jetbrains.exposed.v1.core.inList
|
||||
import org.jetbrains.exposed.v1.core.isNull
|
||||
import org.jetbrains.exposed.v1.core.less
|
||||
import org.jetbrains.exposed.v1.core.like
|
||||
import org.jetbrains.exposed.v1.core.or
|
||||
import org.jetbrains.exposed.v1.jdbc.Query
|
||||
import org.jetbrains.exposed.v1.jdbc.andWhere
|
||||
import org.jetbrains.exposed.v1.jdbc.select
|
||||
import org.jetbrains.exposed.v1.jdbc.selectAll
|
||||
import java.time.Instant
|
||||
|
||||
fun Route.configureAuditLog() {
|
||||
route("/auditlog") {
|
||||
install(SWPermissionCheck) {
|
||||
mustAuth = true
|
||||
permission = UserPerm.MODERATION
|
||||
}
|
||||
|
||||
get {
|
||||
val text = call.request.queryParameters["fullText"]
|
||||
val actionText = call.request.queryParameters["actionText"]
|
||||
val serverText = call.request.queryParameters["server"]
|
||||
val actor = call.request.queryParameters.getAll("actor")?.map { it.toInt() }?.toSet()
|
||||
val actionType =
|
||||
call.request.queryParameters.getAll("actionType")?.map { AuditLog.Type.valueOf(it) }?.toSet()
|
||||
val timeGreater = call.request.queryParameters["timeGreater"]?.let { Instant.ofEpochMilli(it.toLong()) }
|
||||
val timeLess = call.request.queryParameters["timeLess"]?.let { Instant.ofEpochMilli(it.toLong()) }
|
||||
|
||||
val serverOwner = call.request.queryParameters.getAll("serverOwner")?.map { it.toInt() }?.toSet()
|
||||
val velocity = call.request.queryParameters["velocity"]?.toBoolean()
|
||||
|
||||
val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 0
|
||||
val limit = call.request.queryParameters["limit"]?.toIntOrNull() ?: 100
|
||||
val sorting = call.request.queryParameters["sorting"] ?: "DESC"
|
||||
|
||||
call.respond(
|
||||
PagedAuditLog.filter(
|
||||
actionText,
|
||||
serverText,
|
||||
text,
|
||||
actor,
|
||||
actionType,
|
||||
timeGreater,
|
||||
timeLess,
|
||||
serverOwner,
|
||||
velocity,
|
||||
page,
|
||||
limit,
|
||||
sorting
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class PagedAuditLog(val rows: Long, val entries: List<AuditLogEntry>) {
|
||||
|
||||
companion object {
|
||||
fun filter(
|
||||
actionText: String? = null,
|
||||
serverText: String? = null,
|
||||
fullText: String? = null,
|
||||
actor: Set<Int>? = null,
|
||||
actionType: Set<AuditLog.Type>? = null,
|
||||
timeGreater: Instant? = null,
|
||||
timeLess: Instant? = null,
|
||||
serverOwner: Set<Int>? = null,
|
||||
velocity: Boolean? = null,
|
||||
page: Int = 0,
|
||||
limit: Int = 100,
|
||||
sorting: String = "DESC"
|
||||
) = useDb {
|
||||
val actorTable = SteamwarUserTable.alias("actor")
|
||||
val serverOwnerTable = SteamwarUserTable.alias("serverOwner")
|
||||
|
||||
val query = AuditLogTable.join(
|
||||
actorTable,
|
||||
JoinType.INNER,
|
||||
onColumn = actorTable[SteamwarUserTable.id],
|
||||
otherColumn = AuditLogTable.actor
|
||||
)
|
||||
.join(
|
||||
serverOwnerTable,
|
||||
JoinType.LEFT,
|
||||
onColumn = serverOwnerTable[SteamwarUserTable.id],
|
||||
otherColumn = AuditLogTable.serverOwner
|
||||
)
|
||||
.select(
|
||||
actorTable[SteamwarUserTable.username], serverOwnerTable[SteamwarUserTable.username],
|
||||
*AuditLogTable.columns.toTypedArray()
|
||||
)
|
||||
|
||||
PagedAuditLog(
|
||||
AuditLogTable.selectAll().addAuditLogFilters(
|
||||
actionText,
|
||||
serverText,
|
||||
fullText,
|
||||
actor,
|
||||
actionType,
|
||||
timeGreater,
|
||||
timeLess,
|
||||
serverOwner,
|
||||
velocity
|
||||
).count(),
|
||||
query
|
||||
.addAuditLogFilters(
|
||||
actionText,
|
||||
serverText,
|
||||
fullText,
|
||||
actor,
|
||||
actionType,
|
||||
timeGreater,
|
||||
timeLess,
|
||||
serverOwner,
|
||||
velocity
|
||||
)
|
||||
.limit(limit)
|
||||
.offset((page * limit).toLong())
|
||||
.orderBy(AuditLogTable.time, SortOrder.valueOf(sorting.uppercase()))
|
||||
.map {
|
||||
AuditLogEntry(
|
||||
it[AuditLogTable.id].value,
|
||||
it[AuditLogTable.time].toEpochMilli(),
|
||||
it[AuditLogTable.server],
|
||||
it[serverOwnerTable[SteamwarUserTable.username]],
|
||||
it[actorTable[SteamwarUserTable.username]],
|
||||
it[AuditLogTable.action],
|
||||
it[AuditLogTable.actionText]
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun Query.addAuditLogFilters(
|
||||
actionText: String? = null,
|
||||
serverText: String? = null,
|
||||
fullText: String? = null,
|
||||
actor: Set<Int>? = null,
|
||||
actionType: Set<AuditLog.Type>? = null,
|
||||
timeGreater: Instant? = null,
|
||||
timeLess: Instant? = null,
|
||||
serverOwner: Set<Int>? = null,
|
||||
velocity: Boolean? = null,
|
||||
): Query {
|
||||
actionText?.let {
|
||||
andWhere { (AuditLogTable.actionText like "%$it%") }
|
||||
}
|
||||
serverText?.let {
|
||||
andWhere { (AuditLogTable.server like "%$it%") }
|
||||
}
|
||||
fullText?.let {
|
||||
andWhere { (AuditLogTable.actionText like "%$it%") or (AuditLogTable.server like "%$it%") }
|
||||
}
|
||||
actor?.let { andWhere { AuditLogTable.actor inList actor } }
|
||||
actionType?.let { andWhere { AuditLogTable.action inList actionType } }
|
||||
timeGreater?.let { andWhere { AuditLogTable.time greater timeGreater } }
|
||||
timeLess?.let { andWhere { AuditLogTable.time less timeLess } }
|
||||
serverOwner?.let { andWhere { AuditLogTable.serverOwner inList serverOwner } }
|
||||
if (velocity == true) andWhere { AuditLogTable.serverOwner.isNull() }
|
||||
|
||||
return this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class AuditLogEntry(
|
||||
val id: Int,
|
||||
val time: Long,
|
||||
val server: String,
|
||||
val serverOwner: String?,
|
||||
val actor: String,
|
||||
val actionType: AuditLog.Type,
|
||||
val actionText: String
|
||||
)
|
||||
@@ -66,7 +66,7 @@ fun Route.configureAuth() {
|
||||
}
|
||||
|
||||
call.sessions.set(SWUserSession(user.getId()))
|
||||
call.respond(ResponseUser.get(user))
|
||||
call.respond(ResponseUser(user))
|
||||
}
|
||||
|
||||
delete {
|
||||
@@ -100,7 +100,7 @@ fun Route.configureAuth() {
|
||||
}
|
||||
|
||||
call.sessions.set(SWUserSession(user.getId()))
|
||||
call.respond(ResponseUser.get(user))
|
||||
call.respond(ResponseUser(user))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import de.steamwar.plugins.SWAuthPrincipal
|
||||
import de.steamwar.plugins.SWPermissionCheck
|
||||
import de.steamwar.sql.SchematicType
|
||||
import de.steamwar.sql.SteamwarUser
|
||||
import de.steamwar.sql.SteamwarUserTable
|
||||
import de.steamwar.sql.Team
|
||||
import de.steamwar.sql.UserPerm
|
||||
import de.steamwar.sql.internal.useDb
|
||||
@@ -36,6 +37,13 @@ import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.bspfsystems.yamlconfiguration.file.YamlConfiguration
|
||||
import org.jetbrains.exposed.v1.core.ResultRow
|
||||
import org.jetbrains.exposed.v1.core.eq
|
||||
import org.jetbrains.exposed.v1.core.inList
|
||||
import org.jetbrains.exposed.v1.core.like
|
||||
import org.jetbrains.exposed.v1.jdbc.Query
|
||||
import org.jetbrains.exposed.v1.jdbc.andWhere
|
||||
import org.jetbrains.exposed.v1.jdbc.selectAll
|
||||
import java.io.File
|
||||
import java.net.InetSocketAddress
|
||||
import java.util.*
|
||||
@@ -44,28 +52,39 @@ import java.util.*
|
||||
data class ResponseSchematicType(val name: String, val db: String)
|
||||
|
||||
@Serializable
|
||||
data class ResponseUser(val name: String, val uuid: String, val prefix: String, val perms: List<String>) {
|
||||
private constructor(user: SteamwarUser) : this(user.userName, user.uuid.toString(), user.prefix().chatPrefix, user.perms().filter { !it.name.startsWith("PREFIX_") }.map { it.name })
|
||||
data class ResponseUser(
|
||||
val name: String, val uuid: String, val id: Int?, val perms: List<String>?, val prefix: String?
|
||||
) {
|
||||
constructor(user: SteamwarUser, includeId: Boolean = false, includePerms: Boolean = false) : this(
|
||||
user.userName,
|
||||
user.uuid.toString(),
|
||||
if (includeId) user.getId() else null,
|
||||
if (includePerms) user.perms().map { it.name } else null,
|
||||
if (includePerms) user.prefix().chatPrefix else null,
|
||||
)
|
||||
|
||||
companion object {
|
||||
private val cache = mutableMapOf<Int, ResponseUser>()
|
||||
constructor(row: ResultRow, includeId: Boolean = false, includePerms: Boolean = false, prefixes: MutableSet<UserPerm> = mutableSetOf()) : this(
|
||||
row[SteamwarUserTable.username],
|
||||
row[SteamwarUserTable.uuid],
|
||||
if (includeId) row[SteamwarUserTable.id].value else null,
|
||||
if (includePerms) UserPerm.getPerms(row[SteamwarUserTable.id].value).also { prefixes.addAll(it) }.map { it.name } else null,
|
||||
if (includePerms) prefixes.firstOrNull { UserPerm.prefixes.containsKey(it) }?.let { UserPerm.prefixes[it]!!.chatPrefix } else null
|
||||
)
|
||||
}
|
||||
|
||||
fun get(id: Int): ResponseUser {
|
||||
synchronized(cache) {
|
||||
return cache[id] ?: ResponseUser(SteamwarUser.byId(id)!!).also { cache[id] = it }
|
||||
}
|
||||
}
|
||||
@Serializable
|
||||
data class ResponseUserList(val entries: List<ResponseUser>, val rows: Long)
|
||||
|
||||
fun get(user: SteamwarUser): ResponseUser = synchronized(cache) {
|
||||
return cache[user.getId()] ?: ResponseUser(user).also { cache[user.getId()] = it }
|
||||
}
|
||||
private fun Query.addUserFilter(
|
||||
name: String? = null,
|
||||
uuid: UUID? = null,
|
||||
team: Set<Int>? = null,
|
||||
): Query {
|
||||
name?.let { andWhere { (SteamwarUserTable.username like "%$it%") } }
|
||||
uuid?.let { andWhere { (SteamwarUserTable.uuid eq it.toString()) } }
|
||||
team?.let { andWhere { (SteamwarUserTable.team inList team) } }
|
||||
|
||||
fun clearCache() {
|
||||
synchronized(cache) {
|
||||
cache.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun Route.configureDataRoutes() {
|
||||
@@ -76,13 +95,33 @@ fun Route.configureDataRoutes() {
|
||||
permission = UserPerm.MODERATION
|
||||
}
|
||||
get("/users") {
|
||||
call.respond(useDb { SteamwarUser.all().map { ResponseUser.get(it) } })
|
||||
val name = call.request.queryParameters["name"]
|
||||
val uuid = call.request.queryParameters["uuid"]?.let { catchException { UUID.fromString(it) } }
|
||||
val team = call.request.queryParameters.getAll("team")?.map { it.toInt() }?.toSet()
|
||||
|
||||
val limit = call.request.queryParameters["limit"]?.toIntOrNull() ?: 100
|
||||
val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 0
|
||||
|
||||
val includePerms = call.request.queryParameters["includePerms"]?.toBoolean() ?: false
|
||||
val includeId = call.request.queryParameters["includeId"]?.toBoolean() ?: false
|
||||
|
||||
call.respond(
|
||||
useDb {
|
||||
ResponseUserList(
|
||||
SteamwarUserTable.selectAll().addUserFilter(name, uuid, team).limit(limit)
|
||||
.offset((page * limit).toLong())
|
||||
.map { ResponseUser(it, includeId, includePerms) },
|
||||
SteamwarUserTable.selectAll().addUserFilter(name, uuid, team).count()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
get("/teams") {
|
||||
call.respond(Team.getAll().map { ResponseTeam(it) })
|
||||
}
|
||||
get("/schematicTypes") {
|
||||
call.respond(SchematicType.values().filter { !it.check() }.map { ResponseSchematicType(it.name(), it.toDB()) })
|
||||
call.respond(SchematicType.values().filter { !it.check() }
|
||||
.map { ResponseSchematicType(it.name(), it.toDB()) })
|
||||
}
|
||||
get("/gamemodes") {
|
||||
call.respond(
|
||||
@@ -116,11 +155,14 @@ fun Route.configureDataRoutes() {
|
||||
}
|
||||
get("/team") {
|
||||
call.respond(
|
||||
listOf(UserPerm.PREFIX_ADMIN, UserPerm.PREFIX_DEVELOPER, UserPerm.PREFIX_MODERATOR, UserPerm.PREFIX_SUPPORTER, UserPerm.PREFIX_BUILDER)
|
||||
.associateWith { SteamwarUser.getUsersWithPerm(it) }
|
||||
.mapKeys { UserPerm.prefixes[it.key]!!.chatPrefix }
|
||||
.mapValues { it.value.map { ResponseUser.get(it) } }
|
||||
)
|
||||
listOf(
|
||||
UserPerm.PREFIX_ADMIN,
|
||||
UserPerm.PREFIX_DEVELOPER,
|
||||
UserPerm.PREFIX_MODERATOR,
|
||||
UserPerm.PREFIX_SUPPORTER,
|
||||
UserPerm.PREFIX_BUILDER
|
||||
).associateWith { SteamwarUser.getUsersWithPerm(it) }.mapKeys { UserPerm.prefixes[it.key]!!.chatPrefix }
|
||||
.mapValues { it.value.map { ResponseUser(it) } })
|
||||
}
|
||||
get("/skin/{uuid}") {
|
||||
val uuid = call.parameters["uuid"]
|
||||
@@ -138,7 +180,7 @@ fun Route.configureDataRoutes() {
|
||||
route("/me") {
|
||||
install(SWPermissionCheck)
|
||||
get {
|
||||
call.respond(ResponseUser.get(call.principal<SWAuthPrincipal>()!!.user))
|
||||
call.respond(ResponseUser(call.principal<SWAuthPrincipal>()!!.user, includePerms = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ fun Route.configureEventRefereesRouting() {
|
||||
route("/referees") {
|
||||
get {
|
||||
val event = call.receiveEvent() ?: return@get
|
||||
call.respond(Referee.get(event.eventID).map { ResponseUser.get(SteamwarUser.byId(it)!!) })
|
||||
call.respond(Referee.get(event.eventID).map { ResponseUser(SteamwarUser.byId(it)!!) })
|
||||
}
|
||||
put {
|
||||
val event = call.receiveEvent() ?: return@put
|
||||
@@ -39,7 +39,7 @@ fun Route.configureEventRefereesRouting() {
|
||||
referees.forEach {
|
||||
Referee.add(event.eventID, SteamwarUser.get(UUID.fromString(it))!!.getId())
|
||||
}
|
||||
call.respond(Referee.get(event.eventID).map { ResponseUser.get(SteamwarUser.byId(it)!!) })
|
||||
call.respond(Referee.get(event.eventID).map { ResponseUser(SteamwarUser.byId(it)!!) })
|
||||
}
|
||||
delete {
|
||||
val event = call.receiveEvent() ?: return@delete
|
||||
@@ -47,7 +47,7 @@ fun Route.configureEventRefereesRouting() {
|
||||
referees.forEach {
|
||||
Referee.remove(event.eventID, SteamwarUser.get(UUID.fromString(it))!!.getId())
|
||||
}
|
||||
call.respond(Referee.get(event.eventID).map { ResponseUser.get(SteamwarUser.byId(it)!!) })
|
||||
call.respond(Referee.get(event.eventID).map { ResponseUser(SteamwarUser.byId(it)!!) })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ data class ExtendedResponseEvent(
|
||||
TeamTeilnahme.getTeams(event.eventID).map { ResponseTeam(it) },
|
||||
EventGroup.get(event).map { ResponseGroups(it) },
|
||||
EventFight.getEvent(event.eventID).map { ResponseEventFight(it) },
|
||||
Referee.get(event.eventID).map { ResponseUser.get(SteamwarUser.byId(it)!!) },
|
||||
Referee.get(event.eventID).map { ResponseUser(SteamwarUser.byId(it)!!) },
|
||||
EventRelation.get(event).map { ResponseRelation(it) }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ fun Application.configureRoutes() {
|
||||
configurePage()
|
||||
configureSchematic()
|
||||
configureAuth()
|
||||
configureAuditLog()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,9 +34,7 @@ import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.DataInputStream
|
||||
import java.io.InputStream
|
||||
import java.security.MessageDigest
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
@@ -49,16 +47,6 @@ data class ResponseSchematic(val name: String, val id: Int, val type: String?, v
|
||||
constructor(node: SchematicNode) : this(node.name, node.getId(), node.schemtype?.name(), node.owner, node.item, node.lastUpdate.time, node.rank, node.replaceColor(), node.allowReplay())
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ResponseSchematicLong(val members: List<ResponseUser>, val path: String, val schem: ResponseSchematic) {
|
||||
constructor(node: SchematicNode, path: String): this(NodeMember.getNodeMembers(node.getId()).map { ResponseUser.get(it.member) }, path, ResponseSchematic(node))
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ResponseSchematicList(val breadcrumbs: List<ResponseBreadcrumb>, val schematics: List<ResponseSchematic>, val players: Map<String, ResponseUser>) {
|
||||
constructor(schematics: List<ResponseSchematic>, breadcrumbs: List<ResponseBreadcrumb>) : this(breadcrumbs, schematics, schematics.map { it.owner }.distinct().map { ResponseUser.get(it) }.associateBy { it.uuid })
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ResponseBreadcrumb(val name: String, val id: Int)
|
||||
|
||||
|
||||
@@ -23,11 +23,17 @@ import de.steamwar.plugins.SWPermissionCheck
|
||||
import de.steamwar.plugins.getUser
|
||||
import de.steamwar.sql.SteamwarUser
|
||||
import de.steamwar.sql.UserPerm
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.application.ApplicationCall
|
||||
import io.ktor.server.application.call
|
||||
import io.ktor.server.application.install
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.Route
|
||||
import io.ktor.server.routing.delete
|
||||
import io.ktor.server.routing.get
|
||||
import io.ktor.server.routing.put
|
||||
import io.ktor.server.routing.route
|
||||
import kotlinx.serialization.Serializable;
|
||||
|
||||
@Serializable
|
||||
data class RespondPrefix(val name: String, val colorCode: String, val chatPrefix: String)
|
||||
@@ -76,7 +82,12 @@ fun Route.configureUserPerms() {
|
||||
|
||||
val prefixs = UserPerm.prefixes[prefix]!!
|
||||
|
||||
call.respond(RespondUserPermsPrefix(RespondPrefix(prefix.name, prefixs.colorCode, prefixs.chatPrefix), perms))
|
||||
call.respond(
|
||||
RespondUserPermsPrefix(
|
||||
RespondPrefix(prefix.name, prefixs.colorCode, prefixs.chatPrefix),
|
||||
perms
|
||||
)
|
||||
)
|
||||
}
|
||||
put("/prefix/{prefix}") {
|
||||
val (user, prefix) = call.receivePermission("prefix", isPrefix = true) ?: return@put
|
||||
@@ -112,7 +123,10 @@ fun Route.configureUserPerms() {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun ApplicationCall.receivePermission(fieldName: String = "perm", isPrefix: Boolean = false): Pair<SteamwarUser, UserPerm>? {
|
||||
suspend fun ApplicationCall.receivePermission(
|
||||
fieldName: String = "perm",
|
||||
isPrefix: Boolean = false
|
||||
): Pair<SteamwarUser, UserPerm>? {
|
||||
val user = request.getUser()
|
||||
if (user == null) {
|
||||
respond(HttpStatusCode.BadRequest)
|
||||
|
||||
Reference in New Issue
Block a user