Package unibg.overencrypt.server

Source Code of unibg.overencrypt.server.ResourcesManager

/**
* OverEncrypt project hosted by Università degli Studi di Bergamo
*   -> for PrimeLife project {@link http://www.primelife.eu/}
*/
package unibg.overencrypt.server;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import unibg.overencrypt.core.User;
import unibg.overencrypt.domain.OverEncryptedAbstractResource;
import unibg.overencrypt.domain.OverEncryptResourceFactory;
import unibg.overencrypt.domain.OverEncryptedFileResource;
import unibg.overencrypt.domain.OverEncryptedFolderResource;
import unibg.overencrypt.domain.OverEncryptedFriendsFile;
import unibg.overencrypt.domain.OverEncryptedFriendsFolder;
import unibg.overencrypt.domain.OverEncryptedRootFolder;
import unibg.overencrypt.domain.OverEncryptedSharedFolder;
import unibg.overencrypt.domain.PlainSimpleResource;
import unibg.overencrypt.protocol.OverEncryptResponse;
import unibg.overencrypt.protocol.ServerPrimitives;
import unibg.overencrypt.server.managers.RequestManager;
import unibg.overencrypt.server.managers.ServerUpdatePermissionsManager;
import unibg.overencrypt.server.managers.SessionManager;
import unibg.overencrypt.utility.TokensResource;
import unibg.overencrypt.utility.Utils;

import com.bradmcevoy.http.MiltonServlet;
import com.bradmcevoy.http.Request;
import com.bradmcevoy.http.Request.Method;
import com.bradmcevoy.http.Resource;
import com.bradmcevoy.http.ServletRequest;

/**
* Manages resources at server-side.
*
* @author Flavio Giovarruscio & Riccardo Tribbia
* @version 1.1
*/
public class ResourcesManager extends OverEncryptResourceFactory {

  /** Logger for this class. */
  private static final Logger LOGGER = Logger.getLogger(ResourcesManager.class);

  /** Singleton reference*/
  private static ResourcesManager instance;

  /**
   * It allows to know logged users' permissions.
   * HashMap < userLoggedId, HashMap < friendId, array list of files> >
   */
  private static HashMap<Integer, HashMap<Integer,ArrayList<String>>> usersLoggedPermissions = null;

  /** A simple collection that store user logged operations about permissions request. */
  private static HashMap<Integer,Boolean> sharedUpdated = null;

  /** Lock map - HashMap< path , userId >*/
  private HashMap<String, Integer> lockMap = null;

  /* Internal fields to understand the atomicity of a request*/
  /** The previous request. */
  private int previousRequest = 0;

  /** Verify if permissions are updated. */
  private boolean permissionsUpdated = false;

  /**
   * Instantiates a new resource manager.
   */
  public ResourcesManager(){
    super();
    OverEncryptedSecurityManager osm = new OverEncryptedSecurityManager(this);
    setSecurityManager(osm);
    setContextPath(ServerConfiguration.getCONTEXT());
    setRoot(ServerConfiguration.getWebDAVrootPath());
    usersLoggedPermissions = new HashMap<Integer, HashMap<Integer,ArrayList<String>>>();
    sharedUpdated = new HashMap<Integer, Boolean>();
    lockMap = new HashMap<String, Integer>();
    instance = this;
  }

  /**
   * Singleton method
   */
  public static ResourcesManager getInstance(){
    return instance;
  }

