ucb_rails_user 0.9.0
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +166 -0
- data/Rakefile +36 -0
- data/app/assets/config/ucb_rails_user_manifest.js +0 -0
- data/app/assets/javascripts/ucb_rails_user/datatables.js +15441 -0
- data/app/assets/javascripts/ucb_rails_user/scripts.js +15 -0
- data/app/assets/javascripts/ucb_rails_user/ucb_rails_user.js +39 -0
- data/app/assets/stylesheets/ucb_rails_user/components/_add_users_search_results_table.sass +2 -0
- data/app/assets/stylesheets/ucb_rails_user/components/_loader.sass +46 -0
- data/app/assets/stylesheets/ucb_rails_user/components/_users_table.sass +10 -0
- data/app/assets/stylesheets/ucb_rails_user/datatables.css +201 -0
- data/app/assets/stylesheets/ucb_rails_user/main.sass +2 -0
- data/app/assets/stylesheets/ucb_rails_user/styles.css +19 -0
- data/app/controllers/ucb_rails_user/concerns/controller_methods.rb +92 -0
- data/app/controllers/ucb_rails_user/concerns/home_controller.rb +17 -0
- data/app/controllers/ucb_rails_user/concerns/sessions_controller.rb +68 -0
- data/app/controllers/ucb_rails_user/concerns/users_controller.rb +132 -0
- data/app/controllers/ucb_rails_user/home_controller.rb +10 -0
- data/app/controllers/ucb_rails_user/sessions_controller.rb +9 -0
- data/app/controllers/ucb_rails_user/users_controller.rb +8 -0
- data/app/helpers/ucb_rails_user/users_helper.rb +18 -0
- data/app/helpers/ucb_rails_user_helper.rb +17 -0
- data/app/models/concerns/user_concerns.rb +53 -0
- data/app/models/ucb_rails_user/configuration/cas.rb +53 -0
- data/app/models/ucb_rails_user/configuration/configuration.rb +72 -0
- data/app/models/ucb_rails_user/configuration/email.rb +73 -0
- data/app/models/ucb_rails_user/configuration/exception_notification.rb +21 -0
- data/app/models/ucb_rails_user/configuration/ldap.rb +50 -0
- data/app/models/ucb_rails_user/ldap_person/entry.rb +62 -0
- data/app/models/ucb_rails_user/ldap_person/finder.rb +87 -0
- data/app/models/ucb_rails_user/ldap_person/test_finder.rb +57 -0
- data/app/models/ucb_rails_user/user_ldap_service.rb +65 -0
- data/app/models/ucb_rails_user/user_session_manager/active_in_user_table.rb +29 -0
- data/app/models/ucb_rails_user/user_session_manager/admin_in_user_table.rb +13 -0
- data/app/models/ucb_rails_user/user_session_manager/base.rb +54 -0
- data/app/models/ucb_rails_user/user_session_manager/in_people_ou.rb +27 -0
- data/app/models/ucb_rails_user/user_session_manager/in_people_ou_add_to_users_table.rb +21 -0
- data/app/models/ucb_rails_user/user_session_manager/ldap_person_user_wrapper.rb +29 -0
- data/app/models/user.rb +8 -0
- data/app/views/ucb_rails_user/home/logged_in.html.haml +5 -0
- data/app/views/ucb_rails_user/home/not_logged_in.html.haml +5 -0
- data/app/views/ucb_rails_user/lps/_form.html.haml +19 -0
- data/app/views/ucb_rails_user/lps/_modal.html.haml +9 -0
- data/app/views/ucb_rails_user/lps/_results.html.haml +34 -0
- data/app/views/ucb_rails_user/lps/search.js.haml +3 -0
- data/app/views/ucb_rails_user/users/_form.html.haml +14 -0
- data/app/views/ucb_rails_user/users/_search_results.html.haml +24 -0
- data/app/views/ucb_rails_user/users/_user.html.haml +12 -0
- data/app/views/ucb_rails_user/users/edit.html.haml +3 -0
- data/app/views/ucb_rails_user/users/index.html.haml +23 -0
- data/app/views/ucb_rails_user/users/new.html.haml +16 -0
- data/app/views/ucb_rails_user/users/search.js.haml +4 -0
- data/config/initializers/simple_form.rb +171 -0
- data/config/initializers/simple_form_bootstrap.rb +154 -0
- data/config/locales/simple_form.en.yml +31 -0
- data/config/routes.rb +20 -0
- data/db/migrate/20170324221936_create_users.rb +29 -0
- data/lib/tasks/ucb_rails_user_tasks.rake +4 -0
- data/lib/templates/erb/scaffold/_form.html.erb +13 -0
- data/lib/ucb_rails_user.rb +21 -0
- data/lib/ucb_rails_user/engine.rb +28 -0
- data/lib/ucb_rails_user/version.rb +3 -0
- metadata +277 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
module UcbRailsUser::Concerns::SessionsController
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
skip_before_action :ensure_authenticated_user, :log_request
|
6
|
+
end
|
7
|
+
|
8
|
+
# Redirects to authentication provider
|
9
|
+
#
|
10
|
+
# @return [nil]
|
11
|
+
def new
|
12
|
+
provider = UcbRailsUser[:omniauth_provider] || :cas
|
13
|
+
redirect_to "/auth/#{provider}"
|
14
|
+
end
|
15
|
+
|
16
|
+
# Login user after authentication by provider
|
17
|
+
#
|
18
|
+
# @return [nil]
|
19
|
+
def create
|
20
|
+
uid = request.env['omniauth.auth'].uid
|
21
|
+
session[:omniauth_provider] = request.env['omniauth.auth'].provider
|
22
|
+
|
23
|
+
if user_session_manager.login(uid)
|
24
|
+
session[:uid] = uid
|
25
|
+
redirect_to session[:original_url] || root_path
|
26
|
+
else
|
27
|
+
redirect_to not_authorized_path
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Log user out
|
32
|
+
#
|
33
|
+
# @return [nil]
|
34
|
+
def destroy
|
35
|
+
user_session_manager.logout(current_user)
|
36
|
+
provider = session[:omniauth_provider]
|
37
|
+
reset_session
|
38
|
+
p "using #{redirect_url(provider)}"
|
39
|
+
redirect_to redirect_url(provider)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Action called when unauthorized access attempted
|
43
|
+
#
|
44
|
+
# @return [nil]
|
45
|
+
def not_authorized
|
46
|
+
render(:text => "Not Authorized", :status => 401)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Handler for authentication failure.
|
50
|
+
#
|
51
|
+
# @return [nil]
|
52
|
+
def failure
|
53
|
+
Rails.logger.debug("Authentication Failed for: #{request.env['omniauth.auth']}")
|
54
|
+
render(:text => "Not Authorized", :status => 401)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def redirect_url(provider)
|
60
|
+
if provider.to_s == 'cas'
|
61
|
+
"https://#{UcbRailsUser[:cas_host]}/cas/logout?service=#{root_url}"
|
62
|
+
else
|
63
|
+
root_path
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module UcbRailsUser::Concerns::UsersController
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
before_action :find_user, :only => [:edit, :update, :destroy]
|
6
|
+
before_action :ensure_admin_user
|
7
|
+
skip_before_action :ensure_admin_user, if: ->{ action_name == "toggle_superuser" && Rails.env.development? }
|
8
|
+
end
|
9
|
+
|
10
|
+
def index
|
11
|
+
@users = User.all
|
12
|
+
respond_to do |format|
|
13
|
+
format.html { @users = User.all }
|
14
|
+
format.json { render json: UcbRails::UsersDatatable.new(view_context).as_json }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def search
|
19
|
+
@results = UcbRailsUser::LdapPerson::Finder.find_by_attributes(
|
20
|
+
{
|
21
|
+
givenname: params.fetch(:first_name),
|
22
|
+
sn: params.fetch(:last_name),
|
23
|
+
employeenumber: params.fetch(:employee_id)
|
24
|
+
},
|
25
|
+
sort: :last_first_downcase
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def edit
|
30
|
+
end
|
31
|
+
|
32
|
+
def new
|
33
|
+
end
|
34
|
+
|
35
|
+
def create
|
36
|
+
uid = params.fetch(:ldap_uid)
|
37
|
+
user = nil
|
38
|
+
if user = User.find_by_ldap_uid(uid)
|
39
|
+
flash[:warning] = "User already exists"
|
40
|
+
else
|
41
|
+
begin
|
42
|
+
user = UcbRailsUser::UserLdapService.create_user_from_uid(uid)
|
43
|
+
flash[:notice] = "Record created"
|
44
|
+
rescue Exception => e
|
45
|
+
raise e
|
46
|
+
flash[:danger] = "Unable to create new user - please try again"
|
47
|
+
return redirect_to new_admin_user_path()
|
48
|
+
end
|
49
|
+
end
|
50
|
+
redirect_to edit_admin_user_path(user)
|
51
|
+
end
|
52
|
+
|
53
|
+
def update
|
54
|
+
if @user.update_attributes(user_params)
|
55
|
+
redirect_to(admin_users_path, notice: 'Record updated')
|
56
|
+
else
|
57
|
+
render("edit")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def destroy
|
62
|
+
if @user.destroy
|
63
|
+
flash[:notice] = 'Record deleted'
|
64
|
+
else
|
65
|
+
flash[:error] = @user.errors[:base].first
|
66
|
+
end
|
67
|
+
|
68
|
+
redirect_to(admin_users_path)
|
69
|
+
end
|
70
|
+
|
71
|
+
def ldap_search
|
72
|
+
# FIXME: this was retrofitted to support typeahead ajax json queries
|
73
|
+
if(query = params[:query])
|
74
|
+
@lps_entries = UcbRails::OmniUserTypeahead.new.ldap_results(query)
|
75
|
+
@lps_entries.map!{|entry|
|
76
|
+
attrs = entry.attributes.tap{|attrs| attrs["first_last_name"] = "#{attrs['first_name']} #{attrs['last_name']}" }
|
77
|
+
attrs.as_json
|
78
|
+
}
|
79
|
+
|
80
|
+
render json: @lps_entries
|
81
|
+
|
82
|
+
else
|
83
|
+
@lps_entries = UcbRails::LdapPerson::Finder.find_by_first_last(
|
84
|
+
params.fetch(:first_name),
|
85
|
+
params.fetch(:last_name),
|
86
|
+
:sort => :last_first_downcase
|
87
|
+
)
|
88
|
+
@lps_existing_uids = User.where(ldap_uid: @lps_entries.map(&:uid)).pluck(:uid)
|
89
|
+
render 'lps/search'
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
def typeahead_search
|
95
|
+
uta = UcbRails::UserTypeahead.new
|
96
|
+
render json: uta.results(params.fetch(:query))
|
97
|
+
end
|
98
|
+
|
99
|
+
def omni_typeahead_search
|
100
|
+
uta = UcbRails::OmniUserTypeahead.new
|
101
|
+
render json: uta.results(params.fetch(:query))
|
102
|
+
end
|
103
|
+
|
104
|
+
def toggle_superuser
|
105
|
+
current_user.try(:superuser!, !superuser?)
|
106
|
+
redirect_to root_path
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def user_params
|
112
|
+
params.require(:user).permit(
|
113
|
+
:superuser_flag,
|
114
|
+
:inactive_flag,
|
115
|
+
:first_name,
|
116
|
+
:last_name,
|
117
|
+
:email,
|
118
|
+
:alternate_email,
|
119
|
+
:phone,
|
120
|
+
:last_request_at,
|
121
|
+
:last_logout_at,
|
122
|
+
:last_login_at,
|
123
|
+
:uid
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
def find_user
|
128
|
+
@user ||= User.find(params.fetch(:id))
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class UcbRailsUser::HomeController < ApplicationController
|
2
|
+
include UcbRailsUser::Concerns::ControllerMethods
|
3
|
+
include UcbRailsUser::Concerns::HomeController
|
4
|
+
|
5
|
+
# Don't add anything more here - any logic for this class should go into
|
6
|
+
# Concerns::HomeController. This will make it much easier for host
|
7
|
+
# apps to customize behavior if they need to
|
8
|
+
# http://guides.rubyonrails.org/engines.html#implementing-decorator-pattern-using-activesupport-concern
|
9
|
+
end
|
10
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# Manages starting and ending of sessions, i.e., logging in and out.
|
2
|
+
class UcbRailsUser::SessionsController < ApplicationController
|
3
|
+
include UcbRailsUser::Concerns::SessionsController
|
4
|
+
|
5
|
+
# Don't add anything more here - any logic for this class should go into
|
6
|
+
# Concerns::SessionsController. This will make it much easier for host
|
7
|
+
# apps to customize behavior if they need to
|
8
|
+
# http://guides.rubyonrails.org/engines.html#implementing-decorator-pattern-using-activesupport-concern
|
9
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class UcbRailsUser::UsersController < ApplicationController
|
2
|
+
include UcbRailsUser::Concerns::UsersController
|
3
|
+
|
4
|
+
# Don't add anything more here - any logic for this controller should go into
|
5
|
+
# Concerns::UserController. This will make it much easier for host apps to customize
|
6
|
+
# behavior if they need to
|
7
|
+
# http://guides.rubyonrails.org/engines.html#implementing-decorator-pattern-using-activesupport-concern
|
8
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module UcbRailsUser
|
2
|
+
module UsersHelper
|
3
|
+
|
4
|
+
def link_to_new_user
|
5
|
+
text = 'New User'
|
6
|
+
# text = image_tag('ucb_rails/glyphicons_006_user_add.png', size: '14x14')
|
7
|
+
button(text, :primary,
|
8
|
+
class: 'ldap-person-search',
|
9
|
+
data: {
|
10
|
+
search_url: "",
|
11
|
+
result_link_url: new_admin_user_path,
|
12
|
+
result_link_http_method: 'post',
|
13
|
+
}
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# These methods should be extracted into own gem.
|
2
|
+
module UcbRailsUserHelper
|
3
|
+
|
4
|
+
def ucbr_table_tag(*args)
|
5
|
+
options = canonicalize_options(args.extract_options!)
|
6
|
+
|
7
|
+
ar_class = args.first
|
8
|
+
if ar_class.respond_to?(:haml_attributes)
|
9
|
+
options[:id] ||= ar_class.haml_attributes["id"]
|
10
|
+
options = ensure_class(options, ar_class.haml_attributes["class"])
|
11
|
+
end
|
12
|
+
|
13
|
+
bs_table_tag(options) do
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module UserConcerns
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
# Overridden by application
|
5
|
+
def roles
|
6
|
+
[]
|
7
|
+
end
|
8
|
+
|
9
|
+
def has_role?(role)
|
10
|
+
superuser? || roles.include?(role)
|
11
|
+
end
|
12
|
+
|
13
|
+
def active?
|
14
|
+
!inactive?
|
15
|
+
end
|
16
|
+
|
17
|
+
def inactive?
|
18
|
+
inactive_flag
|
19
|
+
end
|
20
|
+
|
21
|
+
def superuser!(_superuser=true)
|
22
|
+
update_attribute(:superuser_flag, _superuser)
|
23
|
+
end
|
24
|
+
|
25
|
+
def superuser?
|
26
|
+
superuser_flag
|
27
|
+
end
|
28
|
+
|
29
|
+
def inactive!(_inactive=true)
|
30
|
+
update_attribute(:inactive_flag, _inactive)
|
31
|
+
end
|
32
|
+
|
33
|
+
def ldap_entry
|
34
|
+
UcbRailsUser::LdapPerson::Finder.find_by_uid!(uid)
|
35
|
+
end
|
36
|
+
|
37
|
+
def full_name
|
38
|
+
return nil unless first_name || last_name
|
39
|
+
"#{first_name} #{last_name}".strip
|
40
|
+
end
|
41
|
+
|
42
|
+
class_methods do
|
43
|
+
def active
|
44
|
+
where(inactive_flag: false)
|
45
|
+
end
|
46
|
+
|
47
|
+
def superuser
|
48
|
+
where(superuser_flag: true)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module UcbRailsUser
|
2
|
+
module Configuration
|
3
|
+
|
4
|
+
class Cas
|
5
|
+
attr_accessor :config
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
self.config = config.presence || {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure
|
12
|
+
configure_omniauth
|
13
|
+
set_ucb_rails_cas_host
|
14
|
+
end
|
15
|
+
|
16
|
+
def configure_omniauth
|
17
|
+
host_name = host
|
18
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
19
|
+
|
20
|
+
unless Rails.env.production?
|
21
|
+
provider(:developer, fields: [:uid], uid_field: :uid)
|
22
|
+
end
|
23
|
+
|
24
|
+
provider :cas,
|
25
|
+
host: host_name,
|
26
|
+
login_url: '/cas/login?renew=true', # renew=true forces the login screen to appear each time
|
27
|
+
service_validate_url: '/cas/serviceValidate'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_ucb_rails_cas_host
|
32
|
+
UcbRailsUser.config.cas_host = host
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def host
|
38
|
+
config.fetch('host', default_host)
|
39
|
+
end
|
40
|
+
|
41
|
+
def default_host
|
42
|
+
Rails.env.production? ? 'auth.berkeley.edu' : 'auth-test.berkeley.edu'
|
43
|
+
end
|
44
|
+
|
45
|
+
class << self
|
46
|
+
def configure(config)
|
47
|
+
new(config).configure
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module UcbRailsUser
|
2
|
+
module Configuration
|
3
|
+
|
4
|
+
# Manage configuration from file. Per environment or overall.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# # config/config.yml
|
8
|
+
# test:
|
9
|
+
# ldap:
|
10
|
+
# username: test_username
|
11
|
+
# password: test_password
|
12
|
+
#
|
13
|
+
# ldap:
|
14
|
+
# username: top_username
|
15
|
+
# password: top_password
|
16
|
+
#
|
17
|
+
# # in config/initializers/ucb_rails.rb (e.g.)
|
18
|
+
# config = UcbRailsUser::Credentials.new
|
19
|
+
#
|
20
|
+
# # in production -- pulls from top level, since no 'production' key
|
21
|
+
# config.for('ldap') #=> { 'username' => 'top_username', 'password' => 'top_password' }
|
22
|
+
#
|
23
|
+
# # in test -- pulls from 'test' key
|
24
|
+
# config.for('ldap') #=> { 'username' => 'test_username', 'password' => 'test_password' }
|
25
|
+
class Configuration
|
26
|
+
FileNotFound = Class.new(StandardError)
|
27
|
+
KeyNotFound = Class.new(StandardError)
|
28
|
+
|
29
|
+
attr_accessor :config_filename, :config_yaml
|
30
|
+
|
31
|
+
def initialize(filename=Rails.root.join('config/config.yml'))
|
32
|
+
self.config_filename = filename.to_s
|
33
|
+
load_file
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return configuration value for _key_.
|
37
|
+
# @param key [String]
|
38
|
+
def for(key)
|
39
|
+
from_environment(key) || from_top_level(key)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return configuration value for _key_.
|
43
|
+
# @raise [UcbRailsUser::Configuration::KeyNotFound] if _key_ not in configuration file.
|
44
|
+
def for!(key)
|
45
|
+
self.for(key) or raise(KeyNotFound, key.inspect)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def from_environment(key)
|
51
|
+
environment_value && environment_value[key]
|
52
|
+
end
|
53
|
+
|
54
|
+
def from_top_level(key)
|
55
|
+
config_yaml[key]
|
56
|
+
end
|
57
|
+
|
58
|
+
def environment_value
|
59
|
+
config_yaml[Rails.env]
|
60
|
+
end
|
61
|
+
|
62
|
+
def load_file
|
63
|
+
if File.exists?(config_filename)
|
64
|
+
self.config_yaml = YAML.load_file(config_filename)
|
65
|
+
else
|
66
|
+
raise(FileNotFound, config_filename)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|