1 package fr.ifremer.quadrige3.ui.swing.content.login;
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
27 import com.google.common.base.Objects;
28 import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
29 import fr.ifremer.quadrige3.core.security.AuthenticationInfo;
30 import fr.ifremer.quadrige3.core.security.SecurityContextHelper;
31 import fr.ifremer.quadrige3.core.security.remote.AuthenticationRemoteException;
32 import fr.ifremer.quadrige3.core.security.remote.AuthenticationRemoteService;
33 import fr.ifremer.quadrige3.core.service.ClientServiceLocator;
34 import fr.ifremer.quadrige3.core.service.administration.user.UserService;
35 import fr.ifremer.quadrige3.core.vo.administration.user.QuserVO;
36 import fr.ifremer.quadrige3.core.vo.system.generalCondition.GeneralConditionVO;
37 import fr.ifremer.quadrige3.synchro.service.client.SynchroRestClientService;
38 import fr.ifremer.quadrige3.ui.swing.DialogHelper;
39 import fr.ifremer.quadrige3.ui.swing.action.AbstractReloadCurrentScreenAction;
40 import fr.ifremer.quadrige3.ui.swing.action.CloseApplicationAction;
41 import fr.ifremer.quadrige3.ui.swing.content.AbstractMainUIHandler;
42 import org.apache.commons.lang3.StringUtils;
43 import org.apache.commons.lang3.builder.ToStringBuilder;
44 import org.apache.commons.lang3.builder.ToStringStyle;
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47 import org.nuiton.jaxx.application.swing.action.AbstractApplicationAction;
48
49 import javax.swing.*;
50
51 import static org.nuiton.i18n.I18n.t;
52
53
54
55
56
57
58
59 public class AuthenticationAction extends AbstractReloadCurrentScreenAction {
60
61 private static final Log LOG = LogFactory.getLog(AuthenticationAction.class);
62
63
64
65
66
67
68
69
70
71
72
73
74 private AbstractApplicationAction callbackAction;
75 private boolean authenticated;
76 private boolean authenticationCanceled;
77
78
79
80
81
82
83 public AuthenticationAction(AbstractMainUIHandler handler) {
84 this(handler, null);
85 }
86
87
88
89
90
91
92
93 public AuthenticationAction(AbstractMainUIHandler handler, AbstractApplicationAction callbackAction) {
94 super(handler, true);
95 this.callbackAction = callbackAction;
96 setActionDescription(t("quadrige3.action.authenticate.title"));
97 }
98
99
100 @Override
101 public void doActionBeforeReload() {
102
103
104 authenticated = false;
105 authenticationCanceled = false;
106 UserService userService = ClientServiceLocator.instance().getUserService();
107
108
109 String message = null;
110 if (callbackAction != null) {
111 message = callbackAction.getActionDescription();
112 }
113
114 while (!authenticated) {
115
116
117 AuthenticationInfo authenticationInfo = getHandler().askAuthenticationInfo(message);
118
119 if (authenticationInfo == null
120 || StringUtils.isBlank(authenticationInfo.getLogin())) {
121
122 if (LOG.isDebugEnabled()) {
123 LOG.debug("insufficient authentication information, cancelling action");
124 }
125 callbackAction = null;
126 authenticationCanceled = true;
127 setSkipScreenReload(true);
128
129 if (getConfig().isAuthenticationForced() && !getContext().isAuthenticated()) {
130
131 getContext().getErrorHelper().showErrorDialog(t("quadrige3.action.authenticate.forced.message", getConfig().getApplicationName()));
132 getActionEngine().runInternalAction(handler, CloseApplicationAction.class);
133 }
134
135 return;
136 }
137
138 String login = authenticationInfo.getLogin();
139 boolean isLocalUserWithEmptyPassword = userService.isLocalUserWithNoPassword(login);
140
141 try {
142
143
144 if (isLocalUserWithEmptyPassword) {
145
146
147 if (StringUtils.isNotEmpty(authenticationInfo.getPassword())) {
148 getContext().getErrorHelper().showErrorDialog(t("quadrige3.error.authenticate.badCredential"));
149
150
151 if (!getConfig().isAuthenticationForced()) {
152 return;
153 }
154 }
155 else {
156 authenticated = SecurityContextHelper.authenticate(login, null);
157 }
158 }
159
160 else {
161
162 if (StringUtils.isBlank(authenticationInfo.getPassword())) {
163 throw new AuthenticationRemoteException(t("quadrige3.error.authenticate.badCredential"));
164 }
165
166 boolean hasPasswordInDatabase;
167 if (getConfig().isAuthenticationDisabled()) {
168
169
170 hasPasswordInDatabase = true;
171 } else {
172
173
174 hasPasswordInDatabase = userService.hasPassword(login);
175 }
176
177
178 if (hasPasswordInDatabase) {
179
180
181 authenticated = SecurityContextHelper.authenticate(login, authenticationInfo.getPassword());
182
183 }
184
185
186 if (!authenticated) {
187
188
189 AuthenticationRemoteService authRemoteService = ClientServiceLocator.instance().getAuthenticationRemoteService();
190 boolean remoteAuthenticated = authRemoteService.canAuthenticate(authenticationInfo);
191
192 if (remoteAuthenticated) {
193
194
195 userService.resetPassword(login);
196 hasPasswordInDatabase = false;
197
198
199 authenticated = SecurityContextHelper.authenticate(login, null);
200
201
202 if (!authenticated) {
203
204 if (tryUpdatePersonFromServer(authenticationInfo)) {
205
206 userService.resetPassword(login);
207 authenticated = SecurityContextHelper.authenticate(login, null);
208 } else {
209 throw new AuthenticationRemoteException(t("quadrige3.error.authenticate.badCredential"));
210 }
211 }
212 }
213 }
214
215 if (!authenticated) {
216 throw new AuthenticationRemoteException(t("quadrige3.error.authenticate.notFound", login));
217 }
218
219 if (LOG.isDebugEnabled()) {
220 LOG.debug("user '" + login + "' authenticated");
221 }
222
223 if (!hasPasswordInDatabase) {
224
225 userService.updatePasswordByUserId(
226 SecurityContextHelper.getQuadrigeUserId(),
227 authenticationInfo.getPassword());
228 }
229 }
230 } catch (AuthenticationRemoteException ae) {
231
232 getContext().getErrorHelper().showErrorDialog(ae.getLocalizedMessage());
233
234
235 if (!getConfig().isAuthenticationForced()) {
236 return;
237 }
238 }
239 }
240
241
242 getContext().setAuthenticated(authenticated);
243
244 if (authenticated) {
245
246 getConfig().setAuthenticationDefaultUsername(getContext().getAuthenticationInfo().getLogin());
247
248
249 SynchroRestClientService synchroRestClientService = ClientServiceLocator.instance().getSynchroRestClientService();
250 GeneralConditionVO condition = null;
251 try {
252 condition = synchroRestClientService.getLastNonAcceptedGeneralCondition(getContext().getAuthenticationInfo());
253 } catch (QuadrigeTechnicalException e) {
254
255 }
256 if (condition != null) {
257
258 int result = getContext().getDialogHelper().showOptionDialog(
259 getContext().getMainUI(),
260 null,
261 condition.getContent(),
262 t("quadrige3.action.authenticate.generalCondition.confirm"),
263 t("quadrige3.action.authenticate.generalCondition.title"),
264 DialogHelper.QUESTION_MESSAGE_WITH_LARGE_TEXT,
265 JOptionPane.YES_NO_OPTION
266 );
267
268
269 if (result == JOptionPane.YES_OPTION) {
270 synchroRestClientService.acceptGeneralCondition(getContext().getAuthenticationInfo(), condition.getId());
271 } else {
272 getActionEngine().runInternalAction(handler, CloseApplicationAction.class);
273 }
274 }
275 }
276
277 }
278
279
280 @Override
281 public void postSuccessAction() {
282 super.postSuccessAction();
283
284
285 if (authenticationCanceled) {
286 return;
287 }
288
289
290 if (authenticated && callbackAction != null) {
291 if (LOG.isDebugEnabled()) {
292 LOG.debug("run callback action " + callbackAction.getClass().getSimpleName());
293 }
294 SwingUtilities.invokeLater(() -> getActionEngine().runAction(callbackAction));
295 }
296
297 }
298
299
300 @Override
301 public void postFailedAction(Throwable error) {
302 super.postFailedAction(error);
303
304 getContext().setAuthenticated(false);
305
306 }
307
308
309
310
311
312
313
314
315
316 protected boolean tryUpdatePersonFromServer(AuthenticationInfo authenticationInfo) {
317 if (!getConfig().isSynchronizationEnabled()) {
318 return false;
319 }
320
321
322 QuserVO user;
323 try {
324 SynchroRestClientService synchroRestClientService = ClientServiceLocator.instance().getSynchroRestClientService();
325 user = synchroRestClientService.getUser(authenticationInfo);
326 } catch (QuadrigeTechnicalException e) {
327 return false;
328 }
329
330 if (user == null) {
331 return false;
332 }
333
334
335 if (!Objects.equal(user.getQuserIntranetLg(), authenticationInfo.getLogin())
336 && !Objects.equal(user.getQuserExtranetLg(), authenticationInfo.getLogin())) {
337 LOG.warn(String.format("Synchronization server send a bad person, with wrong login: expected [%s] but found [username=%s] and [usernameExtranet=%s]. Check configuration on synchro server.",
338 authenticationInfo.getLogin(),
339 user.getQuserIntranetLg(),
340 user.getQuserExtranetLg()));
341 return false;
342 }
343
344 if (LOG.isDebugEnabled()) {
345 LOG.debug("Will save person, retrieve from synchro server: " + ToStringBuilder.reflectionToString(user, ToStringStyle.SHORT_PREFIX_STYLE));
346 }
347 UserService personService = ClientServiceLocator.instance().getUserService();
348 personService.save(user, true);
349
350 return true;
351 }
352
353 }