Skip to content

Commit 108c135

Browse files
committed
Add AuthController and Payload definitions
1 parent b73ffee commit 108c135

File tree

10 files changed

+371
-15
lines changed

10 files changed

+371
-15
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package com.skia.lab.controllers;
2+
3+
import java.util.HashSet;
4+
import java.util.List;
5+
import java.util.Set;
6+
import java.util.stream.Collectors;
7+
8+
import jakarta.validation.Valid;
9+
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.http.ResponseEntity;
12+
import org.springframework.security.authentication.AuthenticationManager;
13+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
14+
import org.springframework.security.core.Authentication;
15+
import org.springframework.security.core.context.SecurityContextHolder;
16+
import org.springframework.security.crypto.password.PasswordEncoder;
17+
import org.springframework.web.bind.annotation.CrossOrigin;
18+
import org.springframework.web.bind.annotation.PostMapping;
19+
import org.springframework.web.bind.annotation.RequestBody;
20+
import org.springframework.web.bind.annotation.RequestMapping;
21+
import org.springframework.web.bind.annotation.RestController;
22+
23+
import com.skia.lab.models.ERole;
24+
import com.skia.lab.models.Role;
25+
import com.skia.lab.models.User;
26+
import com.skia.lab.payload.request.LoginRequest;
27+
import com.skia.lab.payload.request.SignupRequest;
28+
import com.skia.lab.payload.response.JwtResponse;
29+
import com.skia.lab.payload.response.MessageResponse;
30+
import com.skia.lab.repository.RoleRepository;
31+
import com.skia.lab.repository.UserRepository;
32+
import com.skia.lab.security.jwt.JwtUtils;
33+
import com.skia.lab.security.services.UserDetailsImpl;
34+
35+
36+
37+
38+
39+
40+
@CrossOrigin(origins = "*", maxAge = 3600)
41+
@RestController
42+
@RequestMapping("/api/auth")
43+
public class AuthController {
44+
@Autowired
45+
AuthenticationManager authenticationManager;
46+
47+
@Autowired
48+
UserRepository userRepository;
49+
50+
@Autowired
51+
RoleRepository roleRepository;
52+
53+
@Autowired
54+
PasswordEncoder encoder;
55+
56+
@Autowired
57+
JwtUtils jwtUtils;
58+
59+
// /api/auth/signin
60+
// authenticate { username, pasword }
61+
// update SecurityContext using Authentication object
62+
// generate JWT
63+
// get UserDetails from Authentication object
64+
// response contains JWT and UserDetails data
65+
@PostMapping("/signin")
66+
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
67+
68+
Authentication authentication = authenticationManager.authenticate(
69+
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
70+
71+
SecurityContextHolder.getContext().setAuthentication(authentication);
72+
String jwt = jwtUtils.generateJwtToken(authentication);
73+
74+
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
75+
List<String> roles = userDetails.getAuthorities().stream()
76+
.map(item -> item.getAuthority())
77+
.collect(Collectors.toList());
78+
79+
return ResponseEntity.ok(new JwtResponse(jwt,
80+
userDetails.getId(),
81+
userDetails.getUsername(),
82+
userDetails.getEmail(),
83+
roles));
84+
}
85+
86+
87+
// /api/auth/signup
88+
// check existing username/email
89+
// create new User (with ROLE_USER if not specifying role)
90+
// save User to database using UserRepository
91+
@PostMapping("/signup")
92+
public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
93+
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
94+
return ResponseEntity
95+
.badRequest()
96+
.body(new MessageResponse("Error: Username is already taken!"));
97+
}
98+
99+
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
100+
return ResponseEntity
101+
.badRequest()
102+
.body(new MessageResponse("Error: Email is already in use!"));
103+
}
104+
105+
// Create new user's account
106+
User user = new User(signUpRequest.getUsername(),
107+
signUpRequest.getEmail(),
108+
encoder.encode(signUpRequest.getPassword()));
109+
110+
Set<String> strRoles = signUpRequest.getRole();
111+
Set<Role> roles = new HashSet<>();
112+
113+
if (strRoles == null) {
114+
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
115+
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
116+
roles.add(userRole);
117+
} else {
118+
strRoles.forEach(role -> {
119+
switch (role) {
120+
case "admin":
121+
Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
122+
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
123+
roles.add(adminRole);
124+
125+
break;
126+
case "mod":
127+
Role modRole = roleRepository.findByName(ERole.ROLE_MODERATOR)
128+
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
129+
roles.add(modRole);
130+
131+
break;
132+
default:
133+
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
134+
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
135+
roles.add(userRole);
136+
}
137+
});
138+
}
139+
140+
user.setRoles(roles);
141+
userRepository.save(user);
142+
143+
return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
144+
}
145+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.skia.lab.controllers;
2+
3+
import org.springframework.security.access.prepost.PreAuthorize;
4+
import org.springframework.web.bind.annotation.CrossOrigin;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.RequestMapping;
7+
import org.springframework.web.bind.annotation.RestController;
8+
9+
10+
// There are 4 APIs:
11+
// – /api/test/all for public access
12+
// – /api/test/user for users has ROLE_USER or ROLE_MODERATOR or ROLE_ADMIN or ROLE_GOD
13+
// – /api/test/mod for users has ROLE_MODERATOR
14+
// – /api/test/admin for users has ROLE_ADMIN
15+
@CrossOrigin(origins = "*", maxAge = 3600)
16+
@RestController
17+
@RequestMapping("/api/test")
18+
public class TestController {
19+
@GetMapping("/all")
20+
public String allAccess() {
21+
return "Public Content.";
22+
}
23+
24+
@GetMapping("/user")
25+
@PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN') or hasRole('GOD')")
26+
public String userAccess() {
27+
return "User Content.";
28+
}
29+
30+
@GetMapping("/mod")
31+
@PreAuthorize("hasRole('MODERATOR')")
32+
public String moderatorAccess() {
33+
return "Moderator Board.";
34+
}
35+
36+
@GetMapping("/admin")
37+
@PreAuthorize("hasRole('ADMIN')or hasRole('GOD')")
38+
public String adminAccess() {
39+
return "Admin Board.";
40+
}
41+
}

