You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2020/12/01 08:18:57 UTC
[directory-server] 01/01: Created a branch for the member-of
interceptor implementation
This is an automated email from the ASF dual-hosted git repository.
elecharny pushed a commit to branch member
in repository https://gitbox.apache.org/repos/asf/directory-server.git
commit 9c1782bae4aa34e8e70046d0e1f13e6ba4da9849
Author: emmanuel lecharny <em...@busit.com>
AuthorDate: Tue Dec 1 09:17:45 2020 +0100
Created a branch for the member-of interceptor implementation
---
interceptors/members/pom.xml | 194 +++++++++++++++++++++
.../server/core/memberof/MemberOfInterceptor.java | 138 +++++++++++++++
interceptors/pom.xml | 1 +
.../server/operations/search/SearchMembersIT.java | 129 ++++++++++++++
4 files changed, 462 insertions(+)
diff --git a/interceptors/members/pom.xml b/interceptors/members/pom.xml
new file mode 100644
index 0000000..c0639e6
--- /dev/null
+++ b/interceptors/members/pom.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.directory.server</groupId>
+ <artifactId>apacheds-interceptors</artifactId>
+ <version>2.0.0.AM26-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>apacheds-interceptors-members</artifactId>
+ <name>ApacheDS memberOf Virtual Attribute Interceptor</name>
+ <packaging>bundle</packaging>
+
+ <description>
+ Virtual Attribute interceptor to add memberOf attributes to results
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.directory.junit</groupId>
+ <artifactId>junit-addons</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-i18n</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-core-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-core-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-collections4</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-client-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-i18n</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-codec-standalone</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-codec-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-extras-aci</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-extras-trigger</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-extras-util</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-model</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-schema-data</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-ldap-extras-codec</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <workingDirectory>${basedir}/target/server-work</workingDirectory>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>META-INF/MANIFEST.MF</manifestFile>
+ <addMavenDescriptor>false</addMavenDescriptor>
+ </archive>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <inherited>true</inherited>
+ <extensions>true</extensions>
+ <configuration>
+ <manifestLocation>META-INF</manifestLocation>
+ <instructions>
+ <Bundle-SymbolicName>${project.groupId}.interceptors.logger</Bundle-SymbolicName>
+ <Export-Package>
+ org.apache.directory.server.core.logger;version=${project.version}
+ </Export-Package>
+ <Import-Package>
+ org.apache.directory.api.ldap.model.constants;version=${org.apache.directory.api.version},
+ org.apache.directory.api.ldap.model.entry;version=${org.apache.directory.api.version},
+ org.apache.directory.api.ldap.model.exception;version=${org.apache.directory.api.version},
+ org.apache.directory.server.core.api;version=${project.version},
+ org.apache.directory.server.core.api.filtering;version=${project.version},
+ org.apache.directory.server.core.api.interceptor;version=${project.version},
+ org.apache.directory.server.core.api.interceptor.context;version=${project.version},
+ org.slf4j;version=${slf4j.api.bundleversion}
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <excludes>
+ <exclude>**/*.gif</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/interceptors/members/src/main/java/org/apache/directory/server/core/memberof/MemberOfInterceptor.java b/interceptors/members/src/main/java/org/apache/directory/server/core/memberof/MemberOfInterceptor.java
new file mode 100644
index 0000000..c116d4c
--- /dev/null
+++ b/interceptors/members/src/main/java/org/apache/directory/server/core/memberof/MemberOfInterceptor.java
@@ -0,0 +1,138 @@
+/*
+ * 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.server.core.memberof;
+
+
+import org.apache.directory.api.ldap.model.constants.Loggers;
+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.exception.LdapOperationException;
+import org.apache.directory.api.ldap.model.exception.LdapOtherException;
+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.AliasDerefMode;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.server.core.api.CoreSession;
+import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.api.interceptor.BaseInterceptor;
+import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.api.partition.Partition;
+import org.apache.directory.server.core.api.partition.PartitionNexus;
+import org.apache.directory.server.core.api.partition.PartitionTxn;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * An interceptor for adding virtual memberOf attributes to {code}Entry{code}s.
+ *
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MemberOfInterceptor extends BaseInterceptor
+{
+ /** A aggregating logger */
+ private static final Logger OPERATION_STATS = LoggerFactory.getLogger( Loggers.OPERATION_STAT.getName() );
+
+ /** An operation logger */
+ private static final Logger OPERATION_TIME = LoggerFactory.getLogger( Loggers.OPERATION_TIME.getName() );
+
+ /**
+ *
+ * Creates a new instance of MemberOfInterceptor.
+ *
+ * @param name This interceptor's getName()
+ */
+ public MemberOfInterceptor( String name )
+ {
+ super( name );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Entry lookup( LookupOperationContext lookupContext ) throws LdapException
+ {
+ Entry entry = next( lookupContext );
+
+ CoreSession adminSession = directoryService.getAdminSession();
+ Value dnValue = new Value( directoryService.getAtProvider().getMember(), entry.getDn().getNormName() );
+ PartitionNexus nexus = directoryService.getPartitionNexus();
+
+ // either
+ ExprNode filter = new PresenceNode( directoryService.getAtProvider().getAdministrativeRole() );
+ // or
+// ExprNode filter = new PresenceNode( dnValue );
+
+ SearchOperationContext searchOperationContext = new SearchOperationContext( adminSession, Dn.ROOT_DSE, SearchScope.SUBTREE, filter, "1.1" );
+ Partition partition = nexus.getPartition( Dn.ROOT_DSE );
+ searchOperationContext.setAliasDerefMode( AliasDerefMode.NEVER_DEREF_ALIASES );
+ searchOperationContext.setPartition( partition );
+
+ try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
+ {
+ searchOperationContext.setTransaction( partitionTxn );
+ EntryFilteringCursor results = nexus.search( searchOperationContext );
+
+ try
+ {
+ String memberOf = "memberOf";
+ while ( results.next() )
+ {
+ Entry memberEntry = results.get();
+
+ entry = entry.add( memberOf, memberEntry.getDn().getName() );
+ // Note: not sure f I should:
+ // if has memberOf
+ // add to memberOf
+ // else
+ // create memberOf with value of
+ }
+
+ results.close();
+ }
+ catch ( Exception e )
+ {
+ throw new LdapOperationException( e.getMessage(), e );
+ }
+ }
+ catch ( Exception e )
+ {
+ throw new LdapOtherException( e.getMessage(), e );
+ }
+
+ return entry;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException
+ {
+ EntryFilteringCursor cursor = next( searchContext );
+
+ return cursor;
+ }
+}
diff --git a/interceptors/pom.xml b/interceptors/pom.xml
index 3532d91..ecf2c30 100644
--- a/interceptors/pom.xml
+++ b/interceptors/pom.xml
@@ -48,6 +48,7 @@
<module>operational</module>
<module>collective</module>
<module>logger</module>
+ <module>members</module>
<module>exception</module>
<module>hash</module>
<module>schema</module>
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchMembersIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchMembersIT.java
new file mode 100644
index 0000000..87f6f6b
--- /dev/null
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchMembersIT.java
@@ -0,0 +1,129 @@
+/*
+ * 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.server.operations.search;
+
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifs;
+import org.apache.directory.server.core.annotations.ContextEntry;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.annotations.CreateIndex;
+import org.apache.directory.server.core.annotations.CreatePartition;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.apache.directory.server.integ.ServerIntegrationUtils.getAdminConnection;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Testcase with different modify operations on a person entry. Each includes a
+ * single add op only. Created to demonstrate DIREVE-241 ("Adding an already
+ * existing attribute value with a modify operation does not cause an error.").
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(FrameworkRunner.class)
+@CreateDS(partitions =
+{
+ @CreatePartition(
+ name = "example",
+ suffix = "dc=example,dc=com",
+ indexes =
+ {
+ @CreateIndex(attribute = "objectClass"),
+ @CreateIndex(attribute = "dc"),
+ @CreateIndex(attribute = "ou"),
+ @CreateIndex(attribute = "uniqueMember")
+ },
+ contextEntry = @ContextEntry(entryLdif =
+ "dn: dc=example,dc=com\n" +
+ "objectClass: domain\n" +
+ "dc: example"))
+})
+@CreateLdapServer(transports =
+ { @CreateTransport(protocol = "LDAP") })
+
+public class SearchMembersIT extends AbstractLdapTestUnit
+{
+ /**
+ * Test for DIRSERVER-1844
+ */
+ @ApplyLdifs({
+ "dn: ou=users,dc=example,dc=com",
+ "ObjectClass: top",
+ "ObjectClass: organizationalUnit",
+ "ou: users",
+
+ "dn: cn=User1,ou=users,dc=example,dc=com",
+ "objectClass: person",
+ "objectClass: top",
+ "cn: User1",
+ "sn: user 1",
+ "description: User1",
+
+ "dn: ou=groups,dc=example,dc=com",
+ "ObjectClass: top",
+ "ObjectClass: organizationalUnit",
+ "ou: groups",
+
+ "dn: cn=Group1,ou=groups,dc=example,dc=com",
+ "objectClass: groupOfUniqueNames",
+ "objectClass: top",
+ "cn: Group1",
+ "uniqueMember: cn=user1,ou=users,dc=example,dc=com",
+ "description: Group"
+ })
+
+ @Test
+ public void testSearchMemberOf() throws Exception
+ {
+ LdapConnection connection = getAdminConnection( getLdapServer() );
+ SearchRequest req = new SearchRequestImpl();
+ req.setBase( new Dn( "dc=example,dc=com" ) );
+ req.setFilter( "(&(objectClass=person)(memberOf=CN=Group1,ou=groups,DC=example,DC=com))");
+ req.setScope( SearchScope.SUBTREE );
+
+ SearchCursor cursor = connection.search( req );
+ int count = 0;
+
+ while( cursor.next() )
+ {
+ Entry result = cursor.getEntry();
+ count++;
+ assertTrue(result.contains("memberOf" , "CN=Group1,ou=groups,DC=example,DC=com"));
+ }
+
+ assertEquals( 1, count );
+
+ cursor.close();
+
+ connection.close();
+ }
+}