3 * * ============LICENSE_START=======================================================
5 * * ================================================================================
6 * * Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
7 * * ================================================================================
8 * * Licensed under the Apache License, Version 2.0 (the "License");
9 * * you may not use this file except in compliance with the License.
10 * * You may obtain a copy of the License at
12 * * http://www.apache.org/licenses/LICENSE-2.0
14 * * Unless required by applicable law or agreed to in writing, software
15 * * distributed under the License is distributed on an "AS IS" BASIS,
16 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * * See the License for the specific language governing permissions and
18 * * limitations under the License.
19 * * ============LICENSE_END=========================================================
23 package org.onap.dcaegen2.platform.mod.controllers;
25 import org.onap.dcaegen2.platform.mod.exceptions.RoleNotExistsException;
26 import org.onap.dcaegen2.platform.mod.exceptions.UserAlreadyExistsException;
27 import org.onap.dcaegen2.platform.mod.models.LoginRequest;
28 import org.onap.dcaegen2.platform.mod.models.JwtResponse;
29 import org.onap.dcaegen2.platform.mod.models.SignupRequest;
30 import org.onap.dcaegen2.platform.mod.models.ModUser;
31 import org.onap.dcaegen2.platform.mod.models.GenericResponse;
32 import org.onap.dcaegen2.platform.mod.models.Role;
33 import org.onap.dcaegen2.platform.mod.repositories.RoleRepository;
34 import org.onap.dcaegen2.platform.mod.repositories.UserRepository;
35 import org.onap.dcaegen2.platform.mod.security.jwt.JwtUtils;
36 import org.onap.dcaegen2.platform.mod.security.services.UserDetailsImpl;
37 import org.springframework.beans.factory.annotation.Autowired;
38 import org.springframework.http.HttpStatus;
39 import org.springframework.http.ResponseEntity;
40 import org.springframework.security.access.prepost.PreAuthorize;
41 import org.springframework.security.authentication.AuthenticationManager;
42 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
43 import org.springframework.security.core.Authentication;
44 import org.springframework.security.core.GrantedAuthority;
45 import org.springframework.security.core.context.SecurityContextHolder;
46 import org.springframework.security.crypto.password.PasswordEncoder;
47 import org.springframework.web.bind.annotation.RestController;
48 import org.springframework.web.bind.annotation.CrossOrigin;
49 import org.springframework.web.bind.annotation.RequestMapping;
50 import org.springframework.web.bind.annotation.PostMapping;
51 import org.springframework.web.bind.annotation.RequestBody;
54 import javax.validation.Valid;
55 import java.util.HashSet;
56 import java.util.List;
58 import java.util.stream.Collectors;
64 * Authentication Operations
67 @RequestMapping("/api/auth")
68 @CrossOrigin(origins = "*")
69 public class AuthController {
72 AuthenticationManager authenticationManager;
75 UserRepository userRepository;
78 RoleRepository roleRepository;
81 PasswordEncoder passwordEncoder;
86 @PreAuthorize("isAuthenticated()")
87 @PostMapping("/validate-token")
88 public ResponseEntity<?> validateToken() {
89 return new ResponseEntity("true", HttpStatus.OK);
92 @PostMapping("/signin")
93 public ResponseEntity<?> authenticateUser(@RequestBody @Valid LoginRequest loginRequest) {
94 Authentication authentication = authenticateLoginRequest(loginRequest);
95 SecurityContextHolder.getContext().setAuthentication(authentication);
96 String jwt = jwtUtils.generateJwtToken(authentication);
97 return setUserContext(authentication, jwt);
100 private Authentication authenticateLoginRequest(@RequestBody @Valid LoginRequest loginRequest) {
101 return authenticationManager.authenticate(
102 new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())
106 private ResponseEntity<?> setUserContext(Authentication authentication, String jwt) {
107 UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
108 List<String> roles = setRolesFromUserDetails(userDetails);
109 return buildUserContext(jwt, userDetails, roles);
112 private List<String> setRolesFromUserDetails(UserDetailsImpl userDetails) {
113 return userDetails.getAuthorities().stream()
114 .map(item -> ((GrantedAuthority) item).getAuthority())
115 .collect(Collectors.toList());
118 private ResponseEntity<JwtResponse> buildUserContext(String jwt, UserDetailsImpl userDetails, List<String> roles) {
119 return ResponseEntity.ok(JwtResponse.builder()
120 .id(userDetails.getId())
122 .username(userDetails.getUsername())
124 .fullName(userDetails.getFullName())
129 @PreAuthorize("hasRole('ADMIN')")
130 @PostMapping("/signup")
131 public ResponseEntity<?> registerUser(@RequestBody @Valid SignupRequest request) {
132 checkIfUserExists(request);
133 ModUser user = createNewUser(request);
134 userRepository.save(user);
135 return ResponseEntity.ok(new GenericResponse("User registered successfully!"));
138 private void checkIfUserExists(@RequestBody @Valid SignupRequest signUpRequest) {
139 if (userRepository.existsByUsername(signUpRequest.getUsername()))
140 throw new UserAlreadyExistsException("Username already exists!");
143 private ModUser createNewUser(@RequestBody @Valid SignupRequest request) {
144 ModUser user = new ModUser();
145 user.setUsername(request.getUsername());
146 user.setFullName(request.getFullName());
147 user.setPassword(getEncodedPassword(request));
148 Set<Role> roles = createRoles(request.getRoles());
149 user.setRoles(roles);
153 private String getEncodedPassword(@RequestBody @Valid SignupRequest request) {
154 return passwordEncoder.encode(request.getPassword());
157 public Set<Role> createRoles(Set<String> roleStrings) {
158 Set<Role> roles = new HashSet<>();
159 for (String roleStr : roleStrings) {
160 roles.add(getRole(roleStr));
165 private Role getRole(String roleStr) {
166 return roleRepository.findByName(roleStr).orElseThrow(
167 () -> new RoleNotExistsException(String.format("Role %s does not exist", roleStr)));