@@ -27,18 +27,22 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
2727import org .springframework .boot .test .mock .mockito .MockBean
2828import org .springframework .context .annotation .Import
2929import org .springframework .http .MediaType
30+ import org .springframework .security .authentication .UsernamePasswordAuthenticationToken
31+ import org .springframework .security .core .{Authentication , GrantedAuthority }
3032import org .springframework .security .test .web .servlet .request .SecurityMockMvcRequestPostProcessors .authentication
3133import org .springframework .test .context .TestPropertySource
3234import org .springframework .test .web .servlet .MockMvc
33- import org .springframework .test .web .servlet .request .MockMvcRequestBuilders .{post , get }
35+ import org .springframework .test .web .servlet .request .MockMvcRequestBuilders .{get , post }
3436import org .springframework .test .web .servlet .result .MockMvcResultMatchers .{content , status }
3537import za .co .absa .loginsvc .model .User
38+ import za .co .absa .loginsvc .rest .FakeAuthentication .fakeUser
3639import za .co .absa .loginsvc .rest .config .provider .ConfigProvider
3740import za .co .absa .loginsvc .rest .model .{AccessToken , RefreshToken }
3841import za .co .absa .loginsvc .rest .service .jwt .JWTService
3942import za .co .absa .loginsvc .rest .{AuthManagerConfig , FakeAuthentication , RestResponseEntityExceptionHandler , SecurityConfig }
4043
4144import java .security .interfaces .RSAPublicKey
45+ import java .util
4246import java .util .Base64
4347import scala .concurrent .duration ._
4448
@@ -81,9 +85,21 @@ class TokenControllerTest extends AnyFlatSpec
8185 .andExpect(content.json(expectedJsonBody))
8286 }
8387
84- it should " return tokens generated by mocked JWTService for the authenticated user with group-prefixes (single)" in {
88+ // aux methods for user-groups testing
89+
90+ def fakeUserWithGroups (groups: Seq [String ]): User = User (" fakeUser" ,
91+ groups,
92+ Map (
" mail" -> Some (
" [email protected] " ),
" displayname" -> Some (
" Fake Name" )))
93+
94+ def fakeUserAuthenticationForUser (user : User ): Authentication = new UsernamePasswordAuthenticationToken (
95+ user, " fakePassword" , new util.ArrayList [GrantedAuthority ]()
96+ )
97+
98+ it should " return tokens generated by mocked JWTService for the authenticated user with group-prefixes (single)(case irrelevant)" in {
8599 // `groups-prefixes` fill change the groups in user object passed to the jwtService.generateAccessToken
86- val fakeUserFilteredGroups = FakeAuthentication .fakeUser.copy(groups = Seq (" first-fake-group" ))
100+ val fakeUserFilteredGroups = fakeUserWithGroups(groups = Seq (" first-fake-group" ))
101+ val fakeUserAuth = fakeUserAuthenticationForUser(fakeUserFilteredGroups)
102+
87103 when(jwtService.generateAccessToken(fakeUserFilteredGroups)).thenReturn(fakeAccessJwt)
88104 when(jwtService.generateRefreshToken(fakeUserFilteredGroups)).thenReturn(fakeRefreshJwt)
89105 when(jwtService.getConfiguredRefreshExpDuration).thenReturn(refreshDuration)
@@ -92,30 +108,64 @@ class TokenControllerTest extends AnyFlatSpec
92108
93109 mockMvc.perform(
94110 post(" /token/generate?group-prefixes=first" )
95- .`with`(authentication(FakeAuthentication .fakeUserAuthentication ))
111+ .`with`(authentication(fakeUserAuth ))
96112 .contentType(MediaType .APPLICATION_JSON )
97113 )
98114 .andExpect(status.isOk)
99115 .andExpect(content.json(expectedJsonBody))
100116 }
101117
102- it should " return tokens generated by mocked JWTService for the authenticated user with group-prefixes (multiple ,-separated)" in {
103- val fakeUserFilteredGroups = FakeAuthentication .fakeUser.copy(groups = Seq (" second-fake-group" , " third-fake-group" ))
104- when(jwtService.generateAccessToken(fakeUserFilteredGroups)).thenReturn(fakeAccessJwt)
105- when(jwtService.generateRefreshToken(fakeUserFilteredGroups)).thenReturn(fakeRefreshJwt)
118+ it should " return tokens generated by mocked JWTService for the authenticated user with group-prefixes (multiple ,-separated) (case-sensitive)" in {
119+ val userGroups = Seq (" second-fake-group" , " THIRD-FAKE-GROUP" , " FourTH-FaKe-Group" )
120+ val authUser = fakeUserWithGroups(userGroups)
121+ val auth = fakeUserAuthenticationForUser(authUser)
122+
123+ val expectedGroups = Seq (" second-fake-group" , " THIRD-FAKE-GROUP" )
124+ val expectedUser = fakeUserWithGroups(expectedGroups)
125+
126+ when(jwtService.generateAccessToken(expectedUser)).thenReturn(fakeAccessJwt)
127+ when(jwtService.generateRefreshToken(expectedUser)).thenReturn(fakeRefreshJwt)
106128 when(jwtService.getConfiguredRefreshExpDuration).thenReturn(refreshDuration)
107129
108130 val expectedJsonBody = s """ {"token": " ${fakeAccessJwt.token}", "refresh": " ${fakeRefreshJwt.token}"} """
109131
110132 mockMvc.perform(
111- post(" /token/generate?group-prefixes=second,third, nonexistent" )
112- .`with`(authentication(FakeAuthentication .fakeUserAuthentication ))
133+ post(" /token/generate?group-prefixes=second,THIRD,fOurth, nonexistent&case-sensitive=true " ) // fOurth does not match case, so it is not selected for token generation
134+ .`with`(authentication(auth ))
113135 .contentType(MediaType .APPLICATION_JSON )
114136 )
115137 .andExpect(status.isOk)
116138 .andExpect(content.json(expectedJsonBody))
117139 }
118140
141+ Seq (
142+ (" case-insensitive by default" , " /token/generate?group-prefixes=second,THIRD,fOurth,nonexistent" ),
143+ (" case-insensitive explicitly" , " /token/generate?group-prefixes=second,THIRD,fOurth,nonexistent&case-sensitive=false" )
144+ ).foreach { case (caseName, url) =>
145+ it should s " return tokens generated by mocked JWTService for the authenticated user with group-prefixes (multiple ,-separated) ( $caseName) " in {
146+ val userGroups = Seq (" second-fake-group" , " THIRD-FAKE-GROUP" , " FourTH-FaKe-Group" , " otherGroup" )
147+ val authUser = fakeUserWithGroups(userGroups)
148+ val auth = fakeUserAuthenticationForUser(authUser)
149+
150+ val expectedGroups = Seq (" second-fake-group" , " THIRD-FAKE-GROUP" , " FourTH-FaKe-Group" )
151+ val expectedUser = fakeUserWithGroups(expectedGroups)
152+
153+ when(jwtService.generateAccessToken(expectedUser)).thenReturn(fakeAccessJwt)
154+ when(jwtService.generateRefreshToken(expectedUser)).thenReturn(fakeRefreshJwt)
155+ when(jwtService.getConfiguredRefreshExpDuration).thenReturn(refreshDuration)
156+
157+ val expectedJsonBody = s """ {"token": " ${fakeAccessJwt.token}", "refresh": " ${fakeRefreshJwt.token}"} """
158+
159+ mockMvc.perform(
160+ post(url) // fOurth gets matched
161+ .`with`(authentication(auth))
162+ .contentType(MediaType .APPLICATION_JSON )
163+ )
164+ .andExpect(status.isOk)
165+ .andExpect(content.json(expectedJsonBody))
166+ }
167+ }
168+
119169 it should " fail for anonymous (not authenticated) user" in {
120170 when(jwtService.generateAccessToken(any[User ], any[Boolean ])).thenReturn(fakeAccessJwt)
121171
0 commit comments