Add existing WebDAV tokens view
authorLanius Trolling <lanius@laniustrolling.dev>
Mon, 15 Apr 2024 10:25:47 +0000 (06:25 -0400)
committerLanius Trolling <lanius@laniustrolling.dev>
Mon, 15 Apr 2024 10:25:47 +0000 (06:25 -0400)
src/jvmMain/kotlin/info/mechyrdia/auth/WebDav.kt
src/jvmMain/kotlin/info/mechyrdia/data/Data.kt

index 2e952d37128efddf2985950053cdd9d876dc18c0..e7eeb1ee4f9c58c23836f52fa2a6bbfed14c8eb7 100644 (file)
@@ -1,5 +1,6 @@
 package info.mechyrdia.auth
 
+import com.mongodb.client.model.Filters
 import info.mechyrdia.data.*
 import info.mechyrdia.lore.adminPage
 import info.mechyrdia.lore.dateTime
@@ -8,6 +9,7 @@ import info.mechyrdia.route.Root
 import info.mechyrdia.route.href
 import info.mechyrdia.route.installCsrfToken
 import io.ktor.server.application.*
+import kotlinx.coroutines.flow.toList
 import kotlinx.html.*
 import kotlinx.serialization.Serializable
 import java.time.Instant
@@ -23,11 +25,19 @@ data class WebDavToken(
                
                override suspend fun initialize() {
                        Table.index(WebDavToken::holder)
+                       Table.expire(WebDavToken::validUntil)
                }
        }
 }
 
-fun ApplicationCall.adminRequestWebDavToken(): HTML.() -> Unit {
+suspend fun ApplicationCall.adminRequestWebDavToken(): HTML.() -> Unit {
+       val nation = currentNation()
+               ?: redirectHref(Root.Auth.LoginPage(Root.Auth(Root(error = "You must be logged in to request WebDav tokens"))))
+       
+       val existingTokens = WebDavToken.Table
+               .filter(Filters.eq(WebDavToken::holder.serialName, nation.id))
+               .toList()
+       
        return adminPage("Request WebDav Token") {
                div(classes = "message") {
                        div {
@@ -36,6 +46,33 @@ fun ApplicationCall.adminRequestWebDavToken(): HTML.() -> Unit {
                                        installCsrfToken()
                                        submitInput { value = "Request WebDav Token" }
                                }
+                               
+                               if (existingTokens.isNotEmpty()) {
+                                       p {
+                                               +"You already have the following tokens:"
+                                       }
+                                       
+                                       table {
+                                               tr {
+                                                       th { +"Token" }
+                                                       th { +"Expires at" }
+                                               }
+                                               
+                                               for (existingToken in existingTokens) {
+                                                       tr {
+                                                               td {
+                                                                       textInput {
+                                                                               readonly = true
+                                                                               value = existingToken.id.id
+                                                                       }
+                                                               }
+                                                               td {
+                                                                       dateTime(existingToken.validUntil)
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
                        }
                }
        }
index 02a9671934cea29a7c3df4d3ac7b4dc7c2576736..c881da02c4dbe47406aa335f9d7677d3350c68f7 100644 (file)
@@ -6,6 +6,7 @@ import com.mongodb.MongoClientSettings
 import com.mongodb.MongoDriverInformation
 import com.mongodb.client.model.*
 import com.mongodb.kotlin.client.coroutine.MongoDatabase
+import com.mongodb.kotlin.client.coroutine.expireAfter
 import com.mongodb.reactivestreams.client.MongoClients
 import com.mongodb.reactivestreams.client.gridfs.GridFSBucket
 import com.mongodb.reactivestreams.client.gridfs.GridFSBuckets
@@ -27,6 +28,7 @@ import org.bson.codecs.configuration.CodecRegistries
 import org.bson.codecs.kotlinx.KotlinSerializerCodecProvider
 import org.bson.conversions.Bson
 import java.security.SecureRandom
+import java.time.Instant
 import kotlin.reflect.KClass
 import kotlin.reflect.KProperty
 import kotlin.reflect.KProperty1
@@ -115,6 +117,10 @@ class DocumentTable<T : DataDocument<T>>(private val kClass: KClass<T>) {
                collection().createIndex(Indexes.ascending(*properties.map { it.serialName }.toTypedArray()), IndexOptions().unique(true))
        }
        
+       suspend fun expire(property: KProperty1<T, Instant>) {
+               collection().createIndex(Indexes.ascending(property.serialName), IndexOptions().expireAfter(0L))
+       }
+       
        suspend fun indexIf(condition: Bson, vararg properties: KProperty1<T, *>) {
                collection().createIndex(Indexes.ascending(*properties.map { it.serialName }.toTypedArray()), IndexOptions().partialFilterExpression(condition))
        }