Skip to content

Commit 90203c7

Browse files
committed
UserService.findByLogin(): replace by findUserDetailsByLogin().
Addressed to #120 No functional changes.
1 parent 3cc24fe commit 90203c7

File tree

13 files changed

+153
-53
lines changed

13 files changed

+153
-53
lines changed

src/main/java/ru/mystamps/web/dao/JdbcUserDao.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
*/
1818
package ru.mystamps.web.dao;
1919

20+
import ru.mystamps.web.dao.dto.UserDetails;
21+
2022
public interface JdbcUserDao {
2123
long countByLogin(String login);
24+
UserDetails findUserDetailsByLogin(String login);
2225
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (C) 2009-2016 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.dao.dto;
19+
20+
import lombok.Getter;
21+
import lombok.RequiredArgsConstructor;
22+
import lombok.ToString;
23+
24+
@Getter
25+
@RequiredArgsConstructor
26+
@ToString(exclude = "hash")
27+
public class UserDetails {
28+
private final Integer id;
29+
private final String login;
30+
private final String name;
31+
private final String hash;
32+
private final Role role;
33+
private final Integer collectionId;
34+
private final String collectionSlug;
35+
36+
public enum Role {
37+
USER, ADMIN
38+
};
39+
40+
public boolean isAdmin() {
41+
return role == Role.ADMIN;
42+
}
43+
44+
}

src/main/java/ru/mystamps/web/dao/impl/JdbcUserDaoImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
import java.util.Collections;
2121

2222
import org.springframework.beans.factory.annotation.Value;
23+
import org.springframework.dao.EmptyResultDataAccessException;
2324
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
2425

2526
import lombok.RequiredArgsConstructor;
2627

2728
import ru.mystamps.web.dao.JdbcUserDao;
29+
import ru.mystamps.web.dao.dto.UserDetails;
2830

2931
@RequiredArgsConstructor
3032
public class JdbcUserDaoImpl implements JdbcUserDao {
@@ -34,6 +36,9 @@ public class JdbcUserDaoImpl implements JdbcUserDao {
3436
@Value("${user.count_users_by_login}")
3537
private String countByLoginSql;
3638

39+
@Value("${user.find_user_details_by_login}")
40+
private String findUserDetailsByLoginSql;
41+
3742
@Override
3843
public long countByLogin(String login) {
3944
return jdbcTemplate.queryForObject(
@@ -43,4 +48,17 @@ public long countByLogin(String login) {
4348
);
4449
}
4550

51+
@Override
52+
public UserDetails findUserDetailsByLogin(String login) {
53+
try {
54+
return jdbcTemplate.queryForObject(
55+
findUserDetailsByLoginSql,
56+
Collections.singletonMap("login", login),
57+
RowMappers::forUserDetails
58+
);
59+
} catch (EmptyResultDataAccessException ex) {
60+
return null;
61+
}
62+
}
63+
4664
}

src/main/java/ru/mystamps/web/dao/impl/RowMappers.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import ru.mystamps.web.dao.dto.CollectionInfoDto;
2626
import ru.mystamps.web.dao.dto.SeriesFullInfoDto;
2727
import ru.mystamps.web.dao.dto.SuspiciousActivityDto;
28+
import ru.mystamps.web.dao.dto.UserDetails;
2829
import ru.mystamps.web.dao.dto.UsersActivationDto;
2930
import ru.mystamps.web.dao.dto.UsersActivationFullDto;
3031
import ru.mystamps.web.service.dto.LinkEntityDto;
@@ -210,4 +211,16 @@ public static CollectionInfoDto forCollectionInfoDto(ResultSet rs, int i) throws
210211
);
211212
}
212213

214+
public static UserDetails forUserDetails(ResultSet rs, int i) throws SQLException {
215+
return new UserDetails(
216+
rs.getInt("id"),
217+
rs.getString("login"),
218+
rs.getString("name"),
219+
rs.getString("hash"),
220+
UserDetails.Role.valueOf(rs.getString("role")),
221+
rs.getInt("collection_id"),
222+
rs.getString("collection_slug")
223+
);
224+
}
225+
213226
}