  /**
   * It manage all webdav request.
   * In this method has been implemented the communication method (.request <-> .response) between
   * overEncrypt client and server.
   * It catch .request like a file and never show it but manage it and return a relative .response
   *
   * It also manage file system access in this way:
   * -> if user selected his root or his subfolders there's no problems,
   *     he has got permissions for that.
   * -> else if user surfs throuh /shared files and subfolders and OverEncryption system ask for his
   * permissions
   *
   * @param host the hostname of the client
   * @param file the file to resolve
   * @return the resource resolved
   * @see com.ettrema.http.fs.FileSystemResourceFactory#resolveFile(java.lang.String, java.io.File)
   */
  @Override
  public Resource resolveFile(String host, File file) {   
    //Catch request user
    Request request = new ServletRequest((HttpServletRequest)MiltonServlet.request());
    User user = retrieveUserFromRequestAuth(request);
    LOGGER.debug("USER NULL??? - " + user);

    if (user != null && request.getMethod().equals(Method.PROPFIND)) {
      LOGGER.debug("12345");
      if(getRoot().equals(new File(ServerConfiguration.getWebDAVrootPath()))){
        LOGGER.debug("Ehi! I'm here! - user id: " + user.getId());
        setRoot(ServerConfiguration.getWebDAVrootPath() + "/" + user.getId());
        LOGGER.debug("file:_" + file.toString());
        String newPath = file.toString().replace(ServerConfiguration.getWebDAVrootPath(), "");
        file = new File(ServerConfiguration.getWebDAVrootPath() + "/" + user.getId() + "/" + newPath);
        LOGGER.debug("new file: " + file.toString());
        LOGGER.debug("Nuova root: " + getRoot().toString());
      }
    }else if(user == null ){
      LOGGER.debug("USER == NULL 2");

      File fileToConsider = null;
      boolean inSharedFolder = false;
      String username = null;
      if(file.getPath().contains("/Shared"))  {
        fileToConsider = new File(retrieveRealFilePath(file.getPath()));
        inSharedFolder = true;
        username = new User(String.valueOf(Utils.retrieveUserID(fileToConsider.getPath()))).getUsername();
      }else {
        fileToConsider = file;
      }

      if (lockMap.containsKey(fileToConsider.getParent())) {
        LOGGER.debug("user == null and parent: " + fileToConsider.getParent() + " is into lockMap");
        String newPath = fileToConsider.toString().replace(ServerConfiguration.getWebDAVrootPath(), "");
        LOGGER.debug("new Path: " + newPath + " split path lenght: " + newPath.split("/").length);
        if(newPath.split("/").length >= 2)LOGGER.debug("newPath.split(\"/\")[1] : " + newPath.split("/")[1]);
        LOGGER.debug("String.valueOf(lockMap.get(file.getParent()): " + String.valueOf(lockMap.get(fileToConsider.getParent())));
        boolean founded = false;
        if (newPath.split("/").length >= 2 && newPath.split("/")[1].equals(String.valueOf(lockMap.get(fileToConsider.getParent())))) {
          LOGGER.debug("FOUND!!!!");
          newPath = newPath.substring(String.valueOf(lockMap.get(fileToConsider.getParent())).length()+2);
          LOGGER.debug("final new Path: " + newPath);
          founded = true;
        }
        if (inSharedFolder) {
          if (founded) {
            file = new File(ServerConfiguration.getWebDAVrootPath() + "/" + lockMap.get(fileToConsider.getParent()) + "/Shared/" + username + "/" + newPath);               
          }else{
            file = new File(ServerConfiguration.getWebDAVrootPath() + "/" + lockMap.get(fileToConsider.getParent()) + "/Shared/" + username + "/" + newPath.substring(2+(String.valueOf(User.getId(username)).length())));   
          }
        }else{
          file = new File(ServerConfiguration.getWebDAVrootPath() + "/" + lockMap.get(fileToConsider.getParent()) + "/" + newPath);   
        }
        LOGGER.debug("new file: " + file.toString());
      }else if(fileToConsider.getPath().equals(ServerConfiguration.getWebDAVrootPath()) && lockMap.containsKey(fileToConsider.getPath()) && !".tokens".equals(fileToConsider.getName())){
        LOGGER.debug("user == null and root: " + fileToConsider.getPath() + " is into lockMap");
        if (inSharedFolder) {
          file = new File(ServerConfiguration.getWebDAVrootPath() + "/" + lockMap.get(fileToConsider.getPath()) + "/Shared/" + username);   
        }else{
          file = new File(ServerConfiguration.getWebDAVrootPath() + "/" + lockMap.get(fileToConsider.getPath()));   
        }
        LOGGER.debug("new file: " + file.toString());       
      }else if(!fileToConsider.getParent().equals(ServerConfiguration.getWebDAVrootPath()) && !".tokens".equals(fileToConsider.getName())){
        LOGGER.debug("a3a");
        try{
          if (inSharedFolder) {
            throw new NumberFormatException("Forced Exception");
          }
          Utils.retrieveUserID(fileToConsider.getPath());
        }catch (NumberFormatException e) {
          LOGGER.debug("controllo tra gli utenti loggati");
          //ciclo la map che contiene le cartelle locked
          //vedo se c'è una corrispondenza con un utente loggato
          //IMPEDIRE CHE CE NE SIANO PIU' DI UNA
          int userWithSameNameFolderLocked = 0;
          Set<String> usersInSessions = SessionManager.getIdInSession();
          String rootPath = ServerConfiguration.getWebDAVrootPath();
          for (Iterator<String> iterator = usersInSessions.iterator(); iterator
          .hasNext();) {
            String userId = (String) iterator.next();
            String relativePath = fileToConsider.getParent().replace(rootPath, "");
            String pathToCompare = "";
            if (inSharedFolder) {
              if (fileToConsider.isDirectory()) {
                pathToCompare = fileToConsider.getPath();
                relativePath = fileToConsider.getPath().replace(rootPath, "");
              }else{
                pathToCompare = rootPath + relativePath;
              }
            }else{
              pathToCompare = rootPath + "/" + userId + relativePath;
            }
            LOGGER.debug("cerco se lockMap contiene: " + pathToCompare);
            if (lockMap.containsKey(pathToCompare)) {
              userWithSameNameFolderLocked ++;

              if (inSharedFolder) {
                if (fileToConsider.isDirectory()) {
                  file = new File(rootPath + "/" + lockMap.get(rootPath + relativePath) + "/Shared/" + username + relativePath.substring(1 + String.valueOf((User.getId(username))).length()));                     
                }else{
                  file = new File(rootPath + "/" + lockMap.get(rootPath + relativePath) + "/Shared/" + username + relativePath + "/" + fileToConsider.getName());   
                }
              }else{
                file = new File(rootPath + "/" + lockMap.get(rootPath + "/" + userId + relativePath) + relativePath + "/" + fileToConsider.getName());   
              }
              LOGGER.debug("new file: " + fileToConsider.toString());
            }
          }

          if (userWithSameNameFolderLocked > 1) {
            LOGGER.error("CI SONO PIU' DI UN UTENTE CONNESSI CHE HANNO LOCKATO UNA CARTELLA CON PATH IDENTICA");
          }
          if (userWithSameNameFolderLocked == 0) {
            //Se nn ho trovato niente provo a vedere se c'è qualcosa nella root del server
            //Valido per la richiesta di logout che non può sapere se ci sono utenti connessi o meno
            LOGGER.debug("nessuna occorrenza trovata. Provo a vedere se il file è nella root");
            File newFile = new File(rootPath + "/" + fileToConsider.getName());
            if (newFile.exists()) {
              LOGGER.debug("new file esiste! ");
              file = newFile;
            }
          }
        }
      }else if(fileToConsider.getParent().equals(ServerConfiguration.getWebDAVrootPath()) && !".tokens".equals(fileToConsider.getName())){
        LOGGER.debug("b3b");
        try{
          if (inSharedFolder) {
            throw new NumberFormatException("Forced Exception");
          }
          Utils.retrieveUserID(fileToConsider.getPath());
        }catch (NumberFormatException e) {
          LOGGER.debug("controllo tra gli utenti loggati");
          //ciclo la map che contiene le cartelle locked
          //vedo se c'è una corrispondenza con un utente loggato
          //IMPEDIRE CHE CE NE SIANO PIU' DI UNA
          int userWithSameNameFolderLocked = 0;
          Set<String> usersInSessions = SessionManager.getIdInSession();
          String rootPath = ServerConfiguration.getWebDAVrootPath();
          for (Iterator<String> iterator = usersInSessions.iterator(); iterator
          .hasNext();) {
            String userId = (String) iterator.next();
            String relativePath = "";
            if (".response".equals(fileToConsider.getName()) || ".request".equals(fileToConsider.getName())) {
              relativePath = fileToConsider.getParent().replace(rootPath, "");
            }else{
              relativePath = fileToConsider.getPath().replace(rootPath, "");
            }
            String pathToCompare = "";
            if (inSharedFolder) {
              pathToCompare = rootPath + relativePath;
            }else{
              pathToCompare = rootPath + "/" + userId + relativePath;
            }
            LOGGER.debug("cerco se lockMap contiene: " + pathToCompare);
            if (lockMap.containsKey(pathToCompare)) {
              userWithSameNameFolderLocked ++;
              if (inSharedFolder) {
                file = new File(rootPath + "/" + lockMap.get(rootPath + relativePath) + "/Shared/" + username + relativePath);   
              }else{
                file = new File(rootPath + "/" + lockMap.get(rootPath + "/" + userId + relativePath) + relativePath);   
              }
              LOGGER.debug("new file: " + file.toString());
            }
          }

          if (userWithSameNameFolderLocked > 1) {
            LOGGER.error("CI SONO PIU' DI UN UTENTE CONNESSI CHE HANNO LOCKATO UNA CARTELLA CON PATH IDENTICA");
          }
        }
      }else if(".tokens".equals(fileToConsider.getName())){
        String realTokensPath = TokensResource.getLockedPath(fileToConsider.getPath(), lockMap, username);
        file = new File(realTokensPath);
        LOGGER.debug("tokens at path: " + file.getPath() + " exists? " + file.exists());
      }
    }

    Map<String,String> headers = request.getHeaders();

    try{
      Utils.retrieveUserID(file.getPath());
    } catch (NumberFormatException e) {
      //Lock management
      if(!file.getPath().contains("/Shared")){
        if(file.getName().contains(".lock")){
          return new PlainSimpleResource(lockResource(file, user, false));
        }
      }else if(file.getPath().contains("/Shared")){
        File newFile = new File(retrieveRealFilePath(file.getAbsolutePath()));
        if(file.getName().contains(".lock")){
          return new PlainSimpleResource(lockResource(newFile, user, true));
        }
      }
    }

    //Unlock management
    if (file.getName().contains(".unlock")) {
      if (request.getMethod().equals(Method.OPTIONS)) {
        if(!file.getPath().contains("/Shared")){
          return new PlainSimpleResource(unlockResource(file, false));       
        }else if(file.getPath().contains("/Shared")){
          File newFile = new File(retrieveRealFilePath(file.getAbsolutePath()));
          return new PlainSimpleResource(unlockResource(newFile, true));         
        }else return null;
      }else{
        return null;
      }
    }

    //Bypass only for OVER ENCRYPT REQUEST / RESPONSE CLIENT
    LOGGER.debug("FILE '" + file.getPath() +"'EXISTS? " + file.exists());
    if(!file.getPath().contains("/Shared") && file.exists()){
      if(".request".equals(file.getName())){
        LOGGER.debug(".request intercepted");
        return new PlainSimpleResource(RequestManager.manageRequest(file, request, false));
      }
      if(".response".equals(file.getName())){
        return new PlainSimpleResource(file);
      }
    }else if(file.getPath().contains("/Shared")){
      File newFile = new File(retrieveRealFilePath(file.getAbsolutePath()));
      if(newFile.exists()){
        if(".request".equals(file.getName())){
          LOGGER.debug(".request intercepted");
          return new PlainSimpleResource(RequestManager.manageRequest(newFile, request, true));
        }
        if(".response".equals(file.getName())){
          return new PlainSimpleResource(newFile);
        }
      }
    }
    if (".response".equals(file.getName()) && !file.exists() && request.getMethod().equals(Method.DELETE)) {
      return null;
    }

    //TODO CHANGE USER-AGENT NAME IN CLIENT
    if(headers.containsKey("user-agent")){
      if(headers.get("user-agent").contains("Jakarta Commons-HttpClient")){
        LOGGER.debug("user-agent - Jakarta Commons-Http client recognise!");
        if(file.getPath().contains("/Shared")){
          return resolveFileIfPermitted(host, file, false, false);          
        }else{
          return resolveFileIfPermitted(host, file, true, true);
        }
      }
    }

    //Path control
    //In this way, it happens only when the user is IN shared folder with some resources
    if(file.getPath().contains("/Shared") && file.getPath().indexOf("/Shared/") == -1){
      // 1. Special case: "Shared" folder
      return resolveFileIfPermitted(host, file, false, false);
    }else if(file.getPath().contains("/Shared") && doubleCheckOnShared(file.getPath())){
      // 2. Case into shared folders (also 'username' folder, or their subtrees)
      LOGGER.debug("INTO Shared folder with any files");
      if(previousRequest == request.hashCode()){
        LOGGER.debug("same request before");
        if(permissionsUpdated){
          LOGGER.debug("permissionsUpdated");
          return resolveFileIfPermitted(host, file, false, false);
        } else {
          LOGGER.debug("permissions don't updated");
          return null;
        }
      } else {
        permissionsUpdated = false;
        previousRequest = request.hashCode();
        LOGGER.debug("previousRequest: " + previousRequest);

        if(user != null && sharedUpdated.containsKey(user.getId()) && sharedUpdated.get(user.getId())){
          LOGGER.debug("sharedUpdated containsKey(userId) and permissions are not deprecated");
          LOGGER.debug("PERMISSION ALREADY UPDATE AND NOT DEPRECATED. LIST FILES");
          permissionsUpdated = true;
          return resolveFileIfPermitted(host, file, false, false);
        }else{
          //If the user that made request never update permissions or its permissions are out of date
          LOGGER.debug("send update permissions request");
          if(user == null)
            LOGGER.error("Which way has it followed? It's called a webdav request without authorization inside (GET, PUT,...? ");
          return new PlainSimpleResource(ServerUpdatePermissionsManager.sendUpdatePermissionsResponseForSharedFiles(file, user));
        }
      }
    } else {
      // 3. Not in shared folders, owner folders
      LOGGER.debug("Not in /shared/ - user owned file");
      if(this.getRoot().equals(file)){
        if(this.getRoot().getPath().equals(ServerConfiguration.getWebDAVrootPath())){
          LOGGER.debug("resolveFileIfPermitted1");
          return resolveFileIfPermitted(host, file, true, true)
        } else {
          if(user != null) {
            LOGGER.debug("OverEncryptedRootFolder");
            return new OverEncryptedRootFolder(host, this, user.getId());
          }
          else {
            LOGGER.debug("User null");
            return resolveFileIfPermitted(host, new File(file.getParent()), true, true);
          }
        }
      } else {
        LOGGER.debug("resolveFileIfPermitted2");
        return resolveFileIfPermitted(host, file, false, true);
      }
    }
  }

