Java tutorial
// $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; } }; }