edu.harvard.med.screensaver.ui.WebCurrentScreensaverUser.java Source code

Java tutorial

Introduction

Here is the source code for edu.harvard.med.screensaver.ui.WebCurrentScreensaverUser.java

Source

// $HeadURL$
// $Id$

// Copyright  2006, 2010, 2011, 2012 by the President and Fellows of Harvard College.

// Screensaver is an open-source project developed by the ICCB-L and NSRB labs
// at Harvard Medical School. This software is distributed under the terms of
// the GNU General Public License.

package edu.harvard.med.screensaver.ui;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import edu.harvard.med.screensaver.ScreensaverProperties;
import edu.harvard.med.screensaver.db.GenericEntityDAO;
import edu.harvard.med.screensaver.model.screens.Screen;
import edu.harvard.med.screensaver.model.users.LabHead;
import edu.harvard.med.screensaver.model.users.ScreeningRoomUser;
import edu.harvard.med.screensaver.model.users.ScreensaverUser;
import edu.harvard.med.screensaver.model.users.ScreensaverUserRole;
import edu.harvard.med.screensaver.policy.CurrentScreensaverUser;
import edu.harvard.med.screensaver.policy.EntityViewPolicy;
import edu.harvard.med.screensaver.ui.arch.auth.ScreensaverLoginModule;

/**
 * Like {@link CurrentScreensaverUser}, maintains the current ScreensaverUser
 * entity, but also knows how to find that current user within the context of a
 * web application (using servlet session information), in a lazy fashion.
 * Also, thanks to Spring 2.0's session-scoped bean feature, we can declare a
 * single bean of type WebCurrentScreensaverUser and inject it into other UI
 * Spring beans (which can be either session-scoped themselves, or even
 * singletons), and they will have access to the current ScreensaverUser (i.e.,
 * the user being serviced in the current HTTP request). We can't just inject a
 * ScreensaverUser instance directly, since a user hasn't necessarily
 * authenticated themselves when Spring session-scoped beans are instantiated.
 *
 * @see EntityViewPolicy
 *
 * @author <a mailto="andrew_tolopko@hms.harvard.edu">Andrew Tolopko</a>
 * @author <a mailto="john_sullivan@hms.harvard.edu">John Sullivan</a>
 */
public class WebCurrentScreensaverUser extends CurrentScreensaverUser {
    private static Logger log = Logger.getLogger(WebCurrentScreensaverUser.class);

    private GenericEntityDAO _dao;
    private ScreensaverProperties _applicationProperties;

    public void setDao(GenericEntityDAO dao) {
        _dao = dao;
    }

    public void setApplicationProperties(ScreensaverProperties applicationProperties) {
        _applicationProperties = applicationProperties;
    }

    @Override
    @Transactional
    public ScreensaverUser getScreensaverUser() {
        String remoteUser = null;
        FacesContext facesContext = FacesContext.getCurrentInstance();
        if (facesContext != null) {
            remoteUser = facesContext.getExternalContext().getRemoteUser();
        }
        boolean noAuthenticatedUser = StringUtils.isEmpty(remoteUser);
        if (noAuthenticatedUser) {
            if (_applicationProperties.isAllowGuestLogin()) {
                if (super.getScreensaverUser() == null) {
                    setScreensaverUserGuest(new GuestUser("Guest"));
                }
            }
        } else if (super.getScreensaverUser() == null
                || super.getScreensaverUser() instanceof GuestUser /* allow authentication if currently a guest user */) {
            ScreensaverUser screensaverUser = findScreensaverUserForUsername(remoteUser);
            setScreensaverUser(screensaverUser);
        }
        return super.getScreensaverUser();
    }

    private void setScreensaverUserGuest(ScreensaverUser user) {
        super.setScreensaverUser(user);
    }

