directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kayyag...@apache.org
Subject svn commit: r1540511 - in /directory/escimo/trunk: ./ client/src/main/java/org/apache/directory/scim/ common/ common/src/main/java/org/apache/directory/scim/ ldap/src/main/java/org/apache/directory/scim/ldap/ server/ server/src/main/java/org/apache/dir...
Date Sun, 10 Nov 2013 18:43:25 GMT
Author: kayyagari
Date: Sun Nov 10 18:43:25 2013
New Revision: 1540511

URL: http://svn.apache.org/r1540511
Log:
o added BASIC authetication support
o removed HttpHeaders context param, instead using HttpServletRequest

Added:
    directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/
    directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/AuthenticationFilter.java
    directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/BasicAuthenticator.java
    directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoAuthenticator.java
    directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoHttpServletRequest.java
Modified:
    directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java
    directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java
    directory/escimo/trunk/common/pom.xml
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ProviderService.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/RequestContext.java
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java
    directory/escimo/trunk/pom.xml
    directory/escimo/trunk/server/pom.xml
    directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/GroupService.java
    directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java
    directory/escimo/trunk/server/src/main/webapp/WEB-INF/web.xml
    directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java

Modified: directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java
(original)
+++ directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java
Sun Nov 10 18:43:25 2013
@@ -27,8 +27,12 @@ import java.util.Map;
 
 import org.apache.directory.scim.schema.CoreResource;
 import org.apache.directory.scim.schema.ErrorResponse;
+import org.apache.http.Header;
 import org.apache.http.HttpResponse;
 import org.apache.http.StatusLine;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpGet;
@@ -37,6 +41,8 @@ import org.apache.http.client.methods.Ht
 import org.apache.http.client.methods.HttpPut;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 import org.slf4j.Logger;
@@ -69,6 +75,9 @@ public class EscimoClient
     
     private static final Logger LOG = LoggerFactory.getLogger( EscimoClient.class );
 
+    public static final String USER_AUTH_HEADER = "X-Escimo-Auth";
+    
+    private String authToken = null;
 
     public EscimoClient( String providerUrl, Map<String,Class<? extends CoreResource>>
uriClassMap )
     {
@@ -81,6 +90,33 @@ public class EscimoClient
         serializer = gb.create();
     }
 
+    public EscimoResult authenticate( String userName, String password )
+    {
+        HttpGet get = new HttpGet( providerUrl + USERS_URI + "/" + "dummy-req-for-auth" );
+        
+        UsernamePasswordCredentials credentials = new UsernamePasswordCredentials( userName,
password );
+        AuthScope authScope = new AuthScope(get.getURI().getHost(), get.getURI().getPort(),
AuthScope.ANY_REALM, "BASIC");
+        CredentialsProvider cp = new BasicCredentialsProvider();
+        cp.setCredentials( authScope, credentials );
+        
+        HttpClientBuilder clientBuilder = HttpClients.custom();
+        clientBuilder.setDefaultCredentialsProvider( cp );
+
+        HttpClient client = clientBuilder.build();
+        
+        EscimoResult er = getResource( client, get );
+        
+        Header h = er.getHeader( USER_AUTH_HEADER );
+        
+        if( h != null )
+        {
+            authToken = h.getValue();
+        }
+        
+        return er;
+    }
+    
+    
     public EscimoResult addUser( CoreResource resource )
     {
         return addResource( resource, USERS_URI );
@@ -146,6 +182,7 @@ public class EscimoClient
         }
 
         HttpDelete delete = new HttpDelete( providerUrl + uri + "/" + id );
+        delete.addHeader( USER_AUTH_HEADER, authToken );
         
         LOG.debug( "Trying to delete resource with ID {} at URI {}", id, uri );
 
@@ -186,11 +223,18 @@ public class EscimoClient
         }
 
         HttpGet get = new HttpGet( providerUrl + uri + "/" + id );
+        get.addHeader( USER_AUTH_HEADER, authToken );
         
         LOG.debug( "Trying to retrieve resource with ID {} at URI {}", id, uri );
