/* * Copyright 2007 Glencoe Software, Inc. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package ome.services.sessions; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.Future; import ome.annotations.Hidden; import ome.annotations.NotNull; import ome.annotations.RolesAllowed; import ome.api.ISession; import ome.api.ServiceInterface; import ome.conditions.AuthenticationException; import ome.conditions.RootException; import ome.conditions.SecurityViolation; import ome.conditions.SessionException; import ome.model.meta.Session; import ome.security.basic.CurrentDetails; import ome.services.util.Executor; import ome.system.EventContext; import ome.system.Principal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.transaction.annotation.Transactional; /** * Implementation of {@link ISession}. Is merely a wrapper around the * {@link SessionManager} Spring-singleton. * * @author Josh Moore, josh at glencoesoftware.com * @since 3.0-Beta3 */ @Transactional public class SessionBean implements ISession { private final static Logger log = LoggerFactory.getLogger(SessionBean.class); final private SessionManager mgr; final private Executor ex; final private CurrentDetails cd; public SessionBean(SessionManager mgr, Executor ex, CurrentDetails cd) { this.mgr = mgr; this.ex = ex; this.cd = cd; } // ~ Injectors // ========================================================================= public Class<? extends ServiceInterface> getServiceInterface() { return ISession.class; } // ~ Session lifecycle // ========================================================================= @RolesAllowed({"user", "HasPassword"}) public Session createUserSession(final long timeToLiveMs, final long timeToIdleMs, String defaultGroup) { final String user = currentUser(); if (user == null) { throw new SecurityViolation("No current user"); } try { final Principal principal = principal(defaultGroup, user); Future<Session> future = ex.submit(new Callable<Session>(){ public Session call() throws Exception { Session session = mgr.createWithAgent(principal, "createSession", null); session.setTimeToIdle(timeToIdleMs); session.setTimeToLive(timeToLiveMs); return mgr.update(session, false); }}); return ex.get(future); } catch (Exception e) { throw creationExceptionHandler(e); } } @RolesAllowed("user" /* group owner */) public Session createSessionWithTimeout(@NotNull final Principal principal, final long milliseconds) { return createSessionWithTimeouts(principal, milliseconds, 0L); } @RolesAllowed("user" /*group owner*/) public Session createSessionWithTimeouts(@NotNull final Principal principal, final long timeToLiveMilliseconds, final long timeToIdleMilliseconds) { final EventContext context = currentContext(); final List<Long> groupsLed = context.isCurrentUserAdmin() ? null : context.getLeaderOfGroupsList(); try { Future<Session> future = ex.submit(new Callable<Session>(){ public Session call() throws Exception { SessionManager.CreationRequest req = new SessionManager.CreationRequest(); req.principal = principal; req.agent = "OMERO.sudo"; req.groupsLed = groupsLed; req.timeToIdle = timeToIdleMilliseconds; req.timeToLive = timeToLiveMilliseconds; return mgr.createFromRequest(req); }}); return ex.get(future); } catch (Exception e) { throw creationExceptionHandler(e); } } @RolesAllowed( { "user", "guest" }) public Session createSession(@NotNull Principal principal, @Hidden String credentials) { Session session = null; try { session = mgr.createWithAgent(principal, credentials, "createSession", null); } catch (Exception e) { throw creationExceptionHandler(e); } return session; } @RolesAllowed( { "user", "guest" }) public Session getSession(@NotNull String sessionUuid) { return mgr.find(sessionUuid); } @RolesAllowed( { "user", "guest" }) public int getReferenceCount(@NotNull String sessionUuid) { return mgr.getReferenceCount(sessionUuid); } @RolesAllowed( { "user", "guest" }) public Session updateSession(@NotNull final Session session) { Future<Session> future = ex.submit(new Callable<Session>(){ public Session call() throws Exception { return mgr.update(session); }}); return ex.get(future); } @RolesAllowed( { "user", "guest" }) public int closeSession(@NotNull final Session session) { Future<Integer> future = ex.submit(new Callable<Integer>(){ public Integer call() throws Exception { return mgr.close(session.getUuid()); }}); return ex.get(future); } @RolesAllowed("user") public java.util.List<Session> getMyOpenSessions() { final String user = currentUser(); Future<List<Session>> future = ex.submit(new Callable<List<Session>>(){ public List<Session> call() throws Exception { return mgr.findByUser(user); }}); return ex.get(future); } @RolesAllowed("user") public java.util.List<Session> getMyOpenAgentSessions(final String agent) { final String user = currentUser(); Future<List<Session>> future = ex.submit(new Callable<List<Session>>(){ public List<Session> call() throws Exception { return mgr.findByUserAndAgent(user, agent); }}); return ex.get(future); } @RolesAllowed("user") public java.util.List<Session> getMyOpenClientSessions() { final String user = currentUser(); Future<List<Session>> future = ex.submit(new Callable<List<Session>>(){ public List<Session> call() throws Exception { return mgr.findByUserAndAgent(user, "OMERO.insight", "OMERO.web", "OMERO.importer"); }}); return ex.get(future); } // ~ Environment // ========================================================================= @RolesAllowed( { "user", "guest" }) public Object getInput(String session, String key) { return mgr.getInput(session, key); } @RolesAllowed( { "user", "guest" }) public Object getOutput(String session, String key) { return mgr.getOutput(session, key); } @RolesAllowed( { "user", "guest" }) public void setInput(String session, String key, Object object) { mgr.setInput(session, key, object); } @RolesAllowed( { "user", "guest" }) public void setOutput(String session, String key, Object object) { mgr.setOutput(session, key, object); } @RolesAllowed( { "user", "guest" }) public Set<String> getInputKeys(String session) { return mgr.inputEnvironment(session).keySet(); } @RolesAllowed( { "user", "guest" }) public Set<String> getOutputKeys(String session) { return mgr.outputEnvironment(session).keySet(); } @RolesAllowed( { "user", "guest" }) public Map<String, Object> getInputs(String session) { return mgr.inputEnvironment(session); } @RolesAllowed( { "user", "guest" }) public Map<String, Object> getOutputs(String session) { return mgr.outputEnvironment(session); } // ~ Helpers // ========================================================================= String currentUser() { return currentContext().getCurrentUserName(); } EventContext currentContext() { String user = cd.getLast().getName(); return mgr.getEventContext(new Principal(user)); } private Principal principal(String defaultGroup, final String user) { Principal p; if (defaultGroup != null) { p = new Principal(user, defaultGroup, "User"); } else { p = new Principal(user); } return p; } RuntimeException creationExceptionHandler(Exception e) { log.info("Handling session exception: ", e); if (e instanceof SessionException) { return (SessionException) e; } else if (e instanceof SecurityViolation) { return (SecurityViolation) e; } else if (e instanceof RootException) { // This may should be more specific or need to use an event-based // conversion routine like in blitz, to allow exceptions like // NoAvailableLicenseException to be propagated to the client. return (AuthenticationException) new AuthenticationException( "Error creating session.").initCause(e); } else { return new AuthenticationException("Unknown error (" + e.getClass().getName() + "):" + e.getMessage()); } } }