use jaas for authentication, so we can access easily the user object even for webdav...
authorkoutsoub <devnull@localhost>
Tue, 15 Feb 2011 14:39:33 +0000 (16:39 +0200)
committerkoutsoub <devnull@localhost>
Tue, 15 Feb 2011 14:39:33 +0000 (16:39 +0200)
src/gr/ebs/gss/server/webdav/milton/GSSResourceFactory.java
src/gr/ebs/gss/server/webdav/milton/GssAuthenticationService.java
src/gr/ebs/gss/server/webdav/milton/GssFileResource.java
src/gr/ebs/gss/server/webdav/milton/GssFolderResource.java
src/gr/ebs/gss/server/webdav/milton/GssMiltonServlet.java
src/gr/ebs/gss/server/webdav/milton/GssResource.java
src/gr/ebs/gss/server/webdav/milton/GssRootFolderResource.java [new file with mode: 0644]
src/gr/ebs/gss/server/webdav/milton/GssSecurityManager.java
webdav/WEB-INF/web.xml

index 4c9d12d..7788225 100644 (file)
@@ -62,10 +62,23 @@ public class GSSResourceFactory implements ResourceFactory {
     HttpManager httpManager;
        @Override
        public Resource getResource(String host, String url) {
-        log.debug("getResource: host: " + host + " - url:" + url);
+               
+
+
+               log.debug("getResource: host: " + host + " - url:" + url);
         url = stripContext(url);
-        if(url==null||url.trim().equals(""))
+        if(url==null||url.trim().equals("")||url.equals("/")){
                url="/";
+               return new GssRootFolderResource(host, this, null);
+        }
+        /*log.info("URL:"+url);
+        if(url.equals("/OthersShared")||url.equals("/OthersShared/")){
+               log.info("[returning others]");
+               return new GssOthersResource(host, this);
+        }
+        if(url.startsWith("/OthersShared")){
+               
+        }*/
         try {
                
                Object r = getResourceGss(url);
@@ -83,8 +96,21 @@ public class GSSResourceFactory implements ResourceFactory {
        public Long maxAgeSeconds(GssResource resource) {
         return maxAgeSeconds;
     }
-       private Object getResourceGss(String path) throws RpcException{
-               UserDTO user = getService().getUserByUserName("past@ebs.gr");
+       protected Object getResourceGss(String path) throws RpcException{
+               UserDTO user = null;
+               String username = HttpManager.request().getHeaders().get("authorization");
+               
+       if(username!=null){
+       
+               username=getUsernameFromAuthHeader(username);
+               try {
+                               user= getService().getUserByUserName(username);
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                               return null;
+                       }
+       }
                boolean exists = true;
                Object resource = null;
                FileHeaderDTO file = null;
@@ -311,5 +337,12 @@ public class GSSResourceFactory implements ResourceFactory {
                public void setHttpManager(HttpManager httpManager) {
                        this.httpManager = httpManager;
                }
-
+               
+               
+       
+               public static String getUsernameFromAuthHeader(String header) {
+                       String first = header.split(",")[0];
+                       int indx = first.indexOf("\"");
+                       return first.substring(indx+1,first.length()-1);
+               }
 }
index f94ea95..6c56419 100644 (file)
  */
 package gr.ebs.gss.server.webdav.milton;
 
+import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.ejb.ExternalAPI;
+
+import java.util.ArrayList;
 import java.util.List;
 
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.PortableRemoteObject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.bradmcevoy.http.Auth;
 import com.bradmcevoy.http.AuthenticationHandler;
+import com.bradmcevoy.http.AuthenticationService;
+import com.bradmcevoy.http.HttpManager;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.AuthenticationService.AuthStatus;
 
 
 /**
@@ -28,8 +47,55 @@ import com.bradmcevoy.http.AuthenticationHandler;
  *
  */
 public class GssAuthenticationService extends com.bradmcevoy.http.AuthenticationService{
+       private static final Logger log = LoggerFactory.getLogger( GssAuthenticationService.class );
        
-       public GssAuthenticationService( List<AuthenticationHandler> authenticationHandlers ) {
-        super(authenticationHandlers);
+       public GssAuthenticationService( ) {
+        super(new ArrayList<AuthenticationHandler>());
     }
+       
+       public AuthStatus authenticate( Resource resource, Request request ) {
+        Auth auth = request.getAuthorization();
+        boolean preAuthenticated = ( auth != null && auth.getTag() != null );
+        if( preAuthenticated ) {
+            return new AuthStatus( auth, false );
+        }
+        String username = request.getHeaders().get("authorization");
+       if(username!=null){
+               username=GSSResourceFactory.getUsernameFromAuthHeader(username);
+               try {
+                               Object user = getService().getUserByUserName(username);
+                               if( auth == null ) { // some authentication handlers do not require an Auth object
+                    auth = new Auth( Auth.Scheme.FORM, username ,null);
+                    request.setAuthorization( auth );
+                }
+                auth.setTag( user );
+            
+            return new AuthStatus( auth, false );
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                               return null;
+                       }
+       }
+        
+        return null;
+    }
+       
+       /**
+        * A helper method that retrieves a reference to the ExternalAPI bean and
+        * stores it for future use.
+        *
+        * @return an ExternalAPI instance
+        * @throws RpcException in case an error occurs
+        */
+       protected ExternalAPI getService() throws RpcException {
+               try {
+                       final Context ctx = new InitialContext();
+                       final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));
+                       return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);
+               } catch (final NamingException e) {
+                       log.error("Unable to retrieve the ExternalAPI EJB", e);
+                       throw new RpcException("An error occurred while contacting the naming service");
+               }
+       }
 }
index ccb2ea7..3f8e09b 100644 (file)
@@ -236,7 +236,7 @@ public class GssFileResource extends GssResource implements CopyableResource, De
        public boolean authorise(Request request, Method method, Auth auth) {
         boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
         if(result){
-               UserDTO user = (UserDTO) auth.getTag();
+               UserDTO user = getCurrentUser();
                //check permission
                try {
                                factory.getService().getFile(user.getId(), file.getId());
index 2979b36..3516480 100644 (file)
@@ -95,7 +95,9 @@ public class GssFolderResource extends GssResource implements MakeCollectionable
        }
        @Override
        public Date getModifiedDate() {
-               return folder.getAuditInfo().getModificationDate();
+               if(folder!=null && folder.getAuditInfo()!=null)
+                       return folder.getAuditInfo().getModificationDate();
+               return null;
        }
        @Override
        public String getName() {
@@ -126,15 +128,12 @@ public class GssFolderResource extends GssResource implements MakeCollectionable
 
                                        @Override
                                        public Void call() throws Exception {
-                                               factory.getService().moveFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
-                                               log.info("MOVING OK:"+arg1);
-                                               
+                                               factory.getService().moveFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);                                            
                                                return null;
                                        }
                                        
                                });
                                GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
-                               log.info("MOVING:"+folder.getName());
                                
                        } catch (InsufficientPermissionsException e) {
                                throw new NotAuthorizedException(this);
@@ -459,14 +458,15 @@ public class GssFolderResource extends GssResource implements MakeCollectionable
                        }
                return null;
        }
+       
        @Override
        public boolean authorise(Request request, Method method, Auth auth) {
         boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
         if(result){
-               UserDTO user = (UserDTO) auth.getTag();
+               UserDTO user = getCurrentUser();
                //check permission
                try {
-                               factory.getService().getFolder(user.getId(), folder.getId());
+                               this.folder=factory.getService().getFolder(user.getId(), folder.getId());
                        } catch (ObjectNotFoundException e) {
                                return false;
                        } catch (InsufficientPermissionsException e) {
index 0f8ed93..7f06eec 100644 (file)
@@ -18,6 +18,7 @@
  */
 package gr.ebs.gss.server.webdav.milton;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 
 import javax.servlet.ServletConfig;
@@ -46,8 +47,8 @@ public class GssMiltonServlet extends MiltonServlet{
         try {
             this.config = config;
             GssLockManager lockManager = new GssLockManager();
-            GssSecurityManager securityManager = new GssSecurityManager("PITHOS_WEBDAV");
-            AuthenticationService authService = new AuthenticationService();
+            GssSecurityManager securityManager = new GssSecurityManager("Pithos WebDAV");
+            AuthenticationService authService = new GssAuthenticationService();
             authService.setDisableBasic(true);
             authService.setDisableDigest(false);
             DefaultWebDavResponseHandler responseHandler = new DefaultWebDavResponseHandler(authService);
index 5a53836..9209354 100644 (file)
@@ -18,6 +18,7 @@
  */
 package gr.ebs.gss.server.webdav.milton;
 
+import gr.ebs.gss.client.exceptions.RpcException;
 import gr.ebs.gss.server.domain.User;
 import gr.ebs.gss.server.domain.dto.UserDTO;
 
@@ -59,7 +60,7 @@ public abstract class GssResource implements Resource, MoveableResource, Copyabl
                this.host=host;
                this.factory=factory;
                this.resource=resource;
-               this.currentUser=currentUser;
+               
        }
        
        public Object authenticate(String user, String password) {
@@ -67,8 +68,7 @@ public abstract class GssResource implements Resource, MoveableResource, Copyabl
     }
 
     public Object authenticate( DigestResponse digestRequest ) {
-        currentUser = (UserDTO) factory.getSecurityManager().authenticate(digestRequest);
-        return currentUser;
+        return  factory.getSecurityManager().authenticate(digestRequest);
         
     }
 
@@ -115,7 +115,20 @@ public abstract class GssResource implements Resource, MoveableResource, Copyabl
         * @return the currentUser
         */
        public UserDTO getCurrentUser() {
-               return currentUser;
+               if(currentUser!=null)
+                       return currentUser;
+               String username = HttpManager.request().getHeaders().get("authorization");
+       if(username!=null){
+               username=GSSResourceFactory.getUsernameFromAuthHeader(username);
+               try {
+                               currentUser = factory.getService().getUserByUserName(username);
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                               return null;
+                       }
+       }
+       return currentUser;
        }
        
 
diff --git a/src/gr/ebs/gss/server/webdav/milton/GssRootFolderResource.java b/src/gr/ebs/gss/server/webdav/milton/GssRootFolderResource.java
new file mode 100644 (file)
index 0000000..5b998a3
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS 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 GSS.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package gr.ebs.gss.server.webdav.milton;
+
+import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
+import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
+import gr.ebs.gss.client.exceptions.RpcException;
+import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
+import gr.ebs.gss.server.domain.dto.FolderDTO;
+import gr.ebs.gss.server.domain.dto.UserDTO;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.bradmcevoy.http.Auth;
+import com.bradmcevoy.http.Request;
+import com.bradmcevoy.http.Resource;
+import com.bradmcevoy.http.Request.Method;
+import com.bradmcevoy.http.http11.auth.DigestResponse;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GssRootFolderResource extends GssFolderResource{
+
+       /**
+        * @param host
+        * @param factory
+        * @param resource
+        */
+       public GssRootFolderResource(String host, GSSResourceFactory factory, Object resource) {
+               super(host, factory, resource);
+               
+       }
+       
+       @Override
+       public boolean authorise(Request request, Method method, Auth auth) {
+               // TODO Auto-generated method stub
+               boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
+        if(result){
+               UserDTO user = getCurrentUser();
+               try {
+                               this.resource = factory.getResourceGss("/");//getService().getFolder(user.getId(), folder.getId());
+                       } catch (RpcException e) {
+                               return false;
+                       }
+                       return true;
+        }
+        return result;
+    }
+       
+       
+       @Override
+       public Object authenticate(DigestResponse digestRequest) {
+               // TODO Auto-generated method stub
+               return super.authenticate(digestRequest);
+       }
+       
+       @Override
+       public String getName() {
+               return "/";
+       }
+       @Override
+       public String getUniqueId() {
+               return "folder:/";
+       }
+       @Override
+       public Resource child(String name) {
+               try {
+                       this.folder = (FolderDTO) factory.getResourceGss("/");
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               return super.child(name);
+       }
+       @Override
+       public List<? extends Resource> getChildren() {
+               try {
+                       this.folder = (FolderDTO) factory.getResourceGss("/");
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               List<Resource> result = new ArrayList<Resource>();
+               for(FolderDTO f : folder.getSubfolders())
+                       if(!f.isDeleted())
+                               result.add(new GssFolderResource(host, factory, f));
+               try {
+                       for(FileHeaderDTO f : factory.getService().getFiles(getCurrentUser().getId(), folder.getId(), true))
+                               result.add(new GssFileResource(host, factory, f));
+               } catch (ObjectNotFoundException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (InsufficientPermissionsException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } catch (RpcException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               //result.add(new GssOthersResource(host, factory));
+               return result;
+       }
+
+}
index c7a89fd..2390edf 100644 (file)
@@ -40,6 +40,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.bradmcevoy.http.Auth;
+import com.bradmcevoy.http.HttpManager;
 import com.bradmcevoy.http.Request;
 import com.bradmcevoy.http.Resource;
 import com.bradmcevoy.http.Request.Method;
@@ -72,13 +73,7 @@ public class GssSecurityManager  implements com.bradmcevoy.http.SecurityManager{
         this.realm = realm;
         this.digestGenerator = new DigestGenerator();
     }
-    /*
-    public Object getUserByName( String name ) {
-        String actualPassword = nameAndPasswords.get( name );
-        if( actualPassword != null ) return name;
-        return null;
-    }*/
-
+    
 
 
     public Object authenticate( String user, String password ) {
@@ -110,7 +105,7 @@ public class GssSecurityManager  implements com.bradmcevoy.http.SecurityManager{
     }
 
     public Object authenticate( DigestResponse digestRequest ) {
-        String actualPassword=null;
+        /*String actualPassword=null;
                try {
                        actualPassword = getUsersPassword( digestRequest.getUser() );
                } catch (Exception e) {
@@ -132,7 +127,19 @@ public class GssSecurityManager  implements com.bradmcevoy.http.SecurityManager{
                        }
         } else {
             return null;
-        }
+        }*/
+       /*String username = HttpManager.request().getHeaders().get("username");
+       if(username!=null){
+               try {
+                               return getService().getUserByUserName(username);
+                       } catch (RpcException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                               return null;
+                       }
+       }
+       return null;*/
+       return true;
     }
 
 
index 21a03e8..70fa23f 100644 (file)
@@ -1,9 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
-        version="2.4">
+<web-app>
         <servlet>
         <servlet-name>milton_webdav</servlet-name>
         <servlet-class>gr.ebs.gss.server.webdav.milton.GssMiltonServlet</servlet-class>
         <url-pattern>/miltonController</url-pattern>
     </servlet-mapping>
      -->
+     <security-constraint>
+               <!-- Protect /, but leave OPTIONS unauthenticated to get around Windows client bug with DIGEST authentication -->
+                       <web-resource-collection>
+                               <web-resource-name>GSS</web-resource-name>
+                               <description>GSS WebDAV</description>
+                               <url-pattern>/</url-pattern>
+                               <http-method>HEAD</http-method>
+                               <http-method>GET</http-method>
+                               <http-method>POST</http-method>
+                               <http-method>PUT</http-method>
+                               <http-method>DELETE</http-method>
+                               <http-method>PROPFIND</http-method>
+                               <http-method>PROPPATCH</http-method>
+                               <http-method>MKCOL</http-method>
+                               <http-method>COPY</http-method>
+                               <http-method>MOVE</http-method>
+                               <http-method>LOCK</http-method>
+                               <http-method>UNLOCK</http-method>
+                       </web-resource-collection>
+                       <auth-constraint>
+                               <role-name>simpleUser</role-name>
+                       </auth-constraint>
+                       <user-data-constraint>
+                               <description>no description</description>
+                               <transport-guarantee>NONE</transport-guarantee>
+                       </user-data-constraint>
+               </security-constraint>
+               
+               <security-constraint>
+               <!-- Protect everything for every other path -->
+                       <web-resource-collection>
+                               <web-resource-name>GSS</web-resource-name>
+                               <description>GSS WebDAV</description>
+                               <url-pattern>/*</url-pattern>
+                       </web-resource-collection>
+                       <auth-constraint>
+                               <role-name>simpleUser</role-name>
+                       </auth-constraint>
+                       <user-data-constraint>
+                               <description>no description</description>
+                               <transport-guarantee>NONE</transport-guarantee>
+                       </user-data-constraint>
+               </security-constraint>
+               
+               <login-config>
+                       <auth-method>DIGEST</auth-method>
+                       <realm-name>Pithos WebDAV</realm-name>
+               </login-config>
+
+               <security-role>
+                       <description>A plain WebDAV user</description>
+                       <role-name>simpleUser</role-name>
+               </security-role>
 </web-app>