You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2013/04/15 14:11:22 UTC

svn commit: r1467956 - in /sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl: SlingFtpServer.java SlingUser.java SlingUserManager.java

Author: fmeschbe
Date: Mon Apr 15 12:11:22 2013
New Revision: 1467956

URL: http://svn.apache.org/r1467956
Log:
Optimized User Management:

* UserManager is read-only (and documented such)
* Password always returns null (and documented such)
* UserManager set on the FtpServerFactory because there is no cleanup needed

Modified:
    sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingFtpServer.java
    sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUser.java
    sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUserManager.java

Modified: sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingFtpServer.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingFtpServer.java?rev=1467956&r1=1467955&r2=1467956&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingFtpServer.java (original)
+++ sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingFtpServer.java Mon Apr 15 12:11:22 2013
@@ -33,6 +33,7 @@ import org.apache.ftpserver.FtpServer;
 import org.apache.ftpserver.FtpServerFactory;
 import org.apache.ftpserver.ftplet.FtpException;
 import org.apache.ftpserver.ftplet.Ftplet;
+import org.apache.ftpserver.ftplet.UserManager;
 import org.apache.ftpserver.listener.ListenerFactory;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.osgi.framework.Bundle;
@@ -158,8 +159,6 @@ public class SlingFtpServer {
 
     private SlingConfiguration configuration;
 
-    private SlingUserManager userManager;
-
     private FtpServer ftpServer;
 
     private ServiceRegistration webConsolePlugin;
@@ -172,7 +171,7 @@ public class SlingFtpServer {
         // FtpServer from our own custom FtpServerContext
 
         this.configuration = new SlingConfiguration(config);
-        this.userManager = new SlingUserManager(this.rrFactory, this.configuration);
+        UserManager userManager = new SlingUserManager(this.rrFactory, this.configuration);
 
         final ListenerFactory listenerFactory = new ListenerFactory();
         listenerFactory.setPort(this.configuration.getPort());
@@ -181,7 +180,7 @@ public class SlingFtpServer {
 
         final FtpServerFactory factory = new FtpServerFactory();
         factory.setFileSystem(new SlingFileSystemFactory());
-        factory.setUserManager(this.userManager);
+        factory.setUserManager(userManager);
         factory.setConnectionConfig(this.configuration);
         factory.addListener("default", listenerFactory.createListener());
         factory.setFtplets(new HashMap<String, Ftplet>() {
@@ -230,10 +229,5 @@ public class SlingFtpServer {
             this.ftpServer.stop();
             this.ftpServer = null;
         }
-
-        if (this.userManager != null) {
-            this.userManager.dispose();
-            this.userManager = null;
-        }
     }
 }

Modified: sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUser.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUser.java?rev=1467956&r1=1467955&r2=1467956&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUser.java (original)
+++ sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUser.java Mon Apr 15 12:11:22 2013
@@ -127,9 +127,11 @@ public class SlingUser implements User {
         return this.name;
     }
 
+    /**
+     * Always returns {@code null} since the password cannot be read from the
+     * repository.
+     */
     public String getPassword() {
-        // TODO Auto-generated method stub
         return null;
     }
-
 }

Modified: sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUserManager.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUserManager.java?rev=1467956&r1=1467955&r2=1467956&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUserManager.java (original)
+++ sling/whiteboard/fmeschbe/ftpserver/src/main/java/org/apache/sling/ftpserver/impl/SlingUserManager.java Mon Apr 15 12:11:22 2013
@@ -42,38 +42,44 @@ import org.apache.sling.api.resource.Log
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 
+/**
+ * The <code>SlingUserManager</code> is the FTP server's user manager based on
+ * the Jackrabbit Repository user manager.
+ * <p>
+ * This implementation is read-only in that the {@link #save(User)} and
+ * {@link #delete(String)} methods throw an
+ * {@code UnsupportedOperationException}.
+ * <p>
+ * Limitations of the users can be configured globally applying to all users
+ * or on a per-user basis using the following properties:
+ * <table>
+ * <tr><th>
+ */
 public class SlingUserManager implements UserManager {
 
-    static final String FTP_ENABLED = "ftp/enabled";
+    private static final String FTP_PROPERTY_FOLDER = "ftp";
 
-    static final String FTP_MAX_IDLE_TIME_SEC = "ftp/maxIdleTimeSec";
+    static final String FTP_ENABLED = FTP_PROPERTY_FOLDER + "/enabled";
 
-    static final String FTP_MAX_CONCURRENT = "ftp/maxConcurrent";
+    static final String FTP_MAX_IDLE_TIME_SEC = FTP_PROPERTY_FOLDER + "/maxIdleTimeSec";
 
-    static final String FTP_MAX_CONCURRENT_PER_IP = "ftp/maxConcurrentPerIp";
+    static final String FTP_MAX_CONCURRENT = FTP_PROPERTY_FOLDER + "/maxConcurrent";
 
-    static final String FTP_MAX_DOWNLOAD_RATE = "ftp/maxDownloadRate";
+    static final String FTP_MAX_CONCURRENT_PER_IP = FTP_PROPERTY_FOLDER + "/maxConcurrentPerIp";
 
-    static final String FTP_MAX_UPLOAD_RATE = "ftp/maxUploadRate";
+    static final String FTP_MAX_DOWNLOAD_RATE = FTP_PROPERTY_FOLDER + "/maxDownloadRate";
+
+    static final String FTP_MAX_UPLOAD_RATE = FTP_PROPERTY_FOLDER + "/maxUploadRate";
 
     private final ResourceResolverFactory rrFactory;
 
     private final SlingConfiguration config;
 
-    private ResourceResolver admin;
-
     SlingUserManager(final ResourceResolverFactory rrFactory, final SlingConfiguration config) {
         this.rrFactory = rrFactory;
         this.config = config;
     }
 
-    void dispose() {
-        if (this.admin != null) {
-            this.admin.close();
-            this.admin = null;
-        }
-    }
-
     public User authenticate(Authentication auth) throws AuthenticationFailedException {
         if (auth == null) {
             throw new AuthenticationFailedException("Missing Authentication");
@@ -94,10 +100,9 @@ public class SlingUserManager implements
             }
 
             if (resolver != null) {
-                return createUser(resolver.adaptTo(org.apache.jackrabbit.api.security.user.User.class), resolver);
+                return createUser(resolver.getUserID(),
+                    resolver.adaptTo(org.apache.jackrabbit.api.security.user.User.class), resolver);
             }
-        } catch (RepositoryException e) {
-            throw new AuthenticationFailedException("Cannot login user " + auth, e);
         } catch (LoginException e) {
             throw new AuthenticationFailedException("Cannot login user " + auth, e);
         }
@@ -106,81 +111,111 @@ public class SlingUserManager implements
         throw new AuthenticationFailedException("Authentication of type " + auth.getClass() + " not supported");
     }
 
-    public void delete(String name) {
-        throw new UnsupportedOperationException("delete");
+    public String getAdminName() throws FtpException {
+        final ResourceResolver admin = this.getAdminResolver();
+        try {
+            return admin.getUserID();
+        } finally {
+            admin.close();
+        }
     }
 
-    public boolean doesExist(String name) throws FtpException {
-        return getUserByName(name) != null;
+    public boolean isAdmin(String id) throws FtpException {
+        return id != null && id.equals(getAdminName());
     }
 
-    public String getAdminName() throws FtpException {
-        return this.getAdminResolver().getUserID();
+    public boolean doesExist(String name) throws FtpException {
+        return getRepoUser(name) != null;
     }
 
-    public String[] getAllUserNames() throws FtpException {
-        org.apache.jackrabbit.api.security.user.UserManager um = getAdminResolver().adaptTo(
-            org.apache.jackrabbit.api.security.user.UserManager.class);
-        if (um != null) {
-            try {
-                Iterator<Authorizable> ai = um.findAuthorizables(null, null,
-                    org.apache.jackrabbit.api.security.user.UserManager.SEARCH_TYPE_USER);
-                ArrayList<String> list = new ArrayList<String>();
-                while (ai.hasNext()) {
-                    list.add(ai.next().getID());
-                }
-                return list.toArray(new String[list.size()]);
-            } catch (RepositoryException e) {
-                throw new FtpException(e);
-            }
-        }
-
-        // is this correct ??
-        return new String[0];
+    public User getUserByName(String name) throws FtpException {
+        org.apache.jackrabbit.api.security.user.User repoUser = getRepoUser(name);
+        return (repoUser != null) ? createUser(name, repoUser, null) : null;
     }
 
-    public User getUserByName(String name) throws FtpException {
-        org.apache.jackrabbit.api.security.user.UserManager um = getAdminResolver().adaptTo(
-            org.apache.jackrabbit.api.security.user.UserManager.class);
-        if (um != null) {
-            Authorizable a;
-            try {
-                a = um.getAuthorizable(name);
-                if (a != null && !a.isGroup()) {
-                    return createUser((org.apache.jackrabbit.api.security.user.User) a, null);
+    public String[] getAllUserNames() throws FtpException {
+        final ResourceResolver admin = this.getAdminResolver();
+        try {
+            org.apache.jackrabbit.api.security.user.UserManager um = admin.adaptTo(org.apache.jackrabbit.api.security.user.UserManager.class);
+            if (um != null) {
+                try {
+                    Iterator<Authorizable> ai = um.findAuthorizables(null, null,
+                        org.apache.jackrabbit.api.security.user.UserManager.SEARCH_TYPE_USER);
+                    ArrayList<String> list = new ArrayList<String>();
+                    while (ai.hasNext()) {
+                        list.add(ai.next().getID());
+                    }
+                    return list.toArray(new String[list.size()]);
+                } catch (RepositoryException e) {
+                    throw new FtpException(e);
                 }
-            } catch (RepositoryException e) {
-                throw new FtpException(e);
             }
+        } finally {
+            admin.close();
         }
 
-        // is this correct ??
-        return null;
+        // no user managemnent or problem accessing them
+        throw new FtpException("Cannot get users");
     }
 
-    public boolean isAdmin(String id) throws FtpException {
-        return id != null && id.equals(getAdminName());
+    public void delete(String name) {
+        throw new UnsupportedOperationException("delete");
     }
 
     public void save(User user) {
         throw new UnsupportedOperationException("save");
     }
 
-    private ResourceResolver getAdminResolver() throws FtpException {
-        if (this.admin == null) {
-            try {
-                this.admin = this.rrFactory.getAdministrativeResourceResolver(null);
-            } catch (LoginException e) {
-                throw new FtpException("Cannot create administrative ResourceResolver", e);
+    /**
+     * Returns the repository user of the given name or {@code null} if no such
+     * user exists or if a group of that name exists.
+     *
+     * @param name The name of the user to retrieve
+     * @return The repository user or {@code null} if no such user exists or if
+     *         a group of that name exists.
+     * @throws FtpException If the repository user manager cannot be retrieved
+     *             or an error occurrs looking for the user
+     */
+    private org.apache.jackrabbit.api.security.user.User getRepoUser(final String name) throws FtpException {
+        final ResourceResolver admin = this.getAdminResolver();
+        try {
+            org.apache.jackrabbit.api.security.user.UserManager um = admin.adaptTo(org.apache.jackrabbit.api.security.user.UserManager.class);
+            if (um != null) {
+                Authorizable a;
+                try {
+                    a = um.getAuthorizable(name);
+                    return (a != null && !a.isGroup()) ? (org.apache.jackrabbit.api.security.user.User) a : null;
+                } catch (RepositoryException e) {
+                    throw new FtpException(e);
+                }
             }
+        } finally {
+            admin.close();
         }
 
-        return this.admin;
+        throw new FtpException("Missing internal user manager; cannot find user");
+    }
+
+    /**
+     * Returns an administative {@code ResourceResolver}.
+     * <p>
+     * This resource resolver must be closed when not used any more to prevent
+     * memory and performance leaks.
+     *
+     * @return an administrative resource resolver
+     * @throws FtpException If the resource resolver cannot be created
+     */
+    private ResourceResolver getAdminResolver() throws FtpException {
+        try {
+            return this.rrFactory.getAdministrativeResourceResolver(null);
+        } catch (LoginException e) {
+            throw new FtpException("Cannot create administrative ResourceResolver", e);
+        }
     }
 
-    private User createUser(final org.apache.jackrabbit.api.security.user.User repoUser, final ResourceResolver resolver)
-            throws RepositoryException {
-        SlingUser user = new SlingUser(repoUser.getID(), resolver);
+    private User createUser(final String name, final org.apache.jackrabbit.api.security.user.User repoUser,
+            final ResourceResolver resolver) {
+        SlingUser user = new SlingUser(name, resolver);
 
         user.setEnabled(getProperty(repoUser, FTP_ENABLED, config.isEnabled()));
         user.setMaxIdleTimeSec(getProperty(repoUser, FTP_MAX_IDLE_TIME_SEC, config.getMaxIdelTimeSec()));