  /**
   * Make some simple checks with user permission to return the exact file.
   *
   * @param host the hostname of the client
   * @param file the file required
   * @param bypass true, if permission must be bypassed
   * @param owneredFolder the owner of the folder
   * @return the over encrypted resource
   */
  private OverEncryptedAbstractResource resolveFileIfPermitted(String host, File file, boolean bypass, boolean owneredFolder){
    boolean permitted = false;

    //Retrieve user logged id by file path
    int userLoggedID = 0;

    try{
      userLoggedID = Utils.retrieveUserID(file.getAbsolutePath());
    }catch (NumberFormatException e) {
      LOGGER.warn("No user id found in this path");
    }
    LOGGER.debug("user logged id: " + userLoggedID);

    //Check permissions
    if(!bypass){
      if(userLoggedID == 0 || !usersLoggedPermissions.containsKey(userLoggedID)){
        LOGGER.debug("userLoggedId == 0 || userLoggedPermissions !containsKey(userId)");
        permitted = false;
      }else {
        LOGGER.debug("userLoggedPermissions containsKey(UserId)");
        HashMap<Integer, ArrayList<String>> mapOfPermissions = usersLoggedPermissions.get(userLoggedID);


        if(owneredFolder){
          //Ownered folder case
          if(mapOfPermissions.containsKey(userLoggedID)){
            LOGGER.debug("mapsOfPermissions contains user logged id");

            ArrayList<String> owneredFolders = mapOfPermissions.get(userLoggedID);

            for (Iterator<String> iterator = owneredFolders.iterator(); iterator.hasNext();) {
              String string = (String) iterator.next();
              LOGGER.debug("ArrayList<String> owneredFolders: " + string);
            }

            String relativeToUserPath = (file.isDirectory())? file.getAbsolutePath(): file.getParent();

            relativeToUserPath = relativeToUserPath.replace(ServerConfiguration.getWebDAVrootPath(), "");

            LOGGER.debug("relativeToUserPath: " + relativeToUserPath);
            LOGGER.debug("relativeToUserPath.equals(String.valueOf(userLoggedID)): " + relativeToUserPath.equals(String.valueOf(userLoggedID)));

            if(relativeToUserPath.equals(String.valueOf(userLoggedID)) || owneredFolders.contains(relativeToUserPath) ){
              if(file.isDirectory())
                return new OverEncryptedFolderResource(host, this, file, userLoggedID, true);
              else
                return new OverEncryptedFileResource(host, this, file, userLoggedID, true, false);

            }else return null; //--> Unauthorized access

          }else{
            LOGGER.debug("mapsOfPermissions doesn't contain user logged id.");
            permitted = false;
          }
        }else{
          //Shared folder case

          if(file.getAbsolutePath().endsWith("Shared")){
            //Shared folder root
            return new OverEncryptedSharedFolder(this, userLoggedID);
          }else{
            //Shared subfolders

            //Retrieve owner folder id
            int friendID = retrieveOwnerIDFromSharedFilePath(file.getAbsolutePath());
            LOGGER.debug("friend id catch from shared file path: " + friendID);

            //First check: the friend shared folder is a user's friend folder
            if(mapOfPermissions.containsKey(friendID)){
              String realPathSharedFile = retrieveRealFilePath(file.getAbsolutePath());
              LOGGER.debug("realPathSharedFile: " +realPathSharedFile);
              File sharedFile = new File(realPathSharedFile);

              String halfPath = realPathSharedFile.replace(ServerConfiguration.getWebDAVrootPath(), "");
              if(realPathSharedFile.endsWith("/" + friendID)){
                //rootFolder
                //friends folder es: "/67"
                return new OverEncryptedFriendsFolder(this, "/" + friendID, friendID, userLoggedID);
              }else if(mapOfPermissions.get(friendID).contains(halfPath)){
                //If user has permissions into afterShared folder
                if(sharedFile.isDirectory()){
                  return new OverEncryptedFriendsFolder(this, halfPath, friendID, userLoggedID);
                }else{
                  //TODO non dovrebbe mai essere un file qui
                  return new OverEncryptedFriendsFile(this, halfPath, false);
                }         
              }else if(!sharedFile.isDirectory()){
                //TODO Miss a check for allows only files into allowed paths and tokens in parent path
                return new OverEncryptedFriendsFile(this, halfPath, true);               
              }
            }else{
              LOGGER.debug("mapsOfFriendAndFiles doesn't contain friend id.");
              permitted = false;
            }
          }
        }
      }
    }else{
      permitted = true;
    }

    if(permitted){
      if( file.isDirectory() ) {
        return new OverEncryptedFolderResource(host, this, file, userLoggedID, true);
      } else {
        if(file.getName().equals(".tokens") && !file.exists()) {
          return null;
        } else {
          return new OverEncryptedFileResource(host, this, file, userLoggedID, true, bypass);
        }
      }
    } else {
      return null;
    }
  }

