From f17c073a09e1f4e7f05e4fd5c04045597dda8204 Mon Sep 17 00:00:00 2001 From: koutsoub Date: Tue, 15 Feb 2011 16:39:33 +0200 Subject: [PATCH] use jaas for authentication, so we can access easily the user object even for webdav unauthenticated calls, created a RootFolderResource mapped at / path --- .../server/webdav/milton/GSSResourceFactory.java | 43 ++++++- .../webdav/milton/GssAuthenticationService.java | 70 ++++++++++- .../gss/server/webdav/milton/GssFileResource.java | 2 +- .../server/webdav/milton/GssFolderResource.java | 14 +-- .../gss/server/webdav/milton/GssMiltonServlet.java | 5 +- .../ebs/gss/server/webdav/milton/GssResource.java | 21 +++- .../webdav/milton/GssRootFolderResource.java | 124 ++++++++++++++++++++ .../server/webdav/milton/GssSecurityManager.java | 25 ++-- webdav/WEB-INF/web.xml | 58 ++++++++- 9 files changed, 328 insertions(+), 34 deletions(-) create mode 100644 src/gr/ebs/gss/server/webdav/milton/GssRootFolderResource.java diff --git a/src/gr/ebs/gss/server/webdav/milton/GSSResourceFactory.java b/src/gr/ebs/gss/server/webdav/milton/GSSResourceFactory.java index 4c9d12d..7788225 100644 --- a/src/gr/ebs/gss/server/webdav/milton/GSSResourceFactory.java +++ b/src/gr/ebs/gss/server/webdav/milton/GSSResourceFactory.java @@ -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); + } } diff --git a/src/gr/ebs/gss/server/webdav/milton/GssAuthenticationService.java b/src/gr/ebs/gss/server/webdav/milton/GssAuthenticationService.java index f94ea95..6c56419 100644 --- a/src/gr/ebs/gss/server/webdav/milton/GssAuthenticationService.java +++ b/src/gr/ebs/gss/server/webdav/milton/GssAuthenticationService.java @@ -18,9 +18,28 @@ */ 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 authenticationHandlers ) { - super(authenticationHandlers); + public GssAuthenticationService( ) { + super(new ArrayList()); } + + 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"); + } + } } diff --git a/src/gr/ebs/gss/server/webdav/milton/GssFileResource.java b/src/gr/ebs/gss/server/webdav/milton/GssFileResource.java index ccb2ea7..3f8e09b 100644 --- a/src/gr/ebs/gss/server/webdav/milton/GssFileResource.java +++ b/src/gr/ebs/gss/server/webdav/milton/GssFileResource.java @@ -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()); diff --git a/src/gr/ebs/gss/server/webdav/milton/GssFolderResource.java b/src/gr/ebs/gss/server/webdav/milton/GssFolderResource.java index 2979b36..3516480 100644 --- a/src/gr/ebs/gss/server/webdav/milton/GssFolderResource.java +++ b/src/gr/ebs/gss/server/webdav/milton/GssFolderResource.java @@ -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) { diff --git a/src/gr/ebs/gss/server/webdav/milton/GssMiltonServlet.java b/src/gr/ebs/gss/server/webdav/milton/GssMiltonServlet.java index 0f8ed93..7f06eec 100644 --- a/src/gr/ebs/gss/server/webdav/milton/GssMiltonServlet.java +++ b/src/gr/ebs/gss/server/webdav/milton/GssMiltonServlet.java @@ -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); diff --git a/src/gr/ebs/gss/server/webdav/milton/GssResource.java b/src/gr/ebs/gss/server/webdav/milton/GssResource.java index 5a53836..9209354 100644 --- a/src/gr/ebs/gss/server/webdav/milton/GssResource.java +++ b/src/gr/ebs/gss/server/webdav/milton/GssResource.java @@ -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 index 0000000..5b998a3 --- /dev/null +++ b/src/gr/ebs/gss/server/webdav/milton/GssRootFolderResource.java @@ -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 . + */ +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 getChildren() { + try { + this.folder = (FolderDTO) factory.getResourceGss("/"); + } catch (RpcException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + List result = new ArrayList(); + 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; + } + +} diff --git a/src/gr/ebs/gss/server/webdav/milton/GssSecurityManager.java b/src/gr/ebs/gss/server/webdav/milton/GssSecurityManager.java index c7a89fd..2390edf 100644 --- a/src/gr/ebs/gss/server/webdav/milton/GssSecurityManager.java +++ b/src/gr/ebs/gss/server/webdav/milton/GssSecurityManager.java @@ -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; } diff --git a/webdav/WEB-INF/web.xml b/webdav/WEB-INF/web.xml index 21a03e8..70fa23f 100644 --- a/webdav/WEB-INF/web.xml +++ b/webdav/WEB-INF/web.xml @@ -1,9 +1,6 @@ - + milton_webdav gr.ebs.gss.server.webdav.milton.GssMiltonServlet @@ -31,4 +28,57 @@ /miltonController --> + + + + GSS + GSS WebDAV + / + HEAD + GET + POST + PUT + DELETE + PROPFIND + PROPPATCH + MKCOL + COPY + MOVE + LOCK + UNLOCK + + + simpleUser + + + no description + NONE + + + + + + + GSS + GSS WebDAV + /* + + + simpleUser + + + no description + NONE + + + + + DIGEST + Pithos WebDAV + + + + A plain WebDAV user + simpleUser + -- 1.7.10.4