File tree Expand file tree Collapse file tree
main/java/com/survey/backend/service
test/java/com/survey/backend/controller
backoffice/src/app/user-management Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -78,6 +78,18 @@ public LoginResponseDTO login(LoginRequestDTO request) {
7878 User user = userService .saveUser (email );
7979 List <String > roles = keycloakAdminService .getUserRoles (email );
8080
81+ if ("backoffice" .equalsIgnoreCase (keycloakClientId )) {
82+ boolean hasAccess =
83+ roles .stream ()
84+ .anyMatch (
85+ r ->
86+ r .equalsIgnoreCase (KeycloakRole .ADMIN .name ())
87+ || r .equalsIgnoreCase (KeycloakRole .MANAGER .name ()));
88+ if (!hasAccess ) {
89+ throw new ResponseStatusException (HttpStatus .UNAUTHORIZED , "Unauthorized" );
90+ }
91+ }
92+
8193 return new LoginResponseDTO (accessToken , roles , user .isPremium ());
8294 }
8395
Original file line number Diff line number Diff line change @@ -69,7 +69,7 @@ public void testLoginSuccess() throws Exception {
6969 User mockUser = User .builder ().email ("x@test.com" ).isPremium (true ).build ();
7070
7171 Mockito .when (userService .saveUser (email )).thenReturn (mockUser );
72- Mockito .when (keycloakAdminService .getUserRoles (email )).thenReturn (List .of ("CUSTOMER " ));
72+ Mockito .when (keycloakAdminService .getUserRoles (email )).thenReturn (List .of ("Admin " ));
7373
7474 mockMvc
7575 .perform (
@@ -120,4 +120,24 @@ public void testSignupSuccess() throws Exception {
120120 .createUser ("new@example.com" , "pw" , List .of (KeycloakRole .CUSTOMER .name ()));
121121 Mockito .verify (userService ).saveUser ("new@example.com" );
122122 }
123+
124+ @ Test
125+ public void testLoginFailsWhenUserNotAdminOrManager () throws Exception {
126+ LoginRequestDTO loginRequest = new LoginRequestDTO ();
127+ loginRequest .setEmail ("test@example.com" );
128+ loginRequest .setPassword ("password" );
129+
130+ String email = "test@example.com" ;
131+
132+ User mockUser = User .builder ().email ("x@test.com" ).isPremium (false ).build ();
133+ Mockito .when (userService .saveUser (email )).thenReturn (mockUser );
134+ Mockito .when (keycloakAdminService .getUserRoles (email )).thenReturn (List .of ("CUSTOMER" ));
135+
136+ mockMvc
137+ .perform (
138+ post ("/auth/login" )
139+ .contentType (MediaType .APPLICATION_JSON )
140+ .content (objectMapper .writeValueAsString (loginRequest )))
141+ .andExpect (status ().isUnauthorized ());
142+ }
123143}
Original file line number Diff line number Diff line change 11import { Component , OnInit } from '@angular/core'
2- import { DatePipe , NgFor } from '@angular/common'
2+ import { DatePipe , NgFor } from '@angular/common'
33import { MatTableModule , MatTableDataSource } from '@angular/material/table'
44import { Payment } from '../../models/payment'
55import { PaymentsService } from '../../services/payment.service'
Original file line number Diff line number Diff line change @@ -22,6 +22,10 @@ export class KeycloakService {
2222 return this . keycloak . init ( { onLoad : 'login-required' } ) . then ( ( ) => {
2323 const token = this . keycloak ?. token
2424 if ( token ) {
25+ const roles = ( this . keycloak . tokenParsed ?. [ 'realm_access' ] ?. [ 'roles' ] as string [ ] ) || [ ]
26+ if ( ! roles . map ( ( r ) => r . toLowerCase ( ) ) . includes ( 'admin' ) ) {
27+ throw new Error ( 'Unauthorized' )
28+ }
2529 Cookies . set ( 'token' , token , {
2630 secure : true ,
2731 sameSite : 'strict' ,
You can’t perform that action at this time.
0 commit comments