| opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroup.java | ●●●●● patch | view | raw | blame | history | |
| opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm | ●●●●● patch | view | raw | blame | history | |
| opendj-sdk/opendj3/src/main/docbkx/dev-guide/chap-writing.xml | ●●●●● patch | view | raw | blame | history | |
| opendj-sdk/opendj3/src/site/resources/big-group.ldif | ●●●●● patch | view | raw | blame | history |
opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroup.java
New file @@ -0,0 +1,187 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright 2012 ForgeRock AS * */ package org.forgerock.opendj.examples; import java.util.Collection; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.ErrorResultException; import org.forgerock.opendj.ldap.LDAPConnectionFactory; import org.forgerock.opendj.ldap.ModificationType; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.RootDSE; import org.forgerock.opendj.ldap.controls.PermissiveModifyRequestControl; import org.forgerock.opendj.ldap.requests.CompareRequest; import org.forgerock.opendj.ldap.requests.ModifyRequest; import org.forgerock.opendj.ldap.requests.Requests; import org.forgerock.opendj.ldap.responses.CompareResult; /** * This command-line client demonstrates adding and removing a member from a * (potentially large) static group. * * The client takes as arguments the host and port of the directory server, the * group DN, the member DN, and whether to "add" or "del" the specified member * from the group. The client uses the Permissive Modify control if it is * available to avoid having to check whether the member belongs to the group or * not. * * This client expects a group that is a <code>groupOfNames</code> such as: * * <pre> * dn: cn=My Static Group,ou=Groups,dc=example,dc=com * cn: My Static Group * objectClass: groupOfNames * objectClass: top * ou: Groups * member: uid=ahunter,ou=People,dc=example,dc=com * member: uid=bjensen,ou=People,dc=example,dc=com * member: uid=tmorris,ou=People,dc=example,dc=com * </pre> * * This client connects as <code>cn=Directory Manager</code> with password * <code>password</code>. Not a best practice; in real code use application * specific credentials to connect, and ensure that your application has access * to use the Permissive Modify control if your directory server supports it. */ public final class UpdateGroup { /** * Connect to the directory server to update the group. * * @param args * The command line arguments: host, port, group-dn, member-dn, * {add|del} */ public static void main(String[] args) { if (args.length != 5) { printUsage(); } final String host = args[0]; final int port = Integer.parseInt(args[1]); final String groupDN = args[2]; final String memberDN = args[3]; final ModificationType modType = getModificationType(args[4]); final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port); Connection connection = null; try { connection = factory.getConnection(); Collection<String> controls = RootDSE.readRootDSE(connection).getSupportedControls(); final String user = "cn=Directory Manager"; final char[] password = "password".toCharArray(); connection.bind(user, password); if (controls.contains(PermissiveModifyRequestControl.OID)) { final ModifyRequest request = Requests.newModifyRequest(groupDN) .addControl(PermissiveModifyRequestControl.newControl(true)) .addModification(modType, "member", memberDN); connection.modify(request); } else { System.out.println("Checking whether the entry with DN " + memberDN + " belongs to the group with DN " + groupDN + "..."); final CompareRequest request = Requests.newCompareRequest(groupDN, "member", memberDN); CompareResult result = connection.compare(request); if (modType == ModificationType.ADD) { if (result.getResultCode() == ResultCode.COMPARE_FALSE) { System.out.println("Member does not yet belong to group." + " Adding it..."); final ModifyRequest addMember = Requests.newModifyRequest(groupDN) .addModification(modType, "member", memberDN); connection.modify(addMember); } } if (modType == ModificationType.DELETE) { if (result.getResultCode() == ResultCode.COMPARE_TRUE) { System.out.println("Member belongs to group." + " Removing it..."); final ModifyRequest delMember = Requests.newModifyRequest(groupDN) .addModification(modType, "member", memberDN); connection.modify(delMember); } } } String op = (modType == ModificationType.ADD) ? "added to" : "deleted from"; System.out.println("The entry with DN " + memberDN + " has been " + op + " the group with DN " + groupDN + "."); } catch (final ErrorResultException e) { System.err.println(e.getMessage()); System.exit(e.getResult().getResultCode().intValue()); return; } finally { if (connection != null) { connection.close(); } } } /** * Return the modification type for the update operation. * @param operation Operation specified as an argument (add or del). */ private static ModificationType getModificationType(String operation) { if (!(operation.equalsIgnoreCase("add") || operation.equalsIgnoreCase("del"))) { printUsage(); } return (operation.equalsIgnoreCase("add")) ? ModificationType.ADD : ModificationType.DELETE; } /** * Print usage then exit. */ private static void printUsage() { System.err.println("Usage: host port group-dn member-dn {add|del}"); System.err.println("For example: localhost 1389 " + "cn=Static,ou=Groups,dc=example,dc=com " + "uid=user.5150,ou=People,dc=example,dc=com " + "del"); System.exit(1); } /** * Constructor not used. */ private UpdateGroup() { // Not used. } } opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm
@@ -98,6 +98,10 @@ <a href="xref/org/forgerock/opendj/examples/RewriterProxy.html">Rewrite proxy</a> - illustrates how to rewrite DNs and attribute names in a proxy layer </li> <li> <a href="xref/org/forgerock/opendj/examples/UpdateGroup.html">Update group</a> - illustrates how to add or remove a member from a static group </li> </ul> </section> <section name="Get the OpenDJ LDAP SDK Examples"> opendj-sdk/opendj3/src/main/docbkx/dev-guide/chap-writing.xml
@@ -284,4 +284,187 @@ xlink:role="http://docbook.org/xlink/role/olink"><citetitle>Subtree Delete Request Control</citetitle></link>.</para> </section> <section xml:id="updating-static-groups"> <title>Updating Static Groups</title> <indexterm> <primary>Modifications</primary> <secondary>Static groups</secondary> </indexterm> <para>Static groups enumerate user entries. Static groups can grow large. For an example, see the group entry at the end of <link xlink:show="new" xlink:href="http://opendj.forgerock.org/big-group.ldif">big-group.ldif</link>:</para> <programlisting language="ldif">dn: cn=Static,ou=Groups,dc=example,dc=com objectClass: top objectClass: groupofnames cn: Static member: uid=user.0,ou=People,dc=example,dc=com member: uid=user.1,ou=People,dc=example,dc=com member: uid=user.2,ou=People,dc=example,dc=com ... member: uid=user.10000,ou=People,dc=example,dc=com</programlisting> <para>To update a static group, you either add members or remove members. For sample code, see <link xlink:href="http://opendj.forgerock.org/opendj-ldap-sdk-examples/xref/org/forgerock/opendj/examples/UpdateGroup.html" xlink:show="new">UpdateGroup.java</link>, one of the <link xlink:href="http://opendj.forgerock.org/opendj-ldap-sdk-examples/" xlink:show="new">OpenDJ LDAP SDK examples</link>.</para> <para>The <literal>UpdateGroup</literal> example checks that the directory server supports the Permissive Modify control. With directory servers such as OpenDJ that support the LDAP Permissive Modify control, you can use the control to avoid having to determine whether a given member is already in the group before performing the operation. Instead you can simply request an add or a delete modification for the member.</para> <example xml:id="update-group-with-permissive-modify"><?dbfo keep-together="auto"?> <title>Updating a Group With Permissive Modify</title> <programlisting language="java" >final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port); Connection connection = null; try { connection = factory.getConnection(); Collection<String> controls = RootDSE.readRootDSE(connection).getSupportedControls(); final String user = "cn=Directory Manager"; final char[] password = "password".toCharArray(); connection.bind(user, password); if (controls.contains(PermissiveModifyRequestControl.OID)) { final ModifyRequest request = Requests.newModifyRequest(groupDN) .addControl(PermissiveModifyRequestControl.newControl(true)) .addModification(modType, "member", memberDN); connection.modify(request); } else { /* ... */ } String op = (modType == ModificationType.ADD) ? "added to" : "deleted from"; System.out.println("The entry with DN " + memberDN + " has been " + op + " the group with DN " + groupDN + "."); } catch (final ErrorResultException e) { System.err.println(e.getMessage()); System.exit(e.getResult().getResultCode().intValue()); return; } finally { if (connection != null) { connection.close(); } }</programlisting> </example> <para>If the directory server does not support the Permissive Modify control, then the example checks whether the member is present in the group by using an LDAP compare operation. If a member to be added does not yet belong to the group, the example requests an add modification. If a member to be deleted does belong to the group, the example requests a delete modification.</para> <example xml:id="update-group-with-compare-and-modify"><?dbfo keep-together="auto"?> <title>Updating a Group With Compare & Modify</title> <programlisting language="java" >final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port); Connection connection = null; try { connection = factory.getConnection(); Collection<String> controls = RootDSE.readRootDSE(connection).getSupportedControls(); final String user = "cn=Directory Manager"; final char[] password = "password".toCharArray(); connection.bind(user, password); if (controls.contains(PermissiveModifyRequestControl.OID)) { /* ... */ } else { System.out.println("Checking whether the entry with DN " + memberDN + " belongs to the group with DN " + groupDN + "..."); final CompareRequest request = Requests.newCompareRequest(groupDN, "member", memberDN); CompareResult result = connection.compare(request); if (modType == ModificationType.ADD) { if (result.getResultCode() == ResultCode.COMPARE_FALSE) { System.out.println("Member does not yet belong to group." + " Adding it..."); final ModifyRequest addMember = Requests.newModifyRequest(groupDN) .addModification(modType, "member", memberDN); connection.modify(addMember); } } if (modType == ModificationType.DELETE) { if (result.getResultCode() == ResultCode.COMPARE_TRUE) { System.out.println("Member belongs to group." + " Removing it..."); final ModifyRequest delMember = Requests.newModifyRequest(groupDN) .addModification(modType, "member", memberDN); connection.modify(delMember); } } } String op = (modType == ModificationType.ADD) ? "added to" : "deleted from"; System.out.println("The entry with DN " + memberDN + " has been " + op + " the group with DN " + groupDN + "."); } catch (final ErrorResultException e) { System.err.println(e.getMessage()); System.exit(e.getResult().getResultCode().intValue()); return; } finally { if (connection != null) { connection.close(); } }</programlisting> <para>You can change multiple member values with a single modification. The final argument of this form of the <literal>ModifyRequest.addModification()</literal> method takes a series of one or more values. So if you have multiple group members to add or delete, you can loop over your list to perform compare individual compare requests, then construct a single modify request to add or delete the group members. In other words, if you have three members to add, you can list the three member DNs as arguments of <literal>addModification</literal>.</para> <programlisting language="java" >String member1 = "uid=user1,ou=people,dc=example,dc=com"; String member2 = "uid=user1,ou=people,dc=example,dc=com"; String member3 = "uid=user1,ou=people,dc=example,dc=com"; final ModifyRequest addMember = Requests.newModifyRequest(groupDN) .addModification(modType, "member", member1, member2, member3); connection.modify(addMember);</programlisting> </example> <para>To try the example, download and import <filename>big-group.ldif</filename> into your directory server, and then run the sample. For example, if OpenDJ is set up to with directory manager as <literal>cn=Directory Manager</literal>, password <literal>password</literal> listening on <literal>localhost</literal> port <literal>1389</literal>, and you run the example with arguments <literal>localhost 1389 cn=Static,ou=Groups,dc=example,dc=com uid=user.5150,ou=People,dc=example,dc=com del</literal>, the resulting output is <literal>The entry with DN uid=user.5150,ou=People,dc=example,dc=com has been deleted from the group with DN cn=Static,ou=Groups,dc=example,dc=com.</literal>.</para> </section> </chapter> opendj-sdk/opendj3/src/site/resources/big-group.ldif
New file Diff too large