From 6b2d7dfa03ca6ac1fc546972b971a91cb7c60a3a Mon Sep 17 00:00:00 2001 From: william Date: Fri, 13 May 2022 23:01:46 -0400 Subject: [PATCH] #30 Add endpoint to get current group token --- .../config/security/SecurityConfig.kt | 2 +- .../filters/GroupTokenAuthenticationFilter.kt | 14 ++++---------- .../logic/account/GroupTokenLogic.kt | 18 ++++++++++++++++-- .../rest/account/GroupTokenController.kt | 8 ++++++++ 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/security/SecurityConfig.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/security/SecurityConfig.kt index fdb2984..12661ad 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/security/SecurityConfig.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/security/SecurityConfig.kt @@ -88,7 +88,7 @@ abstract class BaseSecurityConfig( .and() .csrf().disable() .addFilterBefore( - GroupTokenAuthenticationFilter(jwtLogic, securityProperties, authManager), + GroupTokenAuthenticationFilter(jwtLogic, securityProperties, groupTokenLogic, authManager), BasicAuthenticationFilter::class.java ) .addFilterBefore( diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/security/filters/GroupTokenAuthenticationFilter.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/security/filters/GroupTokenAuthenticationFilter.kt index d2c7601..f114d8a 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/security/filters/GroupTokenAuthenticationFilter.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/config/security/filters/GroupTokenAuthenticationFilter.kt @@ -4,27 +4,24 @@ import dev.fyloz.colorrecipesexplorer.Constants import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties import dev.fyloz.colorrecipesexplorer.config.security.GroupAuthenticationToken import dev.fyloz.colorrecipesexplorer.dtos.account.UserDetails +import dev.fyloz.colorrecipesexplorer.logic.account.GroupTokenLogic import dev.fyloz.colorrecipesexplorer.logic.account.JwtLogic -import dev.fyloz.colorrecipesexplorer.utils.parseBearer import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.authentication.BadCredentialsException import org.springframework.security.core.Authentication -import org.springframework.web.util.WebUtils import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse class GroupTokenAuthenticationFilter( jwtLogic: JwtLogic, securityProperties: CreSecurityProperties, + private val groupTokenLogic: GroupTokenLogic, private val authManager: AuthenticationManager ) : JwtAuthenticationFilter(Constants.ControllerPaths.GROUP_LOGIN, securityProperties, jwtLogic) { override fun attemptAuthentication(request: HttpServletRequest, response: HttpServletResponse): Authentication { - val groupTokenCookie = getGroupTokenCookie(request) + val groupTokenId = groupTokenLogic.getIdForRequest(request) ?: throw BadCredentialsException("Required group token cookie was not present") - val jwt = parseBearer(groupTokenCookie.value) - val groupTokenId = jwtLogic.parseGroupTokenIdJwt(jwt) - logger.debug("Login attempt for group token $groupTokenId") return authManager.authenticate(GroupAuthenticationToken(groupTokenId)) } @@ -32,7 +29,4 @@ class GroupTokenAuthenticationFilter( override fun afterSuccessfulAuthentication(userDetails: UserDetails) { logger.info("Successful login for group id '${userDetails.group!!.id}' using token '${userDetails.id}' (${userDetails.username})") } - - private fun getGroupTokenCookie(request: HttpServletRequest) = - WebUtils.getCookie(request, Constants.CookieNames.GROUP_TOKEN) -} \ No newline at end of file +} diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/logic/account/GroupTokenLogic.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/logic/account/GroupTokenLogic.kt index 3350224..a3b96d9 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/logic/account/GroupTokenLogic.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/logic/account/GroupTokenLogic.kt @@ -8,15 +8,18 @@ import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException import dev.fyloz.colorrecipesexplorer.exception.NotFoundException import dev.fyloz.colorrecipesexplorer.logic.BaseLogic import dev.fyloz.colorrecipesexplorer.service.account.GroupTokenService +import dev.fyloz.colorrecipesexplorer.utils.parseBearer +import org.springframework.web.util.WebUtils import java.util.* import javax.annotation.PostConstruct -import kotlin.collections.HashSet +import javax.servlet.http.HttpServletRequest interface GroupTokenLogic { fun isDisabled(id: String): Boolean fun getAll(): Collection fun getById(id: String): GroupTokenDto fun getById(id: UUID): GroupTokenDto + fun getIdForRequest(request: HttpServletRequest): UUID? fun save(dto: GroupTokenSaveDto): GroupTokenDto fun enable(id: String): GroupTokenDto fun disable(id: String): GroupTokenDto @@ -27,6 +30,7 @@ interface GroupTokenLogic { class DefaultGroupTokenLogic( private val service: GroupTokenService, private val groupLogic: GroupLogic, + private val jwtLogic: JwtLogic, private val enabledTokensCache: HashSet = hashSetOf() // In constructor for unit testing ) : GroupTokenLogic { @@ -42,9 +46,16 @@ class DefaultGroupTokenLogic( override fun isDisabled(id: String) = !enabledTokensCache.contains(id) override fun getAll() = service.getAll() override fun getById(id: String) = getById(UUID.fromString(id)) - override fun getById(id: UUID) = service.getById(id) ?: throw notFoundException(value = id) + override fun getIdForRequest(request: HttpServletRequest): UUID? { + val groupTokenCookie = getGroupTokenCookie(request) + ?: return null + + val jwt = parseBearer(groupTokenCookie.value) + return jwtLogic.parseGroupTokenIdJwt(jwt) + } + override fun save(dto: GroupTokenSaveDto): GroupTokenDto { throwIfNameAlreadyExists(dto.name) @@ -89,6 +100,9 @@ class DefaultGroupTokenLogic( } } + private fun getGroupTokenCookie(request: HttpServletRequest) = + WebUtils.getCookie(request, Constants.CookieNames.GROUP_TOKEN) + private fun notFoundException(identifierName: String = BaseLogic.ID_IDENTIFIER_NAME, value: Any) = NotFoundException( typeNameLowerCase, diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/account/GroupTokenController.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/account/GroupTokenController.kt index 57d3811..c8221b6 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/account/GroupTokenController.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/account/GroupTokenController.kt @@ -11,7 +11,9 @@ import dev.fyloz.colorrecipesexplorer.rest.noContent import dev.fyloz.colorrecipesexplorer.rest.ok import dev.fyloz.colorrecipesexplorer.utils.addCookie import org.springframework.context.annotation.Profile +import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* +import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse import javax.validation.Valid @@ -25,6 +27,12 @@ class GroupTokenController( @GetMapping fun getAll() = ok(groupTokenLogic.getAll()) + @GetMapping("current") + fun getCurrent(request: HttpServletRequest): ResponseEntity { + val id = groupTokenLogic.getIdForRequest(request) ?: return ok(null) + return ok(groupTokenLogic.getById(id)) + } + @GetMapping("{id}") fun getById(@PathVariable id: String) = ok(groupTokenLogic.getById(id))