1 package fr.ifremer.reefdb.security;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.google.common.collect.Lists;
27 import fr.ifremer.quadrige3.core.dao.administration.user.PrivilegeCode;
28 import fr.ifremer.quadrige3.core.dao.referential.StatusCode;
29 import fr.ifremer.quadrige3.core.dao.technical.Assert;
30 import fr.ifremer.quadrige3.core.dao.technical.hibernate.TemporaryDataHelper;
31 import fr.ifremer.quadrige3.core.security.Encryption;
32 import fr.ifremer.quadrige3.core.security.QuadrigeUserDetails;
33 import fr.ifremer.reefdb.config.ReefDbConfiguration;
34 import fr.ifremer.reefdb.dao.administration.user.ReefDbQuserDao;
35 import fr.ifremer.reefdb.dao.technical.Daos;
36 import fr.ifremer.reefdb.dto.ReefDbBeanFactory;
37 import fr.ifremer.reefdb.dto.ReefDbBeans;
38 import fr.ifremer.reefdb.dto.referential.PersonDTO;
39 import fr.ifremer.reefdb.service.ReefDbTechnicalException;
40 import org.apache.commons.lang3.StringUtils;
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.nuiton.i18n.I18n;
44 import org.springframework.beans.factory.annotation.Autowired;
45 import org.springframework.context.annotation.Lazy;
46 import org.springframework.security.core.userdetails.UserDetails;
47 import org.springframework.security.core.userdetails.UserDetailsService;
48 import org.springframework.security.core.userdetails.UsernameNotFoundException;
49 import org.springframework.stereotype.Service;
50 import org.springframework.transaction.annotation.Transactional;
51
52 import javax.annotation.Resource;
53 import java.util.List;
54
55
56
57
58
59
60 @Lazy
61 @Transactional
62 @Service("reefDbUserDetailsService")
63 public class ReefDbUserDetailsServiceImpl implements UserDetailsService {
64
65 private static final Log LOG = LogFactory.getLog(ReefDbUserDetailsServiceImpl.class);
66
67 private boolean disabled;
68
69 private final String mockUsername;
70 private final String mockCryptPassword;
71 private final Integer mockUserId;
72
73 @Resource
74 protected ReefDbQuserDao reefDbQuserDao;
75
76
77
78
79
80
81 @Autowired
82 public ReefDbUserDetailsServiceImpl(ReefDbConfiguration config) {
83 disabled = config.isAuthenticationDisabled();
84
85
86 if (disabled) {
87 Assert.notBlank(config.getAuthenticationMockUsername(),
88 "Mock username must be set, when authentication is disable");
89 Assert.notBlank(config.getAuthenticationMockPassword(),
90 "Mock username must be set, when authentication is disable");
91
92 mockUsername = config.getAuthenticationMockUsername();
93 mockCryptPassword = Encryption.sha(config.getAuthenticationMockPassword());
94 mockUserId = config.getAuthenticationMockUserId();
95
96 LOG.debug(String.format("Authentication disable. Only this login/password is allowed: [%s/%s]",
97 mockUsername,
98 config.getAuthenticationMockPassword()));
99 } else {
100 mockUsername = null;
101 mockCryptPassword = null;
102 mockUserId = null;
103 }
104 }
105
106
107
108
109
110
111 public void setDisabled(boolean disabled) {
112 this.disabled = disabled;
113
114 if (disabled) {
115 LOG.warn("Authentication has been disabled by the configuration. Please contact your administrator to ask the credentials for test.");
116 }
117 }
118
119
120 @Override
121 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
122
123 if (StringUtils.isBlank(username)) {
124 String error = "username must not be blank";
125 LOG.error(error);
126 throw new UsernameNotFoundException(error);
127 }
128
129 if (disabled) {
130 return loadTestUser(username);
131 }
132
133 PersonDTO person;
134 try {
135
136 person = reefDbQuserDao.getUserByLogin(Lists.newArrayList(
137 StatusCode.ENABLE.value(),
138 StatusCode.LOCAL_ENABLE.value()),
139 username);
140 } catch (Exception e) {
141
142 LOG.error(e.getMessage(), e);
143 throw new ReefDbTechnicalException(e);
144 }
145
146 if (person == null) {
147 String error = I18n.t("reefdb.error.authentication.userNotFoundOrDisable", username);
148 LOG.error(error);
149 throw new UsernameNotFoundException(error);
150 }
151
152 String cryptedPassword = reefDbQuserDao.getPasswordByUserId(person.getId());
153 List<String> privilegeCodes = reefDbQuserDao.getPrivilegeCodesByUserId(person.getId());
154 boolean localUser = TemporaryDataHelper.isTemporaryId(person.getId()) || ReefDbBeans.isLocalStatus(person.getStatus());
155
156 return new QuadrigeUserDetails(person.getId(), person.getFirstName() + " " + person.getName(), cryptedPassword, privilegeCodes, localUser);
157 }
158
159 private UserDetails loadTestUser(String username) throws UsernameNotFoundException {
160
161 if (!mockUsername.equals(username)) {
162 String error = String.format("Bad username [%s]. Only [%s] is allow, because authentication is disable.", username, mockUsername);
163 LOG.error(error);
164 throw new UsernameNotFoundException(error);
165 }
166
167 PersonDTO person = ReefDbBeanFactory.newPersonDTO();
168 person.setId(mockUserId);
169 person.setFirstName(mockUsername);
170 person.setName("ReefDb");
171 person.setDepartment(null);
172
173
174 List<String> privilegesCodes = reefDbQuserDao.getPrivilegeCodesByUserId(person.getId());
175
176
177 if (!privilegesCodes.contains(PrivilegeCode.LOCAL_ADMINISTRATOR.value()))
178 privilegesCodes.add(PrivilegeCode.LOCAL_ADMINISTRATOR.value());
179 if (!privilegesCodes.contains(PrivilegeCode.QUALIFIER.value()))
180 privilegesCodes.add(PrivilegeCode.QUALIFIER.value());
181
182 return new QuadrigeUserDetails(mockUserId, mockUsername, mockCryptPassword, privilegesCodes, TemporaryDataHelper.isTemporaryId(mockUserId));
183 }
184 }