ucb_rails_user 2.0.1 → 3.0.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.
@@ -30,6 +30,20 @@ var addDatatablesToUsersTable = function () {
30
30
  $('#DataTables_Table_0_filter').append(addNewHtml)
31
31
  }
32
32
 
33
+ var resetImpersonateButton = function() {
34
+ var targetId = $('#ucb_rails_user_impersonation_target_id').val()
35
+ if (targetId != null && targetId.toString().length > 0) {
36
+ $('input[data-impersonate-button]').removeAttr('disabled')
37
+ } else {
38
+ $('input[data-impersonate-button]').attr('disabled', 'disabled')
39
+ }
40
+ }
41
+
42
+ var clearImpersonateSelection = function() {
43
+ $('#ucb_rails_user_impersonation_target_id').val('')
44
+ resetImpersonateButton()
45
+ }
46
+
33
47
  $( window ).on("load", function() {
34
48
  // the datatable calling was failing intermittently, but adding the timeout
35
49
  // seemed to fix it, so ¯\_(ツ)_/¯
@@ -39,5 +53,46 @@ $( window ).on("load", function() {
39
53
  $('.search-results').hide()
40
54
  $('.ucb-rails-user-loader').show()
41
55
  })
56
+
57
+ var usersSource = new Bloodhound({
58
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
59
+ queryTokenizer: Bloodhound.tokenizers.whitespace,
60
+ remote: {
61
+ url: '/admin/users/impersonate_search?q=%QUERY',
62
+ wildcard: '%QUERY'
63
+ }
64
+ });
65
+
66
+ $('#ucb_rails_user_impersonation_target').typeahead(null, {
67
+ name: 'users',
68
+ source: usersSource,
69
+ display: 'name',
70
+ templates: {
71
+ empty: [
72
+ '<div class="empty-message">',
73
+ 'No match found',
74
+ '</div>'
75
+ ].join('\n'),
76
+ suggestion: function (data) {
77
+ return '<div><strong>' + data.name + '</strong></div>'
78
+ }
79
+ }
80
+ });
81
+
82
+ $('#ucb_rails_user_impersonation_target').keyup(function(event) {
83
+ if ($(event.target).val().length == 0) {
84
+ clearImpersonateSelection()
85
+ }
86
+ })
87
+
88
+ $('#ucb_rails_user_impersonation_target').bind('typeahead:open', function(event, suggestion) {
89
+ clearImpersonateSelection()
90
+ })
91
+
92
+ $('#ucb_rails_user_impersonation_target').bind('typeahead:select', function(event, suggestion) {
93
+ $('#ucb_rails_user_impersonation_target_id').val(suggestion.id)
94
+ resetImpersonateButton()
95
+ })
96
+
42
97
  })
43
98
 
@@ -0,0 +1,12 @@
1
+ @media screen and (min-width: 768px)
2
+ .impersonation-form
3
+ width: 300px
4
+
5
+ .recent-impersonations
6
+ margin-top: 24px
7
+
8
+ ul
9
+ padding-left: 0px
10
+ li
11
+ list-style-type: none
12
+ font-size: 110%
@@ -1,2 +1,3 @@
1
1
  @import "datatables"
2
+ @import "typeahead_tweaks"
2
3
  @import "components/**/*"
