Package v7db.files.milton

Source Code of v7db.files.milton.ResourceFactory

/**
* Copyright (c) 2011-2012, Thilo Planz. All rights reserved.
*
* 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 v7db.files.milton;

import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.substringAfter;
import static org.apache.commons.lang3.StringUtils.substringAfterLast;

import java.util.Properties;

import org.slf4j.MDC;

import v7db.auth.AuthenticationProvider;
import v7db.auth.AuthenticationProviderFactory;
import v7db.auth.AuthenticationToken;
import v7db.auth.MongoAuthenticationProvider;
import v7db.files.AuthorisationProvider;
import v7db.files.AuthorisationProviderFactory;
import v7db.files.Configuration;
import v7db.files.mongodb.V7File;
import v7db.files.mongodb.V7GridFS;

import com.bradmcevoy.http.ApplicationConfig;
import com.bradmcevoy.http.Auth;
import com.bradmcevoy.http.HttpManager;
import com.bradmcevoy.http.Initable;
import com.bradmcevoy.http.MiltonServlet;
import com.bradmcevoy.http.Request;
import com.bradmcevoy.http.Resource;
import com.bradmcevoy.http.Request.Method;
import com.mongodb.Mongo;

class ResourceFactory implements com.bradmcevoy.http.ResourceFactory, Initable {

  private Mongo mongo;

  private V7GridFS fs;

  private String ROOT;

  private String endpoint;

  private String endpointName;

  private Properties endpointProperties;

  private AuthenticationProvider authentication;

  private AuthorisationProvider authorisation;

  private boolean fakeLocking = false;

  private final String dbName;

  ResourceFactory(String dbName) {
    this.dbName = dbName;
  }

  public void init(ApplicationConfig config, HttpManager manager) {
    try {
      endpoint = config.getInitParameter("webdav.endpoint");

      endpointName = defaultIfBlank(substringAfterLast(endpoint, "/"),
          "/");

      mongo = Configuration.getMongo();

      endpointProperties = new Properties(Configuration
          .getEndpointProperties(endpoint));
      // need to adjust mongo.db in case of multi-tenant mode
      endpointProperties.put("mongo.db", dbName);

      fs = new V7GridFS(mongo.getDB(dbName));

      ROOT = getProperty("root");
      if (ROOT == null)
        ROOT = endpoint;

      authentication = getAuthenticationProvider();

      authorisation = AuthorisationProviderFactory
          .getAuthorisationProvider(endpointProperties);

      fakeLocking = "fake".equals(getProperty("locking.provider"));

    } catch (Exception e) {
      throw new RuntimeException(e);
    }

  }

  private AuthenticationProvider getAuthenticationProvider() {
    String p = endpointProperties.getProperty("auth.provider");
    if ("mongo".equals(p)) {
      return new MongoAuthenticationProvider(mongo, endpointProperties);
    }

    return AuthenticationProviderFactory
        .getAuthenticationProvider(endpointProperties);
  }

  public Resource getResource(String host, String _path) {

    String servletPath = MiltonServlet.request().getServletPath();
    String path = _path.equals(servletPath) ? "/" : substringAfter(_path,
        servletPath);

    if (!path.startsWith("/"))
      throw new IllegalArgumentException("path: " + _path
          + " servletPath: " + servletPath);

    if ("/".equals(path)) {
      return fakeLocking ? new LockableFolderResource(endpointName, fs
          .getFile(ROOT), this) : new FolderResource(endpointName, fs
          .getFile(ROOT), this);
    }

    String[] p = path.split("/");
    p[0] = ROOT;

    V7File f = fs.getFile(p);
    if (f == null)
      return null;

    if (f.hasContent())
      return fakeLocking ? new LockableFileResource(f, this)
          : new FileResource(f, this);

    return fakeLocking ? new LockableFolderResource(f, this)
        : new FolderResource(f, this);
  }

  public void destroy(HttpManager manager) {
    if (mongo != null)
      mongo.close();

  }

  String getProperty(String name) {
    return endpointProperties.getProperty(name);
  }

  String getRealm() {
    return getProperty("auth.realm");
  }

  boolean authorise(V7File file, Request request, Method method, Auth auth) {

    AuthenticationToken tag = auth == null ? null
        : (AuthenticationToken) auth.getTag();
    switch (method) {
    case GET:
    case PROPFIND:
      return authorisation.authoriseRead(file, tag);
    case POST:
    case PUT:
    case MKCOL:
    case DELETE:
    case LOCK:
      return authorisation.authoriseWrite(file, tag);
    case UNLOCK:
      // unlock only works if you have the lock token, so no extra
      // authorisation required
      return true;

    case MOVE:
      // TODO: also need to check write permissions in the target
      // directory
      return authorisation.authoriseWrite(file, tag);
    case COPY:
      // TODO: also need to check write permissions in the target
      // directory
      return authorisation.authoriseRead(file, tag);
    default:
      System.err.println("acl not implemented for " + method + " on "
          + file.getName());
      return false;
    }

  }

  AuthenticationToken authenticate(String user, String password) {
    // Cyberduck does BasicAuth with "anonymous"
    // not sure if that is good, but here we go ...
    // we cannot return null because that would "fail" the anonymous login
    if ("anonymous".equals(user))
      return AuthenticationToken.ANONYMOUS;

    if (authentication == null)
      return null;

    AuthenticationToken auth = authentication.authenticate(user, password);

    if (auth != null)
      MDC.put("user", auth.getUsername());

    return auth;

  }

}
TOP

Related Classes of v7db.files.milton.ResourceFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.