/* * This file is part of DrFTPD, Distributed FTP Daemon. * * DrFTPD 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 2 of the License, or * (at your option) any later version. * * DrFTPD 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 DrFTPD; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.drftpd.commands.request; import java.io.FileNotFoundException; import java.util.Properties; import java.util.ResourceBundle; import org.apache.log4j.Logger; import org.bushe.swing.event.annotation.AnnotationProcessor; import org.bushe.swing.event.annotation.EventSubscriber; import org.drftpd.GlobalContext; import org.drftpd.commandmanager.CommandInterface; import org.drftpd.commandmanager.CommandRequest; import org.drftpd.commandmanager.CommandResponse; import org.drftpd.commandmanager.ImproperUsageException; import org.drftpd.commandmanager.StandardCommandManager; import org.drftpd.event.ReloadEvent; import org.drftpd.event.RequestEvent; import org.drftpd.exceptions.FileExistsException; import org.drftpd.master.Session; import org.drftpd.master.BaseFtpConnection; import org.drftpd.permissions.Permission; import org.drftpd.usermanager.User; import org.drftpd.vfs.DirectoryHandle; import org.tanesha.replacer.ReplacerEnvironment; /** * @author mog * @version $Id: Request.java 2157 2010-10-08 18:50:53Z djb61 $ */ public class Request extends CommandInterface { private static final Logger logger = Logger.getLogger(Request.class); private ResourceBundle _bundle; private String _keyPrefix; private String _requestPath; private boolean _createRequestPath; private String _reqFilledPrefix; private String _requestPrefix; public void initialize(String method, String pluginName, StandardCommandManager cManager) { super.initialize(method, pluginName, cManager); // Subscribe to events AnnotationProcessor.process(this); _bundle = cManager.getResourceBundle(); _keyPrefix = this.getClass().getName()+"."; readConfig(); createDirectory(); } /** * Reads 'conf/plugins/request.conf' */ private void readConfig() { Properties props = GlobalContext.getGlobalContext().getPluginsConfig().getPropertiesForPlugin("request"); _requestPath = props.getProperty("request.dirpath", "/requests/"); _createRequestPath = Boolean.parseBoolean(props.getProperty("request.createpath", "false")); _reqFilledPrefix = props.getProperty("reqfilled.prefix", "FILLED-for."); _requestPrefix = props.getProperty("request.prefix", "REQUEST-by."); } /** * Create the request directory if it does not exist and 'request.createpath' is <code>true</code> */ private void createDirectory() { DirectoryHandle requestDir = new DirectoryHandle(_requestPath); if (_createRequestPath && !requestDir.exists()) { try { requestDir.getParent().createDirectoryRecursive(requestDir.getName(), true); } catch (FileExistsException e) { logger.error("Tried to create a directory that already exists during request plugin initialization.", e); } catch (FileNotFoundException e) { logger.error("How did this happened? It was there couple lines above", e); } } } /** * If the commands has a 'request.dirpath' set we will use this one * otherwise we will use the fallback/default path set in 'conf/plugins/request.conf' * * This allows multiple request dirs. * @param request * @return a {@link DirectoryHandle} representing the correct request dir. */ private DirectoryHandle getRequestDirectory(CommandRequest request) { String requestDirProp = request.getProperties().getProperty("request.dirpath"); if (requestDirProp == null) { return new DirectoryHandle(_requestPath); } return new DirectoryHandle(requestDirProp); } public CommandResponse doSITE_REQFILLED(CommandRequest request) throws ImproperUsageException { if (!request.hasArgument()) { throw new ImproperUsageException(); } Session session = request.getSession(); User user = session.getUserNull(request.getUser()); DirectoryHandle requestDir = getRequestDirectory(request); String requestName = request.getArgument().trim(); ReplacerEnvironment env = new ReplacerEnvironment(); env.add("user", user); env.add("request.name", requestName); try { for (DirectoryHandle dir : requestDir.getDirectoriesUnchecked()) { if (!dir.getName().startsWith(_requestPrefix)) { continue; } RequestParser parser = new RequestParser(dir.getName()); env.add("request.owner", parser.getUser()); if (parser.getRequestName().equals(requestName)) { String filledname = _reqFilledPrefix + parser.getUser() + "-" + parser.getRequestName(); try { dir.renameToUnchecked(requestDir.getNonExistentDirectoryHandle(filledname)); } catch (FileExistsException e) { return new CommandResponse(500, session.jprintf(_bundle, _keyPrefix+"reqfilled.exists", env, request.getUser())); } catch (FileNotFoundException e) { logger.error("File was just here but it vanished", e); return new CommandResponse(500, session.jprintf(_bundle, _keyPrefix+"reqfilled.error", env, request.getUser())); } GlobalContext.getEventService().publishAsync(new RequestEvent("reqfilled", user, requestDir, session.getUserNull(parser.getUser()), requestName)); if (session instanceof BaseFtpConnection) { return new CommandResponse(200, session.jprintf(_bundle, _keyPrefix+"reqfilled.success", env, request.getUser())); } // Return ok status to IRC so we know the command was successful return StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK"); } } } catch (FileNotFoundException e) { return new CommandResponse(500, session.jprintf(_bundle, _keyPrefix+"reqfilled.root.notfound", env, request.getUser())); } return new CommandResponse(500, session.jprintf(_bundle, _keyPrefix+"reqfilled.notfound", env, request.getUser())); } public CommandResponse doSITE_REQUEST(CommandRequest request) throws ImproperUsageException { Session session = request.getSession(); if (!request.hasArgument()) { throw new ImproperUsageException(); } User user = session.getUserNull(request.getUser()); String requestName = request.getArgument().trim(); String createdDirName = _requestPrefix + user.getName() + "-" + requestName; DirectoryHandle requestDir = getRequestDirectory(request); ReplacerEnvironment env = new ReplacerEnvironment(); env.add("user", request.getUser()); env.add("request.name", requestName); env.add("request.root", requestDir.getPath()); try { requestDir.createDirectoryUnchecked(createdDirName, user.getName(), user.getGroup()); } catch (FileExistsException e) { return new CommandResponse(550, session.jprintf(_bundle, _keyPrefix+"request.exists", env, user.getName())); } catch (FileNotFoundException e) { logger.error("File was just here but it vanished", e); return new CommandResponse(550, session.jprintf(_bundle, _keyPrefix+"request.error", env, user.getName())); } GlobalContext.getEventService().publishAsync(new RequestEvent("request", requestDir, user, requestName)); if (session instanceof BaseFtpConnection) { return new CommandResponse(257, session.jprintf(_bundle, _keyPrefix+"request.success", env, user.getName())); } // Return ok status to IRC so we know the command was successful return StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK"); } public CommandResponse doSITE_REQUESTS(CommandRequest request) throws ImproperUsageException { if (request.hasArgument()) { throw new ImproperUsageException(); } ReplacerEnvironment env = new ReplacerEnvironment(); CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK"); response.addComment(request.getSession().jprintf(_bundle, _keyPrefix+"requests.header", env, request.getUser())); int i = 1; User user = request.getSession().getUserNull(request.getUser()); try { for (DirectoryHandle dir : getRequestDirectory(request).getDirectories(user)) { if (!dir.getName().startsWith(_requestPrefix)) { continue; } RequestParser parser = new RequestParser(dir.getName()); env.add("num",Integer.toString(i)); env.add("request.user",parser.getUser()); env.add("request.name",parser.getRequestName()); i++; response.addComment(request.getSession().jprintf(_bundle, _keyPrefix+"requests.list", env, request.getUser())); } } catch (FileNotFoundException e) { response.addComment(request.getSession().jprintf(_bundle, _keyPrefix+"request.error", env, request.getUser())); } response.addComment(request.getSession().jprintf(_bundle, _keyPrefix+"requests.footer", env, request.getUser())); return response; } public CommandResponse doSITE_REQDELETE(CommandRequest request) throws ImproperUsageException { if (!request.hasArgument()) { throw new ImproperUsageException(); } Session session = request.getSession(); User user = session.getUserNull(request.getUser()); String requestName = request.getArgument().trim(); String deleteOthers = request.getProperties().getProperty("request.deleteOthers","=siteop"); DirectoryHandle requestDir = getRequestDirectory(request); ReplacerEnvironment env = new ReplacerEnvironment(); env.add("user", user.getName()); env.add("request.name", requestName); env.add("request.root", requestDir.getPath()); boolean requestNotFound = true; CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK"); try { for (DirectoryHandle dir : requestDir.getDirectories(user)) { if (!dir.getName().startsWith(_requestPrefix)) { continue; } RequestParser parser = new RequestParser(dir.getName()); if (parser.getRequestName().equals(requestName)) { requestNotFound = false; // checking if the user trying to delete this request // is either the owner or has "super-powers" if (parser.getUser().equals(user.getName()) || new Permission(deleteOthers).check(user)) { dir.deleteUnchecked(); if (session instanceof BaseFtpConnection) { response.addComment(session.jprintf(_bundle, _keyPrefix+"reqdel.success", env, request.getUser())); } GlobalContext.getEventService().publishAsync(new RequestEvent("reqdel", user, requestDir, session.getUserNull(parser.getUser()), requestName)); break; } return new CommandResponse(550, session.jprintf(_bundle, _keyPrefix+"reqdel.notowner", env, request.getUser())); } } if (requestNotFound) { return new CommandResponse(550, session.jprintf(_bundle, _keyPrefix+"reqdel.notfound", env, request.getUser())); } } catch (FileNotFoundException e) { return new CommandResponse(550, session.jprintf(_bundle, _keyPrefix+"reqdel.root.notfound", env, request.getUser())); } return response; } /** * Class to centralize how requests are parsed. * * Transforms a 'request.prefix'-'user'-'requestname' in * a nice looking data structure instead of simple strings. */ private class RequestParser { private String _user; private String _requestName; public RequestParser(String dirname) { _user= dirname.substring(_requestPrefix.length()); _requestName = _user.substring(_user.indexOf('-') + 1); _user = _user.substring(0, _user.indexOf('-')); } public String getUser() { return _user; } public String getRequestName() { return _requestName; } } @EventSubscriber public void onReloadEvent(ReloadEvent event) { readConfig(); } }