Adds proper source/file handling and executing

This commit is contained in:
Daniel Svitan 2025-05-11 18:58:42 +02:00
parent beb37d92f6
commit 957e031073
7 changed files with 57 additions and 27 deletions

View File

@ -1,8 +1,8 @@
package dev.svitan.plugins package dev.svitan.plugins
import dev.svitan.routes.ExecutorService import dev.svitan.services.ExecutorService
import dev.svitan.schemas.ActionService import dev.svitan.services.ActionService
import dev.svitan.schemas.AuthService import dev.svitan.services.AuthService
import io.github.cdimascio.dotenv.Dotenv import io.github.cdimascio.dotenv.Dotenv
import io.ktor.server.application.* import io.ktor.server.application.*
import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.Database

View File

@ -20,6 +20,10 @@ fun Application.configureRouting() {
get("/") { get("/") {
call.respond("Hello World!") call.respond("Hello World!")
} }
get("/health") {
call.respond("OK")
}
} }
routeAuth() routeAuth()

View File

@ -1,10 +1,12 @@
package dev.svitan.routes package dev.svitan.routes
import dev.svitan.plugins.AuthorizationException import dev.svitan.plugins.AuthorizationException
import dev.svitan.schemas.ActionService import dev.svitan.services.ActionKind
import dev.svitan.schemas.AuthService import dev.svitan.services.ActionService
import dev.svitan.schemas.NewActionDTO import dev.svitan.services.AuthService
import dev.svitan.schemas.RunActionDTO import dev.svitan.services.ExecutorService
import dev.svitan.services.NewActionDTO
import dev.svitan.services.RunActionDTO
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@ -39,13 +41,17 @@ fun Application.routeAction() {
val action = ActionService.read(id) ?: throw NotFoundException() val action = ActionService.read(id) ?: throw NotFoundException()
val run = call.receive<RunActionDTO>() val run = call.receive<RunActionDTO>()
val auth = AuthService.validate( AuthService.validate(
UUID.fromString(action.authId), UUID.fromString(action.authId),
run.pin, run.pin,
run.key run.key
) ?: throw AuthorizationException("Invalid pin or key") ) ?: throw AuthorizationException("Invalid pin or key")
// TODO: run the action if (action.kind == ActionKind.TEXT) {
ExecutorService.executeSource(id, action.source)
} else {
ExecutorService.executeFile(id)
}
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} }

View File

@ -1,7 +1,7 @@
package dev.svitan.routes package dev.svitan.routes
import dev.svitan.schemas.AuthService import dev.svitan.services.AuthService
import dev.svitan.schemas.NewAuthDTO import dev.svitan.services.NewAuthDTO
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.server.application.Application import io.ktor.server.application.Application
import io.ktor.server.auth.authentication import io.ktor.server.auth.authentication

View File

@ -1,4 +1,4 @@
package dev.svitan.schemas package dev.svitan.services
import io.ktor.server.plugins.NotFoundException import io.ktor.server.plugins.NotFoundException
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -49,7 +49,7 @@ class NewActionDTO(
@Serializable @Serializable
class RunActionDTO( class RunActionDTO(
val pin: String, val pin: String,
val key: String val key: String
) )
class ActionService { class ActionService {
@ -72,19 +72,26 @@ class ActionService {
} }
} }
fun create(action: NewActionDTO): UUID = transaction { fun create(action: NewActionDTO): UUID {
val now = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) val id = transaction {
val authId = UUID.fromString(action.authId) val now = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
AuthService.read(authId) ?: throw NotFoundException("auth not found") val authId = UUID.fromString(action.authId)
AuthService.read(authId) ?: throw NotFoundException("auth not found")
Actions.insert { Actions.insert {
it[name] = action.name it[name] = action.name
it[kind] = ActionKind.from(action.kind).toString() it[kind] = ActionKind.from(action.kind).toString()
it[aSource] = action.source it[aSource] = if (action.kind == ActionKind.SCRIPT.toString()) "" else action.source
it[auth] = authId it[auth] = authId
it[createdAt] = now it[createdAt] = now
it[updatedAt] = now it[updatedAt] = now
}[Actions.id] }[Actions.id]
}
if (action.kind == ActionKind.SCRIPT.toString()) {
ExecutorService.writeFile(id, action.source)
}
return id
} }
fun read(id: UUID): ActionDTO? = transaction { fun read(id: UUID): ActionDTO? = transaction {
@ -118,6 +125,8 @@ class ActionService {
} }
fun update(id: UUID, action: NewActionDTO) { fun update(id: UUID, action: NewActionDTO) {
val oldAction = read(id) ?: throw NotFoundException("action not found")
transaction { transaction {
val now = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) val now = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
Actions.update({ Actions.id eq id }) { Actions.update({ Actions.id eq id }) {
@ -127,12 +136,23 @@ class ActionService {
it[updatedAt] = now it[updatedAt] = now
} }
} }
if (action.kind == ActionKind.SCRIPT.toString()) {
ExecutorService.writeFile(id, action.source)
} else if (oldAction.kind == ActionKind.SCRIPT) {
ExecutorService.deleteFile(id)
}
} }
fun delete(id: UUID) { fun delete(id: UUID) {
val action = read(id) ?: throw NotFoundException("action not found")
transaction { transaction {
Actions.deleteWhere { Actions.id eq id } Actions.deleteWhere { Actions.id eq id }
} }
if (action.kind == ActionKind.SCRIPT) {
ExecutorService.deleteFile(id)
}
} }
} }
} }

View File

@ -1,4 +1,4 @@
package dev.svitan.schemas package dev.svitan.services
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*

View File

@ -1,4 +1,4 @@
package dev.svitan.routes package dev.svitan.services
import io.github.cdimascio.dotenv.Dotenv import io.github.cdimascio.dotenv.Dotenv
import java.io.File import java.io.File