I saw this message and it got me interested.  I was thinking about
this earlier (although this is not what I was searching for) and
decided to take this as a chance to whip up something to do it.
Please keep in mind that this was written in about three hours and is
just a first pass.  I borrowed some existing LDAP code I had lying
around and there's even a TODO telling me to figure out wtf I'm
doing.  :)

Anywho... you'll need to make some changes to this to make it work for
whatever you LDAP infrastructure looks like.

NOTE: Our LDAP server has multiple user DNs.  We have one for
employees and another for contractors/vendors.  Since I need to be
able to search through any of them, I have to use a dictionary for my
LUSER_DN.

"""
#!/usr/bin/python

"""Update ReviewBoard users list with members of an LDAP group.

Connect to LDAP and MySQL and generate users list.  Find the
differences in
the two lists and query LDAP for user data (username, first name, last
name).
Insert unique users into ReviewBoard MySQL server.

TODO(junk):
* If named group doesn't exist in ReviewBoard, add to group list.
* Add new users to named group in ReviewBoard.
* If a user is removed from an LDAP group, remove them from the
ReviewBoard group.
* Check missing users for locaked status and mark inactive.
"""

__author__ = 'Tucker <j...@gmail.com>'


import ldap
import MySQLdb
import sys
import time


# Globals.
L_HOST = 'ldap_server'
LGROUP_DN = 'ou=Group,dc=company,dc=com'
LUSER_DN = {'People': ['ou=People,dc=company,dc=com', 'uid'],
            'Outside': ['ou=Outside,dc=company,dc=com', 'cn'],
           }
RB_HOST = 'localhost'
RB_USER = 'user'
RB_PASS = 'password'
RB_DB = 'reviewboard'

def error_and_exit(msg, ret):
  """Print our error message and exit.

  Args:
    msg: Error message string
    ret: integer return value
  """
  print 'ERROR: %s' % msg
  sys.exit(ret)


def get_ldap_members(ldap_object, group_name):
  """Query LDAP for group members.

  Args:
    ldap_object: LDAP object user to connect and query the LDAP server
    group_name: group name string
  Returns:
    group_members: dictionary containing all group members
  """
  search_scope = ldap.SCOPE_SUBTREE
  ldap_filter = 'cn=%s' % group_name

  # Run our LDAP query.
  try:
    ldap_result_id = ldap_object.search(LGROUP_DN, search_scope,
ldap_filter)
    results = []
    result_type, result_data = ldap_object.result(ldap_result_id, 0)
  except ldap.LDAPError, e:
    error_and_exit(e[0]['desc'], 4)

  # TODO(junk): remember what this does and comment on it
  if result_data:
    if result_type == ldap.RES_SEARCH_ENTRY:
      results.append(result_data)

  # If the group doesn't exist, bail out.
  if not results:
    error_and_exit('Group not found.', 5)

  # If the group has no members, bail out.
  if 'memberUid' not in results[0][0][1]:
    error_and_exit('Group has no members', 6)

  # Send back our results dictionary.
  return results[0][0][1]['memberUid']


def get_member_info(ldap_object, ldap_members):
  """Get user info for each LDAP group member.

  Args:
    ldap_object: LDAP object user to connect and query the LDAP server
    ldap_members: list of LDAP group members
  Return:
    ldap_user_info: dictionary of LDAP user info
  """
  search_scope = ldap.SCOPE_SUBTREE
  ldap_user_info = {}

  # Search through each member in our list.
  for member in ldap_members:
    # Run our LDAP query against all possible user DNs.
    for dn in LUSER_DN:
      ldap_filter = '%s=%s' % (LUSER_DN[dn][1], member)
      try:
        ldap_result_id = ldap_object.search(LUSER_DN[dn][0],
search_scope,
                                            ldap_filter)
        result_type, result_data = ldap_object.result(ldap_result_id,
0)
      except ldap.LDAPError, e:
        error_and_exit(e[0]['desc'], 3)

    # We don't store first and last names, only gecos.
    if result_data:
      first_name = result_data[0][1]['gecos'][0].split()[0]
      last_name = result_data[0][1]['gecos'][0].split()[-1]

    # Add each new user to the list.
    ldap_user_info[member] = [last_name, first_name]

  return ldap_user_info


def add_rb_members(ldap_user_info):
  """Add group members to ReviewBoard.

  Args:
    ldap_user_info: dictionary of LDAP user info to add
  """
  # Get current time in correct format.
  now = time.strftime('%Y-%m-%d %H:%M:%S')

  # Create a MySQL connection object to work with.
  mysql_o = MySQLdb.connect(host=RB_HOST, user=RB_USER,
                            passwd=RB_PASS, db=RB_DB)
  cursor = mysql_o.cursor()

  for user in ldap_user_info:
    first_name = ldap_user_info[user][1]
    last_name = ldap_user_info[user][0]
    try:
      cursor.execute('INSERT INTO auth_user
(username,first_name,last_name,'
                     'email,password,is_staff,is_active,is_superuser,'
                     'last_login,date_joined) VALUES'
 
'("%s","%s","%s","%s...@company.com","!","0","1","0",'
                     '"0000-00-00' '00:00:00","%s")' %
                     (user, first_name, last_name, user, now))
    # Ignore any exceptions and keep moving.
    except:
      pass

def main(argv):
  # Check to make sure our group is an alphabetic string.
  try:
    if not argv[1].isalpha():
      error_and_exit('Group name provided appears invalid.', 2)
    else:
      group = argv[1]
  except IndexError, e:
    error_and_exit('No group specified.', 1)

  # Create out LDAP object.
  try:
    ldap_o = ldap.open(L_HOST)
    ldap_o.protocol_verion = ldap.VERSION3
  except ldap.LDAPError, e:
    error_and_exit(e[0]['desc'], 3)

  # Get our LDAP group members.
  ldap_members = get_ldap_members(ldap_o, group)

  # Get user info for all users.
  ldap_user_info = get_member_info(ldap_o, ldap_members)

  # Add all our users to ReviewBoard.
  add_rb_members(ldap_user_info)

if __name__ == '__main__':
  main(sys.argv)
"""


