package com.bradmcevoy.http;
import com.bradmcevoy.common.Path;
import com.bradmcevoy.http.Request.Method;
import com.bradmcevoy.http.http11.Http11ResponseHandler;
import com.bradmcevoy.http.quota.StorageChecker;
import com.bradmcevoy.http.quota.StorageChecker.StorageErrorReason;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author brad
*/
public class HandlerHelper {
private final static Logger log = LoggerFactory.getLogger( HandlerHelper.class );
private AuthenticationService authenticationService;
private final List<StorageChecker> storageCheckers;
public HandlerHelper( AuthenticationService authenticationService, List<StorageChecker> storageCheckers ) {
this.authenticationService = authenticationService;
this.storageCheckers = storageCheckers;
}
/**
* Checks the expect header, and responds if necessary
*
* @param resource
* @param request
* @param response
* @return - true if the expect header is ok
*/
public boolean checkExpects( Http11ResponseHandler responseHandler, Request request, Response response ) {
String s = request.getExpectHeader();
if(true) //Patched for InfoGlue and Mac OS X
return true;
if( s != null && s.length() > 0 ) {
response.setStatus( Response.Status.SC_CONTINUE);
return false;
} else {
return true;
}
}
public boolean checkAuthorisation( HttpManager manager, Resource resource, Request request ) {
Auth auth = request.getAuthorization();
if( auth != null ) {
if( auth.getTag() == null ) { // don't do double authentication
Object authTag = authenticationService.authenticate( resource, request ); //handler.authenticate( auth.user, auth.password );
if( authTag == null ) {
log.warn( "failed to authenticate - authenticationService:" + authenticationService.getClass() + " resource type:" + resource.getClass() );
return false;
} else {
log.trace( "got authenticated tag: " + authTag.getClass() );
auth.setTag( authTag );
}
} else {
log.trace("request is pre-authenticated");
}
} else {
auth = manager.getSessionAuthentication( request );
}
boolean authorised = resource.authorise( request, request.getMethod(), auth );
if( !authorised ) {
if( log.isWarnEnabled()) {
log.warn( "authorisation declined, requesting authentication: " + request.getAbsolutePath() + ". resource type: " + resource.getClass().getCanonicalName());
if( auth != null ) {
if( log.isTraceEnabled() ) {
log.trace(" - auth: " + auth.getUser() + " tag: " + auth.getTag());
}
} else {
log.trace(" - anonymous request");
}
}
return false;
} else {
return true;
}
}
public boolean doCheckRedirect( Http11ResponseHandler responseHandler, Request request, Response response, Resource resource ) {
String redirectUrl = resource.checkRedirect( request );
if( redirectUrl != null ) {
responseHandler.respondRedirect( response, request, redirectUrl );
return true;
} else {
return false;
}
}
/**
* TODO: move to webdav
*
* @param inRequest
* @param inResource
* @return
*/
public boolean isLockedOut( Request inRequest, Resource inResource ) {
if( inResource == null || !( inResource instanceof LockableResource ) ) {
return false;
}
LockableResource lr = (LockableResource) inResource;
LockToken token = lr.getCurrentLock();
if( token != null ) {
Auth auth = inRequest.getAuthorization();
Object sUser = null;
if( auth != null ) sUser = auth.getUser();
String lockedByUser = token.info.lockedByUser;
if( lockedByUser == null ) {
log.warn( "Resource is locked with a null user. Ignoring the lock" );
return false;
} else if( !lockedByUser.equals( sUser ) ) {
if( log.isInfoEnabled() ) {
if( auth == null ) {
log.trace( "lock owned by: " + lockedByUser );
} else {
log.trace( "lock owned by: " + lockedByUser + " not by " + auth.getUser() );
}
}
String value = inRequest.getIfHeader();
if( value != null ) {
if( value.contains( "opaquelocktoken:" + token.tokenId + ">" ) ) {
log.trace( "Request contains valid token so operation is permitted" );
return false;
}
}
return true;
}
}
return false;
}
public boolean missingLock( Request inRequest, Resource inParentcol ) {
//make sure we are not requiring a lock
String value = inRequest.getIfHeader();
if( value != null ) {
if( value.contains( "(<DAV:no-lock>)" ) ) {
log.info( "Contained valid token. so is unlocked" );
return true;
}
}
return false;
}
public StorageErrorReason checkStorageOnReplace(Request request, CollectionResource parentCol, Resource replaced, String host) {
for( StorageChecker sc : storageCheckers) {
StorageErrorReason res = sc.checkStorageOnReplace( request, parentCol, replaced, host );
if( res != null ) {
log.warn( "insufficient storage reason: " + res + " reported by: " + sc.getClass() );
return res;
}
}
return null;
}
public StorageErrorReason checkStorageOnAdd(Request request, CollectionResource nearestParent, Path parentPath, String host) {
for( StorageChecker sc : storageCheckers) {
StorageErrorReason res = sc.checkStorageOnAdd( request, nearestParent, parentPath, host );
if( res != null ) {
log.warn( "insufficient storage reason: " + res + " reported by: " + sc.getClass() );
return res;
}
}
return null;
}
/**
* Returns true to indicate that the given resource MUST NOT handle the
* given method.
*
* A return value of false indicates that it might.
*
* @param r - the resource to check
* @param m - the HTTP request method
* @return - true to indicate the resource must not handle method m
*/
public boolean isNotCompatible(Resource r, Method m) {
if( r instanceof ConditionalCompatibleResource ){
ConditionalCompatibleResource ccr = (ConditionalCompatibleResource) r;
return !ccr.isCompatible( m );
}
return false;
}
}