/**
* 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;
}
}