On May 16, 11:18 am, Joe <gjwilso...@gmail.com> wrote:
> Thanks Eric.
>
> How were you able to push the data from ldap into reviewboard database
> tables? Can you please provide some information on importing the ldap
> data into our reviewboard database?
>
> On May 15, 3:55 pm, Eric Johnson <ericjohn...@alumni.brown.edu> wrote:
>
>
>
>
>
>
>
> > On our ReviewBoard server, we push the data into the database tables. Has 
> > been working quite well. Of course, you have to pay attention to users from 
> > LDAP that already exist, and perhaps users who have been disabled in LDAP.
>
> > No automated way to do it, other than that, at least that I'm aware.
>
> > Eric
>
> > On May 13, 2011, at 2:20 PM, Joe <gjwilso...@gmail.com> wrote:
>
> > > Hi,
>
> > > Currently, whenever we had to add an user from ldap to a group, the
> > > user has to first login to the system, so that the user is added to
> > > the reviewboard database.
> > > We want a way to avoid having the user to login in order to use that
> > > id from the admin ui.
>
> > > So is there any way to import users from LDAP into the reviewboard?
>
> > > Thanks
>
> > > --
> > > Want to help the Review Board project? Donate today 
> > > athttp://www.reviewboard.org/donate/
> > > Happy user? Let us know athttp://www.reviewboard.org/users/
> > > -~----------~----~----~----~------~----~------~--~---
> > > To unsubscribe from this group, send email to 
> > > reviewboard+unsubscr...@googlegroups.com
> > > For more options, visit this group 
> > > athttp://groups.google.com/group/reviewboard?hl=en

-- 
Want to help the Review Board project? Donate today at 
http://www.reviewboard.org/donate/
Happy user? Let us know at http://www.reviewboard.org/users/
-~----------~----~----~----~------~----~------~--~---
To unsubscribe from this group, send email to 
reviewboard+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/reviewboard?hl=en

Reply via email to