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) |