aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2019-04-13 19:59:48 +0200
committerMarvin Borner2019-04-13 19:59:48 +0200
commit9e91d7e8cd3a3cdfee7f4d10347f48980eeaae93 (patch)
tree3b6e129153a83a88b9f1f85ae35bfe711bced3c5
parent407cd889cada0154faaa06ff4372e237cf260cf7 (diff)
Added support for multiple roles per user
-rw-r--r--src/main/kotlin/App.kt18
-rw-r--r--src/main/kotlin/DatabaseController.kt26
-rw-r--r--src/main/resources/js/login.js9
-rw-r--r--src/main/resources/views/login.rocker.html3
4 files changed, 40 insertions, 16 deletions
diff --git a/src/main/kotlin/App.kt b/src/main/kotlin/App.kt
index ce964e0..0b8cf47 100644
--- a/src/main/kotlin/App.kt
+++ b/src/main/kotlin/App.kt
@@ -59,6 +59,11 @@ fun main() {
post("/login", { ctx -> login(ctx) }, roles(Roles.GUEST))
/**
+ * Logs the user out
+ */
+ get("/logout", { ctx -> ctx.clearCookieStore() }, roles(Roles.USER))
+
+ /**
* Renders the setup page (only on initial use)
*/
get("/setup", { ctx ->
@@ -75,10 +80,10 @@ fun main() {
post("/setup", { ctx -> setup(ctx) }, roles(Roles.GUEST))
/**
- * Sends a json object of filenames in [fileHome]s
+ * Renders the file list view
* TODO: Fix possible security issue with "../"
*/
- get("/files/*", { ctx -> crawlFiles(ctx) }, roles(Roles.ADMIN))
+ get("/files/*", { ctx -> crawlFiles(ctx) }, roles(Roles.USER))
/**
* Renders the upload rocker template
@@ -89,7 +94,7 @@ fun main() {
* Receives and saves multipart media data
* TODO: Fix possible security issue with "../"
*/
- post("/upload/*", { ctx -> upload(ctx) }, roles(Roles.ADMIN))
+ post("/upload/*", { ctx -> upload(ctx) }, roles(Roles.USER))
}
}
@@ -97,12 +102,11 @@ fun main() {
* Sets up the roles with the database and declares the handling of roles
*/
fun roleManager(handler: Handler, ctx: Context, permittedRoles: Set<Role>) {
- val userRole = databaseController.getRole(getUsername(ctx))
when {
getUsername(ctx) == ctx.cookieStore("username") ?: "username" -> handler.handle(ctx)
- permittedRoles.contains(userRole) -> handler.handle(ctx)
+ databaseController.getRoles(getUsername(ctx)).any { it in permittedRoles } -> handler.handle(ctx)
//ctx.host()!!.contains("localhost") -> handler.handle(ctx) // DEBUG
- else -> ctx.status(401).result("This site isn't available for you.")
+ else -> ctx.status(401).redirect("/login")
}
}
@@ -210,7 +214,7 @@ fun login(ctx: Context) {
}
val nextThreshold = 4f.pow(lastHourAttempts + 1)
- if (lastAttemptDifference > 4f.pow(lastHourAttempts)) {
+ if (lastAttemptDifference > 4f.pow(lastHourAttempts) || lastHourAttempts == 0) {
if (databaseController.checkUser(username, password)) {
ctx.cookieStore("uuid", databaseController.getUUID(username))
ctx.cookieStore("username", username)
diff --git a/src/main/kotlin/DatabaseController.kt b/src/main/kotlin/DatabaseController.kt
index 4788057..8b82093 100644
--- a/src/main/kotlin/DatabaseController.kt
+++ b/src/main/kotlin/DatabaseController.kt
@@ -33,7 +33,6 @@ class DatabaseController(dbFileLocation: String = "main.db") {
/**
* Database table indexing the users with their regarding role (multi line per user)
- * TODO: Add support for multiple roles per user (read, write, edit, etc)
*/
object UserRoles : Table() {
val id = integer("id").autoIncrement().primaryKey()
@@ -166,15 +165,32 @@ class DatabaseController(dbFileLocation: String = "main.db") {
/**
* Returns the corresponding role using [usernameString]
*/
- fun getRole(usernameString: String): Roles {
+ fun getRoles(usernameString: String): List<Roles> {
return transaction {
try {
val userId = UserData.select { UserData.username eq usernameString }.map { it[UserData.id] }[0]
val userRoleId = UserRoles.select { UserRoles.userId eq userId }.map { it[UserRoles.roleId] }[0]
- val userRole = RolesData.select { RolesData.id eq userRoleId }.map { it[RolesData.role] }[0]
- if (userRole == "ADMIN") Roles.ADMIN else Roles.USER
+
+ val userRoles = mutableListOf<Roles>()
+ RolesData.select { RolesData.id eq userRoleId }.map { it[RolesData.role] }.forEach {
+ when (it) {
+ "GUEST" -> {
+ userRoles.add(Roles.GUEST)
+ }
+ "USER" -> {
+ userRoles.add(Roles.GUEST)
+ userRoles.add(Roles.USER)
+ }
+ "ADMIN" -> {
+ userRoles.add(Roles.GUEST)
+ userRoles.add(Roles.USER)
+ userRoles.add(Roles.ADMIN)
+ }
+ }
+ }
+ userRoles
} catch (_: Exception) {
- Roles.GUEST
+ listOf(Roles.GUEST)
}
}
}
diff --git a/src/main/resources/js/login.js b/src/main/resources/js/login.js
index f4e2bce..aa991db 100644
--- a/src/main/resources/js/login.js
+++ b/src/main/resources/js/login.js
@@ -1,7 +1,8 @@
const tryAgain = document.getElementById("tryAgain");
const countdown = document.getElementById("counter");
-setInterval(() => {
- if (Number(countdown.innerText) === 0) tryAgain.style.display = "none";
- countdown.innerText = Number(countdown.innerText) - 1;
-}, 1000);
+if (tryAgain !== null)
+ setInterval(() => {
+ if (Number(countdown.innerText) === 0) tryAgain.style.display = "none";
+ countdown.innerText = Number(countdown.innerText) - 1;
+ }, 1000);
diff --git a/src/main/resources/views/login.rocker.html b/src/main/resources/views/login.rocker.html
index 23a9aff..bcee9df 100644
--- a/src/main/resources/views/login.rocker.html
+++ b/src/main/resources/views/login.rocker.html
@@ -20,6 +20,9 @@
@if(message.length() > 0) {
<small>@message</small>
+ }
+
+ @if(counter > 0) {
<small id="tryAgain">Please try again in <span id="counter">@counter</span> seconds.</small>
}
</form>