  /**
   * Update logged users permissions collection
   * Update status of users permissions.
   *
   * @param userLoggedId the user that make update request
   * @param userToUpdate the user linked to permissions to update
   * @param filePaths    the file paths that logged user can access
   */
  public static void setPermissionsCollection(Integer userLoggedId, Integer userToUpdate, ArrayList<String> filePaths){
    if(usersLoggedPermissions.containsKey(userLoggedId)){
      HashMap<Integer, ArrayList<String>> permissions = usersLoggedPermissions.get(userLoggedId);
      permissions.put(userToUpdate, filePaths);     
    }else{
      HashMap<Integer, ArrayList<String>> permissions = new HashMap<Integer, ArrayList<String>>();
      permissions.put(userToUpdate, filePaths);
      usersLoggedPermissions.put(userLoggedId, permissions);
    }
    if(userLoggedId != userToUpdate){
      sharedUpdated.put(userLoggedId, true);
    }
  }

  /**
   * Set the permissions' collection of user passed deprecated
   * -> Has to be called from "Grant" and "Revoke" process.
   *
   * @param userId - user of which permissions' collection is now deprecated
   * 'cause an other user grant or revoke permission with him
   */
  public static void setPermissionCollectionDeprecated(Integer userId){
    if(usersLoggedPermissions.containsKey(userId)){
      sharedUpdated.put(userId, false);
    }
  }

