/** * Base Filters * @Author Jeroen Wesbeek * @Since 20091026 * @see main.gsp * @see http://grails.org/Filters * @Description * * These filters contain generic logic for -every- page request. * * Revision information: * $Rev: 776 $ * $Author: duh $ * $Date: 2010-08-05 12:15:26 +0200 (Thu, 05 Aug 2010) $ */ import grails.converters.* import javax.servlet.http.HttpServletResponse import org.apache.catalina.connector.Response; import org.codehaus.groovy.grails.commons.ConfigurationHolder import nl.tno.metagenomics.auth.User; import nl.tno.metagenomics.integration.*; class BaseFilters { def gscfService def synchronizationService // define filters def filters = { userCheck(controller:'*', action:'*') { before = { if( actionName == "notifyStudyChange" && controllerName == "rest" ) { return true; } if( !ConfigurationHolder.config.gscf.baseURL ) { throw new Exception( "No GSCF instance specified. Please check configuration." ) return false } // We are handling the Rest controller as a special case. The rest calls are made // outside of the users browser session, so it should always contain a session token. // Moreover, it should never redirect the user, but instead send a 403 error if( controllerName == 'rest' ) { if (!params.sessionToken && !session.sessionToken ){ response.setStatus( HttpServletResponse.SC_BAD_REQUEST, "No sessiontoken given" ); render "No sessiontoken given" return false } if( params.sessionToken ) session.sessionToken = params.sessionToken try { def user = gscfService.getUser( session.sessionToken ); if( user ) { session.user = User.findByIdentifierAndUsername( user.id, user.username ); if( !session.user) { session.user = new User( identifier: user.id, username: user.username ).save( flush: true ); } } else { response.setStatus( HttpServletResponse.SC_UNAUTHORIZED, "No user logged in" ); render "No user logged in" return false; } } catch( Exception e ) { log.error( "Unable to fetch user from GSCF", e ); response.setStatus( HttpServletResponse.SC_BAD_REQUEST, "Unable to fetch user from GSCF" ); render "Unable to fetch user from GSCF" return false; } return true; } // enable to inject a session from the outside... if (params.sessionToken){ log.info("Setting SessionToken from params.sessionToken to ${params.sessionToken}") session.sessionToken = params.sessionToken log.info("Redirecting to GSCF to login for session from params.sessionToken") redirect( url: gscfService.urlAuthRemote(params, session.sessionToken) ) return false } // If a user is already logged in, let him continue if( session.user && session.user != null ) { // If we don't refresh the user object, an old hiberante session could still be attached to the object // raising errors later on (Lazy loading errors) session.user.refresh(); return true; } // on all pages of the Metagenomics module a user should be present in the session if (session.sessionToken) { log.info("SessionToken found, ask GSCF for User information") // try to identify the user with the sessionToken, since the user has logged in before try { def user = [:] // First check if the user is authenticated. If he isn't, he should provide credentials at GSCF def authentication = JSON.parse("${ConfigurationHolder.config.gscf.baseURL}/rest/isUser?consumer=${ConfigurationHolder.config.metagenomics.consumerID}&token=${session.sessionToken}".toURL().text) if( !authentication.authenticated ) { log.info "Not authenticated: " + authentication.authenticated redirect( url: gscfService.urlAuthRemote(params, session.sessionToken) ) return false } // Now find the user data JSON.parse("${ConfigurationHolder.config.gscf.baseURL}/rest/getUser?consumer=${ConfigurationHolder.config.metagenomics.consumerID}&token=${session.sessionToken}".toURL().text).each { userProperty -> user["${userProperty.key}"] = "${userProperty.value}" } // Locate user in database or create a new user session.user = User.findByIdentifierAndUsername(user.id, user.username) if (!session.user){ // when not found, create a new user session.user = new User(identifier: user.id, username: user.username).save(flush: true) } return true; } catch(Exception e) { log.error("Unable to fetch user from GSCF", e) throw new Exception( "GSCF instance at " + ConfigurationHolder.config.gscf.baseURL + " could not be reached. Please check configuration.", e ) } } else { session.sessionToken = "${UUID.randomUUID()}" log.info("SessionToken created, redirectiong to GSCF to let the user login! (SessionToken: ${session.sessionToken}") redirect( url: gscfService.urlAuthRemote(params, session.sessionToken) ) return false } } } restSynchronization(controller:'rest', action:'*') { before = { // Synchronize studies normally, but never issue a redirect synchronizationService.sessionToken = session.sessionToken synchronizationService.user = session.user try { synchronizationService.synchronizeStudies() } catch( NotAuthenticatedException e ) { // Something went wrong in authentication. Redirect the user to GSCF to authenticate again log.info "User is not authenticated during synchronizatino. Returning 401 status" response.setStatus( Response.SC_UNAUTHORIZED, "User is not authorized" ) return false; } catch( Exception e ) { // Synchronization fails. Log error and continue; don't bother the user with it log.error e.getMessage() } return true; } } synchronization(controller:'*', action:'*') { before = { // Never perform full synchronization on rest call or when the synchronize controller is used if( controllerName == "rest" || controllerName == "synchronize" || controllerName == "dbUtil" ) { return true; } // Never perform synchronization on a POST request if( request.method == "POST" ) return true; if( synchronizationService.timeForFullSynchronization() ) { redirect( url: synchronizationService.urlForFullSynchronization( params ) ); return false } else { // Synchronize studies normally synchronizationService.sessionToken = session.sessionToken synchronizationService.user = session.user try { synchronizationService.synchronizeStudies() } catch( NotAuthenticatedException e ) { // Something went wrong in authentication. Redirect the user to GSCF to authenticate again log.info "User is not authenticated during synchronizatino. Redirecting to GSCF." redirect( url: gscfService.urlAuthRemote(params, session.sessionToken) ) return false; } catch( Exception e ) { // Synchronization fails. Log error and continue; don't bother the user with it log.error e.getMessage() } } return true } } defineStyle(controller: '*', action: '*') { // before every execution before = { // set the default style in the session if (!session.style) { session.style = 'metagenomics' } // set session lifetime to 1 week session.setMaxInactiveInterval(604800) } } } }