-
+        
         HttpClient client = HttpClients.createDefault();
-
+        
+        return getResource( client, get );
+    }
+    
+    
+    private EscimoResult getResource( HttpClient client, HttpGet get )
+    {
         try
         {
             HttpResponse resp = client.execute( get );
@@ -227,7 +271,8 @@ public class EscimoClient
         }
 
         HttpPost post = new HttpPost( providerUrl + uri );
-
+        post.addHeader( USER_AUTH_HEADER, authToken );
+        
         String payload = serialize( resource ).toString();
 
         LOG.debug( "sending JSON payload to URI {} for adding resource:\n{}", uri, payload
);
@@ -274,7 +319,8 @@ public class EscimoClient
         uri = uri + "/" + resourceId;
         
         HttpPut put = new HttpPut( providerUrl + uri );
-
+        put.addHeader( USER_AUTH_HEADER, authToken );
+        
         String payload = serialize( resource ).toString();
 
         LOG.debug( "sending JSON payload to URI {} for adding resource:\n{}", uri, payload
);
@@ -320,19 +366,20 @@ public class EscimoClient
 
         uri = uri + "/" + resourceId;
         
-        HttpPatch put = new HttpPatch( providerUrl + uri );
-
+        HttpPatch patch = new HttpPatch( providerUrl + uri );
+        patch.addHeader( USER_AUTH_HEADER, authToken );
+        
         String payload = serialize( resource ).toString();
 
         LOG.debug( "sending JSON payload to URI {} for adding resource:\n{}", uri, payload
);
 
-        put.setEntity( new StringEntity( payload, ContentType.APPLICATION_JSON ) );
+        patch.setEntity( new StringEntity( payload, ContentType.APPLICATION_JSON ) );
 
         HttpClient client = HttpClients.createDefault();
 
         try
         {
-            HttpResponse resp = client.execute( put );
+            HttpResponse resp = client.execute( patch );
             StatusLine sl = resp.getStatusLine();
             
             EscimoResult result = new EscimoResult( sl.getStatusCode(), resp.getAllHeaders()
);
@@ -357,7 +404,7 @@ public class EscimoClient
         }
         catch ( Exception e )
         {
-            LOG.warn( "Failed while trying to patch a resource at {}", put.getURI() );
+            LOG.warn( "Failed while trying to patch a resource at {}", patch.getURI() );
             throw new RuntimeException( e );
         }
     }

Modified: directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java
(original)
+++ directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java
Sun Nov 10 18:43:25 2013
@@ -21,6 +21,7 @@ package org.apache.directory.scim;
 
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import org.apache.directory.scim.schema.CoreResource;
@@ -134,4 +135,14 @@ public class EscimoResult
         this.resource = resource;
     }
 
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString()
+    {
+        return "EscimoResult [httpStatusCode=" + httpStatusCode + ", errorResponse=" + errorResponse
+ ", resource="
+            + resource + ", headers=" + Arrays.toString( headers ) + "]";
+    }
+
 }

Modified: directory/escimo/trunk/common/pom.xml
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/pom.xml?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/common/pom.xml (original)
+++ directory/escimo/trunk/common/pom.xml Sun Nov 10 18:43:25 2013
@@ -41,5 +41,9 @@
       <artifactId>wink-server</artifactId>
       <version>${wink.version}</version>
     </dependency>
+    <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>servlet-api</artifactId>
+    </dependency>
    </dependencies>
 </project>

Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ProviderService.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ProviderService.java?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ProviderService.java
(original)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ProviderService.java
Sun Nov 10 18:43:25 2013
@@ -57,4 +57,6 @@ public interface ProviderService 
     GroupResource patchGroup( String groupId, String jsonData, RequestContext ctx ) throws
Exception;
     
     ListResponse search( String filter, String attributes, RequestContext ctx ) throws Exception;
+    
+    String authenticate( String userName, String password ) throws Exception;
 }

Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/RequestContext.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/RequestContext.java?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/RequestContext.java
(original)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/RequestContext.java
Sun Nov 10 18:43:25 2013
@@ -20,8 +20,11 @@
 package org.apache.directory.scim;
 
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.UriInfo;
 