src/main/java/com/skia/lab/models/ERole.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.skia.lab.models;
22

33
public enum ERole {
4-
ROLE_VIEWWR,
4+
ROLE_VIEWER,
55
ROLE_USER,
66
ROLE_MODERATOR,
77
ROLE_ADMIN,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.skia.lab.payload.request;
2+
3+
import jakarta.validation.constraints.NotBlank;
4+
5+
public class LoginRequest {
6+
@NotBlank
7+
private String username;
8+
9+
@NotBlank
10+
private String password;
11+
12+
public String getUsername() {
13+
return username;
14+
}
15+
16+
public void setUsername(String username) {
17+
this.username = username;
18+
}
19+
20+
public String getPassword() {
21+
return password;
22+
}
23+
24+
public void setPassword(String password) {
25+
this.password = password;
26+
}
27+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.skia.lab.payload.request;
2+
3+
import java.util.Set;
4+
5+
import jakarta.validation.constraints.*;
6+
7+
public class SignupRequest {
8+
@NotBlank
9+
@Size(min = 3, max = 20)
10+
private String username;
11+
12+
@NotBlank
13+
@Size(max = 50)
14+
@Email
15+
private String email;
16+
17+
private Set<String> role;
18+
19+
@NotBlank
20+
@Size(min = 6, max = 40)
21+
private String password;
22+
23+
public String getUsername() {
24+
return username;
25+
}
26+
27+
public void setUsername(String username) {
28+
this.username = username;
29+
}
30+
31+
public String getEmail() {
32+
return email;
33+
}
34+
35+
public void setEmail(String email) {
36+
this.email = email;
37+
}
38+
39+
public String getPassword() {
40+
return password;
41+
}
42+
43+
public void setPassword(String password) {
44+
this.password = password;
45+
}
46+
47+
public Set<String> getRole() {
48+
return this.role;
49+
}
50+
51+
public void setRole(Set<String> role) {
52+
this.role = role;
53+
}
54+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.skia.lab.payload.response;
2+
3+
import java.util.List;
4+
5+
public class JwtResponse {
6+
private String token;
7+
private String type = "Bearer";
8+
private Long id;
9+
private String username;
10+
private String email;
11+
private List<String> roles;
12+
13+
public JwtResponse(String accessToken, Long id, String username, String email, List<String> roles) {
14+
this.token = accessToken;
15+
this.id = id;
16+
this.username = username;
17+
this.email = email;
18+
this.roles = roles;
19+
}
20+
21+
public String getAccessToken() {
22+
return token;
23+
}
24+
25+
public void setAccessToken(String accessToken) {
26+
this.token = accessToken;
27+
}
28+
29+
public String getTokenType() {
30+
return type;
31+
}
32+
33+
public void setTokenType(String tokenType) {
34+
this.type = tokenType;
35+
}
36+
37+
public Long getId() {
38+
return id;
39+
}
40+
41+
public void setId(Long id) {
42+
this.id = id;
43+
}
44+
45+
public String getEmail() {
46+
return email;
47+
}
48+
49+
public void setEmail(String email) {
50+
this.email = email;
51+
}
52+
53+
public String getUsername() {
54+
return username;
55+
}
56+
57+
public void setUsername(String username) {
58+
this.username = username;
59+
}
60+
61+
public List<String> getRoles() {
62+
return roles;
63+
}
64+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.skia.lab.payload.response;
2+
3+
public class MessageResponse {
4+
private String message;
5+
6+
public MessageResponse(String message) {
7+
this.message = message;
8+
}
9+
10+
public String getMessage() {
11+
return message;
12+
}
13+
14+
public void setMessage(String message) {
15+
this.message = message;
16+
}
17+
}

0 commit comments

Comments
 (0)