Dateiverwaltung für die WebBox
ulrich
2021-01-12 8ba358fc936b9d3721aa1fea64a4c00eaaa347a4
src/java/de/uhilger/filecms/api/Api.java
@@ -1,25 +1,33 @@
/*
 *  Nutzerverwaltung - User and role management in your browser
 *  Copyright (C) 2011-2017 Ulrich Hilger, http://uhilger.de
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/
 */
    Dateiverwaltung - File management in your browser
    Copyright (C) 2017 Ulrich Hilger, http://uhilger.de
    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 de.uhilger.filecms.api;
import de.uhilger.filecms.data.FileRef;
import de.uhilger.filecms.web.Initialiser;
import de.uhilger.transit.Access;
import de.uhilger.transit.web.RequestKontext;
import de.uhilger.transit.web.WebKontext;
import java.io.File;
import java.security.Principal;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@@ -28,20 +36,168 @@
 */
public abstract class Api implements WebKontext, RequestKontext {
  
  /** Zeiger zum Servlet-Kontext dieser Anwendung */
  private ServletContext ctx;
  protected ServletContext ctx;
  
  private HttpServletRequest request;
  /** Zeiger zum Request, der zur Ausfuehrung fuehrte */
  protected HttpServletRequest request;
  
  private static final Logger logger = Logger.getLogger(Api.class.getName());
  public static final String WBX_DATA_PATH = "daten/";
  public static final String PUB_DIR_PATH = "www/";
  public static final String HOME_DIR_PATH = "home/";
  public static final String DAV_DIR_PATH = "dav/";
  public static final String PUB_DIR_NAME = "Oeffentlich";
  //public static final String HOME_DIR_NAME = "Persoenlicher Ordner";
  public static final String HOME_DIR_NAME = "Persoenlich";
  public static final String DAV_DIR_NAME = "Austausch";
  public static final String WBX_ADMIN_ROLE = "wbxAdmin";
  public static final String WBX_BASE = "$basis";
  public static final String WBX_DATA = "$daten";
  public static final String DAV_DATA = "$dav";
  /**
   * Einen relativen Pfad in einen absoluten Pfad der WebBox
   * aufloesen.
   *
   * Nur die absoluten Pfade zu PUB_DIR_NAME, HOME_DIR_NAME
   * sowie WBX_BASE und WBX_DATA werden ausgegeben. Letztere
   * beiden nur fuer Nutzer mit der Rolle WBX_ADMIN_ROLE.
   *
   * D.h., es werden nur Pfade aufgeloest, die sich innerhalb
   * des Ordners der WeBox befinden.
   *
   * @param relPath
   * @return
   */
  protected File getTargetDir(String relPath) {
    logger.fine(relPath);
    File targetDir;
    String targetPath = null;
    if(relPath.startsWith(PUB_DIR_NAME)) {
      targetPath = PUB_DIR_PATH + getUserName() + relPath.substring(PUB_DIR_NAME.length());
      targetDir = new File(getBase().getAbsolutePath(), targetPath);
    } else if(relPath.startsWith(HOME_DIR_NAME)) {
      targetPath = HOME_DIR_PATH + getUserName() + relPath.substring(HOME_DIR_NAME.length());
      targetDir = new File(getBase().getAbsolutePath(), targetPath);
    } else if(relPath.startsWith(DAV_DIR_NAME)) {
      targetPath = DAV_DIR_PATH + /* getUserName() +*/ relPath.substring(DAV_DIR_NAME.length());
      targetDir = new File(getBase().getAbsolutePath(), targetPath);
    } else if(getRequest().isUserInRole(WBX_ADMIN_ROLE)) {
      logger.fine("in admin role");
      if(relPath.startsWith(WBX_BASE)) {
        logger.fine("is base");
        targetPath = getCatalinaBase(ctx);
        targetDir = new File(targetPath, relPath.substring(WBX_BASE.length()));
      } else if(relPath.startsWith(WBX_DATA)) {
        targetPath = getWbxDataDir(ctx);
        logger.fine("is data, combine " + targetPath + ' ' + relPath.substring(WBX_DATA.length()));
        targetDir = new File(targetPath, relPath.substring(WBX_DATA.length()));
      } else {
        targetDir = getDefaultDir(relPath);
      }
    } else {
      // kann eigentlich nicht sein..
      targetDir = getDefaultDir(relPath);
    }
    logger.fine("returning targetDir " + targetDir.getAbsolutePath());
    //File targetDir = new File(getBase().getAbsolutePath(), targetPath);
    return targetDir;
  }
  protected File getDefaultDir(String relPath) {
    String targetPath = PUB_DIR_PATH + getUserName() + relPath.substring(PUB_DIR_NAME.length());
    return new File(getBase().getAbsolutePath(), targetPath);
  }
  protected FileRef getBase() {
    FileRef base = null;
    Object o = getFileBase(ctx);
    if(o instanceof File) {
      File file = (File) o;
      base = new FileRef(file.getAbsolutePath(), file.isDirectory());
    }
    return base;
  }
  /* -------------- Hilfsfunktionen --------------- */
  /**
   * Das Datenverzeichnis der WebBox ermitteln
   * @return Ordner $wbx/daten
   */
  protected File getFileBase(ServletContext ctx) {
    File file = null;
    Object o = ctx.getAttribute(Initialiser.FILE_BASE);
    if(o instanceof String) {
      String baseStr = (String) o;
      logger.fine(baseStr);
      file = new File(baseStr);
    }
    return file;
  }
  /**
   * Den absoluten Pfad zum Verzeichnis ermitteln das gemaess der
   * Tomcat-Doku als CATALINA_BASE der WebBox gilt
   * @return absoluter Pfad zu $wbx/sys/base
   */
  protected String getCatalinaBase(ServletContext ctx) {
    String path = ctx.getRealPath("/");
    logger.fine("getRealPath: " + path); // file-cms in webapps
    File file = new File(path);
    file = file.getParentFile().getParentFile();
    return file.getAbsolutePath();
  }
  /**
   * Den absoluten Pfad zum Datenverzeichnis der WebBox ermitteln
   * @return absoluter Pfad zu $wbx/daten
   */
  protected String getWbxDataDir(ServletContext ctx) {
    return getFileBase(ctx).getAbsolutePath();
  }
  /**
   * Das Verzeichnis ermitteln, in dem die WebBox laeuft
   * @return der Ordner $wbx
   */
  protected File getWbxDir(ServletContext ctx) {
    String path = ctx.getRealPath("/");
    logger.fine("getRealPath: " + path);
    File file = new File(path);
    file = file.getParentFile().getParentFile().getParentFile().getParentFile();
    logger.fine("WebBox: " + file.getAbsolutePath());
    return file;
  }
  /**
   * den Namen des angemeldeten Benutzers ermitteln
   * @return Name des angemeldeten Benutzers oder null, wenn keiner angemeldet ist
   */
  protected String getUserName() {
    String userName = null;
    Object p = getRequest().getUserPrincipal();
    if(p instanceof Principal) {
      userName = ((Principal) p).getName();
    }
    return userName;
  }
  
  /* ------------- Implementierung WebKontext ------------- */
  @Override
  @Access(type = Access.Type.RESTRICT)
  public ServletContext getServletContext() {
    return ctx;
  }
  @Override
  @Access(type = Access.Type.RESTRICT)
  public void setServletContext(ServletContext servletContext) {
    this.ctx = servletContext;
  }
@@ -49,11 +205,13 @@
  /* ------------- Implementierung RequestKontext ------------- */
  @Override
  @Access(type = Access.Type.RESTRICT)
  public HttpServletRequest getRequest() {
    return request;
  }
  @Override
  @Access(type = Access.Type.RESTRICT)
  public void setRequest(HttpServletRequest r) {
    this.request = r;
  }