diff --git a/CommonCore/SQL/src/de/steamwar/sql/Punishment.kt b/CommonCore/SQL/src/de/steamwar/sql/Punishment.kt index a5fa6baa..f3fcbb4e 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/Punishment.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/Punishment.kt @@ -53,7 +53,8 @@ class Punishment(id: EntityID) : IntEntity(id) { @JvmStatic fun getPunsihmentOfPlayer(user: Int, type: PunishmentType) = useDb { - find { (PunishmentTable.userId eq user) and (PunishmentTable.type eq type) }.orderBy(PunishmentTable.id to SortOrder.DESC).firstOrNull() + find { (PunishmentTable.userId eq user) and (PunishmentTable.type eq type) }.orderBy(PunishmentTable.id to SortOrder.DESC) + .firstOrNull() } @JvmStatic @@ -61,8 +62,8 @@ class Punishment(id: EntityID) : IntEntity(id) { find { PunishmentTable.id inSubQuery PunishmentTable.select(PunishmentTable.id.max()) .where { PunishmentTable.userId eq user }.groupBy( - PunishmentTable.type - ) + PunishmentTable.type + ) }.associateBy { it.type }.toMutableMap() } @@ -130,17 +131,19 @@ class Punishment(id: EntityID) : IntEntity(id) { val playerMessageUntil: String?, val usageNotPunished: String?, val unpunishmentMessage: String?, + val userPerm: UserPerm, val multi: Boolean = false ) { - Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"), - Mute(false, "MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE"), + Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN", UserPerm.TEAM), + Mute(false, "MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE", UserPerm.TEAM), NoSchemReceiving( true, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", - "UNNOSCHEMRECEIVING" + "UNNOSCHEMRECEIVING", + UserPerm.MODERATION ), NoSchemSharing( true, @@ -148,7 +151,8 @@ class Punishment(id: EntityID) : IntEntity(id) { "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", - "UNNOSCHEMSHARING" + "UNNOSCHEMSHARING", + UserPerm.MODERATION ), NoSchemSubmitting( false, @@ -156,7 +160,8 @@ class Punishment(id: EntityID) : IntEntity(id) { "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", - "UNNOSCHEMSUBMITTING" + "UNNOSCHEMSUBMITTING", + UserPerm.TEAM ), NoDevServer( true, @@ -164,7 +169,8 @@ class Punishment(id: EntityID) : IntEntity(id) { "NODEVSERVER_PERMA", "NODEVSERVER_UNTIL", "UNNODEVSERVER_ERROR", - "UNNODEVSERVER" + "UNNODEVSERVER", + UserPerm.PREFIX_DEVELOPER ), NoFightServer( true, @@ -172,7 +178,8 @@ class Punishment(id: EntityID) : IntEntity(id) { "NOFIGHTSERVER_PERMA", "NOFIGHTSERVER_UNTIL", "UNNOFIGHTSERVER_ERROR", - "UNNOFIGHTSERVER" + "UNNOFIGHTSERVER", + UserPerm.MODERATION ), NoTeamServer( true, @@ -180,9 +187,10 @@ class Punishment(id: EntityID) : IntEntity(id) { "NOTEAMSERVER_PERMA", "NOTEAMSERVER_UNTIL", "UNNOTEAMSERVER_ERROR", - "UNNOTEAMSERVER" + "UNNOTEAMSERVER", + UserPerm.MODERATION ), - Note(false, "NOTE_TEAM", null, null, null, null, true); + Note(false, "NOTE_TEAM", null, null, null, null, UserPerm.TEAM, true); fun isNeedsAdmin() = needsAdmin fun isMulti() = multi diff --git a/CommonCore/SQL/src/de/steamwar/sql/SWException.kt b/CommonCore/SQL/src/de/steamwar/sql/SWException.kt index 7c5dc33c..27c62aee 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SWException.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/SWException.kt @@ -21,6 +21,7 @@ package de.steamwar.sql import de.steamwar.sql.internal.useDb import org.jetbrains.exposed.v1.core.dao.id.IntIdTable +import org.jetbrains.exposed.v1.javatime.CurrentTimestamp import org.jetbrains.exposed.v1.javatime.timestamp import org.jetbrains.exposed.v1.jdbc.insert import org.jetbrains.exposed.v1.jdbc.insertAndGetId @@ -28,7 +29,7 @@ import java.io.File import java.time.Instant object ExceptionTable: IntIdTable("Exception") { - val time = timestamp("Time").default(Instant.now()) + val time = timestamp("Time").defaultExpression(CurrentTimestamp) val server = text("Server") val message = text("Message") val stackTrace = text("StackTrace") @@ -39,6 +40,9 @@ class SWException { val cwd = System.getProperty("user.dir") val serverName = File(cwd).name + @JvmStatic + fun init() = Unit + @JvmStatic fun log(message: String, stacktrace: String) = useDb { ExceptionTable.insert { diff --git a/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.kt b/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.kt index c3e01d01..b997fef0 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.kt @@ -26,6 +26,7 @@ import org.jetbrains.exposed.v1.core.dao.id.EntityID import org.jetbrains.exposed.v1.core.dao.id.IntIdTable import org.jetbrains.exposed.v1.dao.IntEntity import org.jetbrains.exposed.v1.dao.IntEntityClass +import org.jetbrains.exposed.v1.javatime.CurrentTimestamp import org.jetbrains.exposed.v1.javatime.timestamp import org.jetbrains.exposed.v1.jdbc.insertAndGetId import java.sql.Timestamp @@ -36,7 +37,7 @@ object SchematicNodeTable : IntIdTable("SchematicNode", "NodeId") { val owner = reference("NodeOwner", SteamwarUserTable) val name = varchar("NodeName", 64) val parent = optReference("ParentNode", SchematicNodeTable) - val lastUpdate = timestamp("LastUpdate") + val lastUpdate = timestamp("LastUpdate").defaultExpression(CurrentTimestamp) val item = text("NodeItem") val type = varchar("NodeType", 16).nullable() val config = integer("Config") diff --git a/CommonCore/SQL/src/de/steamwar/sql/Session.kt b/CommonCore/SQL/src/de/steamwar/sql/Session.kt index 1e50bd08..1ed2978c 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/Session.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/Session.kt @@ -22,6 +22,7 @@ package de.steamwar.sql import de.steamwar.sql.internal.useDb import org.jetbrains.exposed.v1.core.Table import org.jetbrains.exposed.v1.core.dao.id.EntityID +import org.jetbrains.exposed.v1.javatime.CurrentTimestamp import org.jetbrains.exposed.v1.javatime.timestamp import org.jetbrains.exposed.v1.jdbc.insert import java.sql.Timestamp @@ -30,7 +31,7 @@ import java.time.Instant object SessionTable: Table("Session") { val userId = reference("UserId", SteamwarUserTable) val startTime = timestamp("StartTime") - val endTime = timestamp("EndTime").default(Instant.now()) + val endTime = timestamp("EndTime").defaultExpression(CurrentTimestamp) } class Session { diff --git a/CommonCore/SQL/src/de/steamwar/sql/TeamTeilnahme.kt b/CommonCore/SQL/src/de/steamwar/sql/TeamTeilnahme.kt index 8a3ef867..b46e3dd0 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/TeamTeilnahme.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/TeamTeilnahme.kt @@ -73,12 +73,12 @@ class TeamTeilnahme(id: EntityID) : CompositeEntity(id) { @JvmStatic fun getTeams(eventId: Int) = useDb { - find { TeamTeilnahmeTable.eventId eq eventId }.map { it.teamId } + find { TeamTeilnahmeTable.eventId eq eventId }.map { Team.byId(it.teamId.value) }.toSet() } @JvmStatic fun getEvents(teamId: Int) = useDb { - find { TeamTeilnahmeTable.teamId eq teamId }.map { it.eventId } + find { TeamTeilnahmeTable.teamId eq teamId }.map { Event.byId(it.eventId.value) }.toSet() } } diff --git a/CommonCore/SQL/src/de/steamwar/sql/Token.java b/CommonCore/SQL/src/de/steamwar/sql/Token.java deleted file mode 100644 index 01fd56fa..00000000 --- a/CommonCore/SQL/src/de/steamwar/sql/Token.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 . - */ - -package de.steamwar.sql; - -import de.steamwar.sql.internal.Field; -import de.steamwar.sql.internal.SelectStatement; -import de.steamwar.sql.internal.Statement; -import de.steamwar.sql.internal.Table; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.SneakyThrows; -import lombok.ToString; - -import java.security.MessageDigest; -import java.security.SecureRandom; -import java.sql.Timestamp; -import java.util.Base64; -import java.util.List; - -@AllArgsConstructor -@Getter -@ToString -public class Token { - private static final Table table = new Table<>(Token.class); - private static final Statement insert = table.insertFields(true, "Name", "Owner", "Hash"); - private static final SelectStatement get = table.select(Table.PRIMARY); - private static final SelectStatement listUser = table.selectFields("owner"); - private static final SelectStatement getHash = table.selectFields("hash"); - private static final Statement delete = table.delete(Table.PRIMARY); - - @SneakyThrows - private static String getHash(String code) { - return Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-512").digest(code.getBytes())); - } - - @SneakyThrows - public static String createToken(String name, SteamwarUser owner) { - SecureRandom random = new SecureRandom(); - byte[] bytes = new byte[20]; - random.nextBytes(bytes); - - String code = Base64.getEncoder().encodeToString(bytes); - - String hash = getHash(code); - create(name, owner, hash); - return code; - } - - public static Token getTokenByCode(String code) { - String hash = getHash(code); - return get(hash); - } - - public static Token create(String name, SteamwarUser owner, String hash) { - int id = insert.insertGetKey(name, owner, hash); - return get(id); - } - - public static Token get(int id) { - return get.select(id); - } - - public static List listUser(SteamwarUser owner) { - return listUser.listSelect(owner); - } - - public static Token get(String hash) { - return getHash.select(hash); - } - - public static void delete(Token id) { - delete.update(id.getId()); - } - - @Field(keys = Table.PRIMARY, autoincrement = true) - private final int id; - @Field(keys = "NameOwner") - private final String name; - @Field(keys = "NameOwner") - private final int owner; - @Field - private final Timestamp created; - @Field - private final String hash; - - public void delete() { - delete(this); - } - - public SteamwarUser getOwner() { - return SteamwarUser.byId(owner); - } -} diff --git a/CommonCore/SQL/src/de/steamwar/sql/Token.kt b/CommonCore/SQL/src/de/steamwar/sql/Token.kt new file mode 100644 index 00000000..1c0539ab --- /dev/null +++ b/CommonCore/SQL/src/de/steamwar/sql/Token.kt @@ -0,0 +1,94 @@ +/* + * 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 . + */ + +package de.steamwar.sql + +import de.steamwar.sql.internal.useDb +import org.jetbrains.exposed.v1.core.dao.id.EntityID +import org.jetbrains.exposed.v1.core.dao.id.IntIdTable +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.dao.IntEntity +import org.jetbrains.exposed.v1.dao.IntEntityClass +import org.jetbrains.exposed.v1.javatime.CurrentTimestamp +import org.jetbrains.exposed.v1.javatime.timestamp +import java.security.MessageDigest +import java.security.SecureRandom +import java.sql.Timestamp +import java.time.Instant +import java.util.Base64 + +object TokenTable: IntIdTable("Token") { + val name = varchar("Name", 64) + val owner = reference("Owner", SteamwarUserTable) + val created = timestamp("Created").defaultExpression(CurrentTimestamp) + val hash = varchar("Hash", 88) +} + +class Token(id: EntityID): IntEntity(id) { + companion object : IntEntityClass(TokenTable) { + private fun getHash(code: String) = Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-512").digest(code.toByteArray())) + + @JvmStatic + fun createToken(name: String, owner: SteamwarUser): String { + val random = SecureRandom(); + val bytes = ByteArray(20) + random.nextBytes(bytes) + + val code = Base64.getEncoder().encodeToString(bytes) + + val hash = getHash(code) + + useDb { + new { + this.name = name + this.owner = owner + this.hash = hash + } + } + + return code + } + + @JvmStatic + fun getTokenByCode(code: String) = get(getHash(code)) + + @JvmStatic + fun get(hash: String) = useDb { + find { TokenTable.hash eq hash }.firstOrNull() + } + + @JvmStatic + fun listUser(user: SteamwarUser) = useDb { + find { TokenTable.owner eq user.id }.toList() + } + } + + var name by TokenTable.name + private set + var owner by SteamwarUser referencedOn TokenTable.owner + private set + var created by TokenTable.created.transform({ it.toInstant() }, { Timestamp.from(it) }) + private set + var hash by TokenTable.hash + private set + + override fun delete() = useDb { + super.delete() + } +} \ No newline at end of file