  /**
   * Gets the folder path allowed.
   *
   * @param userLoggedID the user logged id
   * @return the folder path allowed
   */
  public static ArrayList<String> getFolderPathAllowed(Integer userLoggedID){
    ArrayList<String> folderPathAllowed = null;
    HashMap<Integer, ArrayList<String>> temp = usersLoggedPermissions.get(userLoggedID);
    if(temp == null){  //If it's null initialize it
      folderPathAllowed = new ArrayList<String>();
      temp = new HashMap<Integer, ArrayList<String>>();
      temp.put(userLoggedID, folderPathAllowed);
      usersLoggedPermissions.put(userLoggedID, temp);
    }
    return usersLoggedPermissions.get(userLoggedID).get(userLoggedID);
  }

  /**
   * Retrieve array of paths shared by ownerID with userID.
   * If this owner has shared nothing with this user yet, initialize the hashmap.
   * If this user is logged but, 'cause of some errors, he hasn't any permissions yet,
   * initialize the hashmap of hashmaps.
   *
   * @param userID - id of the user
   * @param ownerID - id of the folder owner
   * @return - array list of paths shared by this owner with this user
   */
  public static ArrayList<String> getFolderPathsSharedBy(Integer userID, Integer ownerID){
    ArrayList<String> folderPathAllowed = null;
    if(isLogged(userID)){
      HashMap<Integer, ArrayList<String>> temp = usersLoggedPermissions.get(userID);
      if(temp == null){  //If it's null initialize it
        folderPathAllowed = new ArrayList<String>();
        temp = new HashMap<Integer, ArrayList<String>>();
        temp.put(ownerID, folderPathAllowed);
        usersLoggedPermissions.put(userID, temp);
      }else{
        folderPathAllowed = temp.get(ownerID);
        if(folderPathAllowed == null){
          folderPathAllowed = new ArrayList<String>();
          temp.put(ownerID, folderPathAllowed);
        }
      }
    }
    return folderPathAllowed;
  }

