change authentication modes

master
Josha von Gizycki 3 days ago
parent 389a999e8a
commit 7262692764

@ -2,11 +2,11 @@ package alfred.web.http
import alfred.web.core.Handles import alfred.web.core.Handles
import alfred.web.core.build.BuildId import alfred.web.core.build.BuildId
import jakarta.servlet.http.HttpServletRequest
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
@RestController @RestController
@ -23,9 +23,8 @@ class BuildsInfo(
fun info( fun info(
@PathVariable("build") @PathVariable("build")
build: BuildId, build: BuildId,
@RequestParam("key") req: HttpServletRequest
key: String? ) = security.requireAuth(build, req) {
) = security.requireKey(build, key) {
it it
} }
@ -36,9 +35,8 @@ class BuildsInfo(
fun handles( fun handles(
@PathVariable("build") @PathVariable("build")
build: BuildId, build: BuildId,
@RequestParam("key") req: HttpServletRequest
key: String? ) = security.requireAuth(build, req) {
) = security.requireKey(build, key) {
handles.active(build) handles.active(build)
} }

@ -4,6 +4,7 @@ import alfred.web.core.build.BuildId
import alfred.web.core.build.Builds import alfred.web.core.build.Builds
import alfred.web.core.runner.GitRunner import alfred.web.core.runner.GitRunner
import alfred.web.core.runner.ScriptRunner import alfred.web.core.runner.ScriptRunner
import jakarta.servlet.http.HttpServletRequest
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
@ -30,15 +31,12 @@ class HttpTrigger(
fun triggerGit( fun triggerGit(
@PathVariable("build") @PathVariable("build")
build: BuildId, build: BuildId,
@RequestParam("key")
key: String?,
@RequestParam("rev") @RequestParam("rev")
rev: String rev: String,
) = security.requireKey(build, key) { req: HttpServletRequest
) = security.requireAuth(build, req) {
val config = builds.buildConfig(build) val config = builds.buildConfig(build)
if (config.gitRepo == null) { config.gitRepo ?: throw UnsupportedMode()
throw UnsupportedMode()
}
val info = gitRunner.run(build, rev) val info = gitRunner.run(build, rev)
@ -57,15 +55,12 @@ class HttpTrigger(
fun triggerScript( fun triggerScript(
@PathVariable("build") @PathVariable("build")
build: BuildId, build: BuildId,
@RequestParam("key")
key: String?,
@RequestParam("rev") @RequestParam("rev")
rev: String? rev: String?,
) = security.requireKey(build, key) { req: HttpServletRequest
) = security.requireAuth(build, req) {
val config = builds.buildConfig(build) val config = builds.buildConfig(build)
if (config.script == null) { config.script ?: throw UnsupportedMode()
throw UnsupportedMode()
}
val info = scriptRunner.run(build, rev) val info = scriptRunner.run(build, rev)

@ -3,19 +3,37 @@ package alfred.web.http
import alfred.web.core.build.BuildConfig import alfred.web.core.build.BuildConfig
import alfred.web.core.build.BuildId import alfred.web.core.build.BuildId
import alfred.web.core.build.Builds import alfred.web.core.build.Builds
import jakarta.servlet.http.HttpServletRequest
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import java.util.Base64
@Service @Service
class Security( class Security(
val builds: Builds val builds: Builds
) { ) {
fun <T> requireKey(build: BuildId, apikey: String?, block: (BuildConfig) -> T): ResponseEntity<*> { private val unauthorized = ResponseEntity<Any>(
HttpHeaders().also {
it.add(HttpHeaders.WWW_AUTHENTICATE, "Bearer")
it.add(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Alfred\"")
},
HttpStatus.UNAUTHORIZED
)
fun <T> requireAuth(
build: BuildId,
request: HttpServletRequest,
block: (BuildConfig) -> T
): ResponseEntity<*> {
val auth = request.getHeader("Authorization") ?: return unauthorized
val token = bearerToken(auth) ?: basicAuthToken(auth) ?: return unauthorized
val buildConfig = builds.buildConfig(build) val buildConfig = builds.buildConfig(build)
if (buildConfig.apikey != "" && buildConfig.apikey != apikey) { if (buildConfig.apikey != "" && buildConfig.apikey != token) {
return ResponseEntity<T>(HttpStatus.UNAUTHORIZED) return unauthorized
} }
val entity = block(buildConfig) val entity = block(buildConfig)
@ -26,4 +44,21 @@ class Security(
return ResponseEntity.ok(entity) return ResponseEntity.ok(entity)
} }
private fun bearerToken(authHeader: String): String? {
return if (authHeader.startsWith("Bearer ")) {
authHeader.substring(7)
} else {
null
}
}
private fun basicAuthToken(authHeader: String): String? {
return if (authHeader.startsWith("Basic ")) {
String(Base64.getDecoder().decode(authHeader.substring(6)))
.split(":")[1]
} else {
null
}
}
} }

Loading…
Cancel
Save