private boolean canOverwrite(Request request) { Boolean ow = request.getOverwriteHeader(); boolean bHasOverwriteHeader = (ow != null && request.getOverwriteHeader().booleanValue()); if (bHasOverwriteHeader) { return true; } else { String us = request.getUserAgentHeader(); if (userAgentHelper.isMacFinder(us)) { log.debug("no overwrite header, but user agent is Finder so permit overwrite"); return true; } else { return false; } } }
@Override public Resource getResource(String host, String sPath) throws NotAuthorizedException, BadRequestException { LogUtils.trace(log, "getResource", host, sPath); Path path = Path.path(sPath); Path parent = path.getParent(); Request request = HttpManager.request(); String encodedPath = request.getAbsolutePath(); // This is to support a use case where a developer wants their resources to // be accessible through milton-json, but don't want to use DAV urls. Instead // they use a parameter and DO NOT implement PostableResource. if (request.getMethod().equals(Method.POST)) { Resource wrappedResource = wrapped.getResource(host, sPath); if (wrappedResource != null && !(wrappedResource instanceof PostableResource)) { LogUtils.trace(log, "getResource: is post, and got a: ", wrappedResource.getClass()); return new PostJsonResource(host, encodedPath, wrappedResource, methodParamName, this); } } if (request.getMethod().equals(Method.GET) && isMatchingContentType(request.getAcceptHeader())) { Resource wrappedResource = wrapped.getResource(host, sPath); if (wrappedResource != null) { log.trace("getResource: matches content type, and found wrapped resource"); return wrapResource(host, wrappedResource, Method.PROPFIND.code, encodedPath); } else { LogUtils.trace( log, "getResource: is GET and matched type, but found no actual resource on", sPath); } } if (isMatchingPath(parent)) { log.trace("getResource: is matching path"); Path resourcePath = parent.getParent(); if (resourcePath != null) { String method = path.getName(); Resource wrappedResource = wrapped.getResource(host, resourcePath.toString()); if (wrappedResource != null) { Resource r = wrapResource(host, wrappedResource, method, encodedPath); LogUtils.trace(log, "returning a", r.getClass()); return r; } } } else { log.trace("getResource: not matching path"); return wrapped.getResource(host, sPath); } return null; }
public StorageErrorReason checkStorageOnAdd( Request request, CollectionResource nearestParent, Path parentPath, String host) { if (nearestParent instanceof QuotaResource) { QuotaResource qr = (QuotaResource) nearestParent; Long llAvail = qr.getQuotaAvailable(); if (llAvail == null) { Logger.debug(this, "no quota data available"); return null; } if (llAvail <= 0) { Logger.debug(this, "no quota available, reject"); return StorageErrorReason.SER_QUOTA_EXCEEDED; } else { // new content must be less then that available Long newContentLength = request.getContentLengthHeader(); if (newContentLength == null) { Logger.debug(this, "new content length is not available, cant check quota, allow"); return null; } if (newContentLength < llAvail) { return null; } else { Logger.debug(this, "new content length is greater then available storage, reject"); return StorageErrorReason.SER_QUOTA_EXCEEDED; } } } else { return null; } }
public void processExistingResource( HttpManager manager, Request request, Response response, Resource resource) throws NotAuthorizedException, BadRequestException, ConflictException { LockableResource r = (LockableResource) resource; String sToken = request.getLockTokenHeader(); sToken = LockHandler.parseToken(sToken); // this should be checked in processResource now // if( r.getCurrentLock() != null && // !sToken.equals( r.getCurrentLock().tokenId) && // isLockedOut( request, resource )) // { // //Should this be unlocked easily? With other tokens? // response.setStatus(Status.SC_LOCKED); // log.info("cant unlock with token: " + sToken); // return; // } log.debug("unlocking token: " + sToken); try { r.unlock(sToken); responseHandler.respondNoContent(resource, response, request); } catch (PreConditionFailedException ex) { responseHandler.respondPreconditionFailed(request, response, resource); } }
@Override public Object authenticate(Resource resource, Request request) { log.trace("authenticate"); Auth auth = request.getAuthorization(); Object o = resource.authenticate(auth.getUser(), auth.getPassword()); log.trace("result: {}", o); return o; }
@Override public boolean supports(Resource r, Request request) { Auth auth = request.getAuthorization(); if (auth == null) { return false; } log.trace("supports: {}", auth.getScheme()); return auth.getScheme().equals(Scheme.BASIC); }
@Override public String render(RenderContext rc) { log.debug("render"); Resource resource = rc.getTargetPage(); Request request = (Request) rc.getAttribute("request"); if (request == null) throw new RuntimeException("expected to find request in RenderContext attribute"); PermissionsAuthoriser permissionsAuthoriser = RequestContext.getCurrent().get(PermissionsAuthoriser.class); if (permissionsAuthoriser == null) throw new IllegalStateException("Not found in configuration: " + PermissionsAuthoriser.class); Boolean b = permissionsAuthoriser.authorise( resource, request, request.getMethod(), request.getAuthorization()); log.debug("result: " + b); if (b == null) return null; else return b.toString(); }
@Override public Set<CheckResult> checkPermissions( Request request, Method method, PropertyPermission perm, Set<QName> fields, Resource resource) { if (resource.authorise(request, request.getMethod(), request.getAuthorization())) { log.trace("checkPermissions: ok"); return null; } else { // return all properties log.info( "checkPermissions: property authorisation failed because user does not have permission for method: " + method.code); Set<CheckResult> set = new HashSet<CheckResult>(); for (QName name : fields) { set.add(new CheckResult(name, Status.SC_UNAUTHORIZED, "Not authorised", resource)); } return set; } }
@Override public void processExistingResource(HttpManager manager, Request request, Response response, Resource resource) throws NotAuthorizedException, BadRequestException, ConflictException { MoveableResource r = (MoveableResource) resource; String xpUserAgent = "Microsoft Data Access Internet Publishing Provider DAV 1.1"; // TODO: investigating some weird character encoding issues for non english character sets on XP Dest dest = Utils.getDecodedDestination(request.getDestinationHeader()); Resource rDest = manager.getResourceFactory().getResource(dest.host, dest.url); log.debug("process: moving from: " + r.getName() + " -> " + dest.url + " with name: " + dest.name); if (rDest == null) { log.debug("process: destination parent does not exist: " + dest); responseHandler.respondConflict(resource, response, request, "Destination parent does not exist: " + dest); } else if (!(rDest instanceof CollectionResource)) { log.debug("process: destination exists but is not a collection"); responseHandler.respondConflict(resource, response, request, "Destination exists but is not a collection: " + dest); } else { boolean wasDeleted = false; CollectionResource colDest = (CollectionResource) rDest; // check if the dest exists Resource rExisting = colDest.child(dest.name); if (rExisting != null) { // check for overwrite header if (!canOverwrite(request)) { log.info("destination resource exists, and overwrite header is not set"); responseHandler.respondPreconditionFailed(request, response, rExisting); return; } else { if (deleteExistingBeforeMove) { if (rExisting instanceof DeletableResource) { log.debug("deleting existing resource"); DeletableResource drExisting = (DeletableResource) rExisting; if (deleteHelper.isLockedOut(request, drExisting)) { log.debug("destination resource exists but is locked"); responseHandler.respondLocked(request, response, drExisting); return; } log.debug("deleting pre-existing destination resource"); deleteHelper.delete(drExisting, manager.getEventManager()); wasDeleted = true; } else { log.warn("destination exists, and overwrite header is set, but destination is not a DeletableResource"); responseHandler.respondConflict(resource, response, request, "A resource exists at the destination, and it cannot be deleted"); return; } } } } log.debug("process: moving resource to: " + rDest.getName()); try { manager.getEventManager().fireEvent(new MoveEvent(resource, colDest, dest.name)); r.moveTo(colDest, dest.name); // See http://www.ettrema.com:8080/browse/MIL-87 if (wasDeleted) { responseHandler.respondNoContent(resource, response, request); } else { responseHandler.respondCreated(resource, response, request); } } catch (ConflictException ex) { log.warn("conflict", ex); responseHandler.respondConflict(resource, response, request, dest.toString()); } } log.debug("process: finished"); }
public StorageErrorReason checkStorageOnReplace( Request request, CollectionResource parent, Resource replaced, String host) { if (parent instanceof QuotaResource) { QuotaResource qr = (QuotaResource) parent; Long llAvail = qr.getQuotaAvailable(); if (llAvail == null) { Logger.debug(this, "no quota data available"); return null; } if (llAvail <= 0) { // new content length must be less then existing Long newContentLength = request.getContentLengthHeader(); if (newContentLength == null) { Logger.debug(this, "new content length is not available, cant check quota, reject"); return StorageErrorReason.SER_QUOTA_EXCEEDED; } if (replaced instanceof GetableResource) { GetableResource gr = (GetableResource) replaced; Long existingLength = gr.getContentLength(); if (existingLength == null) { Logger.debug( this, "existing content length cant be determined, cant check quota, reject"); return StorageErrorReason.SER_QUOTA_EXCEEDED; } else { long diff = existingLength - newContentLength; if (diff > 0) { return null; } else { Logger.debug( this, "new content is larger then existing content, but no quota is available, reject"); return StorageErrorReason.SER_QUOTA_EXCEEDED; } } } else { Logger.debug( this, "existing content length cant be determined, cant check quota, reject"); return StorageErrorReason.SER_QUOTA_EXCEEDED; } } else { // difference of new content to existing must be less then available, but if in doubt allow Long newContentLength = request.getContentLengthHeader(); if (newContentLength == null) { Logger.debug(this, "new content length is not available, cant check quota, allow"); return null; } if (replaced instanceof GetableResource) { GetableResource gr = (GetableResource) replaced; Long existingLength = gr.getContentLength(); if (existingLength == null) { Logger.debug( this, "existing content length cant be determined, cant check quota, allow"); return null; } else { long diff = newContentLength - existingLength; // this is the amount extra needed if (diff <= llAvail) { return null; } else { Logger.debug( this, "new content is larger then existing content, but no quota is available, reject"); return StorageErrorReason.SER_QUOTA_EXCEEDED; } } } else { Logger.debug(this, "existing content length cant be determined, cant check quota, allow"); return null; } } // if difference between new content and existing is less then available, then ok } else { return null; } }