@@ -0,0 +1,67 @@
1
+ // Ironically, Bootstrap 3.x breaks styles in typeahead.js - these styles provide the needed repair
2
+ // source: https://gist.github.com/AntMooreWebDev/2f7e423a11bc74359323995df4494167
3
+
4
+ .twitter-typeahead .tt-query,
5
+ .twitter-typeahead .tt-hint
6
+ margin-bottom: 0
7
+
8
+ .twitter-typeahead
9
+ display: block !important
10
+
11
+ .tt-hint
12
+ display: block
13
+ width: 100%
14
+ height: 38px
15
+ margin-top: -2px
16
+ padding: 8px 12px
17
+ font-size: 14px
18
+ line-height: 1.428571429
19
+ color: #999
20
+ vertical-align: middle
21
+ background-color: #ffffff
22
+ border: 1px solid #cccccc
23
+ border-radius: 4px
24
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075)
25
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075)
26
+ -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s
27
+ transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s
28
+
29
+
30
+ .tt-menu
31
+ // make this wide enough to accomodate the org unit code and name
32
+ width: 400px
33
+ min-width: 160px
34
+ margin-top: 2px
35
+ padding: 5px
36
+ background-color: #ffffff
37
+ border: 1px solid #cccccc
38
+ border: 1px solid rgba(0, 0, 0, 0.15)
39
+ border-radius: 4px
40
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175)
41
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175)
42
+ background-clip: padding-box
43
+
44
+
45
+ .tt-suggestion
46
+ display: block
47
+ padding: 3px 20px
48
+ width: 100%
49
+
50
+
51
+ .tt-suggestion.tt-selectable
52
+ margin: 5px 0px 5px 0px
53
+
54
+
55
+ .tt-suggestion.tt-cursor
56
+ color: #fff
57
+ background-color: #428bca
58
+
59
+
60
+ .tt-suggestion.tt-cursor a
61
+ color: #fff
62
+
63
+
64
+ .tt-suggestion p
65
+ margin: 0
66
+
67
+
@@ -11,26 +11,30 @@ module UcbRailsUser::Concerns::ControllerMethods
11
11
 
12
12
  after_action :remove_user_settings
13
13
 
14
- helper_method :superuser?, :current_ldap_person, :current_user, :logged_in?
14
+ helper_method :superuser?, :current_ldap_person, :current_user, :logged_in?, :logged_in_user
15
15
  end
16
16
 
17
17
  def superuser?
18
18
  current_user.try(:superuser?)
19
19
  end
20
20
 
21
- def current_user
22
- @current_user ||= begin
23
- logger.debug 'recalc of current_user'
24
- user_session_manager.current_user(session[:uid])
21
+ def logged_in_user
22
+ @logged_in_user ||= begin
23
+ logger.debug 'recalc of logged_in_user'
24
+ user_session_manager&.current_user(session[:uid])
25
25
  end
26
26
  end
27
27
 
28
+ def current_user
29
+ logged_in_user&.impersonation_target || logged_in_user
30
+ end
31
+
28
32
  # Returns +true+ if there is a logged in user
29
33
  #
30
34
  # @return [true] if user logged in
31
35
  # @return [false] if user not logged in
32
36
  def logged_in?
33
- current_user.present?
37
+ logged_in_user.present?
34
38
  end
35
39
 
36
40
  def log_request
@@ -0,0 +1,43 @@
1
+ module UcbRailsUser::Concerns::ImpersonationsController
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ before_action :check_permissions, except: [:stop_impersonation]
6
+ end
7
+
8
+ def index
9
+
10
+ end
11
+
12
+ def create
13
+ target = User.find_by(id: params[:ucb_rails_user_impersonation][:target_id])
14
+ if logged_in_user.impersonate!(target)
15
+ flash[:info] = "You are now impersonating #{target.full_name}"
16
+ return redirect_to "/"
17
+ else
18
+ if target&.id == logged_in_user.id
19
+ flash[:error] = "Sorry - you can't impersonate yourself."
20
+ else
21
+ flash[:error] = "Unable to start impersonating - please try again"
22
+ end
23
+ return redirect_to action: :index
24
+ end
25
+ end
26
+
27
+ def stop_impersonation
28
+ logged_in_user.stop_impersonation!
29
+ flash[:info] = "You are no longer impersonating."
30
+ redirect_to request.referer || "/"
31
+ end
32
+
33
+ private
34
+
35
+ def check_permissions
36
+ unless logged_in_user.can_impersonate?
37
+ # TODO: I'm not crazy about this - should we provide some generic error pages for common situations?
38
+ return render plain: "Not Authorized"
39
+ end
40
+ end
41
+
42
+ end
43
+
@@ -35,7 +35,6 @@ module UcbRailsUser::Concerns::SessionsController
35
35
  user_session_manager.logout(current_user)
36
36
  provider = session[:omniauth_provider]
