
org.integratedmodelling.kmodeler.controller.SessionController Maven / Gradle / Ivy
The newest version!
package org.integratedmodelling.kmodeler.controller;
import javax.servlet.http.HttpServletRequest;
import org.integratedmodelling.api.auth.IUser;
import org.integratedmodelling.api.configuration.IResourceConfiguration;
import org.integratedmodelling.api.configuration.IResourceConfiguration.StaticResource;
import org.integratedmodelling.api.engine.ILock;
import org.integratedmodelling.api.engine.IModelingEngine;
import org.integratedmodelling.api.knowledge.IObservation;
import org.integratedmodelling.api.network.API;
import org.integratedmodelling.api.runtime.IContext;
import org.integratedmodelling.api.runtime.ISession;
import org.integratedmodelling.common.auth.KlabCertificate;
import org.integratedmodelling.common.auth.User;
import org.integratedmodelling.common.beans.Session;
import org.integratedmodelling.common.beans.requests.RunScriptRequest;
import org.integratedmodelling.common.beans.requests.SessionRequest;
import org.integratedmodelling.common.beans.responses.AuthorizationResponse;
import org.integratedmodelling.common.beans.responses.LockResponse;
import org.integratedmodelling.common.beans.responses.RunScriptResponse;
import org.integratedmodelling.common.configuration.KLAB;
import org.integratedmodelling.common.network.EngineNetwork;
import org.integratedmodelling.engine.ModelingEngine;
import org.integratedmodelling.exceptions.KlabAuthenticationException;
import org.integratedmodelling.exceptions.KlabAuthorizationException;
import org.integratedmodelling.exceptions.KlabException;
import org.integratedmodelling.kmodeler.components.SessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @author ferdinando.villa
*
*/
@RestController
public class SessionController {
@Autowired
SessionManager sessionManager;
/**
* We get here with a user who has read its certificate and authenticated successfully
* with the primary server(s) mentioned in it. The user sends the authentication token
* received by the server and the endpoint it used to retrieve it, along with
* session-related information.
*
* In order to know which groups the user belongs to, and to add another layer of
* security, we retrieve the user profile from the same server, using the same token,
* and rebuild the user info at our end. Then based on the user's permissions, we open
* a session and return its id along with the view of the network that the user can
* access.
*
* The call used to validate the token server side should produce both the user
* profile and the network view.
*
* @param request
* @param servletRequest
* @return a descriptor for the session requested
* @throws KlabException
*/
@RequestMapping(value = API.OPEN_SESSION, method = RequestMethod.POST)
public @ResponseBody Session openSession(@RequestBody SessionRequest request, HttpServletRequest servletRequest)
throws KlabException {
IResourceConfiguration rconf = KLAB.ENGINE.getResourceConfiguration();
RestTemplate restTemplate = new RestTemplate();
/*
* if we're requesting to join a known previous session and we have just one that
* can be reopened, just get that w/o reauthenticating.
*/
if (request.getSessionId() != null) {
org.integratedmodelling.common.model.runtime.Session s = sessionManager
.getSession(request.getSessionId());
if (s != null) {
return s.serialize(Session.class);
}
}
if (request.isReopenExisting()) {
org.integratedmodelling.common.model.runtime.Session s = sessionManager
.getReopenableSessionFor(request.getSessionId());
if (s != null) {
return s.serialize(Session.class);
}
}
/*
* get user profile from primary server; abort if authentication fails
*/
IUser user = null;
if (KLAB.CONFIG.isOffline()) {
KlabCertificate certificate = new KlabCertificate(request.getCertificate());
if (!certificate.isValid()) {
throw new KlabAuthenticationException("session manager: certificate is invalid: "
+ certificate.getCause());
}
user = new User(certificate);
KLAB.info("session manager: offline user " + user.getUsername()
+ " authenticated successfully");
((EngineNetwork)KLAB.ENGINE.getNetwork()).setUser(user);
} else {
try {
KLAB.info("session manager: authenticating through primary server "
+ request.getPrimaryServerUrl());
AuthorizationResponse ret = restTemplate
.postForObject(request.getPrimaryServerUrl()
+ API.AUTHENTICATION_CERT_FILE, request
.getCertificate(), AuthorizationResponse.class);
user = new User(ret.getProfile(), ret.getAuthToken());
KLAB.info("session manager: user " + user.getUsername()
+ " authenticated successfully");
/*
* user only retains privileges up to those of the certified engine owner.
*/
((User) user)
.restrictPrivileges(((IModelingEngine) KLAB.ENGINE).getUser());
} catch (Throwable e) {
throw new KlabAuthenticationException("session manager: could not validate user: "
+ e.getMessage());
}
}
/*
* check if user can connect
*/
if (!rconf.isAuthorized(user, servletRequest.getRemoteAddr())) {
throw new KlabAuthenticationException("session manager: user "
+ user.getUsername()
+ " is valid but has no permission to open a session");
}
/*
* if requested, check if user can lock
*/
if (request.isRequestingExclusive()
&& !rconf.isAuthorized(StaticResource.ENGINE_LOCK, user, servletRequest
.getRemoteAddr())) {
throw new KlabAuthenticationException("session manager: user "
+ user.getUsername()
+ " is valid but has no permission to lock this engine");
}
/*
* all clear, get me a session
*/
return sessionManager.getNewSessionForRequest(request, user)
.serialize(Session.class);
}
/**
* Lock the engine until unlock is explicitly called.
*
* @param headers requires session authorization
* @return true if lock is successful
* @throws KlabAuthorizationException
*/
@RequestMapping(value = API.LOCK_ENGINE, method = RequestMethod.GET)
public @ResponseBody LockResponse lockEngine(@RequestHeader HttpHeaders headers)
throws KlabAuthorizationException {
boolean wasLocked = false;
ISession session = sessionManager
.getSession(headers.get(API.AUTHENTICATION_HEADER));
if (session == null || !session.isExclusive()) {
throw new KlabAuthorizationException("only a session with exclusive rights can lock an engine");
}
ILock lock = ((ModelingEngine) KLAB.ENGINE).getLock();
if ((wasLocked = lock.isLocked())) {
if (!lock.getUser().equals(session.getUser())) {
throw new KlabAuthorizationException("engine is locked by "
+ lock.getUser().getUsername()
+ ": cannot create exclusive session");
}
}
boolean locked = lock.lock(session.getUser(), false);
LockResponse ret = new LockResponse();
ret.setLocked(locked
|| lock.isLocked() && lock.getUser().getUsername()
.equals(session.getUser().getUsername()));
ret.setWasLocked(wasLocked);
ret.setLockingUser(lock.getUser().getUsername());
return ret;
}
/**
* Unlock the engine.
*
* @param headers requires session authorization
* @return true if unlock is successful
* @throws KlabAuthorizationException
*/
@RequestMapping(value = API.UNLOCK_ENGINE, method = RequestMethod.GET)
public @ResponseBody LockResponse unlockEngine(@RequestHeader HttpHeaders headers)
throws KlabAuthorizationException {
boolean wasLocked = false;
ILock lock = ((ModelingEngine) KLAB.ENGINE).getLock();
ISession session = sessionManager
.getSession(headers.get(API.AUTHENTICATION_HEADER));
if (session == null || !session.isExclusive()) {
throw new KlabAuthorizationException("only a session with exclusive rights can unlock an engine");
}
boolean locked = false;
if ((wasLocked = lock.isLocked())) {
if (lock.unlock(session.getUser())) {
locked = false;
}
}
LockResponse ret = new LockResponse();
ret.setLocked(locked);
ret.setWasLocked(wasLocked);
return ret;
}
@RequestMapping(value = API.RUN_SCRIPT, method = RequestMethod.POST)
public @ResponseBody RunScriptResponse runScript(@RequestBody RunScriptRequest request, @RequestHeader HttpHeaders headers, HttpServletRequest servletRequest)
throws KlabException {
ISession session = sessionManager
.getSession(headers.get(API.AUTHENTICATION_HEADER));
if (session == null) {
throw new KlabAuthorizationException("observe: session authentication failed");
}
RunScriptResponse ret = new RunScriptResponse();
IContext context = null;
IObservation observation = null;
if (request.getContextId() != null) {
context = sessionManager.getContext(request.getContextId());
if (context != null && request.getObservationPath() != null) {
observation = context.get(request.getObservationPath());
}
}
return ret;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy