1 package org.torweg.pulse.accesscontrol.authentication;
2
3 import java.util.Map;
4
5 import org.hibernate.Session;
6 import org.hibernate.Transaction;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import org.torweg.pulse.accesscontrol.User;
10 import org.torweg.pulse.bundle.ResultSet;
11 import org.torweg.pulse.configuration.Configurable;
12 import org.torweg.pulse.configuration.PoorMansCache;
13 import org.torweg.pulse.invocation.lifecycle.Lifecycle;
14 import org.torweg.pulse.service.event.RedirectEvent;
15 import org.torweg.pulse.service.event.RedirectSafelyEvent;
16 import org.torweg.pulse.service.request.Command;
17 import org.torweg.pulse.service.request.Parameter;
18 import org.torweg.pulse.service.request.ServiceRequest;
19 import org.torweg.pulse.service.request.ServiceSession;
20
21
28 public final class Authentication {
29
30
33 private static final Logger LOGGER = LoggerFactory
34 .getLogger(Authentication.class);
35
36
39 private Authentication() {
40 super();
41 }
42
43
48 private static AuthenticationConfig getConfiguration() {
49 return (AuthenticationConfig) PoorMansCache
50 .getConfig(Authentication.class);
51 }
52
53
63 public static void authenticate(final ServiceRequest request,
64 final ResultSet rs) {
65 Command command = request.getCommand();
66
67 Map<String, String> mappings = Authentication.getConfiguration()
68 .getParameterMappings();
69
70 Parameter login = command.getParameter(mappings.get("login"));
71 command.removeParameter(login);
72 Parameter logout = command.getParameter(mappings.get("logout"));
73 command.removeParameter(logout);
74 if ((login == null) && (logout == null)) {
75 return;
76 }
77
78 Parameter username = command.getParameter(mappings.get("username"));
79 command.removeParameter(username);
80 Parameter password = command.getParameter(mappings.get("password"));
81 command.removeParameter(password);
82
83 AuthenticationResult result = new AuthenticationResult();
84
85 if ((login != null)
86 && Authentication.login(request, result, username, password)) {
87 redirectAfterLogin(request);
88 return;
89 } else if (logout != null) {
90 Authentication.logout(request, request.getSession());
91 request.getEventManager().addEvent(new RedirectSafelyEvent());
92 return;
93 }
94
95 if (request.getCommand().getParameter("redirect") != null) {
96 result.setRedirectURI(request.getCommand().getParameter("redirect")
97 .getFirstValue());
98 }
99
100 result.setLoginStatus(request.getSession().getAttribute(
101 User.class.getCanonicalName()) != null);
102 result.setParameterMappings(mappings);
103 result.setLoginModes(Authentication.getConfiguration().getLoginModes());
104
105 rs.addResult(result);
107 }
108
109
123 private static boolean login(final ServiceRequest request,
124 final AuthenticationResult result, final Parameter username,
125 final Parameter password) {
126 if ((username != null) && (username.getFirstValue() != null)
127 && (password != null) && (password.getFirstValue() != null)) {
128 User user = null;
129 Session s = Lifecycle.getHibernateDataSource().createNewSession();
130 Transaction tx = s.beginTransaction();
131 try {
132 user = (User) s.createQuery("from User as u where u.name = ?")
133 .setString(0, username.getFirstValue()).uniqueResult();
134 tx.commit();
135 } catch (Exception exception) {
136 tx.rollback();
137 throw new AuthenticationException(exception);
138 } finally {
139 s.close();
140 }
141 return postProcessLoadedUser(request, result, password, user);
142 } else {
143 result.setError(1, getConfiguration().getErrorCodes().get(1));
144 return false;
145 }
146 }
147
148
163 private static boolean postProcessLoadedUser(final ServiceRequest request,
164 final AuthenticationResult result, final Parameter password,
165 final User user) {
166 if ((user != null) && (!user.isExpunged())) {
167 if (user.isActive()) {
168 if (user.checkPassword(password.getFirstValue())) {
169 if (user.getLastLoginTime() != null) {
171 request.getSession()
172 .setAttribute(
173 new StringBuilder(Authentication.class
174 .getCanonicalName())
175 .append('#')
176 .append("lastLogin").toString(),
177 Long.valueOf(user.getLastLoginTime()
178 .getTime()));
179 }
180
181 user.setLastLoginTime();
182 Session sess = Lifecycle.getHibernateDataSource()
183 .createNewSession();
184 Transaction trans = sess.beginTransaction();
185 try {
186 sess.saveOrUpdate(user);
187 trans.commit();
188 if (getConfiguration().isSingleSignOn()) {
190 singleSignOnLogin(user, request, password);
191 }
192 } catch (Exception exception) {
193 trans.rollback();
194 throw new AuthenticationException(
195 "Error post-processing user.", exception);
196 } finally {
197 sess.close();
198 }
199 request.getSession().setAttribute(
200 User.class.getCanonicalName(), user.getId());
201 request.refreshUser();
202 return true;
203 } else {
204 result.setError(4, getConfiguration().getErrorCodes()
205 .get(4));
206 return false;
207 }
208 } else {
209 result.setError(3, getConfiguration().getErrorCodes().get(3));
210 return false;
211 }
212 } else {
213 result.setError(2, getConfiguration().getErrorCodes().get(2));
214 return false;
215 }
216 }
217
218
224 private static void redirectAfterLogin(final ServiceRequest request) {
225 String redirectURI = request.getHttpServletRequest().getHeader(
226 "referer");
227 if (request.getCommand().getParameter("redirect") != null) {
228 redirectURI = request.getCommand().getParameter("redirect")
229 .getFirstValue();
230
231 }
232 if (!redirectURI.equals("")) {
233 request.getEventManager().addEvent(new RedirectEvent(redirectURI));
234 } else {
235 request.getEventManager().addEvent(new RedirectSafelyEvent());
236 }
237 }
238
239
247 private static void logout(final ServiceRequest request,
248 final ServiceSession session) {
249 User user = request.getUser();
250 session.removeAttribute(User.class.getCanonicalName());
251 request.refreshUser();
252 if (getConfiguration().isSingleSignOn()) {
253 singleSignOnLogout(user, request);
254 }
255 }
256
257
267 private static void singleSignOnLogin(final User user,
268 final ServiceRequest request, final Parameter password) {
269 for (Class<ISingleSignOnTask> task : getConfiguration()
270 .getSingleSignOnTasks()) {
271 ISingleSignOnTask taskInstance = prepareTask(task);
272 if (taskInstance != null) {
273 taskInstance.signOn(user, password.getFirstValue(), request);
274 }
275 }
276 }
277
278
286 private static void singleSignOnLogout(final User user,
287 final ServiceRequest request) {
288
289 if (user instanceof User.Everybody) {
290 return;
291 }
292 for (Class<ISingleSignOnTask> task : getConfiguration()
293 .getSingleSignOnTasks()) {
294 ISingleSignOnTask taskInstance = prepareTask(task);
295 if (taskInstance != null) {
296 taskInstance.signOff(user, request);
297 }
298 }
299
300 }
301
302
309 private static ISingleSignOnTask prepareTask(
310 final Class<ISingleSignOnTask> task) {
311 try {
312 ISingleSignOnTask taskInstance = task.newInstance();
313
314 configureTask(task, taskInstance);
315 return taskInstance;
316 } catch (InstantiationException e) {
317 LOGGER.error(
318 "Error processing task '{}':{}",
319 new Object[] { task.getCanonicalName(),
320 e.getLocalizedMessage() });
321 return null;
322 } catch (IllegalAccessException e) {
323 LOGGER.error(
324 "Error processing task '{}':{}",
325 new Object[] { task.getCanonicalName(),
326 e.getLocalizedMessage() });
327 return null;
328 }
329 }
330
331
339 @SuppressWarnings("all")
340 private static void configureTask(final Class<ISingleSignOnTask> task,
341 final ISingleSignOnTask taskInstance) {
342 if (taskInstance instanceof Configurable) {
343 ((Configurable) taskInstance).initialize(PoorMansCache
344 .getConfiguration(task));
345 }
346 }
347 }
348