Skip to content

Commit 2a515b0

Browse files
user model, login and registration, authentication added
1 parent 2745138 commit 2a515b0

8 files changed

Lines changed: 243 additions & 5 deletions

File tree

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package org.launchcode.codingevents.controllers;
2+
3+
import jakarta.servlet.http.HttpServletRequest;
4+
import jakarta.servlet.http.HttpSession;
5+
import jakarta.validation.Valid;
6+
import org.launchcode.codingevents.data.UserRepository;
7+
import org.launchcode.codingevents.models.User;
8+
import org.launchcode.codingevents.models.dto.LoginFormDTO;
9+
import org.launchcode.codingevents.models.dto.RegisterFormDTO;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.stereotype.Controller;
12+
import org.springframework.ui.Model;
13+
import org.springframework.validation.Errors;
14+
import org.springframework.web.bind.annotation.GetMapping;
15+
import org.springframework.web.bind.annotation.ModelAttribute;
16+
import org.springframework.web.bind.annotation.PostMapping;
17+
18+
import java.util.Optional;
19+
20+
@Controller
21+
public class AuthenticationController {
22+
23+
@Autowired
24+
UserRepository userRepository;
25+
26+
private static final String userSessionKey = "user";
27+
28+
public User getUserFromSession(HttpSession session) {
29+
Integer userId = (Integer) session.getAttribute(userSessionKey);
30+
if (userId == null) {
31+
return null;
32+
}
33+
34+
Optional<User> user = userRepository.findById(userId);
35+
36+
if (user.isEmpty()) {
37+
return null;
38+
}
39+
40+
return user.get();
41+
}
42+
43+
private static void setUserInSession(HttpSession session, User user) {
44+
session.setAttribute(userSessionKey, user.getId());
45+
}
46+
47+
@GetMapping("/register")
48+
public String displayRegistrationForm(Model model) {
49+
model.addAttribute(new RegisterFormDTO());
50+
model.addAttribute("title", "Register");
51+
return "register";
52+
}
53+
54+
@PostMapping("/register")
55+
public String processRegistrationForm(@ModelAttribute @Valid RegisterFormDTO registerFormDTO,
56+
Errors errors, HttpServletRequest request,
57+
Model model) {
58+
59+
if (errors.hasErrors()) {
60+
model.addAttribute("title", "Register");
61+
return "register";
62+
}
63+
64+
User existingUser = userRepository.findByUsername(registerFormDTO.getUsername());
65+
66+
if (existingUser != null) {
67+
errors.rejectValue("username", "username.alreadyexists", "A user with that username already exists");
68+
model.addAttribute("title", "Register");
69+
return "register";
70+
}
71+
72+
String password = registerFormDTO.getPassword();
73+
String verifyPassword = registerFormDTO.getVerifyPassword();
74+
if (!password.equals(verifyPassword)) {
75+
errors.rejectValue("password", "passwords.mismatch", "Passwords do not match");
76+
model.addAttribute("title", "Register");
77+
return "register";
78+
}
79+
80+
User newUser = new User(registerFormDTO.getUsername(), registerFormDTO.getPassword());
81+
userRepository.save(newUser);
82+
setUserInSession(request.getSession(), newUser);
83+
84+
return "redirect:";
85+
}
86+
87+
@GetMapping("/login")
88+
public String displayLoginForm(Model model) {
89+
model.addAttribute(new LoginFormDTO());
90+
model.addAttribute("title", "Log In");
91+
return "login";
92+
}
93+
94+
@PostMapping("/login")
95+
public String processLoginForm(@ModelAttribute @Valid LoginFormDTO loginFormDTO,
96+
Errors errors, HttpServletRequest request,
97+
Model model) {
98+
99+
if (errors.hasErrors()) {
100+
model.addAttribute("title", "Log In");
101+
return "login";
102+
}
103+
104+
User theUser = userRepository.findByUsername(loginFormDTO.getUsername());
105+
106+
if (theUser == null) {
107+
errors.rejectValue("username", "user.invalid", "The given username does not exist");
108+
model.addAttribute("title", "Log In");
109+
return "login";
110+
}
111+
112+
String password = loginFormDTO.getPassword();
113+
114+
if (!theUser.isMatchingPassword(password)) {
115+
errors.rejectValue("password", "password.invalid", "Invalid password");
116+
model.addAttribute("title", "Log In");
117+
return "login";
118+
}
119+
120+
setUserInSession(request.getSession(), theUser);
121+
122+
return "redirect:";
123+
}
124+
125+
@GetMapping("/logout")
126+
public String logout(HttpServletRequest request){
127+
request.getSession().invalidate();
128+
return "redirect:/login";
129+
}
130+
131+
}

