17d5e4ce5274f49d6cac8aa9e3a66550b60b5e15
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / store / LoginManager.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.taxeditor.store;
10
11 import java.util.Observable;
12 import java.util.Set;
13
14 import org.apache.log4j.Logger;
15 import org.eclipse.core.runtime.IProgressMonitor;
16 import org.eclipse.ui.IMemento;
17 import org.springframework.security.authentication.BadCredentialsException;
18 import org.springframework.security.authentication.LockedException;
19 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
20 import org.springframework.security.core.Authentication;
21 import org.springframework.security.core.GrantedAuthority;
22 import org.springframework.security.core.context.SecurityContextHolder;
23
24 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
25 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
26 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
27 import eu.etaxonomy.cdm.api.util.CdmUserHelper;
28 import eu.etaxonomy.cdm.api.util.RoleProberImpl;
29 import eu.etaxonomy.cdm.api.util.UserHelper;
30 import eu.etaxonomy.cdm.model.permission.Group;
31 import eu.etaxonomy.cdm.model.permission.User;
32 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
33 import eu.etaxonomy.cdm.persistence.permission.Role;
34 import eu.etaxonomy.taxeditor.model.IContextListener;
35 import eu.etaxonomy.taxeditor.model.MessagingUtils;
36
37 /**
38 * <p>LoginManager class.</p>
39 *
40 * @author n.hoffmann
41 * @created 03.07.2009
42 * @version 1.0
43 */
44 public class LoginManager extends Observable implements IConversationEnabled, IContextListener{
45
46 public static final Logger logger = Logger.getLogger(LoginManager.class);
47
48 private ConversationHolder conversation;
49
50 public static final String INCORRECT_CREDENTIALS_MESSAGE = "Login and/or Password incorrect";
51 public static final String ACCOUNT_LOCKED_MESSAGE = "Account is locked";
52 public static final String EMPTY_CREDENTIALS_MESSAGE = "Login and/or Password empty";
53
54
55 private CdmUserHelper userHelper = null;
56
57 public LoginManager(){
58 CdmStore.getContextManager().addContextListener(this);
59
60 }
61
62 private UserHelper userHelper() {
63
64 if (userHelper == null){
65 userHelper = new CdmUserHelper();
66 }
67 return userHelper;
68 }
69
70 /**
71 * <p>authenticate</p>
72 *
73 * @param token a {@link org.springframework.security.authentication.UsernamePasswordAuthenticationToken} object.
74 * @return true if the login attempt was successful even if the authentication has changed or not
75 */
76 public boolean authenticate(String username, String password){
77 try{
78 doAuthenticate(username, password);
79 } catch (CdmAuthenticationException e) {
80 MessagingUtils.warningDialog("Could not authenticate", this, e.getMessage());
81 return false;
82 }
83 return true;
84 }
85
86 public void doAuthenticate(String username, String password) throws CdmAuthenticationException {
87 try {
88 SecurityContextHolder.clearContext();
89 Authentication lastAuthentication = CdmStore.getCurrentAuthentiation();
90
91 UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
92 Authentication authentication = CdmStore.getAuthenticationManager().authenticate(token);
93
94 User user = (User) authentication.getPrincipal();
95 /* circumventing problem with hibernate not refreshing the transient collection authorities in this case,
96 * see http://dev.e-taxonomy.eu/trac/ticket/4053 */
97 user.initAuthorities();
98
99 if(logger.isDebugEnabled()){
100 StringBuilder gaText = new StringBuilder();
101 String indent = " ";
102 Set<GrantedAuthority> gaSet = user.getGrantedAuthorities();
103 _logGrantedAuthotities(gaText, indent, gaSet);
104 for(Group gr : user.getGroups()){
105 gaText.append(indent).append("gr[").append(gr.hashCode()).append("] \"").append(gr.getName()).append("\" ").append(gr.toString()).append("\n");
106 _logGrantedAuthotities(gaText, indent + indent, gr.getGrantedAuthorities());
107 }
108 logger.debug("User authenticated: " + user.getUsername() + "\n" + gaText.toString());
109 }
110
111 authentication = new UsernamePasswordAuthenticationToken(user,password, authentication.getAuthorities());
112 SecurityContextHolder.getContext().setAuthentication(authentication);
113 CdmApplicationState.setCurrentSecurityContext(SecurityContextHolder.getContext());
114
115 if(!authentication.equals(lastAuthentication)){
116 this.setChanged();
117 this.notifyObservers();
118 }
119 } catch(BadCredentialsException e){
120 throw new CdmAuthenticationException(INCORRECT_CREDENTIALS_MESSAGE, e);
121 } catch(LockedException e){
122 throw new CdmAuthenticationException(ACCOUNT_LOCKED_MESSAGE, e);
123 } catch(IllegalArgumentException e){
124 e.printStackTrace();
125 throw new CdmAuthenticationException(EMPTY_CREDENTIALS_MESSAGE, e);
126 }
127
128 }
129
130
131 private void _logGrantedAuthotities(StringBuilder gaText, String indent,
132 Set<GrantedAuthority> gaSet) {
133 for(GrantedAuthority ga : gaSet){
134 gaText.append(indent).append("ga[").append(ga.hashCode()).append("] ").append(ga.toString()).append("\n");
135 }
136 }
137
138 /**
139 * <p>getAuthenticatedUser</p>
140 *
141 * @return a {@link eu.etaxonomy.cdm.model.common.User} object.
142 */
143 public User getAuthenticatedUser(){
144 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
145
146 if(authentication != null
147 && authentication.getPrincipal() != null
148 && authentication.getPrincipal() instanceof User){
149 return (User)authentication.getPrincipal();
150 }
151 return null;
152 }
153
154 public void logoutAll(){
155 SecurityContextHolder.clearContext();
156 notifyObservers();
157 }
158
159 /* (non-Javadoc)
160 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
161 */
162 @Override
163 public void update(CdmDataChangeMap arg) {}
164
165 /* (non-Javadoc)
166 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
167 */
168 @Override
169 public ConversationHolder getConversationHolder() {
170 if(conversation == null){
171 conversation = CdmStore.createConversation();
172 }
173 return conversation;
174 }
175
176 /**
177 * Whether the current user has the role admin
178 *
179 * @return
180 */
181 public boolean isAdmin() {
182 boolean result = userHelper().userIs(new RoleProberImpl(Role.ROLE_ADMIN));
183 return result;
184 }
185
186 /**
187 * Whether the current user has the role user manager
188 *
189 * @return
190 */
191 public boolean isUserManager() {
192 boolean result = userHelper().userIs(new RoleProberImpl(Role.ROLE_USER_MANAGER));
193 return result;
194 }
195
196 @Override
197 public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
198
199 }
200
201 @Override
202 public void contextStop(IMemento memento, IProgressMonitor monitor) {
203
204 }
205
206 @Override
207 public void contextStart(IMemento memento, IProgressMonitor monitor){
208 conversation = CdmStore.createConversation();
209 }
210
211 @Override
212 public void contextRefresh(IProgressMonitor monitor) {
213 conversation = CdmStore.createConversation();
214 }
215
216 @Override
217 public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
218
219 }
220 }