/** * PODD is an OWL ontology database used for scientific project management * * Copyright (C) 2009-2013 The University Of Queensland * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see <http://www.gnu.org/licenses/>. */ package com.github.podd.resources; import java.util.List; import org.openrdf.model.URI; import org.restlet.data.Method; import org.restlet.data.Status; import org.restlet.representation.Variant; import org.restlet.resource.ResourceException; import org.restlet.resource.ServerResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.ansell.propertyutil.PropertyUtil; import com.github.podd.api.PoddArtifactManager; import com.github.podd.api.PoddRepositoryManager; import com.github.podd.api.PoddSchemaManager; import com.github.podd.api.PoddSesameManager; import com.github.podd.restlet.PoddAction; import com.github.podd.restlet.PoddWebServiceApplication; public abstract class AbstractPoddResourceImpl extends ServerResource { protected final Logger log = LoggerFactory.getLogger(this.getClass()); public AbstractPoddResourceImpl() { super(); } /** * Checks the ability of the currently authenticated user to perform the given action and throws * an exception if the current user is not authorised for the given action. * * @param action * The PoddAction that is to be performed. * @throws ResourceException * with Status.CLIENT_ERROR_UNAUTHORIZED (HTTP 401) if the user is not authorised to * perform the given action */ protected boolean checkAuthentication(final PoddAction action) throws ResourceException { // throws an error on failure return this.checkAuthentication(action, null, true); } /** * Checks the ability of the currently authenticated user to perform the given action and throws * an exception if the current user is not authorised for the given action. * * @param action * The PoddAction that is to be performed. * @param optionalObjectUri * A single object URI to be used for authorization, or null if none are needed for * authorization or it could not be determined. * @throws ResourceException * with Status.CLIENT_ERROR_UNAUTHORIZED (HTTP 401) if the user is not authorised to * perform the given action */ protected boolean checkAuthentication(final PoddAction action, final URI optionalObjectUri) throws ResourceException { // throws an error on failure return this.checkAuthentication(action, optionalObjectUri, true); } /** * Checks the ability of the currently authenticated user to perform the given action, * optionally throwing an exception instead of returning false in the case that the check fails. * * @param action * The PoddAction that is to be performed. * @param optionalObjectUri * A single object URIs to be used for authorization, or null if none are needed for * authorization or it could not be determined. * @param throwExceptionOnFailure * If true, this method throws a ResourceException on failure instead of returning * false * @return Returns true if the user is able to perform the given action on the given objects, * and either throws an exception or returns false if they are not able to perform the * given action, depending on the value of the throwExceptionOnFailure parameter. * @throws ResourceException * with Status.CLIENT_ERROR_UNAUTHORIZED (HTTP 401) if the user is not authorised to * perform the given action */ protected boolean checkAuthentication(final PoddAction action, final URI optionalObjectUri, final boolean throwExceptionOnFailure) throws ResourceException { if(this.getPoddApplication().authenticate(action, this.getRequest(), this.getResponse(), optionalObjectUri)) { return true; } else if(throwExceptionOnFailure) { // Strategies for fixing #81 // If they have an existing cookie then we tell them to discard it // CookieSetting cookie = // this.getResponse().getCookieSettings().getFirst(PoddWebConstants.COOKIE_NAME, // false); // if(cookie != null) // { // cookie.setMaxAge(0); // } // TODO: Test the following strategy if the strategy above does not // work // if(this.getResponse().getCookieSettings().removeAll(PoddWebConstants.COOKIE_NAME, // true)) // { // this.getResponse() // .getCookieSettings() // .add(new CookieSetting(0, PoddWebConstants.COOKIE_NAME, "", // this.getRequest().getRootRef() // .getPath(), this.getRequest().getResourceRef().getHostDomain(), // "Reset cookie", 0, // true)); // } this.log.warn("Client unauthorized. Throwing a ResourceException"); throw new ResourceException(Status.CLIENT_ERROR_UNAUTHORIZED, action.getErrorMessage()); } else { // do not log this, as it is a normal part of an operation, as // evidenced by not wanting // to throw an exception return false; } } /** * Sets the data handler for this resource based on the application level data handler. * * NOTE: This requires the application to be an instance of OasWebServiceApplication for it to * function correctly */ @Override public synchronized void doInit() { super.doInit(); } /** * Determines the action to use based on whether there is a user currently logged in, and * whether that user matches the given user identifier parameter. * * @param requestedUserIdentifier * The user to determine the action for. * @param otherUserAction * The action to return if the requested user is not the current user. * @param currentUserAction * The action to return if the requested user is the current user. * @return The action for the logged in user on the requested user */ protected PoddAction getAction(final String requestedUserIdentifier, final PoddAction otherUserAction, final PoddAction currentUserAction) { PoddAction action = otherUserAction; if(this.getRequest().getClientInfo().isAuthenticated()) { if(requestedUserIdentifier != null && requestedUserIdentifier.equals(this.getRequest().getClientInfo().getUser().getIdentifier())) { action = currentUserAction; } } return action; } public PoddWebServiceApplication getPoddApplication() { final PoddWebServiceApplication application = (PoddWebServiceApplication)super.getApplication(); return application; } public PropertyUtil getPropertyUtil() { return this.getPoddApplication().getPropertyUtil(); } public PoddArtifactManager getPoddArtifactManager() { return this.getPoddApplication().getPoddArtifactManager(); } public PoddRepositoryManager getPoddRepositoryManager() { return this.getPoddApplication().getPoddRepositoryManager(); } public PoddSchemaManager getPoddSchemaManager() { return this.getPoddApplication().getPoddSchemaManager(); } public PoddSesameManager getPoddSesameManager() { return this.getPoddApplication().getPoddArtifactManager().getSesameManager(); } /** * Overriding broken ServerResource.getVariants method * * NOTE: This is not a caching implementation, so the way it is used may cause it to be a * performance bottleneck. */ @Override protected List<Variant> getVariants(final Method method) { return super.getVariants(method); } }