@@ -37,15 +40,19 @@ public class RequestContext
 
     private UriInfo uriInfo;
 
-    private HttpHeaders headers;
-    
     private ServerResource resource;
 
-    public RequestContext( ProviderService providerService, UriInfo uriInfo, HttpHeaders
headers )
+    public static final String USER_AUTH_HEADER = "X-Escimo-Auth";
+    
+    private Map<String, String> respHeaders = new HashMap<String, String>();
+    
+    private HttpServletRequest httpReq;
+    
+    public RequestContext( ProviderService providerService, UriInfo uriInfo, HttpServletRequest
httpReq )
     {
         this.providerService = providerService;
         this.uriInfo = uriInfo;
-        this.headers = headers;
+        this.httpReq = httpReq;
     }
 
 
@@ -67,31 +74,21 @@ public class RequestContext
     }
 
 
-    /**
-     * @return the headers
-     */
-    public HttpHeaders getHeaders()
-    {
-        return headers;
-    }
-
-
     public ProviderService getProviderService()
     {
         return providerService;
     }
 
     
-    public String getHeaderValue( String name )
+    public void addRespHeader( String name, String value )
     {
-        List<String> lst = headers.getRequestHeader( name );
-        
-        if( ( lst == null ) || ( lst.isEmpty() ) )
-        {
-            return null;
-        }
-        
-        return lst.get( 0 );
+        respHeaders.put( name, value );
+    }
+    
+    
+    public String getReqHeaderValue( String name )
+    {
+       return httpReq.getHeader( name );
     }
     
     

Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java
(original)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java
Sun Nov 10 18:43:25 2013
@@ -35,6 +35,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.UUID;
 
 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
 import org.apache.directory.api.ldap.model.cursor.EntryCursor;
@@ -46,7 +47,6 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.filter.ExprNode;
-import org.apache.directory.api.ldap.model.filter.PresenceNode;
 import org.apache.directory.api.ldap.model.message.LdapResult;
 import org.apache.directory.api.ldap.model.message.ModifyRequest;
 import org.apache.directory.api.ldap.model.message.ModifyRequestImpl;
@@ -129,12 +129,16 @@ public class LdapResourceProvider implem
 
     private SchemaManager ldapSchema;
     
+    private LdapConnectionConfig config;
+    
     private Map<String,JsonSchema> schemas = new HashMap<String, JsonSchema>();
 
     private static final Logger LOG = LoggerFactory.getLogger( LdapResourceProvider.class
);
 
     private static final String ENTRYDN_HEADER = "X-ENTRYDN";
 
+    private Map<String, LdapConnection> connMap = new HashMap<String, LdapConnection>();
+    
     public LdapResourceProvider()
     {
     }
@@ -221,7 +225,7 @@ public class LdapResourceProvider implem
         String password = prop.getProperty( "escimo.ldap.server.password" );
         String tlsVal = prop.getProperty( "escimo.ldap.server.useTls" );
 
-        LdapConnectionConfig config = new LdapConnectionConfig();
+        config = new LdapConnectionConfig();
         config.setLdapHost( host );
         config.setLdapPort( port );
         config.setUseTls( Boolean.parseBoolean( tlsVal ) );
@@ -233,6 +237,57 @@ public class LdapResourceProvider implem
     }
 
 