37
37
  reset_session
38
- p "using #{redirect_url(provider)}"
39
38
  redirect_to redirect_url(provider)
40
39
  end
41
40
 
@@ -26,6 +26,11 @@ module UcbRailsUser::Concerns::UsersController
26
26
  )
27
27
  end
28
28
 
29
+ def impersonate_search
30
+ result = UcbRailsUser::UserSearch.find_users_by_name(params[:q])
31
+ render json: result.map { |u| { name: u.full_name, id: u.id } }
32
+ end
33
+
29
34
  def edit
30
35
  end
31
36
 
@@ -0,0 +1,8 @@
1
+ class UcbRailsUser::ImpersonationsController < ApplicationController
2
+ include UcbRailsUser::Concerns::ImpersonationsController
3
+
4
+ # Don't add anything more here - any logic for this controller should go into
5
+ # Concerns::ImpersonationsController. 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
@@ -1,6 +1,10 @@
1
1
  module UserConcerns
2
2
  extend ActiveSupport::Concern
3
3
 
4
+ included do
5
+ has_many :impersonations, class_name: "::UcbRailsUser::Impersonation"
6
+ end
7
+
4
8
  # Overridden by application
5
9
  def roles
6
10
  []
@@ -39,6 +43,74 @@ module UserConcerns
39
43
  "#{first_name} #{last_name}".strip
40
44
  end
41
45
 
46
+ def can_impersonate?
47
+ superuser?
48
+ end
49
+
50
+ # target can be a User instance or a user id
51
+ # return true if Impersonation succeeded; false otherwise
52
+ def impersonate!(target)
53
+ target_id =
54
+ if target.respond_to?(:id)
55
+ target.id
56
+ else
57
+ User.find_by(id: target)&.id
58
+ end
59
+ return false unless impersonation_is_valid?(target_id)
60
+ @current_impersonation = create_impersonation(target_id)
61
+ @current_impersonation.present?
62
+ end
63
+
64
+ def current_impersonation
65
+ return @current_impersonation if defined?(@current_impersonation)
66
+ @current_impersonation = UcbRailsUser::Impersonation.find_by(user_id: self.id, active: true)
67
+ end
68
+
69
+ def impersonation_target
70
+ current_impersonation&.target
71
+ end
72
+
73
+ def impersonating?
74
+ current_impersonation.present?
75
+ end
76
+
77
+ def stop_impersonation!
78
+ impersonations.update_all(active: false)
79
+ @current_impersonation = nil
80
+ end
81
+
82
+ def recent_impersonations(max=25)
83
+ @recent_impersonations ||=
84
+ impersonations
85
+ .uniq(&:target_id)
86
+ .reject(&:active)
87
+ .sort_by(&:created_at)
88
+ .reverse
89
+ .take(max)
90
+ end
91
+
92
+ private
93
+
94
+ def impersonation_is_valid?(target_id)
95
+ target_id.present? &&
96
+ can_impersonate? &&
97
+ target_id != self.id
98
+ end
99
+
100
+ def create_impersonation(target_id)
101
+ new_impersonation =
102
+ UcbRailsUser::Impersonation.transaction do
103
+ # make sure any other impersonations are cleared out
104
+ impersonations.update_all(active: false)
105
+ UcbRailsUser::Impersonation.create!(user_id: self.id, target_id: target_id, active: true)
106
+ end
107
+ if new_impersonation.present? && !new_impersonation.new_record?
108
+ new_impersonation
109
+ else
110
+ nil
111
+ end
112
+ end
113
+
42
114
  class_methods do
43
115
  def active
44
116
  where(inactive_flag: false)
