Skip to content

Commit fe198c0

Browse files
committed
9_11_auth_via_user_service
1 parent 465f610 commit fe198c0

File tree

8 files changed

+115
-17
lines changed

8 files changed

+115
-17
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package ru.javawebinar.topjava;
2+
3+
import ru.javawebinar.topjava.model.User;
4+
import ru.javawebinar.topjava.to.UserTo;
5+
import ru.javawebinar.topjava.util.UsersUtil;
6+
7+
import java.io.Serial;
8+
9+
public class AuthorizedUser extends org.springframework.security.core.userdetails.User {
10+
@Serial
11+
private static final long serialVersionUID = 1L;
12+
13+
private UserTo userTo;
14+
15+
public AuthorizedUser(User user) {
16+
super(user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, user.getRoles());
17+
this.userTo = UsersUtil.asTo(user);
18+
}
19+
20+
public int getId() {
21+
return userTo.id();
22+
}
23+
24+
public void update(UserTo newTo) {
25+
userTo = newTo;
26+
}
27+
28+
public UserTo getUserTo() {
29+
return userTo;
30+
}
31+
32+
@Override
33+
public String toString() {
34+
return userTo.toString();
35+
}
36+
}
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
package ru.javawebinar.topjava.model;
22

3-
public enum Role {
3+
import org.springframework.security.core.GrantedAuthority;
4+
5+
public enum Role implements GrantedAuthority {
46
USER,
5-
ADMIN
7+
ADMIN;
8+
9+
// https://stackoverflow.com/a/19542316/548473
10+
@Override
11+
public String getAuthority() {
12+
return "ROLE_" + name();
13+
}
614
}

src/main/java/ru/javawebinar/topjava/service/UserService.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22

33
import org.springframework.cache.annotation.CacheEvict;
44
import org.springframework.cache.annotation.Cacheable;
5+
import org.springframework.context.annotation.Scope;
6+
import org.springframework.context.annotation.ScopedProxyMode;
7+
import org.springframework.security.core.userdetails.UserDetailsService;
8+
import org.springframework.security.core.userdetails.UsernameNotFoundException;
59
import org.springframework.stereotype.Service;
610
import org.springframework.transaction.annotation.Transactional;
711
import org.springframework.util.Assert;
12+
import ru.javawebinar.topjava.AuthorizedUser;
813
import ru.javawebinar.topjava.model.User;
914
import ru.javawebinar.topjava.repository.UserRepository;
1015
import ru.javawebinar.topjava.to.UserTo;
@@ -14,8 +19,9 @@
1419

1520
import static ru.javawebinar.topjava.util.ValidationUtil.checkNotFound;
1621

17-
@Service
18-
public class UserService {
22+
@Service("userService")
23+
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
24+
public class UserService implements UserDetailsService {
1925

2026
private final UserRepository repository;
2127

@@ -72,6 +78,15 @@ public void enable(int id, boolean enabled) {
7278
repository.save(user); // !! need only for JDBC implementation
7379
}
7480

81+
@Override
82+
public AuthorizedUser loadUserByUsername(String email) throws UsernameNotFoundException {
83+
User user = repository.getByEmail(email.toLowerCase());
84+
if (user == null) {
85+
throw new UsernameNotFoundException("User " + email + " is not found");
86+
}
87+
return new AuthorizedUser(user);
88+
}
89+
7590
public User getWithMeals(int id) {
7691
return checkNotFound(repository.getWithMeals(id), id);
7792
}

src/main/java/ru/javawebinar/topjava/to/UserTo.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package ru.javawebinar.topjava.to;
22

3+
import org.hibernate.validator.constraints.Range;
4+
import ru.javawebinar.topjava.util.UsersUtil;
5+
36
import javax.validation.constraints.Email;
47
import javax.validation.constraints.NotBlank;
8+
import javax.validation.constraints.NotNull;
59
import javax.validation.constraints.Size;
10+
import java.io.Serial;
11+
import java.io.Serializable;
612

7-
public class UserTo extends BaseTo {
13+
public class UserTo extends BaseTo implements Serializable {
14+
@Serial
15+
private static final long serialVersionUID = 1L;
816

917
@NotBlank
1018
@Size(min = 2, max = 100)
@@ -19,14 +27,19 @@ public class UserTo extends BaseTo {
1927
@Size(min = 5, max = 32, message = "length must be between 5 and 32 characters")
2028
private String password;
2129

30+
@Range(min = 10, max = 10000)
31+
@NotNull
32+
private Integer caloriesPerDay = UsersUtil.DEFAULT_CALORIES_PER_DAY;
33+
2234
public UserTo() {
2335
}
2436

25-
public UserTo(Integer id, String name, String email, String password) {
37+
public UserTo(Integer id, String name, String email, String password, int caloriesPerDay) {
2638
super(id);
2739
this.name = name;
2840
this.email = email;
2941
this.password = password;
42+
this.caloriesPerDay = caloriesPerDay;
3043
}
3144

3245
public String getPassword() {
@@ -53,12 +66,17 @@ public void setEmail(String email) {
5366
this.email = email;
5467
}
5568

69+
public Integer getCaloriesPerDay() {
70+
return caloriesPerDay;
71+
}
72+
5673
@Override
5774
public String toString() {
5875
return "UserTo{" +
5976
"id=" + id +
6077
", name='" + name + '\'' +
6178
", email='" + email + '\'' +
79+
", caloriesPerDay='" + caloriesPerDay + '\'' +
6280
'}';
6381
}
6482
}

src/main/java/ru/javawebinar/topjava/util/UsersUtil.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ public static User createNewFromTo(UserTo userTo) {
1212
return new User(null, userTo.getName(), userTo.getEmail().toLowerCase(), userTo.getPassword(), Role.USER);
1313
}
1414

15+
public static UserTo asTo(User user) {
16+
return new UserTo(user.getId(), user.getName(), user.getEmail(), user.getPassword(), user.getCaloriesPerDay());
17+
}
18+
1519
public static User updateFromTo(User user, UserTo userTo) {
1620
user.setName(userTo.getName());
1721
user.setEmail(userTo.getEmail().toLowerCase());
22+
user.setCaloriesPerDay(userTo.getCaloriesPerDay());
1823
user.setPassword(userTo.getPassword());
1924
return user;
2025
}
Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
package ru.javawebinar.topjava.web;
22

3-
import ru.javawebinar.topjava.model.AbstractBaseEntity;
3+
import org.springframework.security.core.Authentication;
4+
import org.springframework.security.core.context.SecurityContextHolder;
5+
import ru.javawebinar.topjava.AuthorizedUser;
46

5-
import static ru.javawebinar.topjava.util.UsersUtil.DEFAULT_CALORIES_PER_DAY;
7+
import static java.util.Objects.requireNonNull;
68

79
public class SecurityUtil {
810

9-
private static int id = AbstractBaseEntity.START_SEQ;
10-
1111
private SecurityUtil() {
1212
}
1313

14-
public static int authUserId() {
15-
return id;
14+
public static AuthorizedUser safeGet() {
15+
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
16+
if (auth == null) {
17+
return null;
18+
}
19+
Object principal = auth.getPrincipal();
20+
return (principal instanceof AuthorizedUser) ? (AuthorizedUser) principal : null;
1621
}
1722

18-
public static void setAuthUserId(int id) {
19-
SecurityUtil.id = id;
23+
public static AuthorizedUser get() {
24+
return requireNonNull(safeGet(), "No authorized user found");
25+
}
26+
27+
public static int authUserId() {
28+
return get().getUserTo().id();
2029
}
2130

2231
public static int authUserCaloriesPerDay() {
23-
return DEFAULT_CALORIES_PER_DAY;
32+
return get().getUserTo().getCaloriesPerDay();
2433
}
2534
}

src/main/resources/spring/spring-security.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,19 @@
3030
</http>
3131

3232
<authentication-manager>
33-
<authentication-provider>
33+
<authentication-provider user-service-ref="userService">
3434
<password-encoder ref="noopEncoder"/>
35+
<!--
36+
<jdbc-user-service data-source-ref="dataSource"
37+
users-by-username-query="SELECT email, password, enabled FROM users WHERE email = ?"
38+
authorities-by-username-query="
39+
SELECT u.email, r.role FROM users u, user_roles r WHERE u.id = r.user_id AND u.email = ?"
40+
/>
3541
<user-service>
3642
<user name="user@yandex.ru" password="password" authorities="ROLE_USER"/>
3743
<user name="admin@gmail.com" password="admin" authorities="ROLE_ADMIN"/>
3844
</user-service>
45+
-->
3946
</authentication-provider>
4047
</authentication-manager>
4148
</beans:beans>

src/test/java/ru/javawebinar/topjava/web/user/ProfileRestControllerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void delete() throws Exception {
3939

4040
@Test
4141
void update() throws Exception {
42-
UserTo updatedTo = new UserTo(null, "newName", "user@yandex.ru", "newPassword");
42+
UserTo updatedTo = new UserTo(null, "newName", "user@yandex.ru", "newPassword", 1500);
4343
perform(MockMvcRequestBuilders.put(REST_URL).contentType(MediaType.APPLICATION_JSON)
4444
.content(JsonUtil.writeValue(updatedTo)))
4545
.andDo(print())

0 commit comments

Comments
 (0)