Merge branch 'release/5.32.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / store / LoginManager.java
index 42c6e74930cf78578a5035d6f33747be26b750c0..36b8adffd81adbc8611434f7758b82f169037ae6 100644 (file)
@@ -1,30 +1,38 @@
-// $Id$
 /**
 * Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy 
+* European Distributed Institute of Taxonomy
 * http://www.e-taxonomy.eu
-* 
+*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * See LICENSE.TXT at the top of this package for the full license terms.
 */
-
 package eu.etaxonomy.taxeditor.store;
 
 import java.util.Observable;
+import java.util.Set;
 
+import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.ui.IMemento;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.LockedException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
-import eu.etaxonomy.cdm.model.common.User;
+import eu.etaxonomy.cdm.api.util.CdmUserHelper;
+import eu.etaxonomy.cdm.api.util.RoleProberImpl;
+import eu.etaxonomy.cdm.api.util.UserHelper;
+import eu.etaxonomy.cdm.model.permission.Group;
+import eu.etaxonomy.cdm.model.permission.User;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
+import eu.etaxonomy.cdm.persistence.permission.Role;
 import eu.etaxonomy.taxeditor.model.IContextListener;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 
 /**
  * <p>LoginManager class.</p>
@@ -34,71 +42,118 @@ import eu.etaxonomy.taxeditor.model.IContextListener;
  * @version 1.0
  */
 public class LoginManager extends Observable implements IConversationEnabled, IContextListener{
-       
+
+       public static final Logger logger = LogManager.getLogger(LoginManager.class);
+
        private ConversationHolder conversation;
-       
+
+       public static final String INCORRECT_CREDENTIALS_MESSAGE = "Login and/or Password incorrect";
+       public static final String ACCOUNT_LOCKED_MESSAGE = "Account is locked";
+       public static final String EMPTY_CREDENTIALS_MESSAGE = "Login and/or Password empty";
+
+
+    private CdmUserHelper userHelper = null;
+
        public LoginManager(){
-               CdmStore.getContextManager().addContextListener(this);
+           CdmStore.getContextManager().addContextListener(this);
+
+       }
+
+       private UserHelper userHelper() {
+
+        if (userHelper == null){
+            userHelper = new CdmUserHelper();
+        }
+        return userHelper;
        }
-       
+
        /**
         * <p>authenticate</p>
         *
         * @param token a {@link org.springframework.security.authentication.UsernamePasswordAuthenticationToken} object.
+        * @return true if the login attempt was successful even if the authentication has changed or not
         */
        public boolean authenticate(String username, String password){
+           try{
+               doAuthenticate(username, password);
+           } catch (CdmAuthenticationException e) {
+               MessagingUtils.warningDialog("Could not authenticate", this, e.getMessage());
+               return false;
+        }
+           return true;
+       }
 
-               // close all open editors
-               if(!StoreUtil.closeAll()){
-                       return false;
-               }
-                       
-               
-               try{
-                       getConversationHolder().bind();
-                       
-                       SecurityContextHolder.clearContext();
-                       
-                       UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);                        
-                       Authentication authentication = CdmStore.getAuthenticationManager().authenticate(token);
-               
-                       SecurityContextHolder.getContext().setAuthentication(authentication);                   
-
-                       this.setChanged();
-                       this.notifyObservers();
-                       return true;
-               }
-               catch(BadCredentialsException e){
-                       StoreUtil.warningDialog("Could not authenticate", this, "Could not authenticate. Reason: Bad Credentials.");
-               }
-               catch(LockedException e){
-                       StoreUtil.warningDialog("Could not authenticate", this, "Could not authenticate. Reason: Account is locked.");
-               }
-               catch(IllegalArgumentException e){
-                       StoreUtil.warningDialog("Could not authenticate", this, "Could not authenticate. Reason: Username and/or Password empty.");
+       public void doAuthenticate(String username, String password) throws CdmAuthenticationException {
+           try {
+               SecurityContextHolder.clearContext();
+               Authentication lastAuthentication = CdmStore.getCurrentAuthentiation();
+
+               UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
+               Authentication authentication = CdmStore.getAuthenticationManager().authenticate(token);
+
+               User user = (User) authentication.getPrincipal();
+               /* circumventing problem with hibernate not refreshing the transient collection authorities in this case,
+                * see http://dev.e-taxonomy.eu/trac/ticket/4053 */
+               user.initAuthorities();
+
+               if(logger.isDebugEnabled()){
+                   StringBuilder gaText = new StringBuilder();
+                   String indent = "    ";
+                   Set<GrantedAuthority> gaSet = user.getGrantedAuthorities();
+                   _logGrantedAuthotities(gaText, indent, gaSet);
+                   for(Group gr : user.getGroups()){
+                       gaText.append(indent).append("gr[").append(gr.hashCode()).append("] \"").append(gr.getName()).append("\" ").append(gr.toString()).append("\n");
+                       _logGrantedAuthotities(gaText, indent + indent, gr.getGrantedAuthorities());
+                   }
+                   logger.debug("User authenticated: " + user.getUsername() + "\n" + gaText.toString());
+               }
+
+               authentication = new UsernamePasswordAuthenticationToken(user,password, authentication.getAuthorities());
+               SecurityContextHolder.getContext().setAuthentication(authentication);
+               CdmApplicationState.setCurrentSecurityContext(SecurityContextHolder.getContext());
+
+               if(!authentication.equals(lastAuthentication)){
+                   this.setChanged();
+                   this.notifyObservers();
+               }
+           } catch(BadCredentialsException e){
+               throw new CdmAuthenticationException(INCORRECT_CREDENTIALS_MESSAGE, e);
+           } catch(LockedException e){
+               throw new CdmAuthenticationException(ACCOUNT_LOCKED_MESSAGE, e);
+           } catch(IllegalArgumentException e){
+               e.printStackTrace();
+               throw new CdmAuthenticationException(EMPTY_CREDENTIALS_MESSAGE, e);
+           }
+
+       }
+
+
+       private void _logGrantedAuthotities(StringBuilder gaText, String indent,
+                       Set<GrantedAuthority> gaSet) {
+               for(GrantedAuthority ga : gaSet){
+                       gaText.append(indent).append("ga[").append(ga.hashCode()).append("] ").append(ga.toString()).append("\n");
                }
-               return false;
        }
-       
+
        /**
         * <p>getAuthenticatedUser</p>
         *
         * @return a {@link eu.etaxonomy.cdm.model.common.User} object.
         */
        public User getAuthenticatedUser(){
-               Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-               
-               if(authentication != null 
-                               && authentication.getPrincipal() != null 
+               Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+
+               if(authentication != null
+                               && authentication.getPrincipal() != null
                                && authentication.getPrincipal() instanceof User){
                        return (User)authentication.getPrincipal();
                }
                return null;
        }
-       
+
        public void logoutAll(){
                SecurityContextHolder.clearContext();
-               notifyObservers();              
+               notifyObservers();
        }
 
        /* (non-Javadoc)
@@ -120,24 +175,32 @@ public class LoginManager extends Observable implements IConversationEnabled, IC
 
        /**
         * Whether the current user has the role admin
-        * 
+        *
         * @return
         */
        public boolean isAdmin() {
-               // FIXME until we have rights implemented properly we do this
-               // by a simple string check. This has to change 
-               
-               return "admin".equals(getAuthenticatedUser().getUsername());
+           boolean result = userHelper().userIs(new RoleProberImpl(Role.ROLE_ADMIN));
+        return result;
        }
 
+       /**
+     * Whether the current user has the role user manager
+     *
+     * @return
+     */
+    public boolean isUserManager() {
+        boolean result = userHelper().userIs(new RoleProberImpl(Role.ROLE_USER_MANAGER));
+        return result;
+    }
+
        @Override
        public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
-               
+
        }
 
        @Override
        public void contextStop(IMemento memento, IProgressMonitor monitor) {
-               
+
        }
 
        @Override
@@ -152,6 +215,6 @@ public class LoginManager extends Observable implements IConversationEnabled, IC
 
        @Override
        public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
-               
+
        }
 }