[Bps-public-commit] RT-Extension-LDAPImport branch, 0.32.03/documentation-updates, created. 0.32_03-2-gf5b2b5c

Jim Brandt jbrandt at bestpractical.com
Fri Apr 6 15:56:09 EDT 2012


The branch, 0.32.03/documentation-updates has been created
        at  f5b2b5c7d0a02577f36782bebfdc5ff2082f9951 (commit)

- Log -----------------------------------------------------------------
commit 21e43a96f182106643ca743b359453a5c1648a1f
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Apr 6 11:32:27 2012 -0400

    Documentation updates.

diff --git a/README b/README
index da27925..6f3fc6f 100644
--- a/README
+++ b/README
@@ -7,134 +7,30 @@ How to install:
 1. perl Makefile.PL
 2. make
 3. make install (may need root permissions)
-4. Edit your /opt/rt3/etc/RT_SiteConfig.pm 
+4. Edit your /opt/rt4/etc/RT_SiteConfig.pm 
     Set(@Plugins, qw(RT::Extension::LDAPImport));
     or add RT::Extension::LDAPImport to your existing @Plugins line
 5. Clear your mason cache
-     rm -rf /opt/rt3/var/mason_data/obj
+     rm -rf /opt/rt4/var/mason_data/obj
 6. Restart your webserver
 
-
-This will install an rtldapimport script and the RT::Extension::LDAPImport
+This will install an rtldapimport script in
+/opt/rt4/local/plugins/RT-Extension-LDAPImport/bin
+and install the RT::Extension::LDAPImport
 module.
 
-CONFIGURATION
-
-There are several config variables which must be set in
-your RT_SiteConfig file
-
-Hostname or ldap(s):// uri
- Set($LDAPHost,'our.ldap.host');
-
-Your LDAP username or DN
-Leaving this unset will cause us to use an anonymous bind
- Set($LDAPUser, 'uid=foo,ou=users,dc=example,dc=com');
-
-Your LDAP Password
- Set($LDAPPassword, 'ldap pass');
-
-Where to search
- Set($LDAPBase, 'ou=People,o=Our Place');
-
-The search filter to apply (in this case, find all the bobs)
- Set($LDAPFilter, '(&(cn = bob*))');
-
-A mapping of 
-Attribute in RT => Attribute in LDAP
-(this has changed since version 1, which was the other way around)
- Set($LDAPMapping, {Name         => 'uid',
-                    EmailAddress => 'mail',
-                    RealName     => 'cn',
-                    WorkPhone    => 'telephoneNumber',
-                    Organization => 'departmentName'});
-
-The LDAP attributes can also be an arrayref of LDAP fields
-WorkPhone => [qw/CompanyPhone Extension/] 
-which will be concatenated together with a space
-
-The LDAP attribute can also be a subroutine reference
-that returns either an arrayref or a list of attributes
-
-By default users are created as Unprivileged, but you can change this by
-setting $LDAPCreatePrivileged to 1.
-
-For more information on these see the import_users documentation
-in RT::Extension::LDAPImport
-
-The Group new users belong to (optional)
-All new users will belong to the 'Imported from LDAP' group
-You can change the name of this group using the $LDAPGroupName
-variable
- Set($LDAPGroupName,'Imported Users');
-If you would like to prevent users from being added to this
-group, you can set this to true:
- Set($LDAPSkipAutogeneratedGroup, 1);
-
-Should we update existing users (optional)
-By default, existing users are skipped.  If you
-turn on LDAPUpdateUsers, we will clobber existing
-data with data from LDAP.
- Set($LDAPUpdateUsers,1);
-
-Should we import new users or just update existing ones?
-By default, we create users who don't exist in RT but do
-match your LDAP filter and obey $LDAPUpdateUsers for existing
-users.  This setting overrides $LDAPUpdateUsers but won't create
-users who are found in LDAP but not in RT.
- Set($LDAPUpdateOnly,1);
-
-Where to search for groups to import
- Set($LDAPGroupBase, 'ou=Groups,o=Our Place');
-
-The search filter to apply (in this case, find all the bobs)
- Set($LDAPGroupFilter, '(&(cn = bob*))');
-
-A mapping of
-Attribute in RT => Attribute in LDAP
-(this has changed since version 1, which was the other way around)
- Set($LDAPGroupMapping, {Name               => 'cn',
-                         Member_Attr        => 'member',
-                         Member_Attr_Value  => 'dn' });
-
-The mapping logic is the same as the LDAPMapping.
-There are two important special-case keys, Member_Attr and Member_Attr_Value.
-Member_Attr tells the importer which attribute contains group members.
-Member_Attr_Value, which defaults to 'dn', specifies what kind of user values
-are in Member_Attr.  OpenLDAP, for example, often stores uid instead of dn in
-member.
-
-If you do not specify a Description attribute, it will be filled with
-'Imported from LDAP'
-
-Your LDAP server may have result size limits.  If it does, you should set
-$LDAPSizeLimit appropriately:
- Set($LDAPSizeLimit, 1000);
-
-RUNNING THE IMPORT
-
-If RT is not installed in /opt/rt3, you will need to change the 
-use lib '/opt/rt3/lib';
-line in rtldapimport to point to the directory where RT.pm can be found
-
-executing rtldapimport will run a test that connects to your LDAP server
-and prints out a list of the users found.  To see more about these users,
-include the --debug flag.
-
-executing rtldapimport with the --import flag will cause it to import
-users into your RT database.  It is recommended that you make a database
-backup before doing this.
+RUNNING THE IMPORTER
 
