implemented 07-server-mode.md: added server profile with REST API for builds, artifacts, live logs, and control tokens; lifecycle management for watcher; controller and service tests
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
package de.hoennig.gittally.server
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.attribute.PosixFilePermissions
|
||||
import java.security.MessageDigest
|
||||
import java.security.SecureRandom
|
||||
|
||||
/**
|
||||
* Guards the mutating build endpoints with a shared secret, like the legacy cancel
|
||||
* token. The token is generated once and persisted (mode 600) so operators — and
|
||||
* the step-08 UI, server-side — can read it; delete the file to rotate it.
|
||||
*/
|
||||
class ControlTokenService(
|
||||
private val tokenFile: Path,
|
||||
) {
|
||||
@Synchronized
|
||||
fun token(): String {
|
||||
if (Files.isRegularFile(tokenFile)) {
|
||||
Files
|
||||
.readAllLines(tokenFile)
|
||||
.firstOrNull()
|
||||
?.trim()
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?.let { return it }
|
||||
}
|
||||
val token = generateToken()
|
||||
Files.createDirectories(tokenFile.parent)
|
||||
Files.writeString(tokenFile, token + "\n")
|
||||
restrictToOwner(tokenFile)
|
||||
return token
|
||||
}
|
||||
|
||||
/** Constant-time comparison; null or blank never matches. */
|
||||
fun matches(submittedToken: String?): Boolean =
|
||||
!submittedToken.isNullOrBlank() &&
|
||||
MessageDigest.isEqual(submittedToken.toByteArray(), token().toByteArray())
|
||||
|
||||
/** 24 random bytes as hex, like legacy `openssl rand -hex 24`. */
|
||||
private fun generateToken(): String {
|
||||
val bytes = ByteArray(24)
|
||||
SecureRandom().nextBytes(bytes)
|
||||
return bytes.joinToString("") { "%02x".format(it) }
|
||||
}
|
||||
|
||||
private fun restrictToOwner(file: Path) {
|
||||
try {
|
||||
Files.setPosixFilePermissions(file, PosixFilePermissions.fromString("rw-------"))
|
||||
} catch (_: UnsupportedOperationException) {
|
||||
// non-POSIX filesystem; the file stays with default permissions
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user