Feature #1838 » bulk_import_ldap.patch
| app/views/auth_sources/list.rhtml (working copy) | ||
|---|---|---|
| 19 | 19 | <td align="center"><%= source.auth_method_name %></td> | 
| 20 | 20 | <td align="center"><%= source.host %></td> | 
| 21 | 21 | <td align="center"><%= link_to l(:button_test), :action => 'test_connection', :id => source %></td> | 
| 22 | <td align="center"><%= link_to l(:button_import_ldap), :action => 'import', :id => source %></td> | |
| 22 | 23 |     <td align="center"><%= button_to l(:button_delete), { :action => 'destroy', :id => source }, :confirm => l(:text_are_you_sure), :class => "button-small" %></td>
 | 
| 24 |  | |
| 23 | 25 | </tr> | 
| 24 | 26 | <% end %> | 
| 25 | 27 | </tbody> | 
| app/controllers/auth_sources_controller.rb (working copy) | ||
|---|---|---|
| 61 | 61 | end | 
| 62 | 62 | end | 
| 63 | 63 |  | 
| 64 | def import | |
| 65 | @auth_source = AuthSource.find(params[:id]) | |
| 66 | begin | |
| 67 | @auth_source.import | |
| 68 | flash[:notice] = l(:notice_successful_import) | |
| 69 | rescue => err | |
| 70 |       flash[:error] = "Unable to import (#{err})"
 | |
| 71 | end | |
| 72 | redirect_to :action => 'list' | |
| 73 | end | |
| 74 |  | |
| 64 | 75 | def test_connection | 
| 65 |     @auth_method = AuthSource.find(params[:id])
 | |
| 76 |     @auth_source = AuthSource.find(params[:id])
 | |
| 66 | 77 | begin | 
| 67 |       @auth_method.test_connection
 | |
| 78 |       @auth_source.test_connection
 | |
| 68 | 79 | flash[:notice] = l(:notice_successful_connection) | 
| 69 | 80 | rescue => text | 
| 70 | 81 |       flash[:error] = "Unable to connect (#{text})"
 | 
| lang/en.yml (working copy) | ||
|---|---|---|
| 560 | 562 | button_annotate: Annotate | 
| 561 | 563 | button_update: Update | 
| 562 | 564 | button_configure: Configure | 
| 565 | button_import_ldap: Bulk import | |
| 563 | 566 |  | 
| 564 | 567 | status_active: active | 
| 565 | 568 | status_registered: registered | 
| db/migrate/096_add_auth_sources_user_filter.rb (revision 0) | ||
|---|---|---|
| 1 | class AddAuthSourcesUserFilter < ActiveRecord::Migration | |
| 2 | def self.up | |
| 3 | add_column :auth_sources, :user_filter, :string, :default => '(objectClass=*)', :null => true | |
| 4 | end | |
| 5 |  | |
| 6 | def self.down | |
| 7 | remove_column :auth_sources, :tls | |
| 8 | end | |
| 9 | end | |
| app/models/auth_source.rb (working copy) | ||
|---|---|---|
| 32 | 32 | "Abstract" | 
| 33 | 33 | end | 
| 34 | 34 |  | 
| 35 | def import | |
| 36 | # bulk create AR User classes from auth_source so | |
| 37 | # users from external auth sources don't need to login | |
| 38 | # just to be visible in the UI | |
| 39 | end | |
| 40 |  | |
| 35 | 41 | # Try to authenticate a user not yet registered against available sources | 
| 36 | 42 | def self.authenticate(login, password) | 
| 37 | 43 | AuthSource.find(:all, :conditions => ["onthefly_register=?", true]).each do |source| | 
| app/models/auth_source_ldap.rb (working copy) | ||
|---|---|---|
| 21 | 21 | class AuthSourceLdap < AuthSource | 
| 22 | 22 | validates_presence_of :host, :port, :attr_login | 
| 23 | 23 | validates_length_of :name, :host, :account_password, :maximum => 60, :allow_nil => true | 
| 24 | validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true | |
| 24 |   validates_length_of :account, :base_dn, :user_filter, :maximum => 255, :allow_nil => true
 | |
| 25 | 25 | validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true | 
| 26 | 26 | validates_numericality_of :port, :only_integer => true | 
| 27 | 27 |  | 
| ... | ... | |
| 59 | 59 | raise "LdapError: " + text | 
| 60 | 60 | end | 
| 61 | 61 |  | 
| 62 | def import | |
| 63 | ldap_con = initialize_ldap_con(self.account, self.account_password) | |
| 64 | if self.user_filter | |
| 65 | search_filter = self.user_filter | |
| 66 | else | |
| 67 |       search_filter = Net::LDAP::Filter.eq("objectClass", "*")
 | |
| 68 | end | |
| 69 | found = created = 0 | |
| 70 | skipped = [] | |
| 71 | ldap_con.search( | |
| 72 | :base => self.base_dn, | |
| 73 | :filter => search_filter, | |
| 74 | :attributes => ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail, self.attr_login] | |
| 75 | ) do | entry | | |
| 76 |             logger.debug("Found entry with DN: #{entry.dn}") if logger
 | |
| 77 | found += 1 | |
| 78 | attrs = [:firstname => (AuthSourceLdap.get_attr(entry, self.attr_firstname) != nil ? \ | |
| 79 | AuthSourceLdap.get_attr(entry, self.attr_firstname) : "Unknown"), | |
| 80 | :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname), | |
| 81 | :mail => AuthSourceLdap.get_attr(entry, self.attr_mail), | |
| 82 | :auth_source_id => self.id ] | |
| 83 | begin | |
| 84 |               logger.debug("Trying to create user with attrs: %s" % attrs.to_s) if logger
 | |
| 85 | login = AuthSourceLdap.get_attr(entry, self.attr_login) | |
| 86 | if User.find(:first, :conditions => ["login=?", login]) | |
| 87 |                 logger.debug("User #{login} already there, skipping...") if logger
 | |
| 88 | next | |
| 89 | end | |
| 90 | u = User.create(*attrs) | |
| 91 | u.login = login | |
| 92 | u.language = Setting.default_language | |
| 93 | if u.save | |
| 94 | created += 1 | |
| 95 | else | |
| 96 | skipped.push(login) | |
| 97 | end | |
| 98 | end | |
| 99 | end | |
| 100 |         logger.info("Found #{found} users, imported #{created}.")
 | |
| 101 |         logger.info("Skipped users: #{skipped.join(" ")}")
 | |
| 102 | end | |
| 103 |  | |
| 62 | 104 | # test the connection to the LDAP | 
| 63 | 105 | def test_connection | 
| 64 | 106 | ldap_con = initialize_ldap_con(self.account, self.account_password) |