@@ -0,0 +1,10 @@
1
+ module UcbRailsUser::Concerns::ImpersonationConcerns
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ belongs_to :user
6
+ belongs_to :target, class_name: "User"
7
+ end
8
+
9
+ end
10
+
@@ -0,0 +1,9 @@
1
+ class UcbRailsUser::Impersonation < ApplicationRecord
2
+ include UcbRailsUser::Concerns::ImpersonationConcerns
3
+
4
+ # Don't add anything more here - any logic for the User class should go into
5
+ # UserConcerns. 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
+
9
+ end
@@ -0,0 +1,22 @@
1
+ module UcbRailsUser::UserSearch
2
+
3
+ def self.find_users_by_name(name)
4
+ return [] unless name.present?
5
+ (name1, name2) = name.split
6
+ query = case_insenstive(:first_name, name1)
7
+ .or(case_insenstive(:last_name, name1))
8
+ if name2.present?
9
+ query = query
10
+ .or(case_insenstive(:first_name, name2))
11
+ .or(case_insenstive(:last_name, name2))
12
+ end
13
+ query.order(:last_name, :first_name)
14
+ end
15
+
16
+ private
17
+
18
+ def self.case_insenstive(column, value)
19
+ User.where("LOWER(#{column}) = ?", value.downcase)
20
+ end
21
+
22
+ end
@@ -0,0 +1,20 @@
1
+ %h1 Impersonate user
2
+
3
+ - if current_user.impersonating?
4
+ .clear-impersonation
5
+ = link_to "Stop impersonating #{current_user.impersonation_target.full_name}", admin_stop_impersonation_path(), class: "btn btn-primary"
6
+ - else
7
+ .impersonation-form
8
+ = simple_form_for UcbRailsUser::Impersonation.new, url: admin_impersonations_path(), method: :post do |f|
9
+ = f.input :target, label: "User", input_html: { class: "typeahead" }
10
+ = f.input :target_id, as: :hidden
11
+ = f.button :submit, value: "Impersonate", class: "btn btn-primary", disabled: true, data: { impersonate_button: true }
12
+
13
+ .recent-impersonations
14
+ - if current_user.recent_impersonations.present?
15
+ %h3 Recent impersonations
16
+ %ul
17
+ - current_user.recent_impersonations.each do |imp|
18
+ %li= link_to imp.target.full_name, admin_impersonations_path() + "?ucb_rails_user_impersonation[target_id=#{imp.target.id}]", method: :post
19
+ - else
20
+ %h4 No recent impersonations
data/config/routes.rb CHANGED
@@ -15,6 +15,12 @@ Rails.application.routes.draw do
15
15
 
16
16
  match "/admin/users/search", to: UcbRailsUser::UsersController.action(:search),
17
17
  as: "admin_user_search", via: [:get]
18
+ match "/admin/users/impersonate_search", to: UcbRailsUser::UsersController.action(:impersonate_search),
19
+ as: "admin_user_impersonate_search", via: [:get]
18
20
  resources :users, controller: "ucb_rails_user/users", path: "admin/users", as: :admin_users
19
21
 
22
+ resources :impersonations, controller: "ucb_rails_user/impersonations", path: "admin/impersonations", as: :admin_impersonations
23
+ match "/admin/stop_impersonation", to: UcbRailsUser::ImpersonationsController.action(:stop_impersonation),
24
+ as: :admin_stop_impersonation, via: [:get]
25
+
20
26
  end
@@ -0,0 +1,10 @@
1
+ class CreateImpersonations < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :impersonations do |t|
4
+ t.references :user, null: false, foreign_key: true
5
+ t.references :target, null: false, foreign_key: { to_table: :users }
6
+ t.boolean :active, null: false, default: false
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -3,6 +3,8 @@ module UcbRailsUser
3
3
  config.generators do |g|
4
4
  g.test_framework :rspec
5
5
  g.integration_tool :rspec
6
+ g.fixture_replacement :factory_bot
7
+ g.factory_bot dir: "spec/factories"
6
8
  end
7
9
  end
8
10
 
@@ -9,6 +9,12 @@ module UcbRailsUser
9
9
  follow_redirect!
10
10
  end
11
11
 
12
+ def system_login_user(user)
13
+ OmniAuth.config.test_mode = true
14
+ auth_mock(user.ldap_uid)
15
+ visit login_path()
16
+ end
17
+
12
18
  def auth_mock(uid)