  public static boolean isLogged(int userId){
    return usersLoggedPermissions.containsKey(userId);
  }

  public static void removeUserPermissions(int userId) {
    usersLoggedPermissions.remove(userId);
  }

  public void resetRoot() {
    LOGGER.debug("reset Root");
    setRoot(ServerConfiguration.getWebDAVrootPath());
  }

  public HashMap<Integer,ArrayList<String>> getUserPermissions(Integer user){
    return usersLoggedPermissions.get(user);
  }

  private User retrieveUserFromRequestAuth(Request request){
    User user = null;
    if(request.getAuthorization() != null){
      LOGGER.debug("request.Authorization != null. Request type: " + request.getMethod().toString());
      user = new User();
      String username = request.getAuthorization().getUser();
      String passw = request.getAuthorization().getPassword();
      try {
        user.login(username, passw);
      } catch (Exception e) {
        LOGGER.error("Error while retrieving logged user info",e);
      }
    }else{
      LOGGER.debug("request.Authorization == null.");
    }
    return user;
  }

  private String retrieveRealFilePath(String sharedFilePath){
    if (sharedFilePath.indexOf("/Shared") != 0 && sharedFilePath.indexOf("/Shared/") == -1) {
      LOGGER.debug("Il sistema sta controllando direttamente la cartella /Shared, gli passo la root");
      return ServerConfiguration.getWebDAVrootPath();
    }
   
    String afterShared = sharedFilePath.substring(sharedFilePath.indexOf("/Shared/")+8);
    LOGGER.debug("sharedFilePath: " + sharedFilePath);
    LOGGER.debug("afterShared: " + afterShared);

    //Extract friend id
    int friendID = User.getId(afterShared.split("/")[0]);
    LOGGER.debug("friend id catch from shared file path: " + friendID);
    afterShared = "/" + afterShared.replace(afterShared.split("/")[0], Integer.toString(friendID));
    LOGGER.debug("after shared: " + afterShared);

    String realPathSharedFile = ServerConfiguration.getWebDAVrootPath() + afterShared;
    LOGGER.debug("realPathSharedFile: " +realPathSharedFile);

    return realPathSharedFile;
  }