+    public String authenticate( String userName, String password ) throws Exception
+    {
+        if( ( userName == null ) || ( password == null ) )
+        {
+            LOG.debug( "Missing username and/or password" );
+            return null;
+        }
+        
+        LOG.debug( "Authenticating user {}", userName );
+        
+        String userDn = null;
+        SimpleType st = ( SimpleType ) userSchema.getAttribute( "userName" );
+        
+        String filter = "(" + st.getMappedTo() + "=" + userName + ")";
+        
+        EntryCursor cursor = null;
+        
+        try
+        {
+            cursor = connection.search( userSchema.getBaseDn(), filter, SUBTREE, "1.1" );
+
+            if ( cursor.next() )
+            {
+                userDn = cursor.get().getDn().getName();
+            }
+        }
+        finally
+        {
+            if( cursor != null )
+            {
+                cursor.close();
+            }
+        }
+
+        if( userDn == null )
+        {
+            return null;
+        }
+        
+        LdapConnection conn = new LdapNetworkConnection( config );
+        conn.bind( userDn, password );
+        conn.loadSchema();
+        
+        String sessionId = UUID.randomUUID().toString();
+        
+        connMap.put( sessionId, conn );
+        
+        return sessionId;
+    }
+
+
     public List<AttributeType> getLdapTypes( String scimAtName, ResourceSchema schema
)
     {
         scimAtName = scimAtName.trim();
@@ -350,7 +405,9 @@ public class LdapResourceProvider implem
         String[] requested = getRequestedAttributes( attributes, scimSchema );
         sr.addAttributes( requested );
         
-        SearchCursor cursor = connection.search( sr );
+        LdapConnection conn = getConnection( ctx );
+        
+        SearchCursor cursor = conn.search( sr );
         
         ListResponse lr = new ListResponse();
         
@@ -559,7 +616,7 @@ public class LdapResourceProvider implem
             SimpleType st = ( SimpleType ) userSchema.getCoreAttribute( "userName" );
             String userIdName = st.getMappedTo();
 
-            String dn = ctx.getHeaderValue( ENTRYDN_HEADER );
+            String dn = ctx.getReqHeaderValue( ENTRYDN_HEADER );
             
             if( Strings.isEmpty( dn ) )
             {
@@ -616,7 +673,7 @@ public class LdapResourceProvider implem
             SimpleType st = ( SimpleType ) groupSchema.getCoreAttribute( "displayName" );
             String groupNameAt = st.getMappedTo();
 
-            String dn = ctx.getHeaderValue( ENTRYDN_HEADER );
+            String dn = ctx.getReqHeaderValue( ENTRYDN_HEADER );
             
             if( Strings.isEmpty( dn ) )
             {
@@ -1302,6 +1359,12 @@ public class LdapResourceProvider implem
         return groupSchema;
     }
     
+    
+    private LdapConnection getConnection( RequestContext ctx )
+    {
+        return connMap.get( ctx.getReqHeaderValue( RequestContext.USER_AUTH_HEADER ) );
+    }
+    
     public static void main( String[] args ) throws Exception
     {
         LdapResourceProvider provider = new LdapResourceProvider();

Modified: directory/escimo/trunk/pom.xml
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/pom.xml?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/pom.xml (original)
+++ directory/escimo/trunk/pom.xml Sun Nov 10 18:43:25 2013
@@ -28,7 +28,7 @@
     <ldap.api.version>1.0.0-M20</ldap.api.version>
     <apacheds.version>2.0.0-M15</apacheds.version>
     <jetty.version>7.5.0.v20110901</jetty.version>
-    <wink.version>1.3.0</wink.version>
+    <wink.version>1.4</wink.version>
     <httpclient.version>4.3</httpclient.version>
     <gson.version>2.2.4</gson.version>
     <dom4j.version>1.6.1</dom4j.version>
@@ -59,6 +59,13 @@
      <artifactId>gson</artifactId>
      <version>${gson.version}</version>
    </dependency>
+
+   <dependency>
+     <groupId>javax.servlet</groupId>
+     <artifactId>servlet-api</artifactId>
+     <version>2.5</version>
+     <scope>provided</scope>
+   </dependency>
   </dependencies>
  </dependencyManagement>
 

Modified: directory/escimo/trunk/server/pom.xml
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/pom.xml?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/server/pom.xml (original)
+++ directory/escimo/trunk/server/pom.xml Sun Nov 10 18:43:25 2013
@@ -28,5 +28,14 @@
             <artifactId>escimo-common</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.8</version>
+        </dependency>
     </dependencies>
 </project>

Modified: directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/GroupService.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/GroupService.java?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/GroupService.java
(original)
+++ directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/GroupService.java
Sun Nov 10 18:43:25 2013
@@ -20,10 +20,12 @@
 package org.apache.directory.scim.rest;
 
 
-import static org.apache.directory.scim.ScimUtil.*;
+import static org.apache.directory.scim.ScimUtil.buildError;
+import static org.apache.directory.scim.ScimUtil.sendBadRequest;
 
 import java.net.URI;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -33,14 +35,12 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 
-import org.apache.directory.scim.AttributeNotFoundException;
 import org.apache.directory.scim.GroupResource;
 import org.apache.directory.scim.ListResponse;
 import org.apache.directory.scim.ProviderService;
@@ -63,16 +63,19 @@ public class GroupService
 
     private static final Logger LOG = LoggerFactory.getLogger( GroupService.class );
     
+    @Context
+    HttpServletRequest httpReq;
+
     @GET
     @Produces({MediaType.APPLICATION_JSON})
     @Path("{id}")
-    public Response getGroup( @PathParam("id") String groupId, @Context UriInfo uriInfo,
@Context HttpHeaders headers )
+    public Response getGroup( @PathParam("id") String groupId, @Context UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
         
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             
             GroupResource group = provider.getGroup( ctx, groupId );
             String json = ResourceSerializer.serialize( group );
@@ -89,7 +92,7 @@ public class GroupService
     
     @DELETE
     @Path("{id}")
-    public Response deleteGroup( @PathParam("id") String groupId, @Context UriInfo uriInfo,
@Context HttpHeaders headers )
+    public Response deleteGroup( @PathParam("id") String groupId, @Context UriInfo uriInfo
)
     {
         ResponseBuilder rb = Response.ok();
         
@@ -108,7 +111,7 @@ public class GroupService
     
     @POST
     @Produces({MediaType.APPLICATION_JSON})
-    public Response addGroup( String jsonData, @Context UriInfo uriInfo, @Context HttpHeaders
headers )
+    public Response addGroup( String jsonData, @Context UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
 
@@ -121,7 +124,7 @@ public class GroupService
         
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             
             provider.addGroup( jsonData, ctx );
             
@@ -145,7 +148,7 @@ public class GroupService
     @PUT
     @Path("{id}")
     @Produces({MediaType.APPLICATION_JSON})
-    public Response putGroup( @PathParam("id") String groupId, String jsonData, @Context
UriInfo uriInfo, @Context HttpHeaders headers )
+    public Response putGroup( @PathParam("id") String groupId, String jsonData, @Context
UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
 
@@ -158,7 +161,7 @@ public class GroupService
         
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             
             ServerResource res = provider.putGroup( groupId, jsonData, ctx );
             
@@ -179,7 +182,7 @@ public class GroupService
     @PATCH
     @Path("{id}")
     @Produces({MediaType.APPLICATION_JSON})
-    public Response patchGroup( @PathParam("id") String groupId, String jsonData, @Context
UriInfo uriInfo, @Context HttpHeaders headers )
+    public Response patchGroup( @PathParam("id") String groupId, String jsonData, @Context
UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
 
@@ -192,7 +195,7 @@ public class GroupService
         
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             
             ServerResource resource = provider.patchGroup( groupId, jsonData, ctx );
             
@@ -216,7 +219,7 @@ public class GroupService
 
     @GET
     @Produces({MediaType.APPLICATION_JSON})
-    public Response search( @QueryParam("filter") String filter, @QueryParam("attributes")
String attributes, @Context UriInfo uriInfo, @Context HttpHeaders headers )
+    public Response search( @QueryParam("filter") String filter, @QueryParam("attributes")
String attributes, @Context UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
 
@@ -231,7 +234,7 @@ public class GroupService
     
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             ListResponse lr = provider.search( filter, attributes, ctx );
 
             String json = ResourceSerializer.serialize( lr );

Modified: directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java
(original)
+++ directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java
Sun Nov 10 18:43:25 2013
@@ -18,13 +18,15 @@
  */
 package org.apache.directory.scim.rest;
 
-import static org.apache.directory.scim.ScimUtil.*;
+import static org.apache.directory.scim.ScimUtil.buildError;
+import static org.apache.directory.scim.ScimUtil.sendBadRequest;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URI;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -35,7 +37,6 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
@@ -65,16 +66,19 @@ public class UserService
 
     private static final Logger LOG = LoggerFactory.getLogger( UserService.class );
     
+    @Context
+    HttpServletRequest httpReq;
+    
     @GET
     @Produces({MediaType.APPLICATION_JSON})
     @Path("{id}")
-    public Response getUser( @PathParam("id") String userId, @Context UriInfo uriInfo, @Context
HttpHeaders headers )
+    public Response getUser( @PathParam("id") String userId, @Context UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
         
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             
             UserResource user = provider.getUser( ctx, userId );
             String json = ResourceSerializer.serialize( user );
@@ -91,7 +95,7 @@ public class UserService
 
     @DELETE
     @Path("{id}")
-    public Response deleteUser( @PathParam("id") String userId, @Context UriInfo uriInfo,
@Context HttpHeaders headers )
+    public Response deleteUser( @PathParam("id") String userId, @Context UriInfo uriInfo
)
     {
         ResponseBuilder rb = Response.ok();
         
@@ -110,7 +114,7 @@ public class UserService
     
     @POST
     @Produces({MediaType.APPLICATION_JSON})
-    public Response addUser( String jsonData, @Context UriInfo uriInfo, @Context HttpHeaders
headers )
+    public Response addUser( String jsonData, @Context UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
 
@@ -123,7 +127,7 @@ public class UserService
         
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             
             provider.addUser( jsonData, ctx );
             
@@ -147,7 +151,7 @@ public class UserService
     @PUT
     @Path("{id}")
     @Produces({MediaType.APPLICATION_JSON})
-    public Response putUser( @PathParam("id") String userId, String jsonData, @Context UriInfo
uriInfo, @Context HttpHeaders headers )
+    public Response putUser( @PathParam("id") String userId, String jsonData, @Context UriInfo
uriInfo )
     {
         ResponseBuilder rb = null;
 
@@ -160,7 +164,7 @@ public class UserService
         
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             
             ServerResource res = provider.putUser( userId, jsonData, ctx );
             
@@ -182,7 +186,7 @@ public class UserService
     @PATCH
     @Path("{id}")
     @Produces({MediaType.APPLICATION_JSON})
-    public Response patchUser( @PathParam("id") String userId, String jsonData, @Context
UriInfo uriInfo, @Context HttpHeaders headers )
+    public Response patchUser( @PathParam("id") String userId, String jsonData, @Context
UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
 
@@ -195,7 +199,7 @@ public class UserService
         
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             
             ServerResource resource = provider.patchUser( userId, jsonData, ctx );
             
@@ -220,7 +224,7 @@ public class UserService
 
     @GET
     @Produces({MediaType.APPLICATION_JSON})
-    public Response search( @QueryParam("filter") String filter, @QueryParam("attributes")
String attributes, @Context UriInfo uriInfo, @Context HttpHeaders headers )
+    public Response search( @QueryParam("filter") String filter, @QueryParam("attributes")
String attributes, @Context UriInfo uriInfo )
     {
         ResponseBuilder rb = null;
 
@@ -235,7 +239,7 @@ public class UserService
     
         try
         {
-            RequestContext ctx = new RequestContext( provider, uriInfo, headers );
+            RequestContext ctx = new RequestContext( provider, uriInfo, httpReq );
             ListResponse lr = provider.search( filter, attributes, ctx );
 
             String json = ResourceSerializer.serialize( lr );

Added: directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/AuthenticationFilter.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/AuthenticationFilter.java?rev=1540511&view=auto
==============================================================================
--- directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/AuthenticationFilter.java
(added)
+++ directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/AuthenticationFilter.java
Sun Nov 10 18:43:25 2013
@@ -0,0 +1,145 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.scim.rest.auth;
+
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.directory.scim.ProviderService;
+import org.apache.directory.scim.RequestContext;
+import org.apache.directory.scim.ScimUtil;
+import org.apache.directory.scim.json.ResourceSerializer;
+import org.apache.directory.scim.rest.ServerInitializer;
+import org.apache.directory.scim.schema.ErrorCode;
+import org.apache.directory.scim.schema.ErrorResponse;
+import org.apache.directory.scim.schema.ErrorResponse.ScimError;
+
+/**
+ * 
+ * TODO AuthenticationFilter.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class AuthenticationFilter implements Filter
+{
+
+    private EscimoAuthenticator authenticator;
+
+    private ProviderService provider;
+    
+    public void destroy()
+    {
+    }
+
+
+    public void doFilter( ServletRequest req, ServletResponse resp, FilterChain chain ) throws
IOException,
+        ServletException
+    {
+        if( authenticator == null )
+        {
+            chain.doFilter( req, resp );
+            return;
+        }
+        
+        HttpServletRequest httpReq = ( HttpServletRequest ) req;
+        HttpServletResponse httpResp = ( HttpServletResponse ) resp;
+        
+        String userHeader = httpReq.getHeader( RequestContext.USER_AUTH_HEADER );
+        
+        if( ( userHeader != null ) && ( userHeader.trim().length() > 0 ) )
+        {
+            chain.doFilter( req, resp );
+            return;
+        }
+        
+        String authToken = null;
+        String errorMsg = null;
+        
+        String authHeader = httpReq.getHeader( "Authorization" );
+        
+        if( authHeader == null )
+        {
+            httpResp.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
+            httpResp.setHeader( "WWW-Authenticate", "Basic realm=escimo" );
+            return;
+        }
+        
+        try
+        {
+            authToken = authenticator.authenticate( ( HttpServletRequest ) req, provider
);
+        }
+        catch( Exception e )
+        {
+            errorMsg = ScimUtil.exceptionToStr( e );
+        }
+        
+        
+        if( authToken == null )
+        {
+            if( errorMsg == null )
+            {
+                errorMsg = "Not authenticated";
+            }
+            
+            ScimError error = new ScimError( ErrorCode.UNAUTHORIZED, errorMsg );
+            ErrorResponse erResp = new ErrorResponse( error );
+            
+            String json = ResourceSerializer.serialize( erResp );
+            
+            httpResp.setStatus( error.getCode() );
+            httpResp.getWriter().write( json );
+            
+            return;
+        }
+
+        httpResp.setHeader( RequestContext.USER_AUTH_HEADER, authToken );
+        
+        chain.doFilter( new EscimoHttpServletRequest( httpReq, authToken ), resp );
+    }
+
+
+    public void init( FilterConfig filterConfig ) throws ServletException
+    {
+        String authMethod = filterConfig.getInitParameter( "authMethod" );
+        
+        if( StringUtils.isEmpty( authMethod ) )
+        {
+            authMethod = "NONE";
+        }
+        
+        if( authMethod.equalsIgnoreCase( "BASIC" ) )
+        {
+            authenticator = new BasicAuthenticator();
+        }
+        
+        provider = ServerInitializer.getProvider();
+    }
+
+}

Added: directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/BasicAuthenticator.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/BasicAuthenticator.java?rev=1540511&view=auto
==============================================================================
--- directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/BasicAuthenticator.java
(added)
+++ directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/BasicAuthenticator.java
Sun Nov 10 18:43:25 2013
@@ -0,0 +1,63 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.scim.rest.auth;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.directory.scim.ProviderService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO BasicAuthenticator.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class BasicAuthenticator implements EscimoAuthenticator
+{
+    private static final Logger LOG = LoggerFactory.getLogger( BasicAuthenticator.class );
+    
+    public String authenticate( HttpServletRequest req, ProviderService provider ) throws
Exception
+    {
+        String authHeader = req.getHeader( "Authorization" );
+        
+        LOG.debug( "received authorization header {}", authHeader );
+        
+        int pos = authHeader.indexOf( ' ' );
+        if( pos <= 0 )
+        {
+            return null;
+        }
+        
+        authHeader = new String( Base64.decodeBase64( authHeader.substring( pos + 1 ) ) );
+        
+        String[] credentials = authHeader.split( ":" );
+        
+        if( credentials.length > 1 )
+        {
+            String headerVal = provider.authenticate( credentials[0], credentials[1] );
+            return headerVal;
+        }
+        
+        return null;
+    }
+}

Added: directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoAuthenticator.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoAuthenticator.java?rev=1540511&view=auto
==============================================================================
--- directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoAuthenticator.java
(added)
+++ directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoAuthenticator.java
Sun Nov 10 18:43:25 2013
@@ -0,0 +1,34 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.scim.rest.auth;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.directory.scim.ProviderService;
+
+/**
+ * TODO EscimoAuthenticator.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface EscimoAuthenticator
+{
+    String authenticate( HttpServletRequest req, ProviderService provider ) throws Exception;
+}

Added: directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoHttpServletRequest.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoHttpServletRequest.java?rev=1540511&view=auto
==============================================================================
--- directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoHttpServletRequest.java
(added)
+++ directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/auth/EscimoHttpServletRequest.java
Sun Nov 10 18:43:25 2013
@@ -0,0 +1,98 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.scim.rest.auth;
+
+
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import org.apache.directory.scim.RequestContext;
+
+
+/**
+ * TODO EscimoHttpServletRequest.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class EscimoHttpServletRequest extends HttpServletRequestWrapper
+{
+
+    private String authToken;
+
+
+    public EscimoHttpServletRequest( HttpServletRequest req, String authToken )
+    {
+        super( req );
+        this.authToken = authToken;
+    }
+
+
+    @Override
+    public Enumeration getHeaderNames()
+    {
+        final Enumeration<String> superEn = super.getHeaderNames();
+        
+        Enumeration<String> en = new Enumeration<String>()
+        {
+
+            private int first = -1;
+            
+            public boolean hasMoreElements()
+            {
+                if( first == -1 )
+                {
+                    first = 0;
+                    return true;
+                }
+                
+                return superEn.hasMoreElements();
+            }
+
+            public String nextElement()
+            {
+                if( first == 0 )
+                {
+                    first = 1;
+                    return RequestContext.USER_AUTH_HEADER;
+                }
+                
+                return superEn.nextElement();
+            }
+            
+        };
+        
+        return en;
+    }
+
+
+    @Override
+    public String getHeader( String name )
+    {
+        if ( RequestContext.USER_AUTH_HEADER.equals( name ) )
+        {
+            return authToken;
+        }
+
+        return super.getHeader( name );
+    }
+
+}

Modified: directory/escimo/trunk/server/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/src/main/webapp/WEB-INF/web.xml?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/server/src/main/webapp/WEB-INF/web.xml (original)
+++ directory/escimo/trunk/server/src/main/webapp/WEB-INF/web.xml Sun Nov 10 18:43:25 2013
@@ -4,9 +4,24 @@
     "http://java.sun.com/dtd/web-app_2_3.dtd">
 
 <web-app>
+    <filter>
+     <filter-name>AuthenticationFilter</filter-name>
+     <filter-class>org.apache.directory.scim.rest.auth.AuthenticationFilter</filter-class>
+     <init-param>
+       <param-name>authMethod</param-name>
+       <param-value>basic</param-value>
+     </init-param>
+    </filter>
+    
+    <filter-mapping>
+      <filter-name>AuthenticationFilter</filter-name>
+      <url-pattern>/*</url-pattern>
+    </filter-mapping>
+    
     <listener>
         <listener-class></listener-class>
     </listener>
+    
     <!-- Servlets -->
     <servlet>
         <servlet-name>escimoService</servlet-name>

Modified: directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java?rev=1540511&r1=1540510&r2=1540511&view=diff
==============================================================================
--- directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java
(original)
+++ directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java
Sun Nov 10 18:43:25 2013
@@ -67,6 +67,9 @@ public class UserResourceTest
         client = new EscimoClient( baseUrl, uriClassMap );
         
         JettyServer.start();
+        
+        EscimoResult er = client.authenticate( "admin", "secret" );
+        System.out.println( er );
     }
     
     @AfterClass



Mime
View raw message