Skip to content

Commit

Permalink
Merge pull request #45 from morinoparty/develop
Browse files Browse the repository at this point in the history
Add vault integration
  • Loading branch information
Nlkomaru authored May 22, 2024
2 parents ba55ff4 + e2dc5ff commit 27520e0
Show file tree
Hide file tree
Showing 20 changed files with 177 additions and 22 deletions.
17 changes: 15 additions & 2 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ repositories {
maven("https://repo.codemc.io/repository/maven-public/")
}

group = project.group
group = "party.morino"
version = project.version.toString()

dependencies {
Expand All @@ -40,6 +40,8 @@ dependencies {

implementation(libs.koin.core)
implementation(kotlin("stdlib-jdk8"))

compileOnly(libs.vault.api)
}

kotlin {
Expand All @@ -65,7 +67,18 @@ tasks {
options.encoding = "UTF-8"
}
runServer {
minecraftVersion("1.20.5")
minecraftVersion("1.20.6")
val plugins = runPaper.downloadPluginsSpec {
//Vault
url("https://github.com/MilkBowl/Vault/releases/download/1.7.3/Vault.jar")
//EssestialsX
url("https://ci.ender.zone/job/EssentialsX/lastSuccessfulBuild/artifact/jars/EssentialsX-2.21.0-dev+81-cde7184.jar")
//LuckPerms
url("https://ci.lucko.me/job/LuckPerms/lastSuccessfulBuild/artifact/bukkit/loader/build/libs/LuckPerms-Bukkit-5.4.128.jar")
}
downloadPlugins{
downloadPlugins.from(plugins)
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions core/src/main/kotlin/party/morino/mineauth/core/MineAuth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import party.morino.mineauth.core.commands.HelpCommand
import party.morino.mineauth.core.commands.RegisterCommand
import party.morino.mineauth.core.commands.ReloadCommand
import party.morino.mineauth.core.file.load.FileUtils
import party.morino.mineauth.core.integration.IntegrationInitializer
import party.morino.mineauth.core.web.WebServer
import revxrsal.commands.bukkit.BukkitCommandHandler
import revxrsal.commands.ktx.supportSuspendFunctions
Expand All @@ -23,6 +24,7 @@ open class MineAuth: SuspendingJavaPlugin() , MineAuthAPI {
setupKoin()
FileUtils.loadFiles()
FileUtils.settingDatabase()
IntegrationInitializer.initialize()
Bukkit.getScheduler().runTaskAsynchronously(plugin, Runnable {
WebServer.settingServer()
WebServer.startServer()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package party.morino.mineauth.core.integration

interface Integration {
var available: Boolean
val name: String

fun initialize()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package party.morino.mineauth.core.integration

import party.morino.mineauth.core.integration.vault.VaultIntegration

object IntegrationInitializer {
private val integrations = mutableListOf<Integration>()
val availableIntegrations: List<Integration>
get() = integrations.filter { it.available }

fun initialize() {
integrations.add(VaultIntegration)

integrations.forEach {
it.initialize()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package party.morino.mineauth.core.integration.vault

import net.milkbowl.vault.economy.Economy
import org.bukkit.Bukkit.getServer
import party.morino.mineauth.core.integration.Integration


object VaultIntegration : Integration {
override var available: Boolean = false
override val name: String = "Vault"
lateinit var economy : Economy

override fun initialize() {
val plugin = getServer().pluginManager.getPlugin(name)
plugin?.let {
available = true
}
val rsp = getServer().servicesManager.getRegistration(
Economy::class.java
)
if (rsp == null) {
available = false
return
}
economy = rsp.provider
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ object OfflinePlayerSerializer : KSerializer<OfflinePlayer> {
override val descriptor = PrimitiveSerialDescriptor("OfflinePlayer", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): OfflinePlayer {
return Bukkit.getOfflinePlayer(decoder.decodeString().toUUID())
val string = decoder.decodeString()
return if (string.matches(Regex("([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})"))) {
Bukkit.getOfflinePlayer(string.toUUID())
}else{
Bukkit.getOfflinePlayer(string)
}
}

override fun serialize(encoder: Encoder, value: OfflinePlayer) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package party.morino.mineauth.core.web

enum class JwtCompleteCode(val code: String) {
USER_TOKEN("user-oauth-token"),
SERVICE_TOKEN("service-oauth-token")
}
24 changes: 20 additions & 4 deletions core/src/main/kotlin/party/morino/mineauth/core/web/WebServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private fun Application.module() {
10, 1, TimeUnit.MINUTES
).build()
install(Authentication) {
jwt("user-oauth-token") {
jwt(JwtCompleteCode.USER_TOKEN.code) {
realm = jwtConfigData.realm
verifier(jwkProvider, jwtConfigData.issuer) {
acceptLeeway(3)
Expand Down Expand Up @@ -111,7 +111,7 @@ private fun Application.module() {
}
route("/list") {
get {
val list = getRoutes(this@routing).map { it.toString() }
val list = this@routing.getRoutes().map { it.asString() }
call.respond(
list
)
Expand Down Expand Up @@ -142,11 +142,27 @@ private fun Application.module() {
}
}

private fun getRoutes(route: Route): List<Route> {
fun Route.getRoutes(): List<Route> {
val list = mutableListOf<Route>()
val route = this
route.children.forEach {
list.addAll(getRoutes(it))
list.addAll(it.getRoutes())
}
list.add(route)
return list
}

fun Route.asString(): String {
val route = this
val selector = route.selector
return when (val parentRoute = route.parent?.toString()) {
null -> when (selector) {
is TrailingSlashRouteSelector -> "/"
else -> "/$selector"
}
else -> when (selector) {
is TrailingSlashRouteSelector -> if (parentRoute.endsWith('/')) parentRoute else "$parentRoute/"
else -> if (parentRoute.endsWith('/')) "$parentRoute$selector" else "$parentRoute/${selector}"
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package party.morino.mineauth.core.web.data
package party.morino.mineauth.core.web.router.auth.data

import kotlinx.serialization.Serializable
import party.morino.mineauth.core.utils.UUIDSerializer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package party.morino.mineauth.core.web.data
package party.morino.mineauth.core.web.router.auth.data

import kotlinx.serialization.Serializable

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package party.morino.mineauth.core.web.router.auth.data

class OIDCConfigData
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package party.morino.mineauth.core.web.data
package party.morino.mineauth.core.web.router.auth.data

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import party.morino.mineauth.core.database.UserAuthData
import party.morino.mineauth.core.database.UserAuthData.uuid
import party.morino.mineauth.core.file.data.OAuthConfigData
import party.morino.mineauth.core.utils.json
import party.morino.mineauth.core.web.data.AuthorizedData
import party.morino.mineauth.core.web.data.ClientData
import party.morino.mineauth.core.web.router.auth.data.AuthorizedData
import party.morino.mineauth.core.web.router.auth.data.ClientData
import party.morino.mineauth.core.web.router.auth.oauth.OAuthRouter.authorizedData

object AuthorizeRouter: KoinComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package party.morino.mineauth.core.web.router.auth.oauth

import io.ktor.server.routing.*
import org.koin.core.component.KoinComponent
import party.morino.mineauth.core.web.data.AuthorizedData
import party.morino.mineauth.core.web.router.auth.data.AuthorizedData
import party.morino.mineauth.core.web.router.auth.oauth.AuthorizeRouter.authorizeRouter
import party.morino.mineauth.core.web.router.auth.oauth.ProfileRouter.profileRouter
import party.morino.mineauth.core.web.router.auth.oauth.TokenRouter.tokenRouter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.koin.core.component.inject
import party.morino.mineauth.core.MineAuth
import party.morino.mineauth.core.file.data.JWTConfigData
import party.morino.mineauth.core.file.utils.KeyUtils.getKeys
import party.morino.mineauth.core.web.data.TokenData
import party.morino.mineauth.core.web.router.auth.data.TokenData
import party.morino.mineauth.core.web.router.auth.oauth.OAuthRouter.authorizedData
import java.security.MessageDigest
import java.util.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ package party.morino.mineauth.core.web.router.plugin
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import party.morino.mineauth.core.integration.IntegrationInitializer
import party.morino.mineauth.core.integration.vault.VaultIntegration
import party.morino.mineauth.core.web.router.plugin.vault.VaultRouter.vaultRouter

object PluginRouter {
fun Route.pluginRouter() {
get {
call.respondText("Hello, plugin!")
}
vaultRouter()
get("/availableIntegrators") {
call.respond(IntegrationInitializer.availableIntegrations.map { it.name })
}
if (VaultIntegration.available) {
vaultRouter()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@
package party.morino.mineauth.core.web.router.plugin.vault

import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import org.koin.core.component.KoinComponent
import party.morino.mineauth.core.integration.vault.VaultIntegration
import party.morino.mineauth.core.utils.PlayerUtils.toOfflinePlayer
import party.morino.mineauth.core.utils.PlayerUtils.toUUID
import party.morino.mineauth.core.web.JwtCompleteCode
import party.morino.mineauth.core.web.router.plugin.vault.data.RemittanceData

object VaultRouter : KoinComponent {

object VaultRouter {
fun Route.vaultRouter() {
route("/vault") {
get {
this@route
authenticate(JwtCompleteCode.USER_TOKEN.code) {
get("/balance/me") {
val principal = call.principal<JWTPrincipal>()
val uuid = principal!!.payload.getClaim("playerUniqueId").asString()
val offlinePlayer = uuid.toUUID().toOfflinePlayer()
VaultIntegration.economy.getBalance(offlinePlayer).let {
call.respond(it)
}
}
post("/send") {
val principal = call.principal<JWTPrincipal>()
val uuid = principal!!.payload.getClaim("playerUniqueId").asString()
val sender = uuid.toUUID().toOfflinePlayer()
val target = call.receive<RemittanceData>().target
val amount = call.receive<RemittanceData>().amount

val economy = VaultIntegration.economy
if (amount <= 0) {
call.respond(HttpStatusCode.BadRequest,"Invalid amount")
}
if (economy.getBalance(sender) < amount) {
call.respond(HttpStatusCode.BadRequest,"Insufficient balance")
} else {
economy.withdrawPlayer(sender, amount)
economy.depositPlayer(target, amount)
val balance = economy.getBalance(sender)
val targetName = target.name
call.respond("Successfully sent $amount to $targetName. Your balance is $balance")
}}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package party.morino.mineauth.core.web.router.plugin.vault.data

import kotlinx.serialization.Serializable
import org.bukkit.OfflinePlayer
import party.morino.mineauth.core.utils.OfflinePlayerSerializer

@Serializable
data class RemittanceData(
val target : @Serializable(with = OfflinePlayerSerializer::class) OfflinePlayer,
val amount : Double
)
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ exposed-jdbc = { group = "org.jetbrains.exposed", name = "exposed-jdbc", version
exposed-java-time = { group = "org.jetbrains.exposed", name = "exposed-java-time", version.ref = "exposed" }
koin-core = { group = "io.insert-koin", name = "koin-core", version.ref = "koinVersion" }

vault-api = { group = "com.github.MilkBowl", name = "vaultAPI", version = "1.7" }

[plugins]
run-paper = { id = "xyz.jpenilla.run-paper", version = "2.2.3" }
resource-factory = { id = "xyz.jpenilla.resource-factory", version = "1.1.1" }
Expand All @@ -58,4 +60,4 @@ securities = ["password4j", "nimbus-jose-jwt", "bcpkix-jdk18on", "bcprov-jdk18on
coroutines = ["mccoroutine-bukkit-api", "mccoroutine-bukkit-core" , "kotlinx-coroutines-core"]
exposed = ["exposed-core", "exposed-dao", "exposed-jdbc", "exposed-java-time"]
ktor-client = ["ktor-client-core", "ktor-client-java", "ktor-client-logging", "ktor-client-contentNegotiation"]
ktor-server = ["ktor-server-core", "ktor-server-netty", "ktor-server-contentNegotiation", "ktor-serialization-kotlinxJson", "ktor-server-auth", "ktor-server-authJwt", "ktor-network-tlsCertificates", "ktor-server-velocity", "ktor-server-openapi", "logback-classic"]
ktor-server = ["ktor-server-core", "ktor-server-netty", "ktor-server-contentNegotiation", "ktor-serialization-kotlinxJson", "ktor-server-auth", "ktor-server-authJwt", "ktor-network-tlsCertificates", "ktor-server-velocity", "ktor-server-openapi", "logback-classic"]

0 comments on commit 27520e0

Please sign in to comment.