Skip to content
Snippets Groups Projects
Select Git revision
  • fd9c34cfd3dcaf2a5ba4df6713e8c5c513b5763a
  • master default protected
  • livrable4.1
  • livrable4
  • livrable3
  • livrable2
  • livrable1
7 results

ServiceFTPEndPoint.java

Blame
  • ServiceFTPEndPoint.java 18.75 KiB
    package fil.sr2.endpoints;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.util.zip.ZipOutputStream;
    
    import javax.ws.rs.Consumes;
    import javax.ws.rs.DELETE;
    import javax.ws.rs.DefaultValue;
    import javax.ws.rs.GET;
    import javax.ws.rs.HeaderParam;
    import javax.ws.rs.POST;
    import javax.ws.rs.PUT;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    import javax.ws.rs.QueryParam;
    import javax.ws.rs.WebApplicationException;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    import javax.ws.rs.core.Response.ResponseBuilder;
    import javax.ws.rs.core.StreamingOutput;
    
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPFile;
    import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
    import org.glassfish.jersey.media.multipart.FormDataParam;
    
    import fil.sr2.Main;
    import fil.sr2.Secured;
    import fil.sr2.utils.Utils;
    
    /**
     * Cette classe représente la ressource "/ftp", cette ressource permet de
     * telecharger , de supprimer, de renommer et de lister le contenu d'un
     * repertoire
     * 
     * @author Bouali Hocine
     *
     */
    @Path("ftp")
    public class ServiceFTPEndPoint {
    	private FTPClient ftp;
    	private String server;
    
    	/**
    	 * Methode qui permet d'initialiser une connexion à un serveur FTP ou FTPS
    	 * 
    	 * @param alias    l'alias du serveur FTP
    	 * @param type     FTP ou FTPS
    	 * @param username le username
    	 * @param psw      le mot de passe
    	 * @param mode     le mode d'echange avec le serveur (PASV ou PORT)
    	 * @param port     le Port de connexion
    	 * @return un statut http
    	 */
    	private Response init(String alias, String type, String username, String psw, String mode, int port) {
    		try {
    			server = Utils.findAddress(alias, Main.allAlias);
    		} catch (NullPointerException e) {
    			return Response.status(Response.Status.FORBIDDEN).entity(alias + " not exist").build();
    		}
    		try {
    			switch (type.toLowerCase()) {
    			case "ftp":
    				ftp = Utils.initftp(server, username, psw, port, mode);
    				break;
    			case "ftps":
    				ftp = Utils.initftps(server, username, psw, port, mode);
    				break;
    			default:
    				return Response.status(Response.Status.FORBIDDEN).entity(type + " not supported or not exist").build();
    			}
    		} catch (SocketException e1) {
    			return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("try later pls !").build();
    		} catch (IOException e2) {
    			return Response.status(Response.Status.FORBIDDEN).entity("impossible to connect to " + server).build();
    		}
    		return Response.status(Response.Status.ACCEPTED).build();
    	}
    
    	/**
    	 * Methode qui permet de lister le contenu d'un repertoire
    	 * 
    	 * @param alias    l'alias du serveur
    	 * @param path     le chemin d'acces vers le dossier
    	 * @param username le username par defaut anonymous
    	 * @param psw      le mot de passe par defaut anonymous
    	 * @param mode     le mode d'echange avec le serveur (PASV ou PORT) par defaut
    	 *                 en PASV
    	 * @param type     FTP ou FTPS par defaut FTP
    	 * @param port     le port d'ecoute
    	 * @return un statut http
    	 */
    	@GET
    	@Secured
    	@Path("{alias}/list/{path: .*}")
    	@Produces(MediaType.TEXT_PLAIN)
    	public Response listing(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		FTPFile[] files;
    		try {
    			files = ftp.listFiles(path);
    		} catch (IOException e) {
    			return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("try later pls !").build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		return Response.status(Response.Status.OK).entity(Utils.fileDetails(files)).type(MediaType.APPLICATION_JSON)
    				.build();
    	}
    
    	/**
    	 * Methode qui permet de télécharger un fichier
    	 * 
    	 * @param alias    l'alias du serveur
    	 * @param path     le chemin d'acces vers le fichier
    	 * @param username le username par defaut anonymous
    	 * @param psw      le mot de passe par defaut anonymous
    	 * @param mode     le mode d'echange avec le serveur (PASV ou PORT) par defaut
    	 *                 en PASV
    	 * @param type     FTP ou FTPS par defaut FTP
    	 * @param port     le port d'ecoute
    	 * @return un statut http
    	 */
    	@GET
    	@Secured
    	@Path("{alias}/file/{path: .*}")
    	@Produces(MediaType.APPLICATION_OCTET_STREAM)
    	public Response downloadHttpFile(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
    
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		String filename = path.substring(path.lastIndexOf("/") + 1, path.length());
    		File file = new File("./Downloads/" + filename);
    		OutputStream output;
    		try {
    			output = new FileOutputStream(file);
    			if (!ftp.retrieveFile(path, output)) {
    				output.close();
    				throw new IOException();
    			}
    			output.close();
    		} catch (IOException e) {
    			return Response.status(Response.Status.FORBIDDEN)
    					.entity("file " + path + " not exist on the ftp server or you don't have the right to download it")
    					.build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		return Response.ok(file).header("Content-Disposition", "attachment; filename=\"" + filename + "\"").build();
    	}
    	
    	
    	@GET
    	@Secured
    	@Path("{alias}/file/last-modified/{path: .*}")
    	@Produces(MediaType.TEXT_PLAIN)
    	public Response getLastDateFile(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTPS") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
    
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		String date;
    		try {
    			
    			date = ftp.getModificationTime(path);
    			if(date ==null) {
    				return Response.status(Response.Status.FORBIDDEN)
    						.entity("file " + path + " not exist on the ftp server ")
    						.build();
    			}
    			System.out.println(date);
    			
    		} catch (IOException e) {
    			return Response.status(Response.Status.FORBIDDEN)
    					.entity("file " + path + " not exist on the ftp server or you don't have the right to download it")
    					.build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		return Response.ok(date).build();
    	}
    	/*
    	 * Méthode non fonctionnel qui permet de récuperer un dossier, de le zipper et
    	 * de l'envoyer au client
    	 * 
    	 */
    	/*
    	@GET
    	@Secured
    	@Path("{alias}/dir/{path: .*}")
    	@Produces(MediaType.APPLICATION_OCTET_STREAM)
    	public Response downloadRep(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		if (path.endsWith("/")) {
    			path = path.substring(0, path.length() - 1);
    		}
    		String dirname = path.substring(path.lastIndexOf("/") + 1, path.length());
    
    		StreamingOutput stream = new StreamingOutput() {
    
    			@Override
    			public void write(OutputStream output) throws IOException, WebApplicationException {
    				ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(output));
    
    				//Utils.zip(ftp, path, zip);
    				output.flush();
    				output.close();
    			}
    
    		};
    
    		ResponseBuilder response = Response.ok(stream);
    		response.header("Content-Disposition", "attachment; filename=\"" + dirname + "\"");
    		return response.build();
    
    	}*/
    
    	/**
    	 * Methode qui permet de supprimer un fichier sur le serveur
    	 * 
    	 * @param alias    l'alias du serveur
    	 * @param path     le chemin d'acces vers le fichier
    	 * @param username le username par defaut anonymous
    	 * @param psw      le mot de passe par defaut anonymous
    	 * @param mode     le mode d'echange avec le serveur (PASV ou PORT) par defaut
    	 *                 en PASV
    	 * @param type     FTP ou FTPS par defaut FTP
    	 * @param port     le port d'ecoute
    	 * @return un statut http
    	 */
    	@DELETE
    	@Secured
    	@Path("{alias}/file/{path: .*}")
    	@Produces(MediaType.TEXT_PLAIN)
    	public Response deleteFile(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		if (path.endsWith("/")) {
    			path = path.substring(0, path.length() - 1);
    		}
    		try {
    			if (!ftp.deleteFile(path)) {
    				return Response.status(Response.Status.FORBIDDEN).entity("can't delete the file").build();
    			}
    		} catch (IOException e) {
    			return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("try later pls !").build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		return Response.status(Response.Status.OK).entity("file deleted").build();
    	}
    
    	/**
    	 * Methode qui permet de supprimer un dossier sur le serveur
    	 * 
    	 * @param alias    l'alias du serveur
    	 * @param path     le chemin d'acces vers le dossier
    	 * @param username le username par defaut anonymous
    	 * @param psw      le mot de passe par defaut anonymous
    	 * @param mode     le mode d'echange avec le serveur (PASV ou PORT) par defaut
    	 *                 en PASV
    	 * @param type     FTP ou FTPS par defaut FTP
    	 * @param port     le port d'ecoute
    	 * @return un statut http
    	 */
    	@DELETE
    	@Secured
    	@Path("{alias}/dir/{path: .*}")
    	@Produces(MediaType.TEXT_PLAIN)
    	public Response deleteDir(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type, @DefaultValue("21") @HeaderParam("port") int port) {
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		if (path.endsWith("/")) {
    			path = path.substring(0, path.length() - 1);
    		}
    
    		try {
    			Utils.removedir(ftp, path);
    		} catch (IOException e) {
    			return Response.status(Response.Status.FORBIDDEN)
    					.entity("can't delete one file from the folder" + path + "!").build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		return Response.ok("successfully removed").build();
    	}
    
    	/**
    	 * methode qui permet de rename un fichier ou un dossier sur le serveur
    	 * 
    	 * @param alias    l'alias du serveur
    	 * @param path     le chemin d'acces
    	 * @param username le username par defaut anonymous
    	 * @param psw      le mot de passe par defaut anonymous
    	 * @param mode     le mode d'echange avec le serveur (PASV ou PORT) par defaut
    	 *                 en PASV
    	 * @param type     FTP ou FTPS par defaut FTP
    	 * @param rename   le nouveau nom
    	 * @param port     le port d'ecoute
    	 * @return un statut http
    	 */
    	@PUT
    	@Secured
    	@Path("{alias}/{path: .*}")
    	@Produces(MediaType.TEXT_PLAIN)
    	public Response rename(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type, @QueryParam("name") String rename,
    			@DefaultValue("21") @HeaderParam("port") int port) {
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		if (path.endsWith("/")) {
    			path = path.substring(0, path.length() - 1);
    		}
    		String tmp = path.substring(0, path.lastIndexOf("/") + 1);
    		try {
    			if (!ftp.rename(path, tmp + rename)) {
    				return Response.status(Response.Status.BAD_REQUEST).build();
    			}
    		} catch (IOException e) {
    			return Response.status(Response.Status.FORBIDDEN).entity("can't rename one file " + path + "!").build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		return Response.ok("successfully renamed to " + rename).build();
    	}
    	
    	
    	
    	
    	
    	@PUT
    	@Secured
    	@Path("{alias}/relocate/{path: .*}")
    	@Produces(MediaType.TEXT_PLAIN)
    	public Response relocate(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type, @QueryParam("to") String rename,
    			@DefaultValue("21") @HeaderParam("port") int port) {
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    //		if (path.endsWith("/")) {
    //			path = path.substring(0, path.length() - 1);
    //		}
    		try {
    			if (!ftp.rename(path, rename)) {
    				return Response.status(Response.Status.BAD_REQUEST).build();
    			}
    		} catch (IOException e) {
    			return Response.status(Response.Status.FORBIDDEN).entity("can't rename one file " + path + "!").build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		return Response.ok("successfully renamed to " + rename).build();
    	}
    
    	/**
    	 * Methode qui permet d'upload un fichier sur le serveur, pour envoyer un
    	 * dossier,il faut prealablement le zipper
    	 * 
    	 * @param alias               l'alias du serveur
    	 * @param path                le chemin de destination
    	 * @param uploadedInputStream le fichier à upload
    	 * @param fileDetail          details du fichier à upload
    	 * @param mode                le mode d'echange avec le serveur (PASV ou PORT)
    	 *                            par defaut
    	 * @param type                FTP ou FTPS par defaut FTP
    	 * @param username            le username par defaut anonymous
    	 * @param psw                 le mot de passe par defaut anonymous
    	 * @param port                le port d'ecoute
    	 * @return un statut http
    	 */
    	@POST
    	@Secured
    	@Path("{alias}/file/{path: .*}")
    	@Consumes(MediaType.MULTIPART_FORM_DATA)
    	@Produces(MediaType.TEXT_PLAIN)
    	public Response uploadHttpFile(@PathParam("alias") String alias, @PathParam("path") String path,
    			@FormDataParam("file") InputStream uploadedInputStream,
    			@FormDataParam("file") FormDataContentDisposition fileDetail,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("21") @HeaderParam("port") int port) {
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		if (path.endsWith("/")) {
    			path = path.substring(0, path.length() - 1);
    		}
    		try {
    			if (!Utils.uploadFile(ftp, path + "/" + fileDetail.getFileName(), uploadedInputStream)) {
    				return Response.status(Response.Status.BAD_REQUEST).build();
    			}
    		} catch (IOException e) {
    			return Response.status(Response.Status.FORBIDDEN)
    					.entity("can't upload the file " + fileDetail.getFileName() + "!").build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		String output = "File uploaded to: " + path;
    
    		return Response.status(Response.Status.OK).entity(output).build();
    	}
    
    	/**
    	 * Methode qui permet de creer un repertoire sur le serveur
    	 * 
    	 * @param alias    l'alias du serveur
    	 * @param path     le chemin d'acces vers le repertoire parent
    	 * @param username le username par defaut anonymous
    	 * @param psw      le mot de passe par defaut anonymous
    	 * @param mode     le mode d'echange avec le serveur (PASV ou PORT) par defaut
    	 *                 en PASV
    	 * @param type     FTP ou FTPS par defaut FTP
    	 * @param name     le nom du reperoire à creer
    	 * @param port     le port d'ecoute
    	 * @return un statut http
    	 */
    	@POST
    	@Secured
    	@Path("{alias}/new-dir/{path: .*}")
    	@Produces(MediaType.TEXT_PLAIN)
    	public Response createDir(@PathParam("alias") String alias, @PathParam("path") String path,
    			@DefaultValue("anonymous") @HeaderParam("username") String username,
    			@DefaultValue("anonymous") @HeaderParam("password") String psw,
    			@DefaultValue("pasv") @HeaderParam("mode") String mode,
    			@DefaultValue("FTP") @HeaderParam("type") String type, @QueryParam("name") String name,
    			@DefaultValue("21") @HeaderParam("port") int port) {
    
    		Response r = init(alias, type, username, psw, mode, port);
    		if (!(r.getStatus() == Response.Status.ACCEPTED.getStatusCode())) {// on verifie que l'init s'est bien passer
    			return r;
    		}
    		if (path.endsWith("/")) {
    			path = path.substring(0, path.length() - 1);
    		}
    		try {
    			if (!ftp.makeDirectory(path + "/" + name)) {
    				return Response.status(Response.Status.BAD_REQUEST).build();
    			}
    		} catch (IOException e) {
    			return Response.status(Response.Status.FORBIDDEN).entity("can't create the folder" + path + "!").build();
    		} finally {
    			try {
    				ftp.disconnect();
    			} catch (IOException e) {
    			}
    		}
    		return Response.ok("directory " + name + " created").build();
    	}
    }