Remove debug headers and return 403 on access denied
All checks were successful
build-and-deploy / build-deploy (push) Successful in 26s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 26s
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
package com.android.trisolarisserver.config
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver
|
||||
import org.springframework.web.servlet.ModelAndView
|
||||
|
||||
@Component
|
||||
class DebugExceptionResolver : HandlerExceptionResolver {
|
||||
override fun resolveException(
|
||||
request: HttpServletRequest,
|
||||
response: HttpServletResponse,
|
||||
handler: Any?,
|
||||
ex: Exception
|
||||
): ModelAndView? {
|
||||
if (request.getHeader("X-Debug-Auth") == "1" && !response.isCommitted) {
|
||||
val msg = ex.message?.take(200) ?: ""
|
||||
response.setHeader("X-Exception", "${ex::class.java.simpleName}:$msg")
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import org.springframework.web.bind.annotation.ResponseStatus
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.server.ResponseStatusException
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneId
|
||||
import java.util.UUID
|
||||
@@ -165,76 +164,34 @@ class Rooms(
|
||||
fun createRoom(
|
||||
@PathVariable propertyId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?,
|
||||
response: HttpServletResponse,
|
||||
@org.springframework.web.bind.annotation.RequestHeader(value = "X-Debug-Auth", required = false)
|
||||
debugAuth: String?,
|
||||
@RequestBody request: RoomUpsertRequest
|
||||
): RoomResponse {
|
||||
if (debugAuth == "1") {
|
||||
response.setHeader("X-Principal-Present", (principal != null).toString())
|
||||
response.setHeader("X-Principal-Id", principal?.userId?.toString() ?: "none")
|
||||
response.setHeader("X-Room-Create-Step", "start")
|
||||
}
|
||||
requirePrincipal(principal)
|
||||
try {
|
||||
propertyAccess.requireMember(propertyId, principal!!.userId)
|
||||
} catch (ex: Exception) {
|
||||
if (debugAuth == "1") {
|
||||
val msg = ex.message?.take(200) ?: ""
|
||||
response.setHeader("X-Member-Check", "${ex::class.java.simpleName}:$msg")
|
||||
}
|
||||
throw ex
|
||||
}
|
||||
if (debugAuth == "1") {
|
||||
response.setHeader("X-Room-Create-Step", "member_ok")
|
||||
propertyAccess.requireMember(propertyId, principal!!.userId)
|
||||
|
||||
if (roomRepo.existsByPropertyIdAndRoomNumber(propertyId, request.roomNumber)) {
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Room number already exists for property")
|
||||
}
|
||||
|
||||
try {
|
||||
if (debugAuth == "1") {
|
||||
response.setHeader("X-Room-Create-Step", "check_duplicate")
|
||||
}
|
||||
if (roomRepo.existsByPropertyIdAndRoomNumber(propertyId, request.roomNumber)) {
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Room number already exists for property")
|
||||
}
|
||||
|
||||
if (debugAuth == "1") {
|
||||
response.setHeader("X-Room-Create-Step", "load_property")
|
||||
}
|
||||
val property = propertyRepo.findById(propertyId).orElseThrow {
|
||||
ResponseStatusException(HttpStatus.NOT_FOUND, "Property not found")
|
||||
}
|
||||
if (debugAuth == "1") {
|
||||
response.setHeader("X-Room-Create-Step", "resolve_room_type")
|
||||
}
|
||||
val roomType = resolveRoomType(propertyId, request)
|
||||
|
||||
val room = Room(
|
||||
property = property,
|
||||
roomType = roomType,
|
||||
roomNumber = request.roomNumber,
|
||||
floor = request.floor,
|
||||
hasNfc = request.hasNfc,
|
||||
active = request.active,
|
||||
maintenance = request.maintenance,
|
||||
notes = request.notes
|
||||
)
|
||||
|
||||
if (debugAuth == "1") {
|
||||
response.setHeader("X-Room-Create-Step", "save_room")
|
||||
}
|
||||
val saved = roomRepo.save(room).toRoomResponse()
|
||||
if (debugAuth == "1") {
|
||||
response.setHeader("X-Room-Create-Step", "saved")
|
||||
}
|
||||
roomBoardEvents.emit(propertyId)
|
||||
return saved
|
||||
} catch (ex: Exception) {
|
||||
if (debugAuth == "1") {
|
||||
val msg = ex.message?.take(200) ?: ""
|
||||
response.setHeader("X-Room-Create-Exception", "${ex::class.java.simpleName}:$msg")
|
||||
}
|
||||
throw ex
|
||||
val property = propertyRepo.findById(propertyId).orElseThrow {
|
||||
ResponseStatusException(HttpStatus.NOT_FOUND, "Property not found")
|
||||
}
|
||||
val roomType = resolveRoomType(propertyId, request)
|
||||
|
||||
val room = Room(
|
||||
property = property,
|
||||
roomType = roomType,
|
||||
roomNumber = request.roomNumber,
|
||||
floor = request.floor,
|
||||
hasNfc = request.hasNfc,
|
||||
active = request.active,
|
||||
maintenance = request.maintenance,
|
||||
notes = request.notes
|
||||
)
|
||||
|
||||
val saved = roomRepo.save(room).toRoomResponse()
|
||||
roomBoardEvents.emit(propertyId)
|
||||
return saved
|
||||
}
|
||||
|
||||
@PutMapping("/{roomId}")
|
||||
|
||||
@@ -30,17 +30,9 @@ class FirebaseAuthFilter(
|
||||
response: HttpServletResponse,
|
||||
filterChain: FilterChain
|
||||
) {
|
||||
val debug = request.getHeader("X-Debug-Auth") == "1"
|
||||
fun setDebug(value: String) {
|
||||
if (debug) {
|
||||
response.setHeader("X-Auth-Debug", value)
|
||||
logger.info("Auth debug: {} {} -> {}", request.method, request.requestURI, value)
|
||||
}
|
||||
}
|
||||
val header = request.getHeader(HttpHeaders.AUTHORIZATION)
|
||||
if (header.isNullOrBlank() || !header.startsWith("Bearer ")) {
|
||||
logger.debug("Auth missing/invalid header for {}", request.requestURI)
|
||||
setDebug(if (header.isNullOrBlank()) "missing_authorization" else "invalid_authorization")
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing Authorization token")
|
||||
return
|
||||
}
|
||||
@@ -49,10 +41,7 @@ class FirebaseAuthFilter(
|
||||
val decoded = FirebaseAuth.getInstance().verifyIdToken(token)
|
||||
val firebaseUid = decoded.uid
|
||||
val user = appUserRepo.findByFirebaseUid(firebaseUid)
|
||||
?: run {
|
||||
setDebug("user_not_found")
|
||||
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "User not found")
|
||||
}
|
||||
?: throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "User not found")
|
||||
logger.debug("Auth verified uid={}, userId={}", firebaseUid, user.id)
|
||||
|
||||
val principal = MyPrincipal(
|
||||
@@ -61,19 +50,9 @@ class FirebaseAuthFilter(
|
||||
)
|
||||
val auth = UsernamePasswordAuthenticationToken(principal, token, emptyList())
|
||||
SecurityContextHolder.getContext().authentication = auth
|
||||
setDebug("ok:userId=${principal.userId},superAdmin=${user.superAdmin}")
|
||||
try {
|
||||
filterChain.doFilter(request, response)
|
||||
} catch (ex: Exception) {
|
||||
if (debug) {
|
||||
val msg = ex.message?.take(200) ?: ""
|
||||
response.setHeader("X-Downstream-Exception", "${ex::class.java.simpleName}:$msg")
|
||||
}
|
||||
throw ex
|
||||
}
|
||||
filterChain.doFilter(request, response)
|
||||
} catch (ex: Exception) {
|
||||
logger.debug("Auth failed for {}: {}", request.requestURI, ex.message)
|
||||
setDebug("verify_failed")
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,8 @@ class SecurityConfig(
|
||||
}
|
||||
.exceptionHandling {
|
||||
it.authenticationEntryPoint(HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
|
||||
it.accessDeniedHandler { request, response, ex ->
|
||||
if (request.getHeader("X-Debug-Auth") == "1") {
|
||||
val msg = ex.message?.take(200) ?: "access_denied"
|
||||
response.setHeader("X-Access-Debug", msg)
|
||||
}
|
||||
response.sendError(HttpStatus.UNAUTHORIZED.value(), "Unauthorized")
|
||||
it.accessDeniedHandler { _, response, _ ->
|
||||
response.sendError(HttpStatus.FORBIDDEN.value(), "Forbidden")
|
||||
}
|
||||
}
|
||||
.httpBasic { it.disable() }
|
||||
|
||||
Reference in New Issue
Block a user