Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B20EE1032D for ; Sun, 20 Oct 2013 14:13:10 +0000 (UTC) Received: (qmail 74996 invoked by uid 500); 20 Oct 2013 14:13:10 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 74937 invoked by uid 500); 20 Oct 2013 14:13:10 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 74926 invoked by uid 99); 20 Oct 2013 14:13:09 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 20 Oct 2013 14:13:09 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 20 Oct 2013 14:13:05 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id A3CA4238899C; Sun, 20 Oct 2013 14:12:43 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1533911 - in /directory/escimo/trunk: common/src/main/java/org/apache/directory/scim/ ldap/src/main/java/org/apache/directory/scim/ldap/ ldap/src/main/java/org/apache/directory/scim/ldap/handlers/ Date: Sun, 20 Oct 2013 14:12:43 -0000 To: commits@directory.apache.org From: kayyagari@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131020141243.A3CA4238899C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kayyagari Date: Sun Oct 20 14:12:43 2013 New Revision: 1533911 URL: http://svn.apache.org/r1533911 Log: o fixed the way members of a group are added and deleted o added suppot for deleting comple/multivalued attributes Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapUtil.java directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/LdapAttributeHandler.java directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java?rev=1533911&r1=1533910&r2=1533911&view=diff ============================================================================== --- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java (original) +++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java Sun Oct 20 14:12:43 2013 @@ -37,4 +37,6 @@ public abstract class AttributeHandler public abstract void write( BaseType atType, JsonElement jsonData, Object targetEntry, RequestContext ctx ) throws Exception; public abstract void patch( BaseType atType, JsonElement jsonData, Object targetEntry, RequestContext ctx, Object patchCtx ) throws Exception; + + public abstract void deleteAttribute( BaseType atType, Object targetEntry, RequestContext ctx, Object patchCtx ) throws Exception; } 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=1533911&r1=1533910&r2=1533911&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 Oct 20 14:12:43 2013 @@ -42,8 +42,6 @@ import org.apache.directory.api.ldap.mod import org.apache.directory.api.ldap.model.entry.Entry; import org.apache.directory.api.ldap.model.entry.Value; import org.apache.directory.api.ldap.model.exception.LdapException; -import org.apache.directory.api.ldap.model.ldif.LdifEntry; -import org.apache.directory.api.ldap.model.ldif.LdifReader; 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; @@ -78,6 +76,7 @@ import org.apache.directory.scim.ServerR import org.apache.directory.scim.SimpleAttribute; import org.apache.directory.scim.SimpleAttributeGroup; import org.apache.directory.scim.UserResource; +import org.apache.directory.scim.ldap.handlers.MembersAttributeHandler; import org.apache.directory.scim.ldap.schema.ComplexType; import org.apache.directory.scim.ldap.schema.GroupSchema; import org.apache.directory.scim.ldap.schema.MultiValType; @@ -436,6 +435,7 @@ public class LdapResourceProvider implem _resourceToEntry( entry, obj, ctx, groupSchema ); entry.setDn( dn ); + connection.add( entry ); entry = connection.lookup( entry.getDn(), SchemaConstants.ALL_ATTRIBUTES_ARRAY ); @@ -460,6 +460,15 @@ public class LdapResourceProvider implem private void _resourceToEntry( Entry entry, JsonObject obj, RequestContext ctx, ResourceSchema resourceSchema ) throws Exception { + // add the objectClasses first so a handler will get a chance to + // inspect what attributes can the entry hold + // e.x it is useful for handling Groups, where the handler can + // find if the attribute name is 'member' or 'uniqueMember' + for( String oc : resourceSchema.getObjectClasses() ) + { + entry.add( SchemaConstants.OBJECT_CLASS, oc ); + } + // process the core attributes first addAttributes( entry, obj, ctx, resourceSchema ); @@ -474,10 +483,6 @@ public class LdapResourceProvider implem } } - for( String oc : resourceSchema.getObjectClasses() ) - { - entry.add( SchemaConstants.OBJECT_CLASS, oc ); - } } @@ -640,8 +645,6 @@ public class LdapResourceProvider implem ModifyRequest modReq = new ModifyRequestImpl(); modReq.setName( existingEntry.getDn() ); - List deleteModAtOids = new ArrayList(); - boolean hasAttributesInMeta = false; JsonObject metaObj = ( JsonObject ) obj.get( "meta" ); @@ -662,21 +665,14 @@ public class LdapResourceProvider implem throw new AttributeNotFoundException( "No definition found for the attribute " + name ); } - if( bt.isReadOnly() || ( ! ( bt instanceof SimpleType ) ) ) + AttributeHandler handler = resourceSchema.getHandler( bt.getAtHandlerName() ); + if( handler != null ) { + handler.deleteAttribute( bt, existingEntry, ctx, modReq ); continue; } - SimpleType st = ( SimpleType ) bt; - - name = st.getMappedTo(); - - if( !Strings.isEmpty( name ) ) - { - Attribute ldapAt = existingEntry.get( name ); - modReq.remove( ldapAt ); - deleteModAtOids.add( ldapAt.getAttributeType().getOid() ); - } + LdapUtil.deleteAttribute( bt, existingEntry, modReq ); } } } @@ -1100,39 +1096,22 @@ public class LdapResourceProvider implem { return ldapSchema; } - - private static String HPD_PROVIDER_DN = "m-oid=1.3.6.1.4.1.19376.1.2.4.1,ou=objectClasses,cn=hpd,ou=schema"; - public static void main( String[] args ) throws Exception + + /** + * @return the userSchema + */ + public UserSchema getUserSchema() { -// System.setProperty( StandaloneLdapApiService.CONTROLS_LIST, -// "org.apache.directory.api.ldap.codec.controls.cascade.CascadeFactory," + -// "org.apache.directory.api.ldap.codec.controls.manageDsaIT.ManageDsaITFactory," + -// "org.apache.directory.api.ldap.codec.controls.search.entryChange.EntryChangeFactory," + -// "org.apache.directory.api.ldap.codec.controls.search.pagedSearch.PagedResultsFactory," + -// "org.apache.directory.api.ldap.codec.controls.search.persistentSearch.PersistentSearchFactory," + -// "org.apache.directory.api.ldap.codec.controls.search.subentries.SubentriesFactory" ); - - LdapNetworkConnection c = new LdapNetworkConnection( "localhost", 10389 ); - c.setTimeOut( Long.MAX_VALUE ); - c.bind( "uid=admin,ou=system", "secret" ); -// c.loadSchema(); - //c.loadSchema( new JarLdifSchemaLoader() ); - - Entry hpdProviderEntry = c.lookup(HPD_PROVIDER_DN); - boolean hasBeenApplied = hpdProviderEntry.contains( "m-may", "hpdProviderLegalAddress1"); - System.out.println(hasBeenApplied); - String ldif = "dn: m-oid=1.3.6.1.4.1.19376.1.2.4.1,ou=objectClasses,cn=hpd,ou=schema\n"+ - "changetype: modify\n"+ - "delete: m-may\n" + - "m-may: hpdProviderLegalAddress\n" + - "-\n"; - LdifReader reader = new LdifReader( ldif ); - - LdifEntry entry = reader.next(); - - c.add( entry.getEntry() ); - - c.close(); + return userSchema; + } + + + /** + * @return the groupSchema + */ + public GroupSchema getGroupSchema() + { + return groupSchema; } } Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapUtil.java URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapUtil.java?rev=1533911&r1=1533910&r2=1533911&view=diff ============================================================================== --- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapUtil.java (original) +++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapUtil.java Sun Oct 20 14:12:43 2013 @@ -305,8 +305,6 @@ public class LdapUtil return; } - ModificationOperation operation = ( delete ? REMOVE_ATTRIBUTE : REPLACE_ATTRIBUTE ); - String ldapAtName = st.getMappedTo(); if( Strings.isEmpty( ldapAtName ) ) @@ -357,4 +355,62 @@ public class LdapUtil } } + + public static void deleteAttribute( BaseType bt, Entry existingEntry, ModifyRequest modReq ) + { + if( bt.isReadOnly() ) + { + return; + } + + SimpleTypeGroup stg = null; + + if( bt instanceof MultiValType ) + { + MultiValType mt = ( MultiValType ) bt; + stg = mt.getAtGroup(); + } + else if ( bt instanceof ComplexType ) + { + ComplexType ct = ( ComplexType ) bt; + stg = ct.getAtGroup(); + } + + if( stg != null ) + { + for( SimpleType st : stg.getSubTypes() ) + { + if( st.isReadOnly() ) + { + continue; + } + + String name = st.getMappedTo(); + + if( !Strings.isEmpty( name ) ) + { + Attribute ldapAt = existingEntry.get( name ); + if( ldapAt != null ) + { + modReq.remove( ldapAt ); + } + } + } + + return; + } + + SimpleType st = ( SimpleType ) bt; + + String name = st.getMappedTo(); + + if( !Strings.isEmpty( name ) ) + { + Attribute ldapAt = existingEntry.get( name ); + if( ldapAt != null ) + { + modReq.remove( ldapAt ); + } + } + } } Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/LdapAttributeHandler.java URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/LdapAttributeHandler.java?rev=1533911&r1=1533910&r2=1533911&view=diff ============================================================================== --- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/LdapAttributeHandler.java (original) +++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/LdapAttributeHandler.java Sun Oct 20 14:12:43 2013 @@ -62,4 +62,10 @@ public abstract class LdapAttributeHandl { LdapUtil.patchLdapAttribute( atType, jsonData, ( Entry ) entry, ctx, ( ModifyRequest ) patchCtx ); } + + @Override + public void deleteAttribute( BaseType atType, Object targetEntry, RequestContext ctx, Object patchCtx ) throws Exception + { + LdapUtil.deleteAttribute( atType, (Entry) targetEntry, ( ModifyRequest ) patchCtx ); + } } Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java?rev=1533911&r1=1533910&r2=1533911&view=diff ============================================================================== --- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java (original) +++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java Sun Oct 20 14:12:43 2013 @@ -29,6 +29,7 @@ import org.apache.directory.api.ldap.mod import org.apache.directory.api.ldap.model.cursor.EntryCursor; import org.apache.directory.api.ldap.model.entry.Attribute; import org.apache.directory.api.ldap.model.entry.BinaryValue; +import org.apache.directory.api.ldap.model.entry.DefaultAttribute; import org.apache.directory.api.ldap.model.entry.Entry; import org.apache.directory.api.ldap.model.entry.Value; import org.apache.directory.api.ldap.model.exception.LdapException; @@ -37,17 +38,25 @@ import org.apache.directory.api.ldap.mod import org.apache.directory.api.ldap.model.filter.FilterParser; import org.apache.directory.api.ldap.model.filter.FilterVisitor; import org.apache.directory.api.ldap.model.filter.SimpleNode; +import org.apache.directory.api.ldap.model.message.ModifyRequest; import org.apache.directory.api.ldap.model.message.SearchScope; +import org.apache.directory.api.ldap.model.schema.AttributeType; +import org.apache.directory.api.ldap.model.schema.SchemaManager; import org.apache.directory.api.util.Strings; import org.apache.directory.scim.MultiValAttribute; import org.apache.directory.scim.RequestContext; import org.apache.directory.scim.SimpleAttribute; import org.apache.directory.scim.SimpleAttributeGroup; import org.apache.directory.scim.ldap.LdapResourceProvider; +import org.apache.directory.scim.ldap.schema.ResourceSchema; import org.apache.directory.scim.schema.BaseType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + /** * TODO MembersAttributeHandler. @@ -63,14 +72,8 @@ public class MembersAttributeHandler ext @Override public void read( BaseType bt, Object srcResource, RequestContext ctx ) { - if ( !bt.getName().equals( "members" ) ) - { - LOG.warn( - "MembersAttributeHandler can only be used on members multivalue attribute, invalid attribute name {}", - bt.getName() ); - return; - } - + checkHandler( bt, "members", this ); + Entry groupEntry = ( Entry ) srcResource; Attribute memberAt = groupEntry.get( SchemaConstants.UNIQUE_MEMBER_AT ); @@ -106,6 +109,163 @@ public class MembersAttributeHandler ext } + @Override + public void write( BaseType atType, JsonElement jsonData, Object targetEntry, RequestContext ctx ) throws Exception + { + checkHandler( atType, "members", this ); + + LdapResourceProvider provider = ( LdapResourceProvider ) ctx.getProviderService(); + + SchemaManager ldapSchema = provider.getLdapSchema(); + Entry entry = ( Entry ) targetEntry; + + AttributeType memberType = getMemberType( ldapSchema, entry ); + + JsonArray members = ( JsonArray ) jsonData; + + for( JsonElement je : members ) + { + JsonObject jo = ( JsonObject ) je; + + String dn = getMemberDn( jo, provider ); + + if( dn == null ) + { + continue; + } + + Attribute ldapAt = entry.get( memberType ); + + if( ldapAt == null ) + { + ldapAt = new DefaultAttribute( memberType ); + ldapAt.add( dn ); + entry.add( ldapAt ); + } + else + { + ldapAt.add( dn ); + } + } + } + + + @Override + public void patch( BaseType atType, JsonElement jsonData, Object existingEntry, RequestContext ctx, Object patchCtx ) + throws Exception + { + checkHandler( atType, "members", this ); + + LdapResourceProvider provider = ( LdapResourceProvider ) ctx.getProviderService(); + + SchemaManager ldapSchema = provider.getLdapSchema(); + + Entry entry = ( Entry ) existingEntry; + + AttributeType memberType = getMemberType( ldapSchema, entry ); + + ModifyRequest modReq = ( ModifyRequest ) patchCtx; + + JsonArray members = ( JsonArray ) jsonData; + + for( JsonElement je : members ) + { + JsonObject jo = ( JsonObject ) je; + + String dn = getMemberDn( jo, provider ); + + if( dn == null ) + { + continue; + } + + boolean delete = false; + + JsonElement atOperation = jo.get( "operation" ); + if( atOperation != null ) + { + if( atOperation.getAsString().equalsIgnoreCase( "delete" ) ) + { + delete = true; + } + } + + if( delete ) + { + modReq.remove( memberType.getName(), dn ); + } + else if ( !entry.contains( memberType, dn ) ) + { + modReq.add( memberType.getName(), dn ); + } + } + } + + + @Override + public void deleteAttribute( BaseType atType, Object targetEntry, RequestContext ctx, Object patchCtx ) + throws Exception + { + checkHandler( atType, "members", this ); + + LdapResourceProvider provider = ( LdapResourceProvider ) ctx.getProviderService(); + + SchemaManager ldapSchema = provider.getLdapSchema(); + + Entry entry = ( Entry ) targetEntry; + + AttributeType memberType = getMemberType( ldapSchema, entry ); + + ModifyRequest modReq = ( ModifyRequest ) patchCtx; + + modReq.remove( entry.get( memberType ) ); + // add a dummy member, cause groupOfNames and groupOfUniqueNames OC need atleast one member attribute + modReq.add( memberType.getName(), "uid=dummyUser,ou=system" ); + } + + + private String getMemberDn( JsonObject jo, LdapResourceProvider provider ) + { + String resId = jo.get( "value" ).getAsString(); + String resRef = jo.get( "$ref" ).getAsString(); + + ResourceSchema resSchema = provider.getUserSchema(); + + if( resRef.endsWith( "/Groups/" + resId ) ) + { + resSchema = provider.getGroupSchema(); + } + + Entry resEntry = provider.fetchEntryById( resId, resSchema ); + + if( resEntry == null ) + { + LOG.debug( "No resource found with the member ID {} with reference {}", resId, resRef ); + return null; + } + + return resEntry.getDn().getName(); + } + + + private AttributeType getMemberType( SchemaManager ldapSchema, Entry entry ) + { + AttributeType ocType = ldapSchema.getAttributeType( SchemaConstants.OBJECT_CLASS_AT ); + + AttributeType memberType = null; + + if( entry.contains( ocType, SchemaConstants.GROUP_OF_NAMES_OC ) ) + { + memberType = ldapSchema.getAttributeType( SchemaConstants.MEMBER_AT ); + } + else if( entry.contains( ocType, SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC ) ) + { + memberType = ldapSchema.getAttributeType( SchemaConstants.UNIQUE_MEMBER_AT ); + } + + return memberType; + } + private SimpleAttributeGroup getMemberDetails( String dn, RequestContext ctx ) { LdapResourceProvider provider = ( LdapResourceProvider ) ctx.getProviderService();