-rtldapimport can be run with a --debug flag that will make it 
-print a lot of information to the screen.
+Set the module documentation for details on
+configuration and running the importer.
 
-That debug information is also sent to the RT log with the debug level.
-Errors are logged to the screen and to the RT log 
+>perldoc RT::Extension::LDAPImmport
 
 DEPENDENCIES
 
   Class::Accessor
   Net::LDAP
-  RT: 3.6.x
+  RT: 3.8.x
 
 
 COPYRIGHT AND LICENCE
diff --git a/lib/RT/Extension/LDAPImport.pm b/lib/RT/Extension/LDAPImport.pm
index 411f138..c481021 100644
--- a/lib/RT/Extension/LDAPImport.pm
+++ b/lib/RT/Extension/LDAPImport.pm
@@ -18,10 +18,212 @@ use Data::Dumper;
 
 RT::Extension::LDAPImport - Import Users from an LDAP store
 
-
 =head1 SYNOPSIS
 
-    use RT::Extension::LDAPImport;
+    # In RT_SiteConfig.pm
+
+    Set(LDAPHost,'my.ldap.host')
+    Set(LDAPUSER,'me');
+    Set(LDAPPassword,'mypass');
+    Set($LDAPFilter, '(&(cn = users))');
+    Set($LDAPMapping, {Name         => 'uid', # required
+                       EmailAddress => 'mail',
+                       RealName     => 'cn',
+                       WorkPhone    => 'telephoneNumber',
+                       Organization => 'departmentName'});
+
+    # If you want to sync Groups RT <-> LDAP
+
+    Set($LDAPGroupBase, 'ou=Groups,o=Our Place');
+    Set($LDAPGroupFilter, '(&(cn = Groups))');
+    Set($LDAPGroupMapping, {Name               => 'cn',
+                            Member_Attr        => 'member',
+                            Member_Attr_Value  => 'dn' });}))
+
+    # Run a test import
+    /opt/rt4/local/plugins/RT-Extension-LDAPImport/bin/rtldapimport \
+    --debug > ldapimport.debug
+
+    # Run for real, possibly put in cron
+    /opt/rt4/local/plugins/RT-Extension-LDAPImport/bin/rtldapimport \
+    --import
+
+=head1 CONFIGURATION
+
+All of the configuration for the importer goes
+your RT_SiteConfig.pm file. Some of these values pass through
+to L<Net::LDAP> so you can check there for valid values and more
+advanced options.
+
+=over
+
+=item Set($LDAPHost,'our.ldap.host');
+
+Hostname or ldap(s):// uri:
+
+=item Set($LDAPUser, 'uid=foo,ou=users,dc=example,dc=com');
+
+Your LDAP username or DN. If unset, we'll attempt an anonymous bind.
+
+=item Set($LDAPPassword, 'ldap pass');
+
+Your LDAP password.
+
+=item Set($LDAPBase, 'ou=People,o=Our Place');
+
+Base object to search from.
+
+=item Set($LDAPFilter, '(&(cn = users))');
+
+The LDAP search filter to apply (in this case, find all the users).
+
+=item Set($LDAPMapping...
+
+    Set($LDAPMapping, {Name         => 'uid',
+                       EmailAddress => 'mail',
+                       RealName     => 'cn',
+                       WorkPhone    => 'telephoneNumber',
+                       Organization => 'departmentName'});
+
+This provides the mapping of attributes in RT to attribute in LDAP.
+Only Name is required for RT.
+
+The LDAP attributes can also be an arrayref of LDAP fields
+
+    WorkPhone => [qw/CompanyPhone Extension/]
+
+which will be concatenated together with a space.
+
+The LDAP attribute can also be a subroutine reference
+that returns either an arrayref or a list of attributes.
+
+=item Set($LDAPCreatePrivileged, 1);
+
+By default users are created as Unprivileged, but you can change this by
+setting $LDAPCreatePrivileged to 1.
+
+=item Set($LDAPGroupName,'My Imported Users');
+
+The RT Group new users belong to. By default, all new users will belong
+to the 'Imported from LDAP' group.
+
+=item Set($LDAPSkipAutogeneratedGroup, 1);
+
+Set this to true to prevent users from being automatically
+added to this group.
+
+=item Set($LDAPUpdateUsers, 1);
+
+By default, existing users are skipped.  If you
+turn on LDAPUpdateUsers, we will clobber existing
+data with data from LDAP.
+
+=item Set($LDAPUpdateOnly, 1);
+
+By default, we create users who don't exist in RT but do
+match your LDAP filter and obey $LDAPUpdateUsers for existing
+users.  This setting updates existing users, overriding
+$LDAPUpdateUsers, but won't create new
+users who are found in LDAP but not in RT.
+
+=item Set($LDAPGroupBase, 'ou=Groups,o=Our Place');
+
+Where to search for groups to import.
+
+=item Set($LDAPGroupFilter, '(&(cn = Groups))');
+
+The search filter to apply.
+
+=item Set($LDAPGroupMapping...
+
+    Set($LDAPGroupMapping, {Name               => 'cn',
+                            Member_Attr        => 'member',
+                            Member_Attr_Value  => 'dn' });
+
+A mapping of RT attributes to LDAP attributes to identify group members.
+Name will become the name of the group in RT, in this case pulling
+from the cn attribute on the LDAP group record returned.
+
+Member_Attr is the field in the LDAP group record the importer should
+look at for group members. These values (there may be multiple members)
+will then be compared to the RT user name, which came from the LDAP
+user record.
+
+Member_Attr_Value, which defaults to 'dn', specifies where on the LDAP
+user record the importer should look to compare the member value.
+A match between the member field on the group record and this
+identifier (dn or other LDAP field) on a user record means the
+user will be added to that group in RT.
+
+You can provide a Description key which will be added as the group
+description in RT. The default description is 'Imported from LDAP'.
+
+=item Set($LDAPSizeLimit, 1000);
+
+You can set this value if your LDAP server has result size limits.
+
+=back
+
+=head1 Mapping Groups Between RT and LDAP
+
+If you are using the importer, you likely want to manage access via
+LDAP by putting people in groups like 'DBAs' and 'IT Support', but
+also have groups for other non-RT related things. In this case, you
+won't want to create all of your LDAP groups in RT. To limit the groups
+that get mirrored, construct your $LDAPGroupFilter as an OR (|) with
+all of the RT groups you want to mirror from LDAP. For example:
+
+    Set($LDAPGroupBase, 'OU=Groups,OU=Company,DC=COM');
+    Set($LDAPGroupFilter, '(|(CN=DBAs)(CN=IT Support))');
+
+The importer will then import only the groups that match. In this case,
+import means:
+
+=over
+
+=item * Verifying the group is in AD;
+
+=item * Creating the group in RT if it doesn't exist;
+
+=item * Populating the group with the members identified in AD;
+
+=back
+
+The import script will also issue a warning if a user isn't found in RT,
+but this should only happen when testing. When running with --import on,
+users are created before groups are processed, so all users (group
+members) should exist unless there are inconsistencies in your LDAP configuration.
+
+=head1 Running the Import
+
+If RT is not installed in /opt/rt4, you will need to change the
+
+    use lib '/opt/rt4/lib';
+
+line in rtldapimport to point to the directory where RT.pm can be found.
+
+Executing rtldapimport will run a test that connects to your LDAP server
+and prints out a list of the users found. To see more about these users,
+and to see more general debug information, include the --debug flag.
+
+That debug information is also sent to the RT log with the debug level.
+Errors are logged to the screen and to the RT log.
+
+Executing rtldapimport with the --import flag will cause it to import
+users into your RT database. It is recommended that you make a database
+backup before doing this. If your filters aren't set properly this could
+create a lot of users or groups in your RT instance.
+
+=head1 RT Versions
+
+The importer works with RT 3.8 and newer including RT 4.
+
+It may work with RT 3.6.
+
+=head1 LDAP Filters
+
+The L<ldapsearch|http://www.openldap.org/software/man.cgi?query=ldapsearch&manpath=OpenLDAP+2.0-Release>
+utility in openldap can be very helpful while refining your filters.
 
 =head1 METHODS
 
@@ -937,9 +1139,8 @@ sub disconnect_ldap {
 
 =head3 screendebug
 
-We always log to the RT log file with level debug 
-
-This duplicates the messages to the screen
+We always log to the RT log file with level 'debug'. This duplicates
+the messages to the screen.
 
 =cut
 

commit f5b2b5c7d0a02577f36782bebfdc5ff2082f9951
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Apr 6 15:54:32 2012 -0400

    Added a feature to allow you to use a regex to match an LDAP member field. But upon further review, I don't think it would ever be needed unless someone's LDAP was really mis-configured. So this commit is for posterity only.

diff --git a/lib/RT/Extension/LDAPImport.pm b/lib/RT/Extension/LDAPImport.pm
index c481021..198a14f 100644
--- a/lib/RT/Extension/LDAPImport.pm
+++ b/lib/RT/Extension/LDAPImport.pm
@@ -138,7 +138,7 @@ The search filter to apply.
 
     Set($LDAPGroupMapping, {Name               => 'cn',
                             Member_Attr        => 'member',
-                            Member_Attr_Value  => 'dn' });
+                            Member_Attr_Value  => 'dn'});
 
 A mapping of RT attributes to LDAP attributes to identify group members.
 Name will become the name of the group in RT, in this case pulling
@@ -158,6 +158,21 @@ user will be added to that group in RT.
 You can provide a Description key which will be added as the group
 description in RT. The default description is 'Imported from LDAP'.
 
+If the LDAP group field you are mapping to doesn't have a
+simple username, you provide a regex to pull the name out
+with Member_Attr_Regex. The capture value in the regex will be
+used to find the username.
+
+    Set($LDAPGroupMapping, {Name               => 'cn',
+                            Member_Attr        => 'member',
+                            Member_Attr_Value  => 'dn'
+                            Member_Attr_Regex   => qr/^cn=(\w+)\,/,
+                           });
+
+The above would pull the name out of an entry something like
+
+    cn=somename,ou=company
+
 =item Set($LDAPSizeLimit, 1000);
 
 You can set this value if your LDAP server has result size limits.
@@ -1067,6 +1082,13 @@ sub _get_group_members_from_ldap {
     my $mapping = $RT::LDAPGroupMapping;
 
     my $members = $ldap_entry->get_value($mapping->{Member_Attr}, asref => 1);
+
+    if ( exists $mapping->{Member_Attr_Regex}
+	 and defined $mapping->{Member_Attr_Regex} ) {
+      @{$members} = map{ /$mapping->{Member_Attr_Regex}/ } @{$members};
+    }
+
+    return $members;
 }
 
 
diff --git a/t/group-import.t b/t/group-import.t
index 6d28e80..e15754b 100644
--- a/t/group-import.t
+++ b/t/group-import.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use lib 't/lib';
-use RT::Extension::LDAPImport::Test tests => 66;
+use RT::Extension::LDAPImport::Test tests => 74;
 eval { require Net::LDAP::Server::Test; 1; } or do {
     plan skip_all => 'Unable to test without Net::Server::LDAP::Test';
 };
@@ -99,6 +99,39 @@ RT->Config->Set('LDAPGroupMapping',
                    });
 import_group_members_ok( memberUid => 'uid' );
 
