22 Jan 2009

So my double header post on getting this funky AD lookup control with Perl (post 1 & post 2) was actually prep work for getting to work in a product called RT (or Request Tracker from BestPractical) which is built on Perl. I have never worked with it before so I am slightly (read: exceptionally) ignorant of how to do this. Effectively I want a lookup to include AD users.

The First Option

The first thing I saw was this Include Page option when creating a field, which is described as

RT can include content from another web service when showing this custom field. Fill in this field with a URL. RT will replace __id__ and __CustomField__ with the record id and custom field value, respectively Some browsers may only load content from the same domain as your RT server.

image

Sounds perfect, turns out there is NO knowledge of how this works. I tried various forums and news groups, even emailing people who asked before about it… no answers are available! The documentation is USELESS!

The Second Option

Another option is once you have created a field a new option appears: Field values source:

image

So how do you actually use this without typing in the options yourself?

Custom Perl Module

Well in the /opt/rt3/lib/RT/CustomFieldValues is a file called Groups.pm which allows you to provide the names of the groups as a field source. So this is a possible solution, but first you need to create the module. The module has two methods:

SourceDescription - Which needs to return a string containing the name of what you are returning.

ExternalValues - Which needs to return an array of objects which contain the values. Those object must have a name property which is the name you want to show, and two optional properties description which is the… actually I dunno where it’s used (don’t think it is) and sortorder which you use to do the sorting. So taking the AD code previous the previous posts and combining it into the right format we end up with this code:

package RT::CustomFieldValues::AD;
 
#Start of user configurable settings
 
my $DomainController = "<SERVER>";
my $Username = "<USERNAME@DOMAIN>";
my $Password = "<PASSWORD>";
my $BaseOU = "<SEARCH OU>";
 
#End of user configurable settings
# ------------------- DO NOT CHANGE FROM HERE ---------------
#Start of system settings
my $Attributes = "sAMAccountName,sn,displayName";
my $Filter = "(objectCategory=User)" ;
#End of system settings
 
 
use strict;
use warnings;
use Net::LDAP;
use Net::LDAP::Control::Sort;
use HTML::Entities;
 
use base qw(RT::CustomFieldValues::External);
 
sub SourceDescription {
    return 'Active Directory Users';
}
 
sub ExternalValues {
    
    my @res;
    my $i = 0;
    my $ad = Net::LDAP->new($DomainController)
                or die "Could not connect!";
 
    $ad->bind($Username, password=>$Password, version=>3);
 
    my $sort = Net::LDAP::Control::Sort->new(order => "displayName");
 
    my $results = $ad->search(base=>$BaseOU, filter=>$Filter, attrs=>    $Attributes, control=>[$sort]);
    
    if ($results->count == 0)
    {
      die "No results returned";
    }
    else
    {
        for (my $counter=0; $counter<$results->count; $counter++)
            {
            my $user = $results->entry($counter);
                    if (defined($user->get_value("sn")) && length($user->get_value("sn")) > 0 && defined($user->get_value("sAMAccountName")))
                    {
                push @res, {
                    name => encode_entities($user->get_value("displayName")),
                description => encode_entities($user->get_value("sAMAccountName")),
                sortorder => $i++,
 
                }
            }
            }
      }
 
    $ad->unbind;
 
 
      return \@res;
}
 
1;

So we bundle that nicely in to AD.pm and dump that into the folder.

Configuration

So how do we use that module? Well you need to go to /opt/rt3/etc and edit the RT_SiteConfig.pm file and add the following line to it: Set(@CustomFieldValuesSources, "RT::CustomFieldValues::AD");

Next restart Apache (the command I used was: apache2ctl restart) and go back to the field properties and you should be able to select it.

Tips and Tricks

A few things about building these that I learnt along the way

  1. If, after the IIS reset, there is no drop down for the field source it means you have a bug in a module and you need to fix said bug.
  2. Use the die command excessively. When you select the field source and click save changes it will test your code. Only die will cause it to show error messages! When you get the UI, it will not give you errors!
  3. The autocompletion options may seem the coolest, but they use a (poorly, at least compared to jQuery) written piece of JavaScript. This battles to run with more than 25 results returned (slows down, doesn’t work, errors, freezes browser). I would recommend working with the select one or select many (combo boxes) first and trying to change to it later.
  4. If you change the code after you have set the field, you need to restart apache and then re-configure the field by setting the field source to something else, save and then set it back. It seems there is some caching issues which can prevent your changed results from appearing.

Hopefully this helps you develop with RT, and that this (overcomplicated) process is easier.

Comments

Lanang Sejagat's picture

Hello, I stumble to your blog from searching google on how to use groups.pm for request tracker, and found your answer on the stackoverflow forum. Following the step as per your instruction by putting the Set(@CustomFieldValuesSources, "RT::CustomFieldValues::Groups"); onto the RT_Siteconfig.pm and then restart apache, did not show any different or any new option in the custom field create section. Do I have to created a list of group name. Could u instruct me if possible step by step instruction on how to enable the Groups.pm for the CustomField External Value. I'm using RT 3.8.8 and trying to pull data for to populate custom fields from external mysql database, which is similar to you AD integration above, but I still cannot go through the groups.pm to understand how it work. Hope that you can help me to understand it. Rgds Lanang
Robert MacLean's picture

Everything sounds correct so either it is an issue with the version (I didn't work on such a modern one) or an issue in your groups.pm file which is not working. If that file doesn't work you will get no details back.

Add new comment

dontclickme