##// END OF EJS Templates
Use safe_attributes for auth sources....
Jean-Philippe Lang -
r15310:d7a6c09822bc
parent child
Show More
@@ -1,97 +1,104
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class AuthSourcesController < ApplicationController
18 class AuthSourcesController < ApplicationController
19 layout 'admin'
19 layout 'admin'
20 menu_item :ldap_authentication
20 menu_item :ldap_authentication
21
21
22 before_action :require_admin
22 before_action :require_admin
23 before_action :build_new_auth_source, :only => [:new, :create]
23 before_action :find_auth_source, :only => [:edit, :update, :test_connection, :destroy]
24 before_action :find_auth_source, :only => [:edit, :update, :test_connection, :destroy]
24 require_sudo_mode :update, :destroy
25 require_sudo_mode :update, :destroy
25
26
26 def index
27 def index
27 @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25
28 @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25
28 end
29 end
29
30
30 def new
31 def new
31 klass_name = params[:type] || 'AuthSourceLdap'
32 @auth_source = AuthSource.new_subclass_instance(klass_name, params[:auth_source])
33 render_404 unless @auth_source
34 end
32 end
35
33
36 def create
34 def create
37 @auth_source = AuthSource.new_subclass_instance(params[:type], params[:auth_source])
38 if @auth_source.save
35 if @auth_source.save
39 flash[:notice] = l(:notice_successful_create)
36 flash[:notice] = l(:notice_successful_create)
40 redirect_to auth_sources_path
37 redirect_to auth_sources_path
41 else
38 else
42 render :action => 'new'
39 render :action => 'new'
43 end
40 end
44 end
41 end
45
42
46 def edit
43 def edit
47 end
44 end
48
45
49 def update
46 def update
50 if @auth_source.update_attributes(params[:auth_source])
47 @auth_source.safe_attributes = params[:auth_source]
48 if @auth_source.save
51 flash[:notice] = l(:notice_successful_update)
49 flash[:notice] = l(:notice_successful_update)
52 redirect_to auth_sources_path
50 redirect_to auth_sources_path
53 else
51 else
54 render :action => 'edit'
52 render :action => 'edit'
55 end
53 end
56 end
54 end
57
55
58 def test_connection
56 def test_connection
59 begin
57 begin
60 @auth_source.test_connection
58 @auth_source.test_connection
61 flash[:notice] = l(:notice_successful_connection)
59 flash[:notice] = l(:notice_successful_connection)
62 rescue Exception => e
60 rescue Exception => e
63 flash[:error] = l(:error_unable_to_connect, e.message)
61 flash[:error] = l(:error_unable_to_connect, e.message)
64 end
62 end
65 redirect_to auth_sources_path
63 redirect_to auth_sources_path
66 end
64 end
67
65
68 def destroy
66 def destroy
69 unless @auth_source.users.exists?
67 unless @auth_source.users.exists?
70 @auth_source.destroy
68 @auth_source.destroy
71 flash[:notice] = l(:notice_successful_delete)
69 flash[:notice] = l(:notice_successful_delete)
72 end
70 end
73 redirect_to auth_sources_path
71 redirect_to auth_sources_path
74 end
72 end
75
73
76 def autocomplete_for_new_user
74 def autocomplete_for_new_user
77 results = AuthSource.search(params[:term])
75 results = AuthSource.search(params[:term])
78
76
79 render :json => results.map {|result| {
77 render :json => results.map {|result| {
80 'value' => result[:login],
78 'value' => result[:login],
81 'label' => "#{result[:login]} (#{result[:firstname]} #{result[:lastname]})",
79 'label' => "#{result[:login]} (#{result[:firstname]} #{result[:lastname]})",
82 'login' => result[:login].to_s,
80 'login' => result[:login].to_s,
83 'firstname' => result[:firstname].to_s,
81 'firstname' => result[:firstname].to_s,
84 'lastname' => result[:lastname].to_s,
82 'lastname' => result[:lastname].to_s,
85 'mail' => result[:mail].to_s,
83 'mail' => result[:mail].to_s,
86 'auth_source_id' => result[:auth_source_id].to_s
84 'auth_source_id' => result[:auth_source_id].to_s
87 }}
85 }}
88 end
86 end
89
87
90 private
88 private
91
89
90 def build_new_auth_source
91 @auth_source = AuthSource.new_subclass_instance(params[:type] || 'AuthSourceLdap')
92 if @auth_source
93 @auth_source.safe_attributes = params[:auth_source]
94 else
95 render_404
96 end
97 end
98
92 def find_auth_source
99 def find_auth_source
93 @auth_source = AuthSource.find(params[:id])
100 @auth_source = AuthSource.find(params[:id])
94 rescue ActiveRecord::RecordNotFound
101 rescue ActiveRecord::RecordNotFound
95 render_404
102 render_404
96 end
103 end
97 end
104 end
@@ -1,93 +1,109
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 # Generic exception for when the AuthSource can not be reached
18 # Generic exception for when the AuthSource can not be reached
19 # (eg. can not connect to the LDAP)
19 # (eg. can not connect to the LDAP)
20 class AuthSourceException < Exception; end
20 class AuthSourceException < Exception; end
21 class AuthSourceTimeoutException < AuthSourceException; end
21 class AuthSourceTimeoutException < AuthSourceException; end
22
22
23 class AuthSource < ActiveRecord::Base
23 class AuthSource < ActiveRecord::Base
24 include Redmine::SafeAttributes
24 include Redmine::SubclassFactory
25 include Redmine::SubclassFactory
25 include Redmine::Ciphering
26 include Redmine::Ciphering
26
27
27 has_many :users
28 has_many :users
28
29
29 validates_presence_of :name
30 validates_presence_of :name
30 validates_uniqueness_of :name
31 validates_uniqueness_of :name
31 validates_length_of :name, :maximum => 60
32 validates_length_of :name, :maximum => 60
32 attr_protected :id
33 attr_protected :id
33
34
35 safe_attributes 'name',
36 'host',
37 'port',
38 'account',
39 'account_password',
40 'base_dn',
41 'attr_login',
42 'attr_firstname',
43 'attr_lastname',
44 'attr_mail',
45 'onthefly_register',
46 'tls',
47 'filter',
48 'timeout'
49
34 def authenticate(login, password)
50 def authenticate(login, password)
35 end
51 end
36
52
37 def test_connection
53 def test_connection
38 end
54 end
39
55
40 def auth_method_name
56 def auth_method_name
41 "Abstract"
57 "Abstract"
42 end
58 end
43
59
44 def account_password
60 def account_password
45 read_ciphered_attribute(:account_password)
61 read_ciphered_attribute(:account_password)
46 end
62 end
47
63
48 def account_password=(arg)
64 def account_password=(arg)
49 write_ciphered_attribute(:account_password, arg)
65 write_ciphered_attribute(:account_password, arg)
50 end
66 end
51
67
52 def searchable?
68 def searchable?
53 false
69 false
54 end
70 end
55
71
56 def self.search(q)
72 def self.search(q)
57 results = []
73 results = []
58 AuthSource.all.each do |source|
74 AuthSource.all.each do |source|
59 begin
75 begin
60 if source.searchable?
76 if source.searchable?
61 results += source.search(q)
77 results += source.search(q)
62 end
78 end
63 rescue AuthSourceException => e
79 rescue AuthSourceException => e
64 logger.error "Error while searching users in #{source.name}: #{e.message}"
80 logger.error "Error while searching users in #{source.name}: #{e.message}"
65 end
81 end
66 end
82 end
67 results
83 results
68 end
84 end
69
85
70 def allow_password_changes?
86 def allow_password_changes?
71 self.class.allow_password_changes?
87 self.class.allow_password_changes?
72 end
88 end
73
89
74 # Does this auth source backend allow password changes?
90 # Does this auth source backend allow password changes?
75 def self.allow_password_changes?
91 def self.allow_password_changes?
76 false
92 false
77 end
93 end
78
94
79 # Try to authenticate a user not yet registered against available sources
95 # Try to authenticate a user not yet registered against available sources
80 def self.authenticate(login, password)
96 def self.authenticate(login, password)
81 AuthSource.where(:onthefly_register => true).each do |source|
97 AuthSource.where(:onthefly_register => true).each do |source|
82 begin
98 begin
83 logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
99 logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
84 attrs = source.authenticate(login, password)
100 attrs = source.authenticate(login, password)
85 rescue => e
101 rescue => e
86 logger.error "Error during authentication: #{e.message}"
102 logger.error "Error during authentication: #{e.message}"
87 attrs = nil
103 attrs = nil
88 end
104 end
89 return attrs if attrs
105 return attrs if attrs
90 end
106 end
91 return nil
107 return nil
92 end
108 end
93 end
109 end
General Comments 0
You need to be logged in to leave comments. Login now