+# Test a regex on Member_Attr
+# This is for a case where the member attribute
+# isn't the simple member name.
+
+ at ldap_group_entries = ();
+{
+    my $groupname = "Test Group 5";
+    my $dn = "cn=$groupname,ou=groups,dc=bestpractical,dc=com";
+    my $entry = {
+        cn   =>  $groupname,
+        members => [ map { $_->{dn} } @ldap_user_entries[3,7,11] ],
+       # Make an entries that looks like cn=testuser12,ou=foo,dc=bestpractical
+        memberUid => [ map { 'cn=' . $_->{uid} . ',ou=foo,dc=bestpractical' }
+		       @ldap_user_entries[3,7,11] ],
+        objectClass => 'Test5',
+    };
+    $ldap->add( $dn, attr => [%$entry] );
+
+    # Fix entry for expected value after regex.
+    $entry->{memberUid} = [ map { $_->{uid} } @ldap_user_entries[3,7,11] ];
+    push @ldap_group_entries, $entry;
+}
+
+RT->Config->Set('LDAPGroupFilter','(objectClass=Test5)');
+RT->Config->Set('LDAPGroupMapping',
+                   {Name                => 'cn',
+                    Member_Attr         => 'memberUid',
+                    Member_Attr_Value   => 'uid',
+		    Member_Attr_Regex   => qr/^cn=(\w+)\,/,
+                   });
+
+import_group_members_ok( memberUid => 'uid' );
+
 sub import_group_members_ok {
     my $attr = shift;
     my $user_attr = shift;

-----------------------------------------------------------------------



More information about the Bps-public-commit mailing list