  private Integer retrieveOwnerIDFromSharedFilePath(String sharedFilePath){
    String afterShared = sharedFilePath.substring(sharedFilePath.indexOf("/Shared/")+8);
    LOGGER.debug("sharedFilePath: " + sharedFilePath);
    LOGGER.debug("afterShared: " + afterShared);

    //Extract friend id
    return User.getId(afterShared.split("/")[0]);
  }

  private boolean doubleCheckOnShared(String filePath){
    boolean ok = true;
    String afterShared = filePath.substring(filePath.indexOf("/Shared/")+8);
    LOGGER.debug("filePath: " + filePath);
    LOGGER.debug("afterShared: " + afterShared);

    int userId = User.getId(afterShared.split("/")[0]);

    if(userId <= 0){
      LOGGER.debug("User ID retrieved: " + userId);
      ok = false;
    }
    return ok;
  }

  private File lockResource(File resource, User user, boolean isInSharedFolder){
    boolean returnValue = false;
    String pathResource = resource.getParent();

    String userId = resource.getName().substring(resource.getName().lastIndexOf("_")+1);
    LOGGER.debug("LOCK - user ID? " + userId);

    if(!pathResource.equals(ServerConfiguration.getWebDAVrootPath())){
      String rootPath = ServerConfiguration.getWebDAVrootPath();
      String relativePath = pathResource.replace(rootPath, "");
      if (isInSharedFolder) {
        pathResource = rootPath + relativePath;       
      }else{
        pathResource = rootPath + "/" + userId + relativePath;
      }
    }
    LOGGER.debug("LOCK - parent resource to lock: " + pathResource);

    resource.delete();
    if (lockMap.containsKey(pathResource)) {
      if (lockMap.get(pathResource).equals(Integer.parseInt(userId)))
        returnValue = true;
      else
        returnValue = false;
    }else{
      lockMap.put(pathResource, Integer.parseInt(userId));
      returnValue = true;
    }

    String pathResourceForResponse = (pathResource.equals(ServerConfiguration.getWebDAVrootPath())) ? pathResource + "/" + userId : pathResource;

    return OverEncryptResponse.generateResponse(ServerPrimitives.OE_LOCK, pathResourceForResponse, String.valueOf(returnValue));
  }