src/main/java/org/launchcode/codingevents/models/AbstractEntity.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.launchcode.codingevents.models;
22

33
import jakarta.persistence.GeneratedValue;
4+
import jakarta.persistence.GenerationType;
45
import jakarta.persistence.Id;
56
import jakarta.persistence.MappedSuperclass;
67

@@ -13,7 +14,7 @@
1314
public abstract class AbstractEntity {
1415

1516
@Id
16-
@GeneratedValue
17+
@GeneratedValue(strategy = GenerationType.IDENTITY)
1718
private int id;
1819

1920
public int getId() {

src/main/java/org/launchcode/codingevents/models/User.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public User() {}
1919

2020
public User(String username, String password) {
2121
this.username = username;
22-
this.pwHash = password;
22+
this.pwHash = encoder.encode(password);
2323
}
2424

2525
public String getUsername() {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.launchcode.codingevents.models.dto;
2+
3+
import jakarta.validation.constraints.*;
4+
5+
public class LoginFormDTO {
6+
7+
@NotNull
8+
@NotBlank
9+
@Size(min = 3, max = 20, message = "Invalid username. Must be between 3 and 20 characters.")
10+
private String username;
11+
12+
@NotNull
13+
@NotBlank
14+
@Size(min = 5, max = 30, message = "Invalid password. Must be between 5 and 30 characters.")
15+
private String password;
16+
17+
public String getUsername() {
18+
return username;
19+
}
20+
21+
public void setUsername(String username) {
22+
this.username = username;
23+
}
24+
25+
public String getPassword() {
26+
return password;
27+
}
28+
29+
public void setPassword(String password) {
30+
this.password = password;
31+
}
32+
33+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.launchcode.codingevents.models.dto;
2+
3+
public class RegisterFormDTO extends LoginFormDTO {
4+
5+
private String verifyPassword;
6+
7+
public String getVerifyPassword() {
8+
return verifyPassword;
9+
}
10+
11+
public void setVerifyPassword(String verifyPassword) {
12+
this.verifyPassword = verifyPassword;
13+
}
14+
}

src/main/resources/application.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
spring.datasource.url=jdbc:mysql://localhost:3306/techjobs?useLegacyDatetimeCode=false&verifyServerCertificate=false&useSSL=false&requireSSL=false&allowPublicKeyRetrieval=true&serverTimezone=America/Chicago
2-
spring.datasource.username=techjobs
3-
spring.datasource.password=techjobs
1+
spring.datasource.url=jdbc:mysql://localhost:3306/coding-events
2+
spring.datasource.username=coding-events
3+
spring.datasource.password=password
44

55
# Specify the DBMS
66
spring.jpa.database = MYSQL
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!DOCTYPE html>
2+
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
3+
<head th:replace="fragments :: head"></head>
4+
<body class="container">
5+
6+
<header th:replace="fragments :: header"></header>
7+
8+
<form method="post">
9+
<div class="form-group">
10+
<label th:for="username">Username
11+
<input class="form-control" th:field="${loginFormDTO.username}">
12+
</label>
13+
<p class="error" th:errors="${loginFormDTO.username}"></p>
14+
</div>
15+
<div class="form-group">
16+
<label>Password
17+
<input class="form-control" th:field="${loginFormDTO.password}" type="password">
18+
</label>
19+
<p class="error" th:errors="${loginFormDTO.password}"></p>
20+
</div>
21+
22+
<input type="submit" class="btn btn-primary" value="Log In" />
23+
</form>
24+
25+
<p>Don't have an account? <a href="/register">Register for one.</a></p>
26+
27+
</body>
28+
</html>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!DOCTYPE html>
2+
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
3+
<head th:replace="fragments :: head"></head>
4+
<body class="container">
5+
6+
<header th:replace="fragments :: header"></header>
7+
8+
<form method="post">
9+
<div class="form-group">
10+
<label>Username
11+
<input class="form-control" th:field="${registerFormDTO.username}" />
12+
</label>
13+
<p class="error" th:errors="${registerFormDTO.username}"></p>
14+
</div>
15+
<div class="form-group">
16+
<label>Password
17+
<input class="form-control" th:field="${registerFormDTO.password}" type="password" />
18+
</label>
19+
<p class="error" th:errors="${registerFormDTO.password}"></p>
20+
</div>
21+
<div class="form-group">
22+
<label>Verify Password
23+
<input class="form-control" th:field="${registerFormDTO.verifyPassword}" type="password" />
24+
</label>
25+
</div>
26+
27+
<input type="submit" class="btn btn-primary" value="Register" />
28+
</form>
29+
30+
</body>
31+
</html>

0 commit comments

Comments
 (0)