    @Transactional(propagation = Propagation.MANDATORY)
    public void setScreensaverUser(final ScreensaverUser user) {
        if (user != null) {
            // semi-HACK: fetch relationships needed by data access policy
            _dao.need(user, ScreensaverUser.roles);
            if (user instanceof ScreeningRoomUser) {
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.screensLed);
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.screensCollaborated);
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.LabHead.to(LabHead.labMembers));
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.screensLed.to(Screen.leadScreener));
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.screensLed.to(Screen.labHead));
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.screensLed.to(Screen.collaborators));
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.screensCollaborated.to(Screen.leadScreener));
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.screensCollaborated.to(Screen.labHead));
                _dao.need((ScreeningRoomUser) user, ScreeningRoomUser.screensCollaborated.to(Screen.collaborators));
            }
            if (user instanceof LabHead) {
                _dao.need((LabHead) user, LabHead.screensHeaded);
                _dao.need((LabHead) user, LabHead.labMembers);
                _dao.need((LabHead) user, LabHead.screensHeaded.to(Screen.leadScreener));
                _dao.need((LabHead) user, LabHead.screensHeaded.to(Screen.labHead));
                _dao.need((LabHead) user, LabHead.screensHeaded.to(Screen.collaborators));
            }
        }
        super.setScreensaverUser(user);
    }

    @Override
    public void logActivity(String s) {
        super.logActivity(s);
    }

    public String toString() {
        String sessionId = ((HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false))
                .getId();
        StringBuilder builder = new StringBuilder();
        builder.append("[").append(sessionId).append(']').append(' ');
        if (super.getScreensaverUser() == null) {
            builder.append("<unauthenticated>");
        } else {
            builder.append(super.toString());
        }
        return builder.toString();
    }

    // TODO: make this into a service, and use in ScreensaverLoginModule
    /**
     * Returns a ScreensaverUser object for the specified Principal.
     *
     * @motivation Normally, the ScreensaverUser instance would be the same object
     *             as the Principal instance, but
     *             <code>getExternalContext().getUserPrincipal()</code> does not
     *             return the ScreensaverUserPrincipal object that we provided to
     *             Tomcat during our JAAS authentication process (in
     *             {@link ScreensaverLoginModule#commit}, and so we cannot get at
     *             the ScreensaverUser object that would have available via the
     *             ScreensaverUserPrincipal object. So we have to requery the
     *             database to find the ScreensaverUser given only the user's
     *             login ID.
     * @return the ScreensaverUser that is logged in to the current HTTP session
     */
    private ScreensaverUser findScreensaverUserForUsername(String username) {
        if (username == null) {
            return null;
        }
        int switchToUserPos = username.indexOf(':');

        ScreensaverUser user = null;
        if (switchToUserPos > 0) {
            username = username.substring(switchToUserPos + 1);
            user = _dao.findEntityByProperty(ScreensaverUser.class, "ECommonsId", username.toLowerCase());
        } else {
            user = _dao.findEntityByProperty(ScreensaverUser.class, "loginId", username);
            if (user == null) {
                user = _dao.findEntityByProperty(ScreensaverUser.class, "ECommonsId", username.toLowerCase());
            }
        }
        if (user == null) {
            log.warn("could not find a user for username " + username);
        }
        return user;
    }

    /**
      * for [#3107] Non-authenticated access for LINCS guest users
      */
    public class GuestUser extends ScreeningRoomUser {
        String name;

        public GuestUser(String name) {
            this.name = name;
            addScreensaverUserRole(ScreensaverUserRole.SCREENSAVER_USER);
            addScreensaverUserRole(ScreensaverUserRole.GUEST);
        }

        @Override
        public String getFirstName() {
            return name;
        }

        @Override
        public String getLastName() {
            return "";
        }

        @Override
        public String getFullNameFirstLast() {
            return name;
        }

        @Override
        protected boolean validateRole(ScreensaverUserRole role) {
            return getScreensaverUserRoles().contains(role);
        }

        public Integer getEntityId() {
            return 0;
        }

        public String getLoginId() {
            return name;
        }
    };
}