1
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
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.mylutece.modules.database.authentication;
35
36 import java.sql.Timestamp;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.Collection;
40 import java.util.HashMap;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Locale;
44 import java.util.Map;
45 import java.util.Set;
46 import java.util.stream.Collectors;
47
48 import javax.security.auth.login.FailedLoginException;
49 import javax.security.auth.login.LoginException;
50 import javax.servlet.http.HttpServletRequest;
51
52 import org.apache.commons.lang3.StringUtils;
53
54 import fr.paris.lutece.plugins.mylutece.authentication.PortalAuthentication;
55 import fr.paris.lutece.plugins.mylutece.authentication.logs.ConnectionLog;
56 import fr.paris.lutece.plugins.mylutece.authentication.logs.ConnectionLogHome;
57 import fr.paris.lutece.plugins.mylutece.business.LuteceUserAttributeDescription;
58 import fr.paris.lutece.plugins.mylutece.business.LuteceUserRoleDescription;
59 import fr.paris.lutece.plugins.mylutece.business.attribute.AttributeField;
60 import fr.paris.lutece.plugins.mylutece.business.attribute.AttributeFieldHome;
61 import fr.paris.lutece.plugins.mylutece.business.attribute.AttributeHome;
62 import fr.paris.lutece.plugins.mylutece.business.attribute.IAttribute;
63 import fr.paris.lutece.plugins.mylutece.business.attribute.MyLuteceUserField;
64 import fr.paris.lutece.plugins.mylutece.business.attribute.MyLuteceUserFieldHome;
65 import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseHome;
66 import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseUserHome;
67 import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.GroupRoleHome;
68 import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.parameter.DatabaseUserParameterHome;
69 import fr.paris.lutece.plugins.mylutece.modules.database.authentication.service.DatabaseAccountLifeTimeService;
70 import fr.paris.lutece.plugins.mylutece.modules.database.authentication.service.DatabasePlugin;
71 import fr.paris.lutece.plugins.mylutece.modules.database.authentication.service.DatabaseService;
72 import fr.paris.lutece.plugins.mylutece.modules.database.authentication.web.MyLuteceDatabaseApp;
73 import fr.paris.lutece.plugins.mylutece.service.MyLutecePlugin;
74 import fr.paris.lutece.plugins.mylutece.util.SecurityUtils;
75 import fr.paris.lutece.portal.business.role.RoleHome;
76 import fr.paris.lutece.portal.business.template.DatabaseTemplateHome;
77 import fr.paris.lutece.portal.service.i18n.I18nService;
78 import fr.paris.lutece.portal.service.mail.MailService;
79 import fr.paris.lutece.portal.service.plugin.Plugin;
80 import fr.paris.lutece.portal.service.plugin.PluginService;
81 import fr.paris.lutece.portal.service.security.FailedLoginCaptchaException;
82 import fr.paris.lutece.portal.service.security.LoginRedirectException;
83 import fr.paris.lutece.portal.service.security.LuteceUser;
84 import fr.paris.lutece.portal.service.template.AppTemplateService;
85 import fr.paris.lutece.portal.service.util.AppException;
86 import fr.paris.lutece.portal.service.util.AppLogService;
87 import fr.paris.lutece.portal.service.util.AppPathService;
88 import fr.paris.lutece.portal.service.util.AppPropertiesService;
89 import fr.paris.lutece.util.ReferenceItem;
90 import fr.paris.lutece.util.html.HtmlTemplate;
91 import fr.paris.lutece.util.http.SecurityUtil;
92
93
94
95
96
97
98
99
100
101 public class BaseAuthentication extends PortalAuthentication
102 {
103
104
105 private static final String AUTH_SERVICE_NAME = AppPropertiesService.getProperty( "mylutece-database.service.name" );
106 private static final String PLUGIN_JCAPTCHA = "jcaptcha";
107
108
109 private static final String PROPERTY_MAX_ACCESS_FAILED = "access_failures_max";
110 private static final String PROPERTY_ACCESS_FAILED_CAPTCHA = "access_failures_captcha";
111 private static final String PROPERTY_INTERVAL_MINUTES = "access_failures_interval";
112 private static final String PROPERTY_UNBLOCK_USER = "mylutece_database_unblock_user";
113 private static final String PROPERTY_TOO_MANY_FAILURES = "mylutece.ip.labelTooManyLoginTrials";
114
115
116 private static final String PARAMETER_UNBLOCK_USER_MAIL_SENDER = "unblock_user_mail_sender";
117 private static final String PARAMETER_UNBLOCK_USER_MAIL_SUBJECT = "unblock_user_mail_subject";
118 private static final String PARAMETER_ENABLE_UNBLOCK_IP = "enable_unblock_ip";
119
120
121 private static final String MARK_URL = "url";
122 private static final String MARK_SITE_LINK = "site_link";
123
124
125 private static final String PROPERTY_MESSAGE_USER_NOT_FOUND_DATABASE = "module.mylutece.database.message.userNotFoundDatabase";
126
127
128 private static final String CONSTANT_PATH_ICON = "images/local/skin/plugins/mylutece/modules/database/mylutece-database.png";
129 private static final String BEAN_USER_ATTRIBUTES_SERVICE = "mylutece.myLuteceUserAttributesService";
130
131
132
133
134
135 public BaseAuthentication( )
136 {
137 super( );
138 }
139
140
141
142
143
144
145 @Override
146 public String getAuthServiceName( )
147 {
148 return AUTH_SERVICE_NAME;
149 }
150
151
152
153
154
155
156
157
158 @Override
159 public String getAuthType( HttpServletRequest request )
160 {
161 return HttpServletRequest.BASIC_AUTH;
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179 @Override
180 public LuteceUser login( String strUserName, String strUserPassword, HttpServletRequest request ) throws LoginException
181 {
182 try
183 {
184 return super.login( strUserName, strUserPassword, request );
185 }
186 catch( LoginRedirectException lre )
187 {
188 throw new AppException( "Mylutece-database: impossible. this code should never be reached.", lre );
189 }
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 @Override
206 public LuteceUser processLogin( String strUserName, String strUserPassword, HttpServletRequest request ) throws LoginException
207 {
208 DatabaseService databaseService = DatabaseService.getService( );
209
210 Plugin pluginMyLutece = PluginService.getPlugin( MyLutecePlugin.PLUGIN_NAME );
211 Plugin plugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
212
213
214 ConnectionLog connectionLog = new ConnectionLog( );
215 connectionLog.setIpAddress( SecurityUtil.getRealIp( request ) );
216 connectionLog.setDateLogin( new java.sql.Timestamp( new java.util.Date( ).getTime( ) ) );
217
218
219 int nMaxFailed = DatabaseUserParameterHome.getIntegerSecurityParameter( PROPERTY_MAX_ACCESS_FAILED, plugin );
220 int nMaxFailedCaptcha = 0;
221 int nIntervalMinutes = DatabaseUserParameterHome.getIntegerSecurityParameter( PROPERTY_INTERVAL_MINUTES, plugin );
222 boolean bEnableCaptcha = false;
223
224 if ( PluginService.isPluginEnable( PLUGIN_JCAPTCHA ) )
225 {
226 nMaxFailedCaptcha = DatabaseUserParameterHome.getIntegerSecurityParameter( PROPERTY_ACCESS_FAILED_CAPTCHA, plugin );
227 }
228
229 Locale locale = request.getLocale( );
230
231 if ( ( ( nMaxFailed > 0 ) || ( nMaxFailedCaptcha > 0 ) ) && ( nIntervalMinutes > 0 ) )
232 {
233 int nNbFailed = ConnectionLogHome.getLoginErrors( connectionLog, nIntervalMinutes, pluginMyLutece );
234
235 if ( ( nMaxFailedCaptcha > 0 ) && ( nNbFailed >= nMaxFailedCaptcha ) )
236 {
237 bEnableCaptcha = true;
238 }
239
240 if ( ( nMaxFailed > 0 ) && ( nNbFailed >= nMaxFailed ) )
241 {
242 if ( nNbFailed == nMaxFailed )
243 {
244 ReferenceItem item = DatabaseUserParameterHome.findByKey( PARAMETER_ENABLE_UNBLOCK_IP, plugin );
245
246 if ( ( item != null ) && item.isChecked( ) )
247 {
248 sendUnlockLinkToUser( strUserName, nIntervalMinutes, request, plugin );
249 }
250 }
251
252 Object [ ] args = {
253 Integer.toString( nIntervalMinutes )
254 };
255 String strMessage = I18nService.getLocalizedString( PROPERTY_TOO_MANY_FAILURES, args, locale );
256
257 if ( bEnableCaptcha )
258 {
259 throw new FailedLoginCaptchaException( strMessage, bEnableCaptcha );
260 }
261 else
262 {
263 throw new FailedLoginException( strMessage );
264 }
265 }
266 }
267
268 BaseUser user = DatabaseHome.findLuteceUserByLogin( strUserName, plugin, this );
269
270
271 if ( ( user == null ) || !databaseService.isUserActive( strUserName, plugin ) )
272 {
273 AppLogService.info( "Unable to find user in the database : " + strUserName );
274
275 if ( bEnableCaptcha )
276 {
277 throw new FailedLoginCaptchaException( I18nService.getLocalizedString( PROPERTY_MESSAGE_USER_NOT_FOUND_DATABASE, locale ), bEnableCaptcha );
278 }
279 else
280 {
281 throw new FailedLoginException( I18nService.getLocalizedString( PROPERTY_MESSAGE_USER_NOT_FOUND_DATABASE, locale ) );
282 }
283 }
284
285
286 if ( !databaseService.checkPassword( strUserName, strUserPassword, plugin ) )
287 {
288 AppLogService.info( "User login : Incorrect login or password" + strUserName );
289
290 if ( bEnableCaptcha )
291 {
292 throw new FailedLoginCaptchaException( I18nService.getLocalizedString( PROPERTY_MESSAGE_USER_NOT_FOUND_DATABASE, locale ), bEnableCaptcha );
293 }
294 else
295 {
296 throw new FailedLoginException( I18nService.getLocalizedString( PROPERTY_MESSAGE_USER_NOT_FOUND_DATABASE, locale ) );
297 }
298 }
299
300
301 List<String> arrayRoles = DatabaseHome.findUserRolesFromLogin( strUserName, plugin );
302
303 if ( !arrayRoles.isEmpty( ) )
304 {
305 user.addRoles( arrayRoles );
306 }
307
308
309 List<String> arrayGroups = DatabaseHome.findUserGroupsFromLogin( strUserName, plugin );
310
311 if ( !arrayGroups.isEmpty( ) )
312 {
313 user.setGroups( arrayGroups );
314 }
315
316
317 setLocalDatabaseUserAttributes( locale, user );
318
319
320 Timestamp passwordMaxValidDate = DatabaseHome.findPasswordMaxValideDateFromLogin( strUserName, plugin );
321
322 if ( ( passwordMaxValidDate != null ) && ( passwordMaxValidDate.getTime( ) < new java.util.Date( ).getTime( ) ) )
323 {
324 DatabaseHome.updateResetPasswordFromLogin( strUserName, Boolean.TRUE, plugin );
325 }
326
327 int nUserId = DatabaseHome.findUserIdFromLogin( strUserName, plugin );
328 databaseService.updateUserExpirationDate( nUserId, plugin );
329
330 return user;
331 }
332
333
334
335
336
337
338
339 @Override
340 public void logout( LuteceUser user )
341 {
342
343 }
344
345
346
347
348
349
350
351
352
353
354 @Override
355 public boolean findResetPassword( HttpServletRequest request, String strLogin )
356 {
357 Plugin plugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
358
359 return DatabaseHome.findResetPasswordFromLogin( strLogin, plugin );
360 }
361
362
363
364
365
366
367 @Override
368 public LuteceUser getAnonymousUser( )
369 {
370 return new BaseUser( LuteceUser.ANONYMOUS_USERNAME, this );
371 }
372
373
374
375
376
377
378
379
380
381
382
383
384 @Override
385 public boolean isUserInRole( LuteceUser user, HttpServletRequest request, String strRole )
386 {
387 String [ ] roles = getRolesByUser( user );
388
389 if ( ( roles != null ) && ( strRole != null ) )
390 {
391 for ( String role : roles )
392 {
393 if ( strRole.equals( role ) )
394 {
395 return true;
396 }
397 }
398 }
399
400 return false;
401 }
402
403
404
405
406
407
408 @Override
409 public String getViewAccountPageUrl( )
410 {
411 return MyLuteceDatabaseApp.getViewAccountUrl( );
412 }
413
414
415
416
417
418
419 @Override
420 public String getNewAccountPageUrl( )
421 {
422 return MyLuteceDatabaseApp.getNewAccountUrl( );
423 }
424
425
426
427
428
429
430 public String getChangePasswordPageUrl( )
431 {
432 return MyLuteceDatabaseApp.getChangePasswordUrl( );
433 }
434
435
436
437
438
439
440 @Override
441 public String getLostPasswordPageUrl( )
442 {
443 return MyLuteceDatabaseApp.getLostPasswordUrl( );
444 }
445
446
447
448
449
450
451 @Override
452 public String getLostLoginPageUrl( )
453 {
454 return MyLuteceDatabaseApp.getLostLoginUrl( );
455 }
456
457
458
459
460 @Override
461 public String getResetPasswordPageUrl( HttpServletRequest request )
462 {
463 return AppPathService.getBaseUrl( request ) + MyLuteceDatabaseApp.getMessageResetPasswordUrl( );
464 }
465
466
467
468
469
470
471 @Override
472 public Collection<LuteceUser> getUsers( )
473 {
474 Plugin plugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
475
476 Collection<BaseUser> baseUsers = DatabaseHome.findDatabaseUsersList( plugin, this );
477 Collection<LuteceUser> luteceUsers = new ArrayList<>( );
478
479 for ( BaseUser user : baseUsers )
480 {
481 luteceUsers.add( user );
482 }
483
484 return luteceUsers;
485 }
486
487
488
489
490
491
492
493
494 @Override
495 public LuteceUser getUser( String userLogin )
496 {
497 Plugin plugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
498
499 return DatabaseHome.findLuteceUserByLogin( userLogin, plugin, this );
500 }
501
502
503
504
505
506
507
508
509 @Override
510 public String [ ] getRolesByUser( LuteceUser user )
511 {
512 Plugin plugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
513 Set<String> setRoles = new HashSet<>( );
514 String [ ] strGroups = user.getGroups( );
515 String [ ] strRoles = user.getRoles( );
516
517 if ( strRoles != null )
518 {
519 setRoles.addAll( Arrays.asList( strRoles ) );
520 }
521
522 if ( strGroups != null )
523 {
524 for ( String strGroupKey : strGroups )
525 {
526 Collection<String> arrayRolesGroup = GroupRoleHome.findGroupRoles( strGroupKey, plugin );
527
528 for ( String strRole : arrayRolesGroup )
529 {
530 setRoles.add( strRole );
531 }
532 }
533 }
534
535 String [ ] strReturnRoles = new String [ setRoles.size( )];
536 setRoles.toArray( strReturnRoles );
537
538 return strReturnRoles;
539 }
540
541
542
543
544
545 @Override
546 public String getIconUrl( )
547 {
548 return CONSTANT_PATH_ICON;
549 }
550
551
552
553
554
555
556
557 @Override
558 public String getName( )
559 {
560 return DatabasePlugin.PLUGIN_NAME;
561 }
562
563
564
565
566 @Override
567 public String getPluginName( )
568 {
569 return DatabasePlugin.PLUGIN_NAME;
570 }
571
572
573
574
575 @Override
576 public void updateDateLastLogin( LuteceUser user, HttpServletRequest request )
577 {
578 DatabaseService databaseService = DatabaseService.getService( );
579 Plugin plugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
580 databaseService.updateUserLastLoginDate( user.getName( ), plugin );
581 }
582
583
584
585
586
587 @Override
588 public List<LuteceUserRoleDescription> getLuteceUserRolesProvided(Locale locale)
589 {
590 return RoleHome.findAll().stream().map(x->new LuteceUserRoleDescription(x, LuteceUserRoleDescription.TYPE_MANUAL_ASSIGNMENT, null)).collect(Collectors.toList());
591
592 }
593
594
595
596
597 @Override
598 public List<LuteceUserAttributeDescription> getLuteceUserAttributesProvided(Locale locale)
599 {
600
601 List<LuteceUserAttributeDescription> listUserDescription= new ArrayList<LuteceUserAttributeDescription>();
602 listUserDescription.add(new LuteceUserAttributeDescription( LuteceUser.NAME_FAMILY, "databaseUser.getLastName()", ""));
603 listUserDescription.add(new LuteceUserAttributeDescription( LuteceUser.NAME_GIVEN, "databaseUser.getFirstName()", ""));
604 listUserDescription.add(new LuteceUserAttributeDescription( LuteceUser.BUSINESS_INFO_ONLINE_EMAIL, "databaseUser.getEmail()", ""));
605 listUserDescription.add(new LuteceUserAttributeDescription( LuteceUser.DATE_LAST_LOGIN, "databaseUser.getLastLogin()", ""));
606
607 Plugin myLutecePlugin = PluginService.getPlugin( MyLutecePlugin.PLUGIN_NAME );
608
609 listUserDescription.addAll(AttributeHome.findAll( locale, myLutecePlugin ).stream().map(x->new LuteceUserAttributeDescription(x.getTitle(),x.getTitle(), x.getHelpMessage())).collect(Collectors.toList()));
610
611 return listUserDescription;
612 }
613
614
615 private void sendUnlockLinkToUser( String strLogin, int nIntervalMinutes, HttpServletRequest request, Plugin plugin )
616 {
617 int nIdUser = DatabaseUserHome.findDatabaseUserIdFromLogin( strLogin, plugin );
618
619 if ( nIdUser > 0 )
620 {
621 ReferenceItem referenceItem = DatabaseUserParameterHome.findByKey( PARAMETER_UNBLOCK_USER_MAIL_SENDER, plugin );
622 String strSender = ( referenceItem == null ) ? StringUtils.EMPTY : referenceItem.getName( );
623
624 referenceItem = DatabaseUserParameterHome.findByKey( PARAMETER_UNBLOCK_USER_MAIL_SUBJECT, plugin );
625
626 String strSubject = ( referenceItem == null ) ? StringUtils.EMPTY : referenceItem.getName( );
627
628 String strLink = SecurityUtils.buildResetConnectionLogUrl( nIntervalMinutes, request );
629
630 Map<String, Object> model = new HashMap<>( );
631 model.put( MARK_URL, strLink );
632 model.put( MARK_SITE_LINK, MailService.getSiteLink( AppPathService.getBaseUrl( request ), true ) );
633
634 String strTemplate = DatabaseTemplateHome.getTemplateFromKey( PROPERTY_UNBLOCK_USER );
635 HtmlTemplate template = AppTemplateService.getTemplateFromStringFtl( strTemplate, request.getLocale( ), model );
636
637 DatabaseAccountLifeTimeServicetication/service/DatabaseAccountLifeTimeService.html#DatabaseAccountLifeTimeService">DatabaseAccountLifeTimeService accountLifeTimeService = new DatabaseAccountLifeTimeService( );
638
639 String strUserMail = accountLifeTimeService.getUserMainEmail( nIdUser );
640
641 if ( ( strUserMail != null ) && StringUtils.isNotBlank( strUserMail ) )
642 {
643 MailService.sendMailHtml( strUserMail, strSender, strSender, strSubject, template.getHtml( ) );
644 }
645 }
646 }
647
648
649
650
651
652
653
654
655 private void setLocalDatabaseUserAttributes( Locale locale, BaseUser user )
656 {
657
658
659 Plugin myLutecePlugin = PluginService.getPlugin( MyLutecePlugin.PLUGIN_NAME );
660 int idUser = DatabaseHome.findUserIdFromLogin( user.getAccessCode( ), myLutecePlugin );
661
662 List<IAttribute> listAttributes = AttributeHome.findAll( locale, myLutecePlugin );
663
664 for ( IAttribute attribute : listAttributes )
665 {
666 List<AttributeField> listAttributeFields = AttributeFieldHome.selectAttributeFieldsByIdAttribute( attribute.getIdAttribute( ), myLutecePlugin );
667 attribute.setListAttributeFields( listAttributeFields );
668
669 List<MyLuteceUserField> listUserFields = MyLuteceUserFieldHome.selectUserFieldsByIdUserIdAttribute( idUser, attribute.getIdAttribute( ),
670 myLutecePlugin );
671
672 if ( listUserFields.size( ) == 1 )
673 {
674 user.setUserInfo( attribute.getTitle( ), listUserFields.get( 0 ).getValue( ) );
675 }
676 else
677 if ( listUserFields.size( ) > 0 )
678 {
679 for ( MyLuteceUserField userField : listUserFields )
680 {
681 user.setUserInfo( attribute.getTitle( ) + "_" + userField.getAttributeField( ).getTitle( ), userField.getValue( ) );
682 }
683 }
684 else
685 {
686 user.setUserInfo( String.valueOf( attribute.getTitle( ) ), StringUtils.EMPTY );
687 }
688 }
689 }
690 }