src/main/java/ru/mystamps/web/entity/User.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ public class User {
7575
@OneToOne(mappedBy = "owner", optional = false, fetch = FetchType.LAZY)
7676
private Collection collection;
7777

78-
public boolean isAdmin() {
79-
return role == Role.ADMIN;
80-
}
81-
8278
public enum Role {
8379
USER, ADMIN
8480
};

src/main/java/ru/mystamps/web/service/UserService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
*/
1818
package ru.mystamps.web.service;
1919

20-
import ru.mystamps.web.entity.User;
20+
import ru.mystamps.web.dao.dto.UserDetails;
2121
import ru.mystamps.web.service.dto.ActivateAccountDto;
2222

2323
public interface UserService {
2424
void registerUser(ActivateAccountDto dto);
25-
User findByLogin(String login);
25+
UserDetails findUserDetailsByLogin(String login);
2626
long countByLogin(String login);
2727
}

src/main/java/ru/mystamps/web/service/UserServiceImpl.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
import ru.mystamps.web.dao.JdbcUserDao;
3535
import ru.mystamps.web.dao.UserDao;
36+
import ru.mystamps.web.dao.dto.UserDetails;
3637
import ru.mystamps.web.dao.dto.UsersActivationDto;
3738
import ru.mystamps.web.entity.User;
3839
import ru.mystamps.web.service.dto.ActivateAccountDto;
@@ -102,10 +103,10 @@ public void registerUser(ActivateAccountDto dto) {
102103

103104
@Override
104105
@Transactional(readOnly = true)
105-
public User findByLogin(String login) {
106-
Validate.isTrue(login != null, "Login should be non null");
106+
public UserDetails findUserDetailsByLogin(String login) {
107+
Validate.isTrue(login != null, "Login must be non null");
107108

108-
return userDao.findByLogin(login);
109+
return jdbcUserDao.findUserDetailsByLogin(login);
109110
}
110111

111112
@Override

src/main/java/ru/mystamps/web/support/spring/security/CustomUserDetails.java

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,30 @@
2121

2222
import org.springframework.security.core.GrantedAuthority;
2323

24-
import ru.mystamps.web.entity.User;
24+
import lombok.Getter;
2525

26+
import ru.mystamps.web.dao.dto.UserDetails;
27+
28+
@Getter
29+
@SuppressWarnings("PMD.SingularField")
2630
public class CustomUserDetails extends org.springframework.security.core.userdetails.User {
27-
private final User user;
28-
29-
public CustomUserDetails(User user, Collection<? extends GrantedAuthority> authorities) {
30-
super(user.getLogin(), user.getHash(), authorities);
31-
this.user = user;
32-
}
3331

34-
@Deprecated
35-
public User getUser() {
36-
return user;
37-
}
32+
private final Integer userId;
3833

3934
// used in controllers for getting info about current user
35+
private final String userName;
36+
private final Integer userCollectionId;
37+
private final String userCollectionSlug;
4038

41-
public String getUserName() {
42-
return user.getName();
43-
}
44-
45-
public Integer getUserCollectionId() {
46-
return user.getCollection().getId();
47-
}
48-
49-
public String getUserCollectionSlug() {
50-
return user.getCollection().getSlug();
39+
public CustomUserDetails(
40+
UserDetails userDetails,
41+
Collection<? extends GrantedAuthority> authorities) {
42+
43+
super(userDetails.getLogin(), userDetails.getHash(), authorities);
44+
this.userId = userDetails.getId();
45+
this.userName = userDetails.getName();
46+
this.userCollectionId = userDetails.getCollectionId();
47+
this.userCollectionSlug = userDetails.getCollectionSlug();
5148
}
5249

5350
}

src/main/java/ru/mystamps/web/support/spring/security/CustomUserDetailsService.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,12 @@
3030

3131
import org.springframework.security.core.GrantedAuthority;
3232
import org.springframework.security.core.authority.SimpleGrantedAuthority;
33-
import org.springframework.security.core.userdetails.UserDetails;
3433
import org.springframework.security.core.userdetails.UserDetailsService;
3534
import org.springframework.security.core.userdetails.UsernameNotFoundException;
3635

3736
import lombok.RequiredArgsConstructor;
3837

39-
import ru.mystamps.web.entity.User;
38+
import ru.mystamps.web.dao.dto.UserDetails;
4039
import ru.mystamps.web.service.UserService;
4140

4241
/**
@@ -49,31 +48,32 @@ public class CustomUserDetailsService implements UserDetailsService {
4948

5049
private final UserService userService;
5150

51+
// CheckStyle: ignore LineLength for next 3 lines
5252
@Override
5353
@Transactional(readOnly = true)
54-
public UserDetails loadUserByUsername(String login) {
54+
public org.springframework.security.core.userdetails.UserDetails loadUserByUsername(String login) {
5555
Validate.isTrue(login != null, "Login should be non null");
5656

5757
LOG.debug("Find user by login '{}'", login);
5858

59-
User user = userService.findByLogin(login);
60-
if (user == null) {
59+
UserDetails userDetails = userService.findUserDetailsByLogin(login);
60+
if (userDetails == null) {
6161
LOG.debug("User '{}' not found", login);
6262
throw new UsernameNotFoundException("User not found");
6363
}
6464

6565
LOG.debug("User '{}' found", login);
6666

67-
return new CustomUserDetails(user, getAuthorities(user));
67+
return new CustomUserDetails(userDetails, getAuthorities(userDetails));
6868
}
6969

70-
private static Collection<? extends GrantedAuthority> getAuthorities(User user) {
70+
private static Collection<? extends GrantedAuthority> getAuthorities(UserDetails userDetails) {
7171
List<SimpleGrantedAuthority> authorities = new LinkedList<>();
7272
authorities.add(new SimpleGrantedAuthority("CREATE_SERIES"));
7373
authorities.add(new SimpleGrantedAuthority("UPDATE_COLLECTION"));
7474
authorities.add(new SimpleGrantedAuthority("ADD_IMAGES_TO_SERIES"));
7575

76-
if (user.isAdmin()) {
76+
if (userDetails.isAdmin()) {
7777
authorities.add(new SimpleGrantedAuthority("CREATE_CATEGORY"));
7878
authorities.add(new SimpleGrantedAuthority("CREATE_COUNTRY"));
7979
authorities.add(new SimpleGrantedAuthority("ADD_COMMENTS_TO_SERIES"));

src/main/java/ru/mystamps/web/support/spring/security/SecurityContextUtils.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
import org.springframework.security.core.context.SecurityContextHolder;
2626
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
2727

28-
import ru.mystamps.web.entity.User;
29-
3028
public final class SecurityContextUtils {
3129

3230
private SecurityContextUtils() {
@@ -46,8 +44,7 @@ public static Integer getUserId() {
4644
.map(Authentication::getPrincipal)
4745
.filter(CustomUserDetails.class::isInstance)
4846
.map(CustomUserDetails.class::cast)
49-
.map(CustomUserDetails::getUser)
50-
.map(User::getId)
47+
.map(CustomUserDetails::getUserId)
5148
.orElse(null);
5249
}
5350

src/main/resources/sql/user_dao_queries.properties

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,16 @@ user.count_users_by_login = \
22
SELECT COUNT(*) \
33
FROM users \
44
WHERE login = :login
5+
6+
user.find_user_details_by_login = \
7+
SELECT u.id \
8+
, u.login \
9+
, u.name \
10+
, u.hash \
11+
, u.role \
12+
, c.id AS collection_id \
13+
, c.slug AS collection_slug \
14+
FROM users u \
15+
JOIN collections c \
16+
ON c.user_id = u.id \
17+
WHERE u.login = :login

src/test/groovy/ru/mystamps/web/service/UserServiceImplTest.groovy

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import spock.lang.Specification
2323

2424
import ru.mystamps.web.dao.JdbcUserDao
2525
import ru.mystamps.web.dao.UserDao
26+
import ru.mystamps.web.dao.dto.UserDetails
2627
import ru.mystamps.web.dao.dto.UsersActivationDto
2728
import ru.mystamps.web.entity.User
2829
import ru.mystamps.web.entity.User.Role
@@ -275,31 +276,31 @@ class UserServiceImplTest extends Specification {
275276
}
276277

277278
//
278-
// Tests for findByLogin()
279+
// Tests for findUserDetailsByLogin()
279280
//
280281

281-
def "findByLogin() should throw exception when login is null"() {
282+
def "findUserDetailsByLogin() should throw exception when login is null"() {
282283
when:
283-
service.findByLogin(null)
284+
service.findUserDetailsByLogin(null)
284285
then:
285286
thrown IllegalArgumentException
286287
}
287288

288-
def "findByLogin() should call dao"() {
289+
def "findUserDetailsByLogin() should call dao"() {
289290
given:
290-
User expectedUser = TestObjects.createUser()
291-
userDao.findByLogin(_ as String) >> expectedUser
291+
UserDetails expectedUserDetails = TestObjects.createUserDetails()
292+
jdbcUserDao.findUserDetailsByLogin(_ as String) >> expectedUserDetails
292293
when:
293-
User user = service.findByLogin('any-login')
294+
UserDetails userDetails = service.findUserDetailsByLogin('any-login')
294295
then:
295-
user == expectedUser
296+
userDetails == expectedUserDetails
296297
}
297298

298-
def "findByLogin() should pass login to dao"() {
299+
def "findUserDetailsByLogin() should pass login to dao"() {
299300
when:
300-
service.findByLogin('john')
301+
service.findUserDetailsByLogin('john')
301302
then:
302-
1 * userDao.findByLogin('john')
303+
1 * jdbcUserDao.findUserDetailsByLogin('john')
303304
}
304305

305306
//

src/test/java/ru/mystamps/web/service/TestObjects.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.util.Date;
2121

22+
import ru.mystamps.web.dao.dto.UserDetails;
2223
import ru.mystamps.web.dao.dto.UsersActivationDto;
2324
import ru.mystamps.web.dao.dto.UsersActivationFullDto;
2425
import ru.mystamps.web.entity.Image;
@@ -85,6 +86,22 @@ public static User createUser() {
8586
return user;
8687
}
8788

89+
public static UserDetails createUserDetails() {
90+
final Integer anyId = 777;
91+
Integer collectionId = anyId;
92+
String collectionSlug = TEST_LOGIN;
93+
94+
return new UserDetails(
95+
anyId,
96+
TEST_LOGIN,
97+
TEST_NAME,
98+
TEST_HASH,
99+
UserDetails.Role.USER,
100+
collectionId,
101+
collectionSlug
102+
);
103+
}
104+
88105
public static Image createImage() {
89106
Image image = new Image();
90107
image.setId(1);

0 commit comments

Comments
 (0)