  private File unlockResource(File resource, boolean isInSharedFolder){
    String rootPath = ServerConfiguration.getWebDAVrootPath();
    String pathWithoutRoot = resource.getParent().replace(rootPath, "");
    LOGGER.debug("UNLOCK - path without root: " + pathWithoutRoot);
    String[] splittedStrings = pathWithoutRoot.split("/");
    LOGGER.debug("splittedStrings.lenght: " + splittedStrings.length);

    String userId = resource.getName().substring(resource.getName().lastIndexOf("_")+1);

    String pathToUnlock = "";
    if (splittedStrings.length == 2 ) {   //Root path
      pathToUnlock = rootPath;
    }else if (splittedStrings.length > 2) { //Subfolder path
      try {
        String userIdExtractedFromPath = String.valueOf(Integer.parseInt(splittedStrings[1]));
        LOGGER.debug("UNLOCK - user id extracted: " + userIdExtractedFromPath);
        LOGGER.debug("UNLOCK - user id to unlock: " + userId);
        if (userIdExtractedFromPath.equals(userId)) {
          LOGGER.debug("UNLOCK users are the same");
        }else{
          LOGGER.error("UNLOCK - user extracted and user to unlock aren't the same");
        }
      } catch (NumberFormatException e) {
        LOGGER.debug("UNLOCK - no user id into resource path");
      }       
      pathToUnlock = rootPath + pathWithoutRoot;
    }else{
      LOGGER.warn("UNLOCK - Splitted string lenght ? -> " + splittedStrings.length);
    }

    LOGGER.debug("UNLOCK - parent resource to unlock: " + pathToUnlock);
    LOGGER.debug("UNLOCK - user ID? " + userId);
    resource.delete();
    if (lockMap.containsKey(pathToUnlock)) {
      LOGGER.debug("UNLOCK - path to remove: " + pathToUnlock);
      lockMap.remove(pathToUnlock);

      //Search if there is any .response in pathresource
      File root = new File(pathToUnlock);
      String[] files = root.list();
      for (int i = 0; i < files.length; i++) {
        if (".response".equals(files[i])) {
          LOGGER.debug("---Delete request into resource path");
          new File(pathToUnlock + "/.response").delete();
        }
      }     
    }
    return null;
  }
}
TOP

Related Classes of unibg.overencrypt.server.ResourcesManager

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.