Merge "adding catalog-service for mod2"
[dcaegen2/platform.git] / mod2 / auth-service / src / main / java / org / onap / dcaegen2 / platform / mod / controllers / AuthController.java
1 /*
2  *
3  *  * ============LICENSE_START=======================================================
4  *  *  org.onap.dcae
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
11  *  *
12  *  *       http://www.apache.org/licenses/LICENSE-2.0
13  *  *
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=========================================================
20  *
21  */
22
23 package org.onap.dcaegen2.platform.mod.controllers;
24
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;
52
53
54 import javax.validation.Valid;
55 import java.util.HashSet;
56 import java.util.List;
57 import java.util.Set;
58 import java.util.stream.Collectors;
59
60
61 /**
62  * @author
63  * @date 09/08/2020
64  * Authentication Operations
65  */
66 @RestController
67 @RequestMapping("/api/auth")
68 @CrossOrigin(origins = "*")
69 public class AuthController {
70
71     @Autowired
72     AuthenticationManager authenticationManager;
73
74     @Autowired
75     UserRepository userRepository;
76
77     @Autowired
78     RoleRepository roleRepository;
79
80     @Autowired
81     PasswordEncoder passwordEncoder;
82
83     @Autowired
84     JwtUtils jwtUtils;
85
86     @PreAuthorize("isAuthenticated()")
87     @PostMapping("/validate-token")
88     public ResponseEntity<?> validateToken() {
89         return new ResponseEntity("true", HttpStatus.OK);
90     }
91
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);
98     }
99
100     private Authentication authenticateLoginRequest(@RequestBody @Valid LoginRequest loginRequest) {
101         return authenticationManager.authenticate(
102                 new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())
103         );
104     }
105
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);
110     }
111
112     private List<String> setRolesFromUserDetails(UserDetailsImpl userDetails) {
113         return userDetails.getAuthorities().stream()
114                 .map(item -> ((GrantedAuthority) item).getAuthority())
115                 .collect(Collectors.toList());
116     }
117
118     private ResponseEntity<JwtResponse> buildUserContext(String jwt, UserDetailsImpl userDetails, List<String> roles) {
119         return ResponseEntity.ok(JwtResponse.builder()
120                 .id(userDetails.getId())
121                 .roles(roles)
122                 .username(userDetails.getUsername())
123                 .token(jwt)
124                 .fullName(userDetails.getFullName())
125                 .build()
126         );
127     }
128
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!"));
136     }
137
138     private void checkIfUserExists(@RequestBody @Valid SignupRequest signUpRequest) {
139         if (userRepository.existsByUsername(signUpRequest.getUsername()))
140             throw new UserAlreadyExistsException("Username already exists!");
141     }
142
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);
150         return user;
151     }
152
153     private String getEncodedPassword(@RequestBody @Valid SignupRequest request) {
154         return passwordEncoder.encode(request.getPassword());
155     }
156
157     public Set<Role> createRoles(Set<String> roleStrings) {
158         Set<Role> roles = new HashSet<>();
159         for (String roleStr : roleStrings) {
160             roles.add(getRole(roleStr));
161         }
162         return roles;
163     }
164
165     private Role getRole(String roleStr) {
166         return roleRepository.findByName(roleStr).orElseThrow(
167                 () -> new RoleNotExistsException(String.format("Role %s does not exist", roleStr)));
168     }
169 }
170
171