rules_engine_users 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/rules_engine/controller_user_mail.rb +29 -0
- data/lib/rules_engine/controller_users.rb +170 -0
- data/lib/rules_engine_users.rb +4 -0
- data/rails_generators/USAGE +97 -0
- data/rails_generators/manifests/rules_engine_users.rb +79 -0
- data/rails_generators/manifests/rules_engine_users.yml +32 -0
- data/rails_generators/rules_engine_users_generator.rb +21 -0
- data/rails_generators/templates/app/controllers/admin/users_controller.rb +64 -0
- data/rails_generators/templates/app/controllers/users_controller.rb +215 -0
- data/rails_generators/templates/app/models/user.rb +113 -0
- data/rails_generators/templates/app/models/user_mailer.rb +26 -0
- data/rails_generators/templates/app/models/user_observer.rb +19 -0
- data/rails_generators/templates/app/views/admin/users/_form.html.erb +6 -0
- data/rails_generators/templates/app/views/admin/users/edit.html.erb +18 -0
- data/rails_generators/templates/app/views/admin/users/index.html.erb +52 -0
- data/rails_generators/templates/app/views/admin/users/new.html.erb +17 -0
- data/rails_generators/templates/app/views/admin/users/show.html.erb +15 -0
- data/rails_generators/templates/app/views/user_mailer/forgot_password.html.erb +11 -0
- data/rails_generators/templates/app/views/user_mailer/welcome_message.html.erb +11 -0
- data/rails_generators/templates/app/views/users/change_form.html.erb +22 -0
- data/rails_generators/templates/app/views/users/details.html.erb +11 -0
- data/rails_generators/templates/app/views/users/login_form.html.erb +35 -0
- data/rails_generators/templates/app/views/users/pswd_change_form.html.erb +20 -0
- data/rails_generators/templates/app/views/users/pswd_forgot_form.html.erb +18 -0
- data/rails_generators/templates/app/views/users/pswd_reset_form.html.erb +22 -0
- data/rails_generators/templates/app/views/users/welcome_form.html.erb +21 -0
- data/rails_generators/templates/db/migrate/20100104014507_create_users.rb +41 -0
- data/rails_generators/templates/doc/README.rules_engine_users +122 -0
- data/rails_generators/templates/doc/README.rules_engine_users_paths +12 -0
- data/rails_generators/templates/features/admin/user/edit.feature +46 -0
- data/rails_generators/templates/features/admin/user/index.feature +78 -0
- data/rails_generators/templates/features/admin/user/new.feature +26 -0
- data/rails_generators/templates/features/admin/user/show.feature +22 -0
- data/rails_generators/templates/features/admin/user/step_definitions/edit_steps.rb +3 -0
- data/rails_generators/templates/features/admin/user/step_definitions/index_steps.rb +13 -0
- data/rails_generators/templates/features/admin/user/step_definitions/show_steps.rb +3 -0
- data/rails_generators/templates/features/support/blueprint_users.rb +14 -0
- data/rails_generators/templates/features/user/change.feature +37 -0
- data/rails_generators/templates/features/user/details.feature +15 -0
- data/rails_generators/templates/features/user/login.feature +65 -0
- data/rails_generators/templates/features/user/pswd_change.feature +46 -0
- data/rails_generators/templates/features/user/pswd_forgot.feature +32 -0
- data/rails_generators/templates/features/user/pswd_reset.feature +52 -0
- data/rails_generators/templates/features/user/step_definitions/login_steps.rb +46 -0
- data/rails_generators/templates/features/user/step_definitions/pswd_reset_steps.rb +15 -0
- data/rails_generators/templates/features/user/step_definitions/welcome_steps.rb +15 -0
- data/rails_generators/templates/features/user/welcome.feature +52 -0
- data/rails_generators/templates/spec/controllers/admin/users_controller_spec.rb +191 -0
- data/rails_generators/templates/spec/controllers/users_controller_spec.rb +579 -0
- data/rails_generators/templates/spec/models/user_mailer_spec.rb +39 -0
- data/rails_generators/templates/spec/models/user_observer_spec.rb +56 -0
- data/rails_generators/templates/spec/models/user_spec.rb +253 -0
- data/rails_generators/templates/spec/support/rules_engine_macros.rb +16 -0
- data/rules_engine_users.gemspec +141 -0
- data/spec/railsenv/app/controllers/application_controller.rb +10 -0
- data/spec/railsenv/config/boot.rb +110 -0
- data/spec/railsenv/config/database.yml +22 -0
- data/spec/railsenv/config/environment.rb +41 -0
- data/spec/railsenv/config/environments/development.rb +17 -0
- data/spec/railsenv/config/environments/production.rb +28 -0
- data/spec/railsenv/config/environments/test.rb +28 -0
- data/spec/railsenv/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/railsenv/config/initializers/inflections.rb +10 -0
- data/spec/railsenv/config/initializers/mime_types.rb +5 -0
- data/spec/railsenv/config/initializers/new_rails_defaults.rb +19 -0
- data/spec/railsenv/config/initializers/session_store.rb +15 -0
- data/spec/railsenv/config/locales/en.yml +5 -0
- data/spec/railsenv/config/routes.rb +43 -0
- data/spec/railsenv/db/test.sqlite3 +1 -0
- data/spec/railsenv/log/debug.log +1 -0
- data/spec/railsenv/log/test.log +1 -0
- data/spec/rcov.opts +3 -0
- data/spec/rules_engine/controller_user_mail_spec.rb +43 -0
- data/spec/rules_engine/controller_users_spec.rb +337 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +30 -0
- data/tasks/rspec.rake +18 -0
- metadata +180 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
class UsersController < ApplicationController
|
|
2
|
+
|
|
3
|
+
skip_before_filter :verify_authenticity_token, :only => [:login_form, :login] # allow login from anywhere
|
|
4
|
+
before_filter :login_required, :only=>[:details, :change_form, :change, :pswd_change_form, :pswd_change]
|
|
5
|
+
|
|
6
|
+
def login_form
|
|
7
|
+
if logged_in?
|
|
8
|
+
flash[:success] = "User already logged in"
|
|
9
|
+
redirect_to(root_path)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def login
|
|
14
|
+
user_params = params[:user] || {}
|
|
15
|
+
user = User.authenticate_by_email(user_params[:name], user_params[:password]) || User.authenticate_by_login(user_params[:name], user_params[:password])
|
|
16
|
+
unless user.nil?
|
|
17
|
+
if (user.access_level == User::ACCESS_LEVEL_DISABLED)
|
|
18
|
+
flash[:error] = "User access disabled"
|
|
19
|
+
redirect_to(root_path)
|
|
20
|
+
else
|
|
21
|
+
self.current_user = user
|
|
22
|
+
|
|
23
|
+
if params[:remember_me] == "1"
|
|
24
|
+
current_user.set_remember_token
|
|
25
|
+
cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
redirect_to(session[:return_to] || root_path)
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
flash.now[:error] = "Unable to login user"
|
|
32
|
+
render :action => 'login_form'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def logout
|
|
37
|
+
self.current_user.reset_remember_token if logged_in?
|
|
38
|
+
cookies.delete :auth_token
|
|
39
|
+
reset_session
|
|
40
|
+
redirect_to(user_login_path)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def details
|
|
44
|
+
@user = current_user
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def change_form
|
|
48
|
+
@user = current_user
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def change
|
|
52
|
+
@user=current_user
|
|
53
|
+
|
|
54
|
+
if @user.update_attributes(params[:user].except(:access_level, :password))
|
|
55
|
+
flash[:success]="User Details Changed"
|
|
56
|
+
redirect_to user_details_path
|
|
57
|
+
else
|
|
58
|
+
render :action => 'change_form'
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def pswd_change_form
|
|
63
|
+
@user=current_user
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def pswd_change
|
|
67
|
+
user_params = params[:user] || {}
|
|
68
|
+
|
|
69
|
+
@user=current_user
|
|
70
|
+
if user_params[:old_password].blank? || user_params[:password].blank? || user_params[:password_confirmation].blank?
|
|
71
|
+
flash.now[:error] = "Old and New Password Required"
|
|
72
|
+
render :action => 'pswd_change_form'
|
|
73
|
+
elsif !User.authenticate_by_email(@user.email, user_params[:old_password])
|
|
74
|
+
flash.now[:error] = "Invalid Old Password"
|
|
75
|
+
render :action => 'pswd_change_form'
|
|
76
|
+
elsif @user.update_attributes(:password => user_params[:password], :password_confirmation => user_params[:password_confirmation])
|
|
77
|
+
flash[:success]="Password Changed"
|
|
78
|
+
redirect_to user_details_path
|
|
79
|
+
else
|
|
80
|
+
flash.now[:error] = "Could not change password"
|
|
81
|
+
render :action => 'pswd_change_form'
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def pswd_forgot_form
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def pswd_forgot
|
|
89
|
+
user_params = params[:user] || {}
|
|
90
|
+
user = User.set_reset_token(user_params[:email])
|
|
91
|
+
if user
|
|
92
|
+
flash[:success] = "An email has been sent with the password reset details."
|
|
93
|
+
redirect_to user_login_path
|
|
94
|
+
else
|
|
95
|
+
flash.now[:error] = "Could not reset password"
|
|
96
|
+
render :action => 'pswd_forgot_form'
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def pswd_reset_form
|
|
101
|
+
@token = params[:token]
|
|
102
|
+
if @token.blank?
|
|
103
|
+
# flash[:error]="Reset Token Required"
|
|
104
|
+
redirect_to user_pswd_forgot_path
|
|
105
|
+
return
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
user = User.authenticate_by_reset_token(@token)
|
|
109
|
+
unless user
|
|
110
|
+
flash[:error]="Could not reset password"
|
|
111
|
+
redirect_to user_pswd_forgot_path
|
|
112
|
+
return
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def pswd_reset
|
|
117
|
+
user_params = params[:user] || {}
|
|
118
|
+
|
|
119
|
+
@token = params[:token]
|
|
120
|
+
if @token.blank?
|
|
121
|
+
# flash.now[:error] = "Reset Token Expired"
|
|
122
|
+
render :action => 'pswd_forgot_form'
|
|
123
|
+
return
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
if user_params[:email].blank? || user_params[:password].blank?
|
|
127
|
+
flash.now[:error] = "Email and Password Required"
|
|
128
|
+
render :action => 'pswd_reset_form'
|
|
129
|
+
return
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
if user_params[:password] != user_params[:password_confirmation]
|
|
133
|
+
flash.now[:error] = "Password Confirmation does not match"
|
|
134
|
+
render :action => 'pswd_reset_form'
|
|
135
|
+
return
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
@token = params[:token]
|
|
139
|
+
user = User.authenticate_by_reset_token(@token)
|
|
140
|
+
|
|
141
|
+
unless user && user.email == user_params[:email]
|
|
142
|
+
flash.now[:error] = "Invalid Email"
|
|
143
|
+
render :action => 'pswd_reset_form'
|
|
144
|
+
return
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
if !user.update_attributes(:password=>user_params[:password], :password_confirmation=>user_params[:password])
|
|
148
|
+
flash.now[:error] = "Could not change password"
|
|
149
|
+
render :action => 'pswd_reset_form'
|
|
150
|
+
return
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
flash[:success]="Password Changed"
|
|
154
|
+
self.current_user = user
|
|
155
|
+
redirect_to root_path
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def welcome_form
|
|
159
|
+
@token = params[:token]
|
|
160
|
+
if @token.blank?
|
|
161
|
+
# flash[:error]="Welcome Token Required"
|
|
162
|
+
redirect_to user_pswd_forgot_path
|
|
163
|
+
return
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
user = User.authenticate_by_reset_token(@token)
|
|
167
|
+
unless user
|
|
168
|
+
flash[:error]="Unable to validate user details"
|
|
169
|
+
redirect_to user_pswd_forgot_path
|
|
170
|
+
return
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def welcome
|
|
175
|
+
user_params = params[:user] || {}
|
|
176
|
+
|
|
177
|
+
@token = params[:token]
|
|
178
|
+
if @token.blank?
|
|
179
|
+
flash.now[:error] = "Welcome Token Expired"
|
|
180
|
+
render :action => 'pswd_forgot_form'
|
|
181
|
+
return
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
if user_params[:email].blank? || user_params[:password].blank?
|
|
185
|
+
flash.now[:error] = "Email and Password Required"
|
|
186
|
+
render :action => 'welcome_form'
|
|
187
|
+
return
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
if user_params[:password] != user_params[:password_confirmation]
|
|
191
|
+
flash.now[:error] = "Password Confirmation does not match"
|
|
192
|
+
render :action => 'welcome_form'
|
|
193
|
+
return
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
@token = params[:token]
|
|
197
|
+
user = User.authenticate_by_reset_token(@token)
|
|
198
|
+
|
|
199
|
+
unless user && user.email == user_params[:email]
|
|
200
|
+
flash.now[:error] = "Invalid Email"
|
|
201
|
+
render :action => 'welcome_form'
|
|
202
|
+
return
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
if user.update_attributes(:password=>user_params[:password], :password_confirmation=>user_params[:password])
|
|
206
|
+
flash[:success]="Password Created"
|
|
207
|
+
self.current_user = user
|
|
208
|
+
redirect_to root_path
|
|
209
|
+
else
|
|
210
|
+
flash.now[:error] = "Could not change password"
|
|
211
|
+
render :action => 'welcome_form'
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
|
|
3
|
+
class User < ActiveRecord::Base
|
|
4
|
+
|
|
5
|
+
ACCESS_LEVEL_ADMIN = 999 # administrator access
|
|
6
|
+
ACCESS_LEVEL_DISABLED = 0 # disabled access
|
|
7
|
+
|
|
8
|
+
# validation
|
|
9
|
+
validates_presence_of :full_name
|
|
10
|
+
validates_presence_of :email
|
|
11
|
+
validates_presence_of :time_zone
|
|
12
|
+
validates_presence_of :login
|
|
13
|
+
# validates_presence_of :password, :on => :create
|
|
14
|
+
# validates_length_of :password, :within => 4..40, :on => :create
|
|
15
|
+
validates_confirmation_of :password, :unless => Proc.new{|user| user.password.blank? }
|
|
16
|
+
validates_length_of :password_confirmation, :within => 4..40, :unless => Proc.new{|user| user.password.blank? }
|
|
17
|
+
validates_uniqueness_of :email, :case_sensitive => false, :message=>"alread taken."
|
|
18
|
+
validates_presence_of :login
|
|
19
|
+
validates_format_of :login, :with => /\A[a-zA-ZZ0-9._]+\Z/, :unless => Proc.new { |user| user.login.blank? }
|
|
20
|
+
validates_uniqueness_of :login, :case_sensitive => false, :message=>"alread taken."
|
|
21
|
+
|
|
22
|
+
# anything else you want your user to change should be added here.
|
|
23
|
+
attr_accessor :password, :old_password
|
|
24
|
+
attr_accessible :full_name, :login, :email, :time_zone, :password, :password_confirmation, :access_level, :old_password
|
|
25
|
+
|
|
26
|
+
before_create :set_fields_before_create
|
|
27
|
+
before_save :set_fields_before_save
|
|
28
|
+
|
|
29
|
+
# named scope
|
|
30
|
+
named_scope :by_email, lambda {|email| {:conditions => ['email = ?', email]} }
|
|
31
|
+
named_scope :by_login, lambda {|login| {:conditions => ['login = ?', login]} }
|
|
32
|
+
named_scope :by_ge_email, lambda {|email| {:conditions => ['email >= ?', email]} }
|
|
33
|
+
named_scope :by_ge_login, lambda {|login| {:conditions => ['login >= ?', login]} }
|
|
34
|
+
named_scope :by_ge_full_name, lambda {|full_name| {:conditions => ['full_name >= ?', full_name]} }
|
|
35
|
+
named_scope :by_access_level, lambda {|access_level| {:conditions => ['access_level = ?', access_level]} }
|
|
36
|
+
named_scope :by_remember_token, lambda {|remember_token| {:conditions => ['remember_token = ?', remember_token]} }
|
|
37
|
+
named_scope :by_reset_token, lambda {|reset_token| {:conditions => ['reset_token = ?', reset_token]} }
|
|
38
|
+
named_scope :order_email, :order => 'email ASC'
|
|
39
|
+
named_scope :order_login, :order => 'email ASC'
|
|
40
|
+
named_scope :order_full_name, :order => 'full_name ASC'
|
|
41
|
+
# def self.at_page(page, options = {})
|
|
42
|
+
# paginate(options.reverse_merge(:page => page, :per_page => 20))
|
|
43
|
+
# end
|
|
44
|
+
|
|
45
|
+
##### Authentication
|
|
46
|
+
def self.authenticate_by_email(email, password)
|
|
47
|
+
u = User.by_email(email).find(:first)
|
|
48
|
+
return nil unless u
|
|
49
|
+
return nil unless u.crypted_password == generate_encryption(password, u.salt)
|
|
50
|
+
u
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.authenticate_by_login(login, password)
|
|
54
|
+
u = User.by_login(login).find(:first)
|
|
55
|
+
return nil unless u
|
|
56
|
+
return nil unless u.crypted_password == generate_encryption(password, u.salt)
|
|
57
|
+
u
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.authenticate_by_remember_token(remember_token)
|
|
61
|
+
u= self.by_remember_token(remember_token).find(:first)
|
|
62
|
+
return nil unless u
|
|
63
|
+
return nil unless u.remember_token_expires_at > Time.now.utc
|
|
64
|
+
u
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.authenticate_by_reset_token(reset_token)
|
|
68
|
+
u= self.by_reset_token(reset_token).find(:first)
|
|
69
|
+
return nil unless u
|
|
70
|
+
return nil unless u.reset_token_expires_at > Time.now.utc
|
|
71
|
+
u
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
##### Tokens
|
|
75
|
+
def set_remember_token
|
|
76
|
+
self.remember_token_expires_at = 30.days.from_now.utc
|
|
77
|
+
self.remember_token = User.generate_encryption(email, "#{self.remember_token_expires_at}")
|
|
78
|
+
save(false)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def reset_remember_token
|
|
82
|
+
self.remember_token_expires_at = nil
|
|
83
|
+
self.remember_token = nil
|
|
84
|
+
save(false)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def self.set_reset_token(email)
|
|
88
|
+
u = self.by_email(email).find(:first)
|
|
89
|
+
return nil unless u
|
|
90
|
+
u.reset_token_expires_at = 2.days.from_now.utc
|
|
91
|
+
u.reset_token = self.generate_encryption(email, "#{u.reset_token_expires_at}")
|
|
92
|
+
u.save(false)
|
|
93
|
+
u
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
def set_fields_before_create
|
|
98
|
+
self.reset_token_expires_at = 2.days.from_now.utc
|
|
99
|
+
self.reset_token = User.generate_encryption(self.email, "#{self.reset_token_expires_at}")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def set_fields_before_save
|
|
103
|
+
return if self.password.blank? # if password not set no need to change the crypted password
|
|
104
|
+
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{self.email}--") if new_record?
|
|
105
|
+
self.crypted_password = User.generate_encryption(self.password, self.salt)
|
|
106
|
+
self.reset_token_expires_at = nil
|
|
107
|
+
self.reset_token = nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def self.generate_encryption(password, salt)
|
|
111
|
+
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class UserMailer < ActionMailer::Base
|
|
2
|
+
default_url_options[:host] = "#{RulesEngine::ControllerUserMail.host}"
|
|
3
|
+
|
|
4
|
+
def welcome_message(options)
|
|
5
|
+
|
|
6
|
+
@recipients = options[:to_email]
|
|
7
|
+
@from = "#{RulesEngine::ControllerUserMail.from}"
|
|
8
|
+
@subject = "#{RulesEngine::ControllerUserMail.prefix} Account Created"
|
|
9
|
+
|
|
10
|
+
@body[:to_name] = options[:to_name]
|
|
11
|
+
@body[:to_url] = "http://#{RulesEngine::ControllerUserMail.host}#{user_pswd_reset_path(:token => options[:token])}"
|
|
12
|
+
|
|
13
|
+
@sent_on = Time.current
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def forgot_password(options)
|
|
17
|
+
@recipients = options[:to_email]
|
|
18
|
+
@from = "#{RulesEngine::ControllerUserMail.from}"
|
|
19
|
+
@subject = "#{RulesEngine::ControllerUserMail.prefix} Reset Password"
|
|
20
|
+
|
|
21
|
+
@body[:to_name] = options[:to_name]
|
|
22
|
+
@body[:to_url] = "http://#{RulesEngine::ControllerUserMail.host}#{user_pswd_reset_path(:token => options[:token])}"
|
|
23
|
+
|
|
24
|
+
@sent_on = Time.current
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class UserObserver < ActiveRecord::Observer
|
|
2
|
+
|
|
3
|
+
def after_create(record)
|
|
4
|
+
return unless ActionMailer::Base.perform_deliveries
|
|
5
|
+
|
|
6
|
+
UserMailer.deliver_welcome_message(:to_email => record.email,
|
|
7
|
+
:to_name => record.full_name,
|
|
8
|
+
:token => record.reset_token)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def after_update(record)
|
|
12
|
+
return if record.reset_token.nil?
|
|
13
|
+
return unless ActionMailer::Base.perform_deliveries
|
|
14
|
+
|
|
15
|
+
UserMailer.deliver_forgot_password(:to_email => record.email,
|
|
16
|
+
:to_name => record.full_name,
|
|
17
|
+
:token => record.reset_token)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<%= f.text_field :full_name, :size => 30, :required => true %>
|
|
2
|
+
<%= f.text_field :login, :size => 20, :required => true, :label => "Login Name" %>
|
|
3
|
+
<%= f.text_field :email, :size => 40, :required => true %>
|
|
4
|
+
<%= f.time_zone_select :time_zone, :required => true %>
|
|
5
|
+
<%= f.select :access_level, user_access_levels, :ordered => "false", :required => true, :hint => '<strong class="red">Making the user an administrator will allow them <br> to remove other users INCLUDING YOU!!</strong>' %>
|
|
6
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<% set_re_breadcrumbs link_to('Home Page', root_path), link_to('List Users', admin_users_path), link_to('User Details', admin_user_path(@user)), 'Edit User' %>
|
|
2
|
+
|
|
3
|
+
<div class="top-5 prepend-1 span-16">
|
|
4
|
+
<% re_form_for(@user, :url => admin_user_path(@user), :span => "3x13") do |f| %>
|
|
5
|
+
<%= f.error_messages :message => "Unable to Update User" %>
|
|
6
|
+
<% re_whitebox do %>
|
|
7
|
+
<h2 class="float-left">Edit User</h2>
|
|
8
|
+
<div class="float-right">
|
|
9
|
+
<%= re_button_submit_green('Update') %>
|
|
10
|
+
<%= re_button_link_red('Delete', admin_user_path(@user), :confirm => 'Are you sure?', :method => :delete) %>
|
|
11
|
+
<%= re_button_link_orange('Cancel', admin_user_path(@user)) %>
|
|
12
|
+
</div>
|
|
13
|
+
<hr/>
|
|
14
|
+
<%= render :partial => 'form', :locals => {:f => f} %>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% end %>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="clear"></div>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<% set_re_breadcrumbs_right link_to('Home Page', root_path), link_to('List Users', admin_users_path), link_to("+ Create New User", new_admin_user_path, :class=>"dkgreen") %>
|
|
2
|
+
|
|
3
|
+
<div class="span-22 prepend-1 append-1 last">
|
|
4
|
+
<% form_tag(admin_users_path, :method => :get) do %>
|
|
5
|
+
<div class="float-right">
|
|
6
|
+
<%= re_button_submit("Search", "orange") %>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="float-right">
|
|
9
|
+
<span class="float-left right-10 largetext blue">Search Users :</span>
|
|
10
|
+
<span class="float-left right-5">
|
|
11
|
+
<%= text_field_tag 'query', params[:query], :required => true, :size => 25, :class=>'right-10'%>
|
|
12
|
+
</span>
|
|
13
|
+
<span class="float-left right-5">
|
|
14
|
+
<%= select_tag 'query_type', options_for_select([["Search Name", 'full_name'],
|
|
15
|
+
["Search Login", 'login'],
|
|
16
|
+
["Search Email", 'email']], params['query_type'])%>
|
|
17
|
+
</span>
|
|
18
|
+
</div>
|
|
19
|
+
<% end %>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="clear"></div>
|
|
22
|
+
|
|
23
|
+
<div class="span-22 prepend-1 append-1 last">
|
|
24
|
+
<table width="100%" border="0" cellpadding="0" cellspacing="0" class="data">
|
|
25
|
+
<tr>
|
|
26
|
+
<th align="left">Login Name</th>
|
|
27
|
+
<th align="left">Full Name</th>
|
|
28
|
+
<th align="left">Email</th>
|
|
29
|
+
<th align="left">Time Zone</th>
|
|
30
|
+
<th align="left">Access Level</th>
|
|
31
|
+
</tr>
|
|
32
|
+
<% if @users.empty? %>
|
|
33
|
+
<tr>
|
|
34
|
+
<td colspan="6">
|
|
35
|
+
<h3>No Users Found</h3>
|
|
36
|
+
</td>
|
|
37
|
+
</tr>
|
|
38
|
+
<% end %>
|
|
39
|
+
<% @users.each do | user | %>
|
|
40
|
+
<tr class="<%= cycle('', 'odd') %>">
|
|
41
|
+
<td><%=link_to(h(user.login), admin_user_path(user))%></td>
|
|
42
|
+
<td><%=link_to(h(user.full_name), admin_user_path(user))%></td>
|
|
43
|
+
<td><%=h user.email%></td>
|
|
44
|
+
<td><%=h user.time_zone%></td>
|
|
45
|
+
<td><%= user_access_level(user)%></td>
|
|
46
|
+
</tr>
|
|
47
|
+
<% end %>
|
|
48
|
+
</table>
|
|
49
|
+
|
|
50
|
+
<%= will_paginate(@users) %>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="clear"></div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<% set_re_breadcrumbs link_to('Home Page', root_path), link_to('List Users', admin_users_path), 'New User' %>
|
|
2
|
+
|
|
3
|
+
<div class="top-5 prepend-1 span-16">
|
|
4
|
+
<% re_form_for(@user, :url => admin_users_path, :span => "3x13") do |f| %>
|
|
5
|
+
<%= f.error_messages :user => "Unable to Create User" %>
|
|
6
|
+
<% re_whitebox do %>
|
|
7
|
+
<h2 class="float-left">New User</h2>
|
|
8
|
+
<div class="float-right">
|
|
9
|
+
<%= re_button_submit_green('Create') %>
|
|
10
|
+
<%= re_button_link_orange('Cancel', admin_users_path) %>
|
|
11
|
+
</div>
|
|
12
|
+
<hr/>
|
|
13
|
+
<%= render :partial => 'form', :locals => {:f => f} %>
|
|
14
|
+
<% end %>
|
|
15
|
+
<% end %>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="clear"></div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<% set_re_breadcrumbs link_to('Home Page', root_path), link_to('List Users', admin_users_path), 'User Details' %>
|
|
2
|
+
|
|
3
|
+
<div class="top-5 prepend-1 span-16">
|
|
4
|
+
<% re_whitebox do %>
|
|
5
|
+
<h2 class="float-left">User Details</h2>
|
|
6
|
+
<div class="float-right"><%=re_button_link_blue('Edit', edit_admin_user_path(@user)) %></div>
|
|
7
|
+
<hr/>
|
|
8
|
+
|
|
9
|
+
<%= re_form_text 'Full Name', @user.full_name, :span => "3x13" %>
|
|
10
|
+
<%= re_form_text 'Login Name', @user.login, :span => "3x13" %>
|
|
11
|
+
<%= re_form_text 'Email', @user.email, :span => "3x13" %>
|
|
12
|
+
<%= re_form_text 'Time Zone', @user.time_zone, :span => "3x13" %>
|
|
13
|
+
<%= re_form_text 'Access Level', user_access_level(@user), :span => "3x13" %>
|
|
14
|
+
<% end %>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Hello <%= @to_name %>,
|
|
2
|
+
|
|
3
|
+
An [My Cool New Application] account has been created for you.
|
|
4
|
+
|
|
5
|
+
You can login at : <%= @to_url %>
|
|
6
|
+
|
|
7
|
+
Kind Regards
|
|
8
|
+
[My Cool New Application] Team
|
|
9
|
+
|
|
10
|
+
Note : This is an automatically generated email. Please do not reply to this email
|
|
11
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="prepend-1 prepend-top span-15">
|
|
2
|
+
<h2>Change Your Details</h2>
|
|
3
|
+
<% re_form_for(@user, :url=> user_change_path, :method => "post", :html => {:id => 'user_change'}, :span => "3x11") do |f| %>
|
|
4
|
+
<%= f.error_messages :message => "Unable to Change User Details" %>
|
|
5
|
+
<% re_whitebox do %>
|
|
6
|
+
<%= f.text_field :full_name, :size=>30, :required => true%>
|
|
7
|
+
<%= f.text_field :login, :size=>20, :required => true, :label => "Login Name"%>
|
|
8
|
+
<%= f.text_field :email, :size=>40, :required => true%>
|
|
9
|
+
<%= f.time_zone_select :time_zone, :required => true %>
|
|
10
|
+
|
|
11
|
+
<div class="span-4">
|
|
12
|
+
<%= link_to("Change Your Password", user_pswd_change_path) %>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="span-10" style="text-align:right;">
|
|
15
|
+
<%= re_button_submit("Update", "green") %>
|
|
16
|
+
<%= re_button_link("Cancel", user_details_path, "red") %>
|
|
17
|
+
<div class="clear"></div>
|
|
18
|
+
</div>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="clear"></div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div class="prepend-1 prepend-top span-15">
|
|
2
|
+
<h2>Your Details</h2>
|
|
3
|
+
<% re_whitebox do %>
|
|
4
|
+
<%= re_form_text 'Full Name', @user.full_name, :span => '3x11' %>
|
|
5
|
+
<%= re_form_text 'Login', @user.login, :span => '3x11' %>
|
|
6
|
+
<%= re_form_text 'Email', @user.email, :span => '3x11' %>
|
|
7
|
+
<%= re_form_text 'Time Zone', @user.time_zone, :span => '3x11' %>
|
|
8
|
+
<%= re_button_link("Update Your Details", user_change_path, "green") %>
|
|
9
|
+
<% end %>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="clear"></div>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<% javascript_tag do %>
|
|
2
|
+
|
|
3
|
+
$(document).ready(function() {
|
|
4
|
+
|
|
5
|
+
$('#user_password').bind('keypress', function(e) {
|
|
6
|
+
var code = (e.keyCode ? e.keyCode : e.which);
|
|
7
|
+
if (code == 13) { //Enter keycode
|
|
8
|
+
$('#user_login').submit();
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
});
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
<div class="prepend-1 prepend-top span-15">
|
|
18
|
+
<h2>Login</h2>
|
|
19
|
+
<% re_form_for(:user, :url => user_login_path, :html => {:id => 'user_login'}, :span => "5x11") do |f|%>
|
|
20
|
+
<% re_whitebox do %>
|
|
21
|
+
<%= f.text_field :name, :size => 38, :required => true, :label => "Email or Login Name" %>
|
|
22
|
+
<%= f.password_field :password, :size => 25, :required => true%>
|
|
23
|
+
<%= re_check_box "Remember Me", :remember_me, false, false, :span => "5x11" %>
|
|
24
|
+
|
|
25
|
+
<div class="span-11">
|
|
26
|
+
<%= link_to("Forgot Password?", user_pswd_forgot_path) %>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="span-3">
|
|
29
|
+
<%= re_button_submit("Login", "green", :span => "3") %>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="clear"></div>
|
|
32
|
+
<% end %>
|
|
33
|
+
<% end %>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="clear"></div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<div class="prepend-1 prepend-top span-15">
|
|
2
|
+
<h2>Change Your Password</h2>
|
|
3
|
+
<% re_form_for(:user, :url => user_pswd_change_path, :html => {:id => 'user_pswd_change'}, :span => "5x9") do |f|%>
|
|
4
|
+
<% re_whitebox do %>
|
|
5
|
+
<%= f.password_field :old_password, :label => 'Old Password', :size=>25, :required => true%>
|
|
6
|
+
<%= f.password_field :password, :label => 'New Password', :size=>25, :required => true%>
|
|
7
|
+
<%= f.password_field :password_confirmation, :label => 'Confirm New Password', :size=>25, :required => true%>
|
|
8
|
+
|
|
9
|
+
<div class="span-4">
|
|
10
|
+
<%= link_to("Change Your Details", user_change_path) %>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="span-10" style="text-align:right;">
|
|
13
|
+
<%= re_button_submit("Update", "green") %>
|
|
14
|
+
<%= re_button_link("Cancel", user_details_path, "red") %>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="clear"></div>
|
|
17
|
+
<% end %>
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="clear"></div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<div class="prepend-1 prepend-top span-16">
|
|
2
|
+
<h2>Reset Your Password</h2>
|
|
3
|
+
|
|
4
|
+
<% re_form_for(:user, :url => user_pswd_forgot_path, :html => {:id => 'user_pswd_forgot'}, :span => "4x12") do |f| %>
|
|
5
|
+
<% re_whitebox do %>
|
|
6
|
+
<%= f.text_field :email, :required => true, :size => 40, :label => 'Your Email' %>
|
|
7
|
+
|
|
8
|
+
<div class="span-10">
|
|
9
|
+
<%= link_to("Login", user_login_path) %>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="span-4">
|
|
12
|
+
<%= re_button_submit("Reset Password", "green", :span => "4") %>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="clear"></div>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% end %>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="clear"></div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="prepend-1 prepend-top span-16">
|
|
2
|
+
<h2>Reset Your Password</h2>
|
|
3
|
+
<% re_form_for(:user, :url => user_pswd_reset_path, :html => {:id => "user_pswd_reset"}, :span => "5x11") do |f| %>
|
|
4
|
+
<% re_whitebox do %>
|
|
5
|
+
<%= hidden_field_tag :token, @token%>
|
|
6
|
+
|
|
7
|
+
<%= f.text_field :email, :label => 'Your Email', :size=>40, :required => true%>
|
|
8
|
+
<%= f.password_field :password, :label => 'New Password', :size=>25, :required => true%>
|
|
9
|
+
<%= f.password_field :password_confirmation, :label => 'Confirm New Password', :size=>25, :required => true%>
|
|
10
|
+
|
|
11
|
+
<div class="span-10">
|
|
12
|
+
<%= link_to("Login", user_login_path) %>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="span-5">
|
|
15
|
+
<%= re_button_submit("Reset Password", "green", :span => "4") %>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="clear"></div>
|
|
18
|
+
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="clear"></div>
|