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.portal.web.admin;
35
36 import java.io.Serializable;
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Locale;
42 import java.util.Map;
43
44 import javax.servlet.http.HttpServletRequest;
45
46 import org.apache.commons.collections.CollectionUtils;
47 import org.apache.commons.lang3.StringUtils;
48 import org.apache.logging.log4j.LogManager;
49 import org.apache.logging.log4j.Logger;
50
51 import fr.paris.lutece.portal.business.right.FeatureGroup;
52 import fr.paris.lutece.portal.business.right.FeatureGroupHome;
53 import fr.paris.lutece.portal.business.right.Right;
54 import fr.paris.lutece.portal.business.user.AdminUser;
55 import fr.paris.lutece.portal.business.user.AdminUserHome;
56 import fr.paris.lutece.portal.business.user.authentication.LuteceDefaultAdminUser;
57 import fr.paris.lutece.portal.business.user.menu.AccessibilityModeAdminUserMenuItemProvider;
58 import fr.paris.lutece.portal.business.user.menu.LanguageAdminUserMenuItemProvider;
59 import fr.paris.lutece.portal.service.admin.AccessDeniedException;
60 import fr.paris.lutece.portal.service.admin.AdminUserService;
61 import fr.paris.lutece.portal.service.dashboard.DashboardService;
62 import fr.paris.lutece.portal.service.dashboard.IDashboardComponent;
63 import fr.paris.lutece.portal.service.datastore.DatastoreService;
64 import fr.paris.lutece.portal.service.init.AppInfo;
65 import fr.paris.lutece.portal.service.message.AdminMessage;
66 import fr.paris.lutece.portal.service.message.AdminMessageService;
67 import fr.paris.lutece.portal.service.plugin.Plugin;
68 import fr.paris.lutece.portal.service.plugin.PluginService;
69 import fr.paris.lutece.portal.service.portal.PortalService;
70 import fr.paris.lutece.portal.service.security.SecurityTokenService;
71 import fr.paris.lutece.portal.service.spring.SpringContextService;
72 import fr.paris.lutece.portal.service.template.AppTemplateService;
73 import fr.paris.lutece.portal.service.user.menu.AdminUserMenuService;
74 import fr.paris.lutece.portal.service.util.AppLogService;
75 import fr.paris.lutece.portal.service.util.AppPathService;
76 import fr.paris.lutece.portal.service.util.AppPropertiesService;
77 import fr.paris.lutece.portal.web.constants.Markers;
78 import fr.paris.lutece.portal.web.constants.Messages;
79 import fr.paris.lutece.portal.web.constants.Parameters;
80 import fr.paris.lutece.portal.web.l10n.LocaleService;
81 import fr.paris.lutece.util.html.HtmlTemplate;
82 import fr.paris.lutece.util.password.IPassword;
83 import fr.paris.lutece.util.password.IPasswordFactory;
84
85
86
87
88 public class AdminMenuJspBean implements Serializable
89 {
90
91
92 private static final String ERROR_INVALID_TOKEN = "Invalid security token";
93 public static final String PROPERTY_LOGOUT_URL = "lutece.admin.logout.url";
94 public static final String PROPERTY_MENU_DEFAULT_POS = "top";
95 public static final String PROPERTY_MENU_DATASTORE_POS = "portal.site.site_property.menu.position";
96 private static final long serialVersionUID = -8939026727319948581L;
97
98
99 private static final String MARK_FEATURE_GROUP_LIST = "feature_group_list";
100 private static final String MARK_USER = "user";
101 private static final String MARK_ADMIN_URL = "admin_url";
102 private static final String MARK_PROD_BASE_URL = "prod_base_url";
103 private static final String MARK_ADMIN_LOGOUT_URL = "admin_logout_url";
104 private static final String MARK_SITE_NAME = "site_name";
105 private static final String MARK_MENU_POS = "menu_pos";
106 private static final String MARK_DASHBOARD_ZONE = "dashboard_zone_";
107 private static final String MARK_JAVASCRIPT_FILE = "javascript_file";
108 private static final String MARK_JAVASCRIPT_FILES = "javascript_files";
109 private static final String MARK_PLUGIN_NAME = "plugin_name";
110 private static final String MARK_PLUGINS_LIST = "plugins_list";
111 private static final String MARK_ADMIN_AVATAR = "adminAvatar";
112 private static final String MARK_MINIMUM_PASSWORD_SIZE = "minimumPasswordSize";
113 private static final String MARK_USER_MENU_ITEMS = "userMenuItems";
114 private static final String MARK_LIST_LOGGER_INFO = "listLoggersInfo";
115
116
117 private static final String TEMPLATE_ADMIN_HOME = "admin/user/admin_home.html";
118 private static final String TEMPLATE_ADMIN_MENU_HEADER = "admin/user/admin_header.html";
119 private static final String TEMPLATE_ADMIN_MENU_FOOTER = "admin/user/admin_footer.html";
120 private static final String TEMPLATE_MODIFY_PASSWORD_DEFAULT_MODULE = "admin/user/modify_password_default_module.html";
121 private static final String TEMPLATE_STYLESHEET_LINK = "admin/stylesheet_link.html";
122 private static final String TEMPLATE_JAVASCRIPT_FILE = "admin/javascript_file.html";
123
124
125 private static final String PARAMETER_LANGUAGE = "language";
126
127
128 private static final String PROPERTY_DEFAULT_FEATURE_ICON = "lutece.admin.feature.default.icon";
129 private static final String PROPERTY_DASHBOARD_ZONES = "lutece.dashboard.zones.count";
130 private static final int PROPERTY_DASHBOARD_ZONES_DEFAULT = 4;
131 private static final String REFERER = "referer";
132
133
134 private static final String PROPERTY_JSP_URL_ADMIN_LOGOUT = "lutece.admin.logout.url";
135 private static final String MESSAGE_CONTROL_PASSWORD_NO_CORRESPONDING = "portal.users.message.password.confirm.error";
136 private static final String PASSWORD_ERROR = "portal.users.message.password.wrong.current";
137 private static final String PASSWORD_CURRENT_ERROR = "portal.users.message.password.new.equals.current";
138 private static final String MESSAGE_PASSWORD_REDIRECT = "portal.users.message.password.ok.redirect";
139 private static final String LOGGER_ACCESS = "lutece.adminaccess";
140
141 private static String _strStylesheets;
142 private static boolean _bResetAdminStylesheets;
143 private static String _strJavascripts;
144 private boolean _bAdminAvatar = PluginService.isPluginEnable( "adminavatar" );
145 private static Logger _loggerAccess = LogManager.getLogger( LOGGER_ACCESS );
146
147
148
149
150
151
152
153
154 public String getAdminMenuHeader( HttpServletRequest request )
155 {
156 Map<String, Object> model = new HashMap<>( );
157 String strSiteName = PortalService.getSiteName( );
158 AdminUser user = AdminUserService.getAdminUser( request );
159 List<FeatureGroup> aFeaturesGroupList = getFeatureGroupsList( user );
160
161
162 model.put( MARK_SITE_NAME, strSiteName );
163 model.put( MARK_MENU_POS, DatastoreService.getInstanceDataValue( PROPERTY_MENU_DATASTORE_POS, PROPERTY_MENU_DEFAULT_POS ) );
164 model.put( MARK_FEATURE_GROUP_LIST, aFeaturesGroupList );
165 model.put( MARK_ADMIN_URL, AppPathService.getBaseUrl( request ) + AppPathService.getAdminMenuUrl( ) );
166 model.put( MARK_PROD_BASE_URL, AppPathService.getProdUrl( request ) );
167 model.put( MARK_USER, user );
168 if ( user.isAdmin( ) )
169 {
170 model.put( MARK_LIST_LOGGER_INFO, AppLogService.getLoggersInfo( ) );
171 }
172
173 String strLogoutUrl = AppPropertiesService.getProperty( PROPERTY_LOGOUT_URL );
174 model.put( MARK_ADMIN_LOGOUT_URL, ( strLogoutUrl == null ) ? "" : strLogoutUrl );
175
176 int nZoneMax = AppPropertiesService.getPropertyInt( PROPERTY_DASHBOARD_ZONES, PROPERTY_DASHBOARD_ZONES_DEFAULT );
177 setDashboardData( model, user, request, nZoneMax );
178
179 model.put( MARK_ADMIN_AVATAR, _bAdminAvatar );
180 AdminUserMenuService registry = SpringContextService.getBean( AdminUserMenuService.BEAN_NAME );
181 model.put( MARK_USER_MENU_ITEMS, registry.getItems( request ) );
182
183 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_MENU_HEADER, user.getLocale( ), model );
184
185 return template.getHtml( );
186 }
187
188
189
190
191
192
193
194
195 public String getAdminMenuFooter( HttpServletRequest request )
196 {
197 Map<String, Object> model = new HashMap<>( );
198 String strFooterVersion = AppInfo.getVersion( );
199 String strFooterSiteName = PortalService.getSiteName( );
200 AdminUser user = AdminUserService.getAdminUser( request );
201 Locale locale = ( user != null ) ? user.getLocale( ) : LocaleService.getDefault( );
202 model.put( Markers.VERSION, strFooterVersion );
203 model.put( MARK_SITE_NAME, strFooterSiteName );
204 model.put( MARK_JAVASCRIPT_FILES, getAdminJavascripts( ) );
205
206 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_MENU_FOOTER, locale, model );
207
208 traceAdminAccess( request );
209
210 return template.getHtml( );
211 }
212
213
214
215
216
217
218
219
220 public String getAdminMenuUser( HttpServletRequest request )
221 {
222 AdminUser user = AdminUserService.getAdminUser( request );
223
224 Map<String, Object> model = new HashMap<>( );
225
226 setDashboardData( model, user, request );
227
228 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_HOME, user.getLocale( ), model );
229
230 return template.getHtml( );
231 }
232
233
234
235
236
237
238
239
240
241
242
243 private void setDashboardData( Map<String, Object> model, AdminUser user, HttpServletRequest request )
244 {
245 List<IDashboardComponent> listDashboards = DashboardService.getInstance( ).getDashboards( user, request );
246 int nZoneMax = AppPropertiesService.getPropertyInt( PROPERTY_DASHBOARD_ZONES, PROPERTY_DASHBOARD_ZONES_DEFAULT );
247
248 if ( CollectionUtils.isNotEmpty( listDashboards ) )
249 {
250 int nColumnCount = DashboardService.getInstance( ).getColumnCount( );
251
252
253 for ( int i = 1; i <= nColumnCount; i++ )
254 {
255 model.put( MARK_DASHBOARD_ZONE + i, DashboardService.getInstance( ).getDashboardData( listDashboards, user, i, request ) );
256 }
257
258
259 for ( int i = nColumnCount + 1; i < nZoneMax; i++ )
260 {
261 model.put( MARK_DASHBOARD_ZONE + i, DashboardService.getInstance( ).getDashboardData( user, i, request ) );
262 }
263 }
264 else
265 {
266 for ( int i = 1; i < nZoneMax; i++ )
267 {
268 model.put( MARK_DASHBOARD_ZONE + i, DashboardService.getInstance( ).getDashboardData( user, i, request ) );
269 }
270 }
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285 private void setDashboardData( Map<String, Object> model, AdminUser user, HttpServletRequest request, int nDashboardZone )
286 {
287 model.put( MARK_DASHBOARD_ZONE + nDashboardZone, DashboardService.getInstance( ).getDashboardData( user, nDashboardZone, request ) );
288 }
289
290
291
292
293
294
295
296
297 private List<FeatureGroup> getFeatureGroupsList( AdminUser user )
298 {
299
300 ArrayList<FeatureGroup> aOutFeatureGroupList = new ArrayList<>( );
301
302
303 Map<String, Right> featuresMap = user.getRights( );
304 List<Right> features = new ArrayList<>( featuresMap.values( ) );
305
306 List<Right> rightsToDelete = new ArrayList<>( );
307
308
309 for ( Right right : features )
310 {
311 if ( right.getUrl( ) == null )
312 {
313 rightsToDelete.add( right );
314 }
315 }
316
317 features.removeAll( rightsToDelete );
318
319 Collections.sort( features );
320
321
322 for ( FeatureGroup featureGroup : FeatureGroupHome.getFeatureGroupsList( ) )
323 {
324 ArrayList<Right> aLeftFeatures = new ArrayList<>( );
325
326 for ( Right right : features )
327 {
328 right.setLocale( user.getLocale( ) );
329 right.setIconUrl( getFeatureIcon( right ) );
330
331 String strFeatureGroup = right.getFeatureGroup( );
332
333 if ( featureGroup.getId( ).equalsIgnoreCase( strFeatureGroup ) )
334 {
335 featureGroup.addFeature( right );
336 }
337 else
338 {
339 aLeftFeatures.add( right );
340 }
341 }
342
343 if ( !featureGroup.isEmpty( ) )
344 {
345 featureGroup.setLocale( user.getLocale( ) );
346 aOutFeatureGroupList.add( featureGroup );
347 }
348
349 features = aLeftFeatures;
350 }
351
352
353 if ( CollectionUtils.isNotEmpty( aOutFeatureGroupList ) )
354 {
355 FeatureGroup lastFeatureGroup = aOutFeatureGroupList.get( aOutFeatureGroupList.size( ) - 1 );
356
357 for ( Right right : features )
358 {
359 lastFeatureGroup.addFeature( right );
360 }
361 }
362
363 return aOutFeatureGroupList;
364 }
365
366
367
368
369
370
371
372
373
374
375 public String doChangeLanguage( HttpServletRequest request ) throws AccessDeniedException
376 {
377 if ( !SecurityTokenService.getInstance( ).validate( request, LanguageAdminUserMenuItemProvider.TEMPLATE ) )
378 {
379 throw new AccessDeniedException( ERROR_INVALID_TOKEN );
380 }
381 String strLanguage = request.getParameter( PARAMETER_LANGUAGE );
382 AdminUser user = AdminUserService.getAdminUser( request );
383 Locale locale = new Locale( strLanguage );
384 user.setLocale( locale );
385 AppPathService.getBaseUrl( request );
386
387 return AppPathService.getBaseUrl( request ) + AppPathService.getAdminMenuUrl( );
388 }
389
390
391
392
393
394
395
396
397 private String getFeatureIcon( Right right )
398 {
399 String strIconUrl = AppPropertiesService.getProperty( PROPERTY_DEFAULT_FEATURE_ICON );
400
401 if ( ( right.getIconUrl( ) != null ) && ( !right.getIconUrl( ).equals( "" ) ) )
402 {
403 strIconUrl = right.getIconUrl( );
404 }
405 else
406 {
407 String strPluginName = right.getPluginName( );
408 Plugin plugin = PluginService.getPlugin( strPluginName );
409
410 if ( plugin != null )
411 {
412 strIconUrl = plugin.getIconUrl( );
413 }
414 }
415
416 return strIconUrl;
417 }
418
419
420
421
422
423
424
425
426 public String getModifyDefaultAdminUserPassword( HttpServletRequest request )
427 {
428 AdminUser user = AdminUserService.getAdminUser( request );
429 Locale locale = user.getLocale( );
430 Map<String, Object> model = new HashMap<>( );
431 model.put( MARK_MINIMUM_PASSWORD_SIZE, AdminUserService.getIntegerSecurityParameter( AdminUserService.DSKEY_PASSWORD_MINIMUM_LENGTH ) );
432 model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MODIFY_PASSWORD_DEFAULT_MODULE ) );
433 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MODIFY_PASSWORD_DEFAULT_MODULE, locale, model );
434
435 return template.getHtml( );
436 }
437
438
439
440
441
442
443
444
445
446
447 public String doModifyDefaultAdminUserPassword( HttpServletRequest request ) throws AccessDeniedException
448 {
449 AdminUser user = AdminUserService.getAdminUser( request );
450
451 String strCurrentPassword = request.getParameter( Parameters.PASSWORD_CURRENT );
452 String strNewPassword = request.getParameter( Parameters.NEW_PASSWORD );
453 String strConfirmNewPassword = request.getParameter( Parameters.CONFIRM_NEW_PASSWORD );
454
455 LuteceDefaultAdminUser userStored = AdminUserHome.findLuteceDefaultAdminUserByPrimaryKey( user.getUserId( ) );
456
457 IPassword password = userStored.getPassword( );
458
459
460 if ( StringUtils.isEmpty( strCurrentPassword ) || StringUtils.isEmpty( strNewPassword ) || StringUtils.isEmpty( strConfirmNewPassword ) )
461 {
462 return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
463 }
464
465
466 if ( !strNewPassword.equals( strConfirmNewPassword ) )
467 {
468 return AdminMessageService.getMessageUrl( request, MESSAGE_CONTROL_PASSWORD_NO_CORRESPONDING, AdminMessage.TYPE_STOP );
469 }
470
471 String strUrl = AdminUserService.checkPassword( request, strNewPassword, user.getUserId( ) );
472
473 if ( StringUtils.isNotEmpty( strUrl ) )
474 {
475 return strUrl;
476 }
477
478
479 if ( !password.check( strCurrentPassword ) )
480 {
481 return AdminMessageService.getMessageUrl( request, PASSWORD_ERROR, AdminMessage.TYPE_STOP );
482 }
483
484
485 if ( strCurrentPassword.equals( strNewPassword ) )
486 {
487 return AdminMessageService.getMessageUrl( request, PASSWORD_CURRENT_ERROR, AdminMessage.TYPE_STOP );
488 }
489 if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_MODIFY_PASSWORD_DEFAULT_MODULE ) )
490 {
491 throw new AccessDeniedException( ERROR_INVALID_TOKEN );
492 }
493
494
495 IPasswordFactory passwordFactory = SpringContextService.getBean( IPasswordFactory.BEAN_NAME );
496 userStored.setPassword( passwordFactory.getPasswordFromCleartext( strNewPassword ) );
497 userStored.setPasswordReset( Boolean.FALSE );
498 userStored.setPasswordMaxValidDate( AdminUserService.getPasswordMaxValidDate( ) );
499 AdminUserHome.update( userStored );
500 AdminUserHome.insertNewPasswordInHistory( userStored.getPassword( ), userStored.getUserId( ) );
501
502 return AdminMessageService.getMessageUrl( request, MESSAGE_PASSWORD_REDIRECT, AppPropertiesService.getProperty( PROPERTY_JSP_URL_ADMIN_LOGOUT ),
503 AdminMessage.TYPE_INFO );
504 }
505
506
507
508
509
510
511
512
513
514
515 public String doModifyAccessibilityMode( HttpServletRequest request ) throws AccessDeniedException
516 {
517 if ( !SecurityTokenService.getInstance( ).validate( request, AccessibilityModeAdminUserMenuItemProvider.TEMPLATE ) )
518 {
519 throw new AccessDeniedException( ERROR_INVALID_TOKEN );
520 }
521 AdminUser user = AdminUserService.getAdminUser( request );
522
523 if ( user != null )
524 {
525 boolean bIsAccessible = !user.getAccessibilityMode( );
526 user.setAccessibilityMode( bIsAccessible );
527 AdminUserHome.update( user );
528 }
529
530 String strReferer = request.getHeader( REFERER );
531
532 if ( StringUtils.isNotBlank( strReferer ) )
533 {
534 return strReferer;
535 }
536
537 return AppPathService.getBaseUrl( request ) + AppPathService.getAdminMenuUrl( );
538 }
539
540
541
542
543
544
545
546 public String getAdminStyleSheets( )
547 {
548 loadStylesheets( );
549 return _strStylesheets;
550 }
551
552 private static synchronized void loadStylesheets( )
553 {
554 if ( _strStylesheets == null || _bResetAdminStylesheets )
555 {
556 List<Plugin> listPlugins = new ArrayList<>( );
557 listPlugins.add( PluginService.getCore( ) );
558 listPlugins.addAll( PluginService.getPluginList( ) );
559
560 Map<String, Object> model = new HashMap<>( );
561 model.put( MARK_PLUGINS_LIST, listPlugins );
562
563 _strStylesheets = AppTemplateService.getTemplate( TEMPLATE_STYLESHEET_LINK, LocaleService.getDefault( ), model ).getHtml( );
564 _bResetAdminStylesheets = false;
565 }
566 }
567
568 public static void resetAdminStylesheets( )
569 {
570 _bResetAdminStylesheets = true;
571 }
572
573
574
575
576
577
578
579 private static synchronized String getAdminJavascripts( )
580 {
581 if ( _strJavascripts == null )
582 {
583 StringBuilder sbJavascripts = new StringBuilder( );
584 List<Plugin> listPlugins = new ArrayList<>( );
585 listPlugins.add( PluginService.getCore( ) );
586 listPlugins.addAll( PluginService.getPluginList( ) );
587
588 for ( Plugin plugin : listPlugins )
589 {
590 if ( plugin.getAdminJavascriptFiles( ) != null )
591 {
592 for ( String strJavascript : plugin.getAdminJavascriptFiles( ) )
593 {
594 Map<String, Object> model = new HashMap<>( );
595 model.put( MARK_JAVASCRIPT_FILE, strJavascript );
596 model.put( MARK_PLUGIN_NAME, plugin.getName( ) );
597 sbJavascripts.append( AppTemplateService.getTemplate( TEMPLATE_JAVASCRIPT_FILE, LocaleService.getDefault( ), model ).getHtml( ) );
598 }
599 }
600 }
601
602 _strJavascripts = sbJavascripts.toString( );
603 }
604
605 return _strJavascripts;
606 }
607
608
609
610
611
612
613
614 private void traceAdminAccess( HttpServletRequest request )
615 {
616 AdminUser user = AdminUserService.getAdminUser( request );
617 if ( user != null )
618 {
619 StringBuilder sbAccessLog = new StringBuilder( );
620 sbAccessLog.append( "USER id:" ).append( user.getUserId( ) ).append( ", name: " ).append( user.getFirstName( ) ).append( " " )
621 .append( user.getLastName( ) ).append( ", ip: " ).append( request.getRemoteAddr( ) ).append( ", url: " ).append( request.getScheme( ) )
622 .append( "://" ).append( request.getServerName( ) ).append( ':' ).append( request.getServerPort( ) ).append( request.getRequestURI( ) );
623 String strQuery = request.getQueryString( );
624 if ( strQuery != null )
625 {
626 sbAccessLog.append( "?" ).append( strQuery );
627 }
628 _loggerAccess.info( sbAccessLog.toString( ) );
629
630 }
631 }
632 }