133 lines
3.6 KiB
Kotlin
133 lines
3.6 KiB
Kotlin
package dev.solsynth.snConnect.services
|
|
|
|
import kotlinx.datetime.Instant
|
|
import kotlinx.serialization.SerialName
|
|
import kotlinx.serialization.Serializable
|
|
import kotlinx.serialization.json.Json
|
|
import okhttp3.Request
|
|
import java.io.IOException
|
|
|
|
@Serializable
|
|
data class DraslPlayer(
|
|
@SerialName("userUuid")
|
|
val userUuid: String,
|
|
val name: String,
|
|
val uuid: String,
|
|
@SerialName("offlineUuid")
|
|
val offlineUuid: String,
|
|
@SerialName("fallbackPlayer")
|
|
val fallbackPlayer: String,
|
|
@SerialName("skinModel")
|
|
val skinModel: String,
|
|
@SerialName("skinUrl")
|
|
val skinUrl: String?,
|
|
@SerialName("capeUrl")
|
|
val capeUrl: String?,
|
|
@SerialName("createdAt")
|
|
val createdAt: String, // ISO string
|
|
@SerialName("nameLastChangedAt")
|
|
val nameLastChangedAt: String
|
|
)
|
|
|
|
@Serializable
|
|
data class DraslOIDCIdentity(
|
|
@SerialName("userUuid")
|
|
val userUuid: String,
|
|
@SerialName("oidcProviderName")
|
|
val oidcProviderName: String,
|
|
val issuer: String,
|
|
val subject: String
|
|
)
|
|
|
|
@Serializable
|
|
data class DraslUser(
|
|
@SerialName("isAdmin")
|
|
val isAdmin: Boolean,
|
|
@SerialName("isLocked")
|
|
val isLocked: Boolean,
|
|
val uuid: String,
|
|
val username: String,
|
|
@SerialName("preferredLanguage")
|
|
val preferredLanguage: String,
|
|
@SerialName("maxPlayerCount")
|
|
val maxPlayerCount: Int,
|
|
val players: List<DraslPlayer>,
|
|
@SerialName("oidcIdentities")
|
|
val oidcIdentities: List<DraslOIDCIdentity>
|
|
)
|
|
|
|
@Serializable
|
|
data class APILoginRequest(
|
|
val username: String,
|
|
val password: String
|
|
)
|
|
|
|
@Serializable
|
|
data class APILoginResponse(
|
|
val user: DraslUser,
|
|
val token: String,
|
|
@SerialName("expires_at")
|
|
val expiresAt: Instant
|
|
)
|
|
|
|
@Serializable
|
|
data class APIOIDCTokenRequest(
|
|
@SerialName("provider")
|
|
val provider: String,
|
|
val code: String,
|
|
val state: String
|
|
)
|
|
|
|
@Serializable
|
|
data class APIOIDCTokenResponse(
|
|
val user: DraslUser,
|
|
val token: String,
|
|
@SerialName("expires_at")
|
|
val expiresAt: Instant
|
|
)
|
|
|
|
class AuthUserService(private val sn: AuthService) {
|
|
private val json = Json {
|
|
ignoreUnknownKeys = true
|
|
}
|
|
|
|
private fun addAuthHeader(builder: Request.Builder): Request.Builder {
|
|
sn.siteSecret?.let { builder.header("Authorization", "Bearer $it") }
|
|
return builder
|
|
}
|
|
|
|
fun getUser(id: String): DraslUser {
|
|
val requestBuilder = Request.Builder()
|
|
.url(sn.getUrl("/drasl/api/v2/users/$id"))
|
|
.get()
|
|
|
|
sn.client.newCall(addAuthHeader(requestBuilder).build()).execute().use { response ->
|
|
if (!response.isSuccessful) throw IOException("Unexpected code $response")
|
|
val responseBody = response.body!!.string()
|
|
return json.decodeFromString<DraslUser>(responseBody)
|
|
}
|
|
}
|
|
|
|
fun getPlayerByUuid(uuid: String): DraslPlayer {
|
|
val requestBuilder = Request.Builder()
|
|
.url(sn.getUrl("/drasl/api/v2/players/$uuid"))
|
|
.get()
|
|
|
|
sn.client.newCall(addAuthHeader(requestBuilder).build()).execute().use { response ->
|
|
if (!response.isSuccessful) throw IOException("Unexpected code $response")
|
|
val responseBody = response.body!!.string()
|
|
return json.decodeFromString<DraslPlayer>(responseBody)
|
|
}
|
|
}
|
|
|
|
fun getSnByPlayer(playerUuid: String): String? {
|
|
return try {
|
|
val player = getPlayerByUuid(playerUuid)
|
|
val user = getUser(player.userUuid)
|
|
user.oidcIdentities.find { it.oidcProviderName == "Solarpass" }?.subject
|
|
} catch (e: IOException) {
|
|
null
|
|
}
|
|
}
|
|
}
|