Skip to content

Commit 18e44b5

Browse files
committed
authentication midway on dashboard;yaml
1 parent 725e1d9 commit 18e44b5

36 files changed

+982
-126
lines changed

.DS_Store

0 Bytes
Binary file not shown.

client-mapl-auth/src/main/java/app/mapl/RegistrationLoginSystemApplication.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ public RestTemplate restTemplate(){
2323
public WebClient webClient(){
2424
return WebClient.builder().build();
2525
}
26-
2726
public static void main(String[] args) {
2827
SpringApplication.run(RegistrationLoginSystemApplication.class, args);
2928
}

client-mapl-dashboard/src/main/java/app/mapl/controllers/UsersController.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import app.mapl.models.auth.UserRequest;
77
import app.mapl.models.auth.UserResponse;
88
import app.mapl.exception.ResourceNotFoundException;
9+
import app.mapl.models.dto.UserDto;
910
import app.mapl.service.UsersService;
1011
import io.swagger.v3.oas.annotations.Operation;
1112
import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -214,8 +215,8 @@ public ResponseEntity createUser(@RequestBody UserRequest user) {
214215
description = "HTTP Status 200 SUCCESS"
215216
)
216217
@PutMapping(value = USER_PATH + "/{userId}", consumes = "application/json") // userId in body
217-
public ResponseEntity<UserResponse> updateUser(@PathVariable("userId") int userId, @RequestBody UserResponse userResponse) {
218-
Optional<UserResponse> updated = usersService.updateUser(userResponse);
218+
public ResponseEntity<UserDto> updateUser(@PathVariable("userId") int userId, @RequestBody UserDto userDto) {
219+
Optional<UserDto> updated = usersService.updateUser(userDto);
219220
return updated.map(dto -> new ResponseEntity<>(
220221
dto,
221222
HttpStatus.CREATED)).orElseGet(() -> new ResponseEntity<>(HttpStatus.NO_CONTENT));
@@ -233,8 +234,8 @@ public ResponseEntity<UserResponse> updateUser(@PathVariable("userId") int userI
233234
description = "HTTP Status 200 SUCCESS"
234235
)
235236
@PatchMapping(USER_PATH_ID)
236-
public ResponseEntity<UserResponse> patchUserById(@PathVariable("userId") Integer userId,
237-
@RequestBody UserResponse user) {
237+
public ResponseEntity<UserDto> patchUserById(@PathVariable("userId") Integer userId,
238+
@RequestBody UserDto user) {
238239

239240
usersService.patchUserById(userId, user);
240241

@@ -256,7 +257,7 @@ public ResponseEntity<UserResponse> patchUserById(@PathVariable("userId") Intege
256257
public ResponseEntity<Boolean> deleteUser(@PathVariable("userId") int userId) {
257258
Boolean boolSuccess = null;
258259

259-
Optional<UserResponse> tempUser = usersService.getUser(userId);
260+
Optional<UserDto> tempUser = usersService.getUser(userId);
260261
if (tempUser == null) throw new ResourceNotFoundException("User " + userId + "not found to delete");
261262
try {
262263
boolSuccess = usersService.deleteUser(String.valueOf(tempUser));
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package app.mapl.mapper;
22

3-
import app.mapl.models.auth.UserResponse;
4-
import app.mapl.models.auth.UserRequest;
53
import app.mapl.models.auth.User;
4+
import app.mapl.models.dto.UserDto;
65
import org.mapstruct.*;
76

87

98
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING)
109
public interface UserMapper {
11-
User toUser(UserRequest userDto); // REQUEST FROM UI
10+
User toUser(UserDto userDto); // REQUEST FROM UI
1211

13-
UserResponse toDto(User user); // RESPONSE TO UI
12+
UserDto toDto(User user); // RESPONSE TO UI
1413

1514
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
16-
User partialUpdate(UserResponse userResponse, @MappingTarget User user);
15+
User partialUpdate(UserDto userResponse, @MappingTarget User user);
1716

1817
}

client-mapl-dashboard/src/main/java/app/mapl/models/auth/AuthenticationFilter.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package app.mapl.models.auth;
22

3+
import app.mapl.models.dto.UserDto;
34
import app.mapl.service.UsersService;
45
import com.fasterxml.jackson.databind.ObjectMapper;
56
import jakarta.servlet.FilterChain;
67
import jakarta.servlet.ServletException;
78
import jakarta.servlet.http.HttpServletRequest;
89
import jakarta.servlet.http.HttpServletResponse;
910
import lombok.extern.slf4j.Slf4j;
11+
import org.springframework.http.HttpStatus;
1012
import org.springframework.security.authentication.AuthenticationManager;
1113
import org.springframework.security.authentication.BadCredentialsException;
1214
import org.springframework.security.core.Authentication;
@@ -37,13 +39,13 @@ public AuthenticationFilter(AuthenticationManager authenticationManager, UsersSe
3739
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException , ServletException {
3840

3941
try {
40-
var user = new ObjectMapper().configure(AUTO_CLOSE_SOURCE, true).readValue(request.getInputStream(), LoginRequest.class);
42+
var user = new ObjectMapper().configure(AUTO_CLOSE_SOURCE, true).readValue(request.getInputStream(), UserDto.class); // LoginRequest
4143
userService.updateLoginAttempt(user.getEmail(), LoginType.LOGIN_ATTEMPT);
4244
var authentication = unauthenticated(user.getEmail(), user.getPassword());
4345
} catch (Exception exception) {
4446
throw new BadCredentialsException("Invalid username or password");
4547
}
46-
User user = userService.updateLoginAttempt(request.getParameter("email"), LoginType.valueOf(request.getParameter("password")));
48+
UserDto user = userService.updateLoginAttempt(request.getParameter("email"), LoginType.valueOf(request.getParameter("password")));
4749
if (user == null) {
4850
// log.error(exception.getMessage());
4951
handleErrorResponse(request, response, new BadCredentialsException("User not found"));
@@ -56,9 +58,28 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ
5658

5759
@Override
5860
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain, Authentication authResult) throws IOException, ServletException {
59-
super.successfulAuthentication(request, response, filterChain, authResult);
61+
var user = (UserDto) authResult.getPrincipal(); // PRINCIPAL is the DTO
62+
userService.updateLoginAttempt(user.getEmail(), LoginType.LOGIN_SUCCESS);
63+
var httpResponse = user.isMfa();
64+
if ( httpResponse==true ) {
65+
sendQrCode(request, user); }
66+
else {
67+
sendResponse(request, response, user);
68+
}
69+
response.setContentType("application/json");
70+
response.setStatus(HttpStatus.OK.value());
71+
var out = response.getOutputStream();
72+
var mapper = new ObjectMapper();
73+
mapper.writeValue(out, httpResponse);
74+
out.flush();
75+
76+
}
77+
78+
private void sendResponse(HttpServletRequest request, HttpServletResponse response, UserDto user) {
6079
}
6180

81+
private void sendQrCode(HttpServletRequest request, UserDto user) {
82+
}
6283

6384

6485
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package app.mapl.models.auth;
2+
3+
4+
import app.mapl.models.dto.UserDto;
5+
import app.mapl.service.UsersService;
6+
import io.jsonwebtoken.Claims;
7+
import io.jsonwebtoken.JwtBuilder;
8+
import io.jsonwebtoken.Jwts;
9+
import io.jsonwebtoken.io.Decoders;
10+
import io.jsonwebtoken.security.Keys;
11+
import jakarta.servlet.http.Cookie;
12+
import jakarta.servlet.http.HttpServletRequest;
13+
import lombok.RequiredArgsConstructor;
14+
import lombok.extern.slf4j.Slf4j;
15+
import org.apache.commons.lang3.function.TriConsumer;
16+
17+
import javax.crypto.SecretKey;
18+
import java.time.LocalDateTime;
19+
import java.util.Date;
20+
import java.util.Map;
21+
import java.util.Objects;
22+
import java.util.Optional;
23+
import java.util.UUID;
24+
import java.util.function.BiFunction;
25+
import java.util.function.Function;
26+
import java.util.function.Supplier;
27+
28+
import static app.mapl.models.auth.TokenType.ACCESS_TOKEN;
29+
import static app.mapl.models.auth.TokenType.REFRESH_TOKEN;
30+
import static app.mapl.models.auth.User.from;
31+
import static com.google.common.collect.Streams.stream;
32+
import static io.jsonwebtoken.Header.JWT_TYPE;
33+
import static io.micrometer.core.instrument.config.validate.PropertyValidator.getSecret;
34+
35+
import static java.util.Optional.empty;
36+
37+
@RequiredArgsConstructor
38+
@Slf4j
39+
public class JWTServiceImpl extends JwtConfiguration implements JwtService {
40+
public static final String TYPE = "TYPE";
41+
private final UsersService userService;
42+
private final Supplier<SecretKey> key = () -> Keys.hmacShaKeyFor(Decoders.BASE64.decode(getSecret()));
43+
private final Function<String, Claims> claimsFunction = token ->
44+
Jwts.parser()
45+
.verifyWith(key.get())
46+
.build()
47+
.parseSignedClaims(token)
48+
.getPayload();
49+
private final Function<String, String> subject = token -> getClaimsValue(token, Claims::getSubject);
50+
51+
52+
53+
private final BiFunction<HttpServletRequest, String, Optional<String>> extractToken = (request, cookieName) ->
54+
Optional.of(stream(request.getCookies() == null ? new Cookie[]{new Cookie("empty"," ")} : request.getCookies())
55+
.filter(cookie -> Objects.equals(cookieName, cookie.getName()))
56+
.map(Cookie::getValue)
57+
.findAny()
58+
.orElse(empty()));
59+
60+
private final Supplier<JwtBuilder> builder = () ->
61+
Jwts.builder()
62+
.header().add(Map.of(TYPE, JWT_TYPE))
63+
.and()
64+
.audience().add("mapl")
65+
.and()
66+
.id(UUID.randomUUID().toString())
67+
.issuedAt(from(LocalDateTime.now()))
68+
.notBefore(new Date())
69+
.signWith(key.get(), Jwts.SIG.HS512);
70+
71+
72+
73+
private final BiFunction<UserDto, TokenType, String> buildToken = (userDto, type) ->
74+
Objects.equals(type, ACCESS_TOKEN) ?
75+
Jwts.builder()
76+
.setSubject(userDto.getUserId())
77+
.claim("authorities", userDto.getAuthorities())
78+
.claim(RoleEntity.class.getSimpleName(), userDto.getRole())
79+
.expiration(from(LocalDateTime.now().plusSeconds((Long) getExpiration())))
80+
.compact() :
81+
Jwts.builder()
82+
.setSubject(userDto.getUserId())
83+
.claim("authorities", userDto.getRole())
84+
.expiration(from(LocalDateTime.now().plusSeconds((Long) getExpiration())))
85+
.compact();
86+
87+
private Object Token;
88+
private final TriConsumer<HttpServletRequest, UserDto, TokenType> addCookie = (response, user, type) -> {
89+
switch(type) {
90+
case ACCESS_TOKEN:
91+
var accessToken = createToken(userDto, Token::getAccess);
92+
var cookie = new Cookie(type.getValue().accessToken);
93+
cookie.setHttpOnly(true);
94+
//cookie.setSecure(true);
95+
cookie.setMaxAge(2 * 60 * 60);
96+
cookie.setPath("/");
97+
cookie.setAttribute("SameSite", "NONE ");
98+
case REFRESH_TOKEN:
99+
response.addCookie(new Cookie("refresh_token", buildToken.apply(user, REFRESH_TOKEN)));
100+
break;
101+
}
102+
};
103+
private Object getExpiration() {
104+
return null;
105+
}
106+
107+
private String getClaimsValue(String token, Function<Claims, String> claimsResolver) {
108+
return claimsResolver.apply(claimsFunction.apply(token));
109+
}
110+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package app.mapl.models.auth;
2+
3+
public class JwtConfiguration {
4+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
package app.mapl.models.auth;
22

3-
public class JwtService {
3+
public interface JwtService {
4+
45
}

client-mapl-dashboard/src/main/java/app/mapl/models/auth/MaplAuthentication.java

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package app.mapl.models.auth;
22

33
import app.mapl.exception.ApiException;
4+
import app.mapl.models.dto.UserDto;
45
import org.springframework.security.authentication.AbstractAuthenticationToken;
56
import org.springframework.security.core.GrantedAuthority;
67
import org.springframework.security.core.authority.AuthorityUtils;
@@ -11,53 +12,53 @@
1112
public class MaplAuthentication extends AbstractAuthenticationToken {
1213
private static final String PASSWORD_PROTECTED = "PASSWORD_PROTECTED";
1314
private static final String EMAIL_PROTECTED = "EMAAL_PROTECTED";
14-
private User user;
15+
private UserDto userDto;
1516
private String email;
1617
private String password;
1718

1819
private boolean authenticated;
19-
// private ApiAuthentication(String email, String password) {
20+
21+
private MaplAuthentication(String email, String password) {
22+
super(AuthorityUtils.NO_AUTHORITIES);
23+
this.email = email;
24+
this.password = password;
25+
this.authenticated = false;
26+
}
27+
28+
private MaplAuthentication(UserDto userDto, Collection<? extends GrantedAuthority> authorities) {
29+
super(authorities);
30+
this.userDto = userDto;
31+
this.password = PASSWORD_PROTECTED;
32+
this.email = EMAIL_PROTECTED;
33+
this.authenticated = true;
34+
}
35+
// public MaplAuthentication(String email, String password) {
2036
// super(AuthorityUtils.NO_AUTHORITIES);
2137
// this.email = email;
2238
// this.password = password;
2339
// this.authenticated = false;
2440
// }
25-
//
26-
// private ApiAuthentication(User user, Collection<? extends GrantedAuthority> authorities) {
41+
// public MaplAuthentication(UserDto userDto, Collection<? extends GrantedAuthority> authorities) {
2742
// super(authorities);
28-
// this.user = user;
43+
// this.userDto = userDto;
2944
// this.password = PASSWORD_PROTECTED;
3045
// this.email = EMAIL_PROTECTED;
3146
// this.authenticated = true;
3247
//
3348
// }
34-
public MaplAuthentication(String email, String password) {
35-
super(AuthorityUtils.NO_AUTHORITIES);
36-
this.email = email;
37-
this.password = password;
38-
this.authenticated = false;
39-
}
40-
public MaplAuthentication(User user, Collection<? extends GrantedAuthority> authorities) {
41-
super(authorities);
42-
this.user = user;
43-
this.password = PASSWORD_PROTECTED;
44-
this.email = EMAIL_PROTECTED;
45-
this.authenticated = true;
46-
47-
}
4849
public MaplAuthentication unauthenticated(String email, String password) {
4950
return new MaplAuthentication(email, password);
5051
}
51-
public static MaplAuthentication authenticated(User user, Collection<? extends GrantedAuthority> authorities) {
52-
return new MaplAuthentication(user, authorities);
52+
public static MaplAuthentication authenticated(UserDto userDto, Collection<? extends GrantedAuthority> authorities) {
53+
return new MaplAuthentication(userDto, authorities);
5354
}
5455
@Override
5556
public Object getCredentials() {
5657
return PASSWORD_PROTECTED;
5758
}
5859
@Override
5960
public Object getPrincipal() {
60-
return this.user;
61+
return this.userDto;
6162

6263
}
6364
@Override

client-mapl-dashboard/src/main/java/app/mapl/models/auth/MaplAuthenticationProvider.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ public class MaplAuthenticationProvider implements AuthenticationProvider {
1717
* @param authentication
1818
* @return
1919
* @throws AuthenticationException
20+
*
21+
* userAuthToken.getPrincipal() returns the userDto - email
22+
* userAuthToken.getCredentials() returns the password
23+
*
2024
*/
2125
@Override
2226
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
2327

24-
var userAuthToken = (UsernamePasswordAuthenticationToken) authentication;
28+
var userAuthToken = (UsernamePasswordAuthenticationToken) authentication; // soon to deprecate UsernamePasswordAuthenticationToken
2529

2630
var userFromDb = userDetailsService.loadUserByUsername((String) userAuthToken.getPrincipal());
2731
var password = (String) userAuthToken.getCredentials();

0 commit comments

Comments
 (0)