Project

General

Profile

LDAP auth modification to sync LDAP groups and Redmine groups

Added by jacob briggs over 14 years ago

Hi all

I am working on some changes to allow redmine to pick up groups that are stored in LDAP somewhere. Basically, I store a bunch of groups here:

ou=Group,dc=foobar,dc=co,dc=nz

so I'll have :

cn=Employee,ou=Group,dc=foobar,dc=co,dc=nz
cn=Customer,ou=Group,dc=foobar,dc=co,dc=nz
....

The uid of the members of the groups are stored in the groups in the memberUid attribute, the uid is the username in redmine since we currently authenticate against LDAP. This is how I plan it to work :

Upon login, the groups that the user belongs to are gathered.
Add all those groups to redmine.
The user is added to the groups they belong to.

The point of this exercise is so that I can just add a user into LDAP, chuck them in the Employee group, and when they log into redmine they get to see all the projects that the Employee group in redmine is allowed to see. If the User is a customer, then they don't see anything by default.

I have it to the point that when a user logs in, the groups are added to redmine (I don't check to see if they are there already....). But how would I add a user to a group?

The code is this :

    ldap_con.search( :base => self.group_base_dn,
                     :filter => Net::LDAP::Filter.eq("memberUid", login),
                     :attributes => [ "cn" ]) do |entry|
      logger.debug "cn '#{entry.cn}'" 
      @group = Group.new(:lastname => entry.cn)
      if @group.save
        logger.debug "group save worked" 
      else
        logger.debug "group save didn't work" 
      end
    end

and I have it in app/models/auth_source_ldap.rb in the authenticate method just after the

    logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?

Plus I added the column group_base_dn in the database and various other places....


Replies (3)

RE: LDAP auth modification to sync LDAP groups and Redmine groups - Added by jacob briggs over 14 years ago

Hi All

I have finished the LDAP groups sync modification for when users are in groups (rather than "groups on users"). I changed these files :

M app/models/auth_source_ldap.rb
M app/views/auth_sources/_form.rhtml
M db/migrate/001_setup.rb
M config/locales/en.yml

The majority of the code changes are in auth_source_ldap.rb, with only one liners in the other files to support the group base dn :

devmine:/usr/local/redmine# svn diff app/models/auth_source_ldap.rb
Index: app/models/auth_source_ldap.rb
===================================================================
--- app/models/auth_source_ldap.rb    (revision 3111)
+++ app/models/auth_source_ldap.rb    (working copy)
@@ -21,7 +21,7 @@
 class AuthSourceLdap < AuthSource 
   validates_presence_of :host, :port, :attr_login
   validates_length_of :name, :host, :account_password, :maximum => 60, :allow_nil => true
-  validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true
+  validates_length_of :account, :base_dn, :group_base_dn, :maximum => 255, :allow_nil => true
   validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
   validates_numericality_of :port, :only_integer => true

@@ -56,6 +56,50 @@
     return nil unless ldap_con.bind
     # return user's attributes
     logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
+
+    if self.group_base_dn != "" 
+      # Search for ldap groups that the user is in
+      ldap_con.search( :base => self.group_base_dn,
+                       :filter => Net::LDAP::Filter.eq("memberUid", login),
+                       :attributes => [ "cn" ]) do |entry|
+        logger.debug "cn '#{entry.cn}'" 
+
+        # look to see if the group exists
+        # then add it if it doesn't
+      
+        @matchinggroups = Group.find(:all, :conditions => "lastname = '#{entry.cn}'")
+ 
+        if @matchinggroups.length == 0
+          @group = Group.new(:lastname => "#{entry.cn}")
+
+          if @group.save
+            logger.debug "group '#{entry.cn}' save worked" 
+          else
+            logger.debug "group '#{entry.cn}' save didn't work" 
+          end
+        end
+      
+        # look to see if the user is a member of the group 
+        # and add them if they are not
+      
+        @currentgroup = Group.find(:first, :conditions => "lastname = '#{entry.cn}'")
+        @userdetails = User.find(:first, :conditions => "login = '#{login}'")
+
+        if !@currentgroup.user_ids.include?(@userdetails.id)
+          # add the user to the group
+
+          @currentgroup.user_ids = @currentgroup.user_ids + [@userdetails.id]
+
+          if @currentgroup.save
+            logger.debug "user added to group" 
+          else
+            logger.debug "user NOT added to group" 
+          end
+        end
+      
+      end
+    end
+
     attrs    
   rescue  Net::LDAP::LdapError => text
     raise "LdapError: " + text
devmine:/usr/local/redmine#

Obviously I need to remove debugging etc.... So, how do I contribute this back? Is it even wanted? What would I need to do to make it acceptable to contribute back? Is this post even in the right sub forum? I am just to damn lazy to fork a private branch of redmine, and then merge mainline redmine back everytime I want to upgrade....

RE: LDAP auth modification to sync LDAP groups and Redmine groups - Added by alten benelux over 14 years ago

This would be extremely useful.
If I understand correctly, an issue has been filed for this : #1113

    (1-3/3)