This repository was archived by the owner on Sep 25, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathusers_controller.rb
More file actions
148 lines (126 loc) · 4.37 KB
/
users_controller.rb
File metadata and controls
148 lines (126 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# encoding: UTF-8
require 'ntlm_hashes.rb'
class UsersController < ApplicationController
load_and_authorize_resource
def edit
end
def update
pw_fields_set = !params[:user].nil? && !params[:user][:password].nil? && !params[:user][:password_confirmation].nil?
unless !pw_fields_set || params[:user][:password].empty? && params[:user][:password_confirmation].empty?
# password should be changed
return unless check_password
return unless @user.reset_password! params[:user][:reset_password_token], params[:user][:password]
return unless update_ldap_password
end
@user.update_attributes params[:user]
if @user.save!
flash[:notice] = t 'Account updated'
end
respond_to do |format|
format.html { redirect_to edit_user_path(@user) }
end
end
def sign_up
@user = User.new
end
def register
return unless check_password
ldap = bind_ldap
return if ldap.nil?
dn = "cn=#{params[:user][:nick]},#{ldap_config("base")}"
@user = User.new(:nick => params[:user][:nick])
ldap.add(:dn => dn, :attributes => ldap_hash)
if ldap.get_operation_result.code != 0 then
logger.fatal "LDAP error: #{ldap.get_operation_result.message}"
flash[:error] = ldap.get_operation_result.message
redirect_to users_sign_up_path
return
end
flash[:notice] = 'User created, now please sign in.'
redirect_to new_user_session_path
end
def reset_password
return unless check_password
@user = User.find_by_reset_password_token params[:user][:reset_password_token]
if @user.nil?
flash[:error] = "Unable to reset password, please follow the instructions in the mail."
redirect_to new_user_password_path
return
end
return unless @user.reset_password! params[:user][:reset_password_token], params[:user][:password]
return unless update_ldap_password
flash[:notice] = 'Password updated, welcome back.'
sign_in(:user, @user)
redirect_to edit_user_path(@user)
end
rescue_from CanCan::AccessDenied do |exception|
render :file => "#{Rails.root}/public/403", :status => 403, :layout => false, :format => :html
end
private
def check_password
if params[:user][:password].empty? then
flash[:error] = "Password can’t be blank"
redirect_to users_sign_up_path
return false
end
if params[:user][:password] != params[:user][:password_confirmation] then
flash[:error] = "Passwords do not match"
redirect_to users_sign_up_path
return false
end
return true
end
def ldap_hash
# FIXME: why do I have to use force_encoding all over the place? :/
pass = params[:user][:password]
pass.force_encoding('utf-8')
salt = OpenSSL::Random.random_bytes 5
salt.force_encoding('utf-8')
h = Digest::SHA1.digest("#{pass}#{salt}")
h.force_encoding('utf-8')
ssha_pw = "{SSHA}"+Base64.encode64(h+salt).chomp!
# this is a little insecure, because if the ldap db is lost, crackers might attack the passwords
# it would be nice to change this to a more secure algorithm, once the VPN is configured to support it
nt_pw = NTLM::Hashes.nt_hash pass
lm_pw = NTLM::Hashes.lm_hash pass
{
:objectclass => ["top", "inetOrgPerson", "sambaSamAccount"],
:cn => @user.nick,
:sn => @user.nick,
:uid => @user.nick,
:sambaSID => @user.nick,
:userPassword => ssha_pw,
:sambaNTPassword => nt_pw,
:sambaLMPassword => lm_pw
}
end
def update_ldap_password
ldap = bind_ldap
return if ldap.nil?
dn = "cn=#{@user.nick},#{ldap_config("base")}"
ldap.delete(:dn => dn)
ldap.add(:dn => dn, :attributes => ldap_hash)
if ldap.get_operation_result.code != 0 then
logger.fatal "LDAP error: #{ldap.get_operation_result.message}"
flash[:error] = ldap.get_operation_result.message
redirect_to users_sign_up_path
return false
end
true
end
def bind_ldap
ldap = Net::LDAP.new
ldap.host = ldap_config("host")
ldap.auth ldap_config("admin_user"), ldap_config("admin_password")
if !ldap.bind then
flash[:error] = 'Couldn’t connect to LDAP Server'
redirect_to users_sign_up_path
return
end
ldap
end
def ldap_config key
@_ldap_c = YAML.load(ERB.new(File.read(::Devise.ldap_config || "#{Rails.root}/config/ldap.yml")).result)[Rails.env] if @_ldap_c.nil?
@_ldap_c[key]
end
end