13
19
  OmniAuth.config.mock_auth[:cas] = OmniAuth::AuthHash.new(
14
20
  provider: "cas",
@@ -1,3 +1,3 @@
1
1
  module UcbRailsUser
2
- VERSION = '2.0.1'
2
+ VERSION = '3.0.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ucb_rails_user
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Downey
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2019-07-11 00:00:00.000000000 Z
14
+ date: 2019-08-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails
@@ -139,6 +139,20 @@ dependencies:
139
139
  - - "~>"
140
140
  - !ruby/object:Gem::Version
141
141
  version: '3.0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: puma
144
+ requirement: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - "~>"
147
+ - !ruby/object:Gem::Version
148
+ version: '3.11'
149
+ type: :development
150
+ prerelease: false
151
+ version_requirements: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - "~>"
154
+ - !ruby/object:Gem::Version
155
+ version: '3.11'
142
156
  - !ruby/object:Gem::Dependency
143
157
  name: sqlite3
144
158
  requirement: !ruby/object:Gem::Requirement
@@ -173,6 +187,90 @@ dependencies:
173
187
  - - "~>"
174
188
  - !ruby/object:Gem::Version
175
189
  version: '3.5'
190
+ - !ruby/object:Gem::Dependency
191
+ name: factory_bot_rails
192
+ requirement: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
197
+ type: :development
198
+ prerelease: false
199
+ version_requirements: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ">="
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ - !ruby/object:Gem::Dependency
205
+ name: faker
206
+ requirement: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - ">="
209
+ - !ruby/object:Gem::Version
210
+ version: '0'
211
+ type: :development
212
+ prerelease: false
213
+ version_requirements: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - ">="
216
+ - !ruby/object:Gem::Version
217
+ version: '0'
218
+ - !ruby/object:Gem::Dependency
219
+ name: capybara
220
+ requirement: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - "~>"
223
+ - !ruby/object:Gem::Version
224
+ version: '3.0'
225
+ type: :development
226
+ prerelease: false
227
+ version_requirements: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - "~>"
230
+ - !ruby/object:Gem::Version
231
+ version: '3.0'
232
+ - !ruby/object:Gem::Dependency
233
+ name: capybara-screenshot
234
+ requirement: !ruby/object:Gem::Requirement
235
+ requirements:
236
+ - - ">="
237
+ - !ruby/object:Gem::Version
238
+ version: '0'
239
+ type: :development
240
+ prerelease: false
241
+ version_requirements: !ruby/object:Gem::Requirement
242
+ requirements:
243
+ - - ">="
244
+ - !ruby/object:Gem::Version
245
+ version: '0'
246
+ - !ruby/object:Gem::Dependency
247
+ name: selenium-webdriver
248
+ requirement: !ruby/object:Gem::Requirement
249
+ requirements:
250
+ - - ">="
251
+ - !ruby/object:Gem::Version
252
+ version: '0'
253
+ type: :development
254
+ prerelease: false
255
+ version_requirements: !ruby/object:Gem::Requirement
256
+ requirements:
257
+ - - ">="
258
+ - !ruby/object:Gem::Version
259
+ version: '0'
260
+ - !ruby/object:Gem::Dependency
261
+ name: chromedriver-helper
262
+ requirement: !ruby/object:Gem::Requirement
263
+ requirements:
264
+ - - ">="
265
+ - !ruby/object:Gem::Version
266
+ version: '0'
267
+ type: :development
268
+ prerelease: false
269
+ version_requirements: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - ">="
272
+ - !ruby/object:Gem::Version
273
+ version: '0'
176
274
  description: Rails engine for managing user accounts within UC Berkeley's auth system
177
275
  email:
178
276
  - darinwilson@gmail.com
@@ -186,31 +284,39 @@ files:
186
284
  - app/assets/config/ucb_rails_user_manifest.js
187
285
  - app/assets/javascripts/ucb_rails_user/datatables.js
188
286
  - app/assets/javascripts/ucb_rails_user/scripts.js
287
+ - app/assets/javascripts/ucb_rails_user/typeahead.bundle.js
189
288
  - app/assets/javascripts/ucb_rails_user/ucb_rails_user.js
289
+ - app/assets/stylesheets/ucb_rails_user/components/_impersonations.sass
190
290
  - app/assets/stylesheets/ucb_rails_user/components/_loader.sass
191
291
  - app/assets/stylesheets/ucb_rails_user/components/_users_table.sass
192
292
  - app/assets/stylesheets/ucb_rails_user/datatables.css
193
293
  - app/assets/stylesheets/ucb_rails_user/main.sass
194
294
  - app/assets/stylesheets/ucb_rails_user/styles.css
295
+ - app/assets/stylesheets/ucb_rails_user/typeahead_tweaks.sass
195
296
  - app/controllers/ucb_rails_user/concerns/controller_methods.rb
196
297
  - app/controllers/ucb_rails_user/concerns/home_controller.rb
298
+ - app/controllers/ucb_rails_user/concerns/impersonations_controller.rb
197
299
  - app/controllers/ucb_rails_user/concerns/sessions_controller.rb
198
300
  - app/controllers/ucb_rails_user/concerns/users_controller.rb
199
301
  - app/controllers/ucb_rails_user/home_controller.rb
302
+ - app/controllers/ucb_rails_user/impersonations_controller.rb
200
303
  - app/controllers/ucb_rails_user/sessions_controller.rb
201
304
  - app/controllers/ucb_rails_user/users_controller.rb
202
305
  - app/helpers/ucb_rails_user/users_helper.rb
203
306
  - app/helpers/ucb_rails_user_helper.rb
204
307
  - app/models/concerns/user_concerns.rb
308
+ - app/models/ucb_rails_user/concerns/impersonation_concerns.rb
205
309
  - app/models/ucb_rails_user/configuration/cas.rb
206
310
  - app/models/ucb_rails_user/configuration/configuration.rb
207
311
  - app/models/ucb_rails_user/configuration/email.rb
208
312
  - app/models/ucb_rails_user/configuration/exception_notification.rb
209
313
  - app/models/ucb_rails_user/configuration/ldap.rb
314
+ - app/models/ucb_rails_user/impersonation.rb
210
315
  - app/models/ucb_rails_user/ldap_person/entry.rb
211
316
  - app/models/ucb_rails_user/ldap_person/finder.rb
212
317
  - app/models/ucb_rails_user/ldap_person/test_finder.rb
213
318
  - app/models/ucb_rails_user/user_ldap_service.rb
319
+ - app/models/ucb_rails_user/user_search.rb
214
320
  - app/models/ucb_rails_user/user_session_manager/active_in_user_table.rb
215
321
  - app/models/ucb_rails_user/user_session_manager/admin_in_user_table.rb
216
322
  - app/models/ucb_rails_user/user_session_manager/base.rb
@@ -221,6 +327,7 @@ files:
221
327
  - app/models/user.rb
222
328
  - app/views/ucb_rails_user/home/logged_in.html.haml
223
329
  - app/views/ucb_rails_user/home/not_logged_in.html.haml
330
+ - app/views/ucb_rails_user/impersonations/index.html.haml
224
331
  - app/views/ucb_rails_user/lps/_form.html.haml
225
332
  - app/views/ucb_rails_user/lps/_modal.html.haml
226
333
  - app/views/ucb_rails_user/lps/_results.html.haml
@@ -237,6 +344,7 @@ files:
237
344
  - config/locales/simple_form.en.yml
238
345
  - config/routes.rb
239
346
  - db/migrate/20170324221936_create_users.rb
347
+ - db/migrate/20190807231505_create_impersonations.rb
240
348
  - lib/tasks/ucb_rails_user_tasks.rake
241
349
  - lib/templates/erb/scaffold/_form.html.erb
242
350
  - lib/ucb_rails_user.rb
@@ -262,8 +370,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
262
370
  - !ruby/object:Gem::Version
263
371
  version: '0'
264
372
  requirements: []
265
- rubyforge_project:
266
- rubygems_version: 2.7.7
373
+ rubygems_version: 3.0.3
267
374
  signing_key:
268
375
  specification_version: 4
269
376
  summary: Rails engine for UCB user accounts