At the present we have the following situation:

                    +--------------+
                    |Authentication|
                    +--------------+
                           ^
                           |
         +-----------------+---------------+
         |                                 |
+-----------------------+       +------------------------------+
|AnonymousAuthentication|       |UsernamePasswordAuthentication|
+-----------------------+       +------------------------------+

And we have a UserManager interface defined like this:

public interface UserManager {
   ...
   User authenticate(Authentication authentication)
           throws AuthenticationFailedException;
   ...
}

But while the Authentication is contained in the Ftplet API module the AnonymousAuthentication and UsernamePasswordAuthentication are in the FTP Server module.

As far I understand the Ftplet API should be interface to decouple the ftp server implementation and the ftplet implementation. In that way one can develop its ftplet with ftpserver-core and then plug it another ftpserver implementation.

But this is not possible because the Ftplet doesn't contains the AnonymousAuthentication and UsernamePasswordAuthentication.

Even more I don't like the way of which type of implementation of Authentication is chosen. The implementation (AnonymousAuthentication, or UsernamePasswordAuthentication) is choosed by the org.apache.ftpserver.command.impl.PASS command while I think this should be a responsibility of the UserManager.

Even more if the Authentication is an anonymous one the PASS doesn't send the username and password to UserManager. This is bad because one can not create an UserManager that accept , for example, only those authentications that have a valid email as password.

So I propose to:
- remove the anonymous authentication
- move the UsernamePasswordAuthentication to the Ftplet API module.
- modify the UsernamePasswordAuthentication in that way:

class UsernamePasswordAuthentication {

   public String getPassword() { ... }
   public String getUsername() { ... }
   public UserMetadata getUserMetadata() { ... }

   /**
    * Convenienve method to test if the username is "anonymous",
    * the UserManager implemenation can choose to authenticate
    * or not the anonymous users based on its own policy
    */
   public boolean isAnonymous() {
      return "anonymous".equals(getUsername());
   }

}

This way can support:
- UserManagers where the anonymous username is like the other usernames
- UserManagers that want test password of a anonymous authentication
- UserManagers that have a different concept of a anonymous user.
- UserManagers that threat anonymous users in the traditional way.

If and when this is will be agreed I can create and provide a patch that implement these modifications.

--
Andrea Francia
http://andreafrancia.blogspot.com/2008/07/colinux-linux-dentro-windows.html

Reply via email to