001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2008
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.core.security;
034:
035: import com.flexive.shared.FxContext;
036: import com.flexive.shared.exceptions.FxAccountInUseException;
037: import com.flexive.shared.exceptions.FxLoginFailedException;
038: import com.flexive.shared.exceptions.FxLogoutFailedException;
039: import com.flexive.shared.security.UserTicket;
040: import org.apache.commons.logging.Log;
041: import org.apache.commons.logging.LogFactory;
042:
043: import javax.ejb.SessionContext;
044: import javax.security.auth.Subject;
045: import javax.sql.DataSource;
046: import java.security.Principal;
047: import java.util.Arrays;
048: import java.util.HashSet;
049:
050: /**
051: * Provides convenience methods for login and logout of flexive users.
052: *
053: * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
054: */
055: public final class LoginLogoutHandler {
056:
057: private static final String LOGIN_CTX = "FxLogin";
058: private static final transient Log LOG = LogFactory
059: .getLog(LoginLogoutHandler.class);
060:
061: /**
062: * Private construcutor
063: */
064: private LoginLogoutHandler() {
065: }
066:
067: /**
068: * Login function.
069: *
070: * @param username The username
071: * @param password The users password
072: * @param takeOver If a other session is already logged in with this unique username the other session is
073: * invalidated (logged out), and this session is logged in.
074: * @param ctx the session context
075: * @param ds the datasource to be used
076: * @return The new UserTicket if the login succeeded, or null if the login failed.
077: * @throws FxLoginFailedException if the login failed
078: * @throws FxAccountInUseException if a other session is already logged in (with this unique username) AND take
079: * over is false
080: */
081: public static UserTicket doLogin(String username, String password,
082: boolean takeOver, SessionContext ctx, DataSource ds)
083: throws FxLoginFailedException, FxAccountInUseException {
084: boolean success = false;
085: try {
086: // Actually logged in?
087: UserTicket ticket = UserTicketStore.getTicket();
088: if (!ticket.isGuest()) {
089: doLogout();
090: }
091:
092: // Try a login
093: /*PassiveCallbackHandler pch = new PassiveCallbackHandler(username, password, takeOver, ctx, ds);
094: LoginContext lc = new LoginContext(LOGIN_CTX, pch);
095: lc.login();
096: final Subject sub = lc.getSubject();
097: ticket = FxDefaultLogin.getUserTicket(sub);*/
098: final FxCallback callback = new FxCallback();
099: callback.setTakeOverSession(takeOver);
100: callback.setSessionContext(ctx);
101: callback.setDataSource(ds);
102: ticket = FxDBAuthentication.login(username, password,
103: callback);
104: // Log out any other sessions of the user
105: if (!ticket.isMultiLogin() && !ticket.isWebDav()) {
106: // TODO: real logout?
107: UserTicketStore.removeUserId(ticket.getUserId(), ticket
108: .getApplicationId());
109: }
110: // Set session informations in cluster cache
111: final Subject sub = new Subject(false,
112: new HashSet<Principal>(Arrays
113: .asList(new FxPrincipal(ticket))),
114: new HashSet(), new HashSet());
115: UserTicketStore.storeSubject(sub);
116: // flag success
117: success = true;
118: // Return the ticket
119: return ticket;
120: } catch (FxLoginFailedException exc) {
121: throw exc;
122: } catch (FxAccountInUseException exc) {
123: throw exc;
124: } catch (Exception exc) {
125: FxLoginFailedException le = new FxLoginFailedException(
126: "Login failed (internal error): "
127: + exc.getMessage(),
128: FxLoginFailedException.TYPE_UNKNOWN_ERROR);
129: LOG.error(le);
130: throw le;
131: } finally {
132: if (!success)
133: try {
134: doLogout();
135: } catch (Exception exc) {
136: // ignore, this is only a cleanup attempt that will most likely fail
137: }
138: }
139: }
140:
141: /**
142: * Logoff a user defined by its session.
143: *
144: * @throws com.flexive.shared.exceptions.FxLogoutFailedException
145: * if the system is unable to logoff the session
146: */
147: public static void doLogout() throws FxLogoutFailedException {
148: Subject sub = UserTicketStore.getSubject(FxContext.get());
149: if (sub == null) {
150: // No information available, user is not logged in.
151: return;
152: }
153:
154: try {
155: FxDBAuthentication.logout(FxContext.get().getTicket());
156: UserTicketStore.removeSubject();
157: } catch (Exception exc) {
158: FxLogoutFailedException lfe = new FxLogoutFailedException(
159: "Logout failed", exc);
160: if (LOG.isDebugEnabled())
161: LOG.debug(lfe);
162: throw lfe;
163: }
164: }
165:
166: }
|