* Improves document display
* Adds Roles * Adds Role based auth
This commit is contained in:
parent
aa940cc42a
commit
68cbb94977
9 changed files with 114 additions and 24 deletions
|
@ -1,8 +1,11 @@
|
|||
package net.h34t.filemure
|
||||
|
||||
import io.javalin.Javalin
|
||||
import io.javalin.http.UnauthorizedResponse
|
||||
import net.h34t.filemure.controller.*
|
||||
import net.h34t.filemure.repository.SqliteRepository
|
||||
import net.h34t.filemure.tpl.Frame
|
||||
import net.h34t.filemure.tpl.Unauthorized
|
||||
|
||||
class FilemureApp(repository: SqliteRepository) {
|
||||
|
||||
|
@ -16,20 +19,36 @@ class FilemureApp(repository: SqliteRepository) {
|
|||
private val documentController = DocumentController(modifiers, repository)
|
||||
|
||||
fun register(server: Javalin) {
|
||||
server.get("/") { ctx ->
|
||||
if (ctx.getSession() != null) {
|
||||
overviewController.overview(ctx)
|
||||
} else {
|
||||
server.beforeMatched { ctx ->
|
||||
val userRole = getUserRole(ctx)
|
||||
if (!ctx.routeRoles().contains(userRole)) {
|
||||
ctx.redirectPRG("/login")
|
||||
throw UnauthorizedResponse()
|
||||
}
|
||||
}
|
||||
server.get("/login", loginPageController::formLogin)
|
||||
server.post("/login", loginPageController::doLogin)
|
||||
server.post("/logout", loginPageController::doLogout)
|
||||
|
||||
server.post("/upload", uploadController::upload)
|
||||
server.get("/limbo", limboController::formLimbo)
|
||||
server.get("/document/new", documentController::createDocumentForm)
|
||||
server.post("/document/new", documentController::createDocument)
|
||||
server.get("/", overviewController::overview, Role.USER)
|
||||
server.get("/login", loginPageController::formLogin, Role.ANON, Role.USER)
|
||||
server.post("/login", loginPageController::doLogin, Role.ANON, Role.USER)
|
||||
server.post("/logout", loginPageController::doLogout, Role.USER)
|
||||
|
||||
server.post("/upload", uploadController::upload, Role.USER)
|
||||
server.get("/limbo", limboController::formLimbo, Role.USER)
|
||||
|
||||
server.get("/document/new", documentController::createDocumentForm, Role.USER)
|
||||
server.post("/document/new", documentController::createDocument, Role.USER)
|
||||
server.get("/document/{extId}", documentController::documentDetail, Role.USER)
|
||||
|
||||
|
||||
server.exception(UnauthorizedResponse::class.java) { e, ctx ->
|
||||
ctx.tempolin(
|
||||
Frame(
|
||||
modifiers = modifiers,
|
||||
title = "unauthorized",
|
||||
isTarget = false,
|
||||
content = Unauthorized()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
18
app/src/main/kotlin/net/h34t/filemure/Role.kt
Normal file
18
app/src/main/kotlin/net/h34t/filemure/Role.kt
Normal file
|
@ -0,0 +1,18 @@
|
|||
package net.h34t.filemure
|
||||
|
||||
import io.javalin.http.Context
|
||||
import io.javalin.security.RouteRole
|
||||
|
||||
enum class Role : RouteRole {
|
||||
ANON, USER, ADMIN
|
||||
}
|
||||
|
||||
fun getUserRole(ctx: Context): Role {
|
||||
val session = ctx.getSession()
|
||||
|
||||
return if (session == null) {
|
||||
Role.ANON
|
||||
} else {
|
||||
Role.USER
|
||||
}
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
package net.h34t.filemure
|
||||
|
||||
import net.h34t.filemure.tpl.Frame
|
||||
import net.h34t.filemure.tpl.Limbo
|
||||
import net.h34t.filemure.tpl.NewDocumentForm
|
||||
import net.h34t.filemure.tpl.*
|
||||
import org.apache.commons.text.StringEscapeUtils
|
||||
import java.net.URLEncoder
|
||||
|
||||
class TemplateModifiers : Frame.Modifiers, Limbo.Modifiers, NewDocumentForm.Modifiers {
|
||||
class TemplateModifiers : Frame.Modifiers, Limbo.Modifiers, NewDocumentForm.Modifiers, Overview.Modifiers,
|
||||
Document.Modifiers {
|
||||
|
||||
fun hashPrefix(arg: String): String {
|
||||
return URLEncoder.encode(arg, Charsets.UTF_8)
|
||||
|
|
|
@ -5,6 +5,7 @@ import io.javalin.http.Context
|
|||
import io.javalin.http.ForbiddenResponse
|
||||
import net.h34t.filemure.*
|
||||
import net.h34t.filemure.repository.SqliteRepository
|
||||
import net.h34t.filemure.tpl.Document
|
||||
import net.h34t.filemure.tpl.Frame
|
||||
import net.h34t.filemure.tpl.NewDocumentForm
|
||||
import java.io.File
|
||||
|
@ -21,6 +22,31 @@ class DocumentController(val modifiers: TemplateModifiers, val repository: Sqlit
|
|||
val session = ctx.requireSession()
|
||||
val extId = ctx.pathParam("extId")
|
||||
|
||||
val document = repository.getDocumentByExtId(accountId = session.id, extId = extId)
|
||||
|
||||
ctx.tempolin(
|
||||
Frame(
|
||||
modifiers = modifiers,
|
||||
title = document.title,
|
||||
isTarget = true,
|
||||
content = Document(
|
||||
modifiers = modifiers,
|
||||
title = document.title,
|
||||
referenceDate = dtf.format(document.referenceDate),
|
||||
tags = { document.tags.map { TagsBlock(tag = it.value) }.asSequence() },
|
||||
description = document.description,
|
||||
files = {
|
||||
document.files.map { file ->
|
||||
FilesBlock(
|
||||
extId = file.extId,
|
||||
filename = file.filename,
|
||||
contentType = file.contentType ?: "?"
|
||||
)
|
||||
}.asSequence()
|
||||
},
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -7,21 +7,37 @@ import net.h34t.filemure.requireSession
|
|||
import net.h34t.filemure.tempolin
|
||||
import net.h34t.filemure.tpl.Frame
|
||||
import net.h34t.filemure.tpl.Overview
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.FormatStyle
|
||||
|
||||
class OverviewController(val modifiers: TemplateModifiers, val repository: SqliteRepository) {
|
||||
|
||||
val dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)
|
||||
|
||||
fun overview(ctx: Context) {
|
||||
val session = ctx.requireSession()
|
||||
|
||||
val limboFileCount = repository.getLimboFileCount(accountId = session.id)
|
||||
|
||||
val documents = repository.getDocuments(accountId = session.id)
|
||||
|
||||
ctx.tempolin(
|
||||
Frame(
|
||||
modifiers = modifiers,
|
||||
title = "Filemure Overview",
|
||||
isTarget = true,
|
||||
content = Overview(
|
||||
limboFileCount = limboFileCount.toString()
|
||||
modifiers = modifiers,
|
||||
limboFileCount = limboFileCount.toString(),
|
||||
document = {
|
||||
documents.map { document ->
|
||||
DocumentBlock(
|
||||
extId = document.extId,
|
||||
referenceDate = dtf.format(document.referenceDate),
|
||||
title = document.title.ifBlank { "untitled" },
|
||||
)
|
||||
}.asSequence()
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<h1>{*$title}</h1>
|
||||
|
||||
<p>Date: {*$referenceDate}"></p>
|
||||
<p>Date: {*$referenceDate}</p>
|
||||
|
||||
<p>Tags: <span id="tags">{for $tags}<span>{*$tag}</span>{/for}</span></p>
|
||||
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
<h1>Hello to Filemure</h1>
|
||||
|
||||
Files in <a href="/limbo">limbo: {$limboFileCount}</a>.
|
||||
<p>Files in <a href="/limbo">limbo: {$limboFileCount}</a>.</p>
|
||||
|
||||
<table>
|
||||
{for $document}
|
||||
<tr>
|
||||
<td>{*$referenceDate}</td>
|
||||
<td>{*$title}</td>
|
||||
<td><a href="/document/{*$extId}">details</a></td>
|
||||
</tr>
|
||||
{/for}
|
||||
</table>
|
|
@ -0,0 +1,3 @@
|
|||
<h1>Unauthorized</h1>
|
||||
|
||||
<p><a href="/login">Please log in</a>.</p>
|
|
@ -1,7 +1,6 @@
|
|||
package net.h34t.filemure.core.entity
|
||||
|
||||
import java.time.LocalDateTime
|
||||
import java.util.*
|
||||
|
||||
class Document(
|
||||
val id: Long,
|
||||
|
@ -11,7 +10,7 @@ class Document(
|
|||
val tags: List<Tag>,
|
||||
val created: LocalDateTime,
|
||||
val referenceDate: LocalDateTime,
|
||||
val files: List<DocFile>,
|
||||
val files: List<FileRef>,
|
||||
)
|
||||
|
||||
@JvmInline
|
||||
|
@ -25,10 +24,11 @@ value class MimeType(val value: String) {
|
|||
}
|
||||
}
|
||||
|
||||
data class DocFile(
|
||||
val id: UUID,
|
||||
data class FileRef(
|
||||
val id: Long,
|
||||
val extId: String,
|
||||
val filename: String,
|
||||
val mimeType: MimeType,
|
||||
val contentType: String?,
|
||||
val created: LocalDateTime,
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue