openstax_accounts 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +89 -58
  3. data/app/controllers/openstax/accounts/application_controller.rb +3 -12
  4. data/app/controllers/openstax/accounts/dev/accounts_controller.rb +19 -0
  5. data/app/controllers/openstax/accounts/dev/base_controller.rb +2 -8
  6. data/app/controllers/openstax/accounts/sessions_controller.rb +31 -19
  7. data/app/handlers/openstax/accounts/dev/{users_index.rb → accounts_index.rb} +4 -4
  8. data/app/handlers/openstax/accounts/sessions_callback.rb +43 -0
  9. data/app/models/openstax/accounts/{user.rb → account.rb} +7 -22
  10. data/app/models/openstax/accounts/anonymous_account.rb +24 -0
  11. data/app/models/openstax/accounts/application_account.rb +7 -0
  12. data/app/representers/openstax/accounts/api/v1/{user_representer.rb → account_representer.rb} +1 -1
  13. data/app/representers/openstax/accounts/api/v1/{user_search_representer.rb → account_search_representer.rb} +7 -6
  14. data/app/representers/openstax/accounts/api/v1/{application_user_representer.rb → application_account_representer.rb} +5 -4
  15. data/app/representers/openstax/accounts/api/v1/application_account_search_representer.rb +20 -0
  16. data/app/representers/openstax/accounts/api/v1/{application_users_representer.rb → application_accounts_representer.rb} +3 -3
  17. data/app/routines/openstax/accounts/dev/{search_users.rb → search_accounts.rb} +5 -5
  18. data/app/routines/openstax/accounts/{search_users.rb → search_accounts.rb} +55 -46
  19. data/app/routines/openstax/accounts/sync_accounts.rb +47 -0
  20. data/app/views/openstax/accounts/dev/{users → accounts}/_search_results.html.erb +13 -13
  21. data/app/views/openstax/accounts/dev/{users/login.html.erb → accounts/index.html.erb} +3 -3
  22. data/app/views/openstax/accounts/dev/{users → accounts}/index.js.erb +1 -1
  23. data/app/views/openstax/accounts/shared/{users → accounts}/_index.html.erb +4 -1
  24. data/config/initializers/action_interceptor.rb +14 -0
  25. data/config/routes.rb +18 -15
  26. data/db/migrate/0_create_openstax_accounts_accounts.rb +22 -0
  27. data/lib/generators/openstax/accounts/schedule/USAGE +1 -1
  28. data/lib/generators/openstax/accounts/schedule/templates/schedule.rb +1 -1
  29. data/lib/openstax/accounts/current_user_manager.rb +74 -65
  30. data/lib/openstax/accounts/default_account_user_mapper.rb +15 -0
  31. data/lib/openstax/accounts/engine.rb +2 -0
  32. data/lib/openstax/accounts/extend_builtins.rb +37 -0
  33. data/lib/openstax/accounts/version.rb +1 -1
  34. data/lib/openstax_accounts.rb +46 -25
  35. data/spec/controllers/openstax/accounts/dev/accounts_controller_spec.rb +21 -0
  36. data/spec/controllers/openstax/accounts/sessions_controller_spec.rb +12 -9
  37. data/spec/dummy/app/controllers/api/application_users_controller.rb +0 -4
  38. data/spec/dummy/app/controllers/api/users_controller.rb +7 -0
  39. data/spec/dummy/app/models/anonymous_user.rb +48 -0
  40. data/spec/dummy/app/models/user.rb +26 -0
  41. data/spec/dummy/config/initializers/openstax_accounts.rb +3 -2
  42. data/spec/dummy/config/routes.rb +5 -3
  43. data/spec/dummy/db/migrate/1_create_users.rb +11 -0
  44. data/spec/dummy/db/schema.rb +18 -6
  45. data/spec/factories/openstax_accounts_account.rb +6 -0
  46. data/spec/lib/openstax/accounts/current_user_manager_spec.rb +151 -0
  47. data/spec/lib/openstax_accounts_spec.rb +16 -9
  48. data/spec/models/openstax/accounts/account_spec.rb +9 -0
  49. data/spec/models/openstax/accounts/anonymous_account_spec.rb +9 -0
  50. data/spec/routines/openstax/accounts/{search_users_spec.rb → search_accounts_spec.rb} +38 -38
  51. metadata +87 -50
  52. data/app/controllers/openstax/accounts/dev/users_controller.rb +0 -22
  53. data/app/handlers/openstax/accounts/sessions_omniauth_authenticated.rb +0 -48
  54. data/app/models/openstax/accounts/application_user.rb +0 -7
  55. data/app/representers/openstax/accounts/api/v1/application_user_search_representer.rb +0 -19
  56. data/app/routines/openstax/accounts/dev/create_user.rb +0 -37
  57. data/app/routines/openstax/accounts/sync_users.rb +0 -44
  58. data/config/initializers/extend_builtins.rb +0 -42
  59. data/db/migrate/0_create_openstax_accounts_users.rb +0 -18
  60. data/lib/openstax/accounts/action_list.rb +0 -42
  61. data/lib/openstax/accounts/route_helper.rb +0 -34
  62. data/lib/openstax/accounts/user_provider.rb +0 -15
  63. data/spec/controllers/openstax/accounts/dev/users_controller_spec.rb +0 -21
  64. data/spec/factories/openstax_accounts_user.rb +0 -6
  65. data/spec/models/openstax/accounts/user_spec.rb +0 -13
  66. data/spec/routines/openstax/accounts/dev/create_user_spec.rb +0 -26
@@ -1,10 +1,10 @@
1
- # Routine for searching for users
1
+ # Routine for searching for accounts
2
2
  #
3
3
  # Caller provides a query and some options. The query follows the rules of
4
4
  # https://github.com/bruce/keyword_search , e.g.:
5
5
  #
6
- # "username:jps,richb" --> returns the "jps" and "richb" users
7
- # "name:John" --> returns Users with first, last, or full name
6
+ # "username:jps,richb" --> returns the "jps" and "richb" accounts
7
+ # "name:John" --> returns accounts with first, last, or full name
8
8
  # starting with "John"
9
9
  #
10
10
  # Query terms can be combined, e.g. "username:jp first_name:john"
@@ -21,15 +21,15 @@
21
21
  #
22
22
  # Finally, you can also specify a maximum allowed number of results:
23
23
  #
24
- # :max_matching_users -- the max number of results allowed (default: 10)
24
+ # :max_matching_accounts -- the max number of results allowed (default: 10)
25
25
  #
26
26
  # This routine will return an empty relation if the number of results exceeds
27
- # max_matching_users. You can tell that this happened because the result will
28
- # have a non-zero num_matching_users.
27
+ # max_matching_accounts. You can tell that this situation happened when
28
+ # the result has an empty accounts array, but a non-zero num_matching_accounts.
29
29
 
30
30
  module OpenStax
31
31
  module Accounts
32
- class SearchUsers
32
+ class SearchAccounts
33
33
 
34
34
  lev_routine transaction: :no_transaction
35
35
 
@@ -45,60 +45,65 @@ module OpenStax
45
45
  KeywordSearch.search(query).values_at('email', :default).compact.any?
46
46
  # Delegate to Accounts
47
47
 
48
- response = OpenStax::Accounts.application_users_index(query)
48
+ response = OpenStax::Accounts.search_application_accounts(query)
49
49
 
50
- user_search = OpenStruct.new
51
- search_rep = OpenStax::Accounts::Api::V1::UserSearchRepresenter.new(user_search)
50
+
51
+ search = OpenStruct.new
52
+ search_rep = OpenStax::Accounts::Api::V1::AccountSearchRepresenter.new(search)
52
53
  search_rep.from_json(response.body)
53
54
 
54
55
  # Need to query local database in order to obtain ID's (primary keys)
55
- outputs[:users] = OpenStax::Accounts::User.where{
56
- openstax_uid.in user_search.users.collect{ |u| u.openstax_uid }
57
- }
58
- outputs[:query] = user_search.q
59
- outputs[:per_page] = user_search.per_page
60
- outputs[:page] = user_search.page
61
- outputs[:order_by] = user_search.order_by
62
- outputs[:num_matching_users] = user_search.num_matching_users
56
+ outputs[:accounts] = OpenStax::Accounts::Account.where {
57
+ openstax_uid.in search.accounts.collect{ |u| u.openstax_uid }
58
+ }
59
+ outputs[:query] = search.q
60
+ outputs[:per_page] = search.per_page
61
+ outputs[:page] = search.page
62
+ outputs[:order_by] = search.order_by
63
+ outputs[:num_matching_accounts] = search.num_matching_accounts
63
64
 
64
65
  else
65
66
 
66
67
  # Local search
67
- users = OpenStax::Accounts::User.scoped
68
+ accounts = OpenStax::Accounts::Account.scoped
68
69
 
69
70
  KeywordSearch.search(query) do |with|
70
71
 
71
72
  with.default_keyword :any
72
73
 
73
74
  with.keyword :username do |usernames|
74
- users = users.where{username.like_any my{prep_usernames(usernames)}}
75
+ accounts = accounts.where{username
76
+ .like_any my{prep_usernames(usernames)}}
75
77
  end
76
78
 
77
79
  with.keyword :first_name do |first_names|
78
- users = users.where{lower(first_name).like_any my{prep_names(first_names)}}
80
+ accounts = accounts.where{lower(first_name)
81
+ .like_any my{prep_names(first_names)}}
79
82
  end
80
83
 
81
84
  with.keyword :last_name do |last_names|
82
- users = users.where{lower(last_name).like_any my{prep_names(last_names)}}
85
+ accounts = accounts.where{lower(last_name)
86
+ .like_any my{prep_names(last_names)}}
83
87
  end
84
88
 
85
89
  with.keyword :full_name do |full_names|
86
- users = users.where{lower(full_name).like_any my{prep_names(full_names)}}
90
+ accounts = accounts.where{lower(full_name)
91
+ .like_any my{prep_names(full_names)}}
87
92
  end
88
93
 
89
94
  with.keyword :name do |names|
90
95
  names = prep_names(names)
91
- users = users.where{ (lower(full_name).like_any names) |
92
- (lower(last_name).like_any names) |
93
- (lower(first_name).like_any names) }
96
+ accounts = accounts.where{ (lower(full_name).like_any names) |
97
+ (lower(last_name).like_any names) |
98
+ (lower(first_name).like_any names) }
94
99
  end
95
100
 
96
101
  with.keyword :id do |ids|
97
- users = users.where{openstax_uid.in ids}
102
+ accounts = accounts.where{openstax_uid.in ids}
98
103
  end
99
104
 
100
105
  with.keyword :email do |emails|
101
- users = OpenStax::Accounts::User.where('0=1')
106
+ accounts = OpenStax::Accounts::Account.where('0=1')
102
107
  end
103
108
 
104
109
  # Rerun the queries above for 'any' terms (which are ones without a
@@ -107,13 +112,13 @@ module OpenStax
107
112
  with.keyword :any do |terms|
108
113
  names = prep_names(terms)
109
114
 
110
- users = users.where{
111
- ( lower(username).like_any my{prep_usernames(terms)}) |
112
- (lower(first_name).like_any names) |
113
- (lower(last_name).like_any names) |
114
- (lower(full_name).like_any names) |
115
- (id.in terms)
116
- }
115
+ accounts = accounts.where{
116
+ ( lower(username).like_any my{prep_usernames(terms)}) |
117
+ (lower(first_name).like_any names) |
118
+ (lower(last_name).like_any names) |
119
+ (lower(full_name).like_any names) |
120
+ (id.in terms)
121
+ }
117
122
  end
118
123
 
119
124
  end
@@ -123,14 +128,15 @@ module OpenStax
123
128
  page = options[:page] || 0
124
129
  per_page = options[:per_page] || 20
125
130
 
126
- users = users.limit(per_page).offset(per_page*page)
131
+ accounts = accounts.limit(per_page).offset(per_page*page)
127
132
 
128
133
  #
129
134
  # Ordering
130
135
  #
131
136
 
132
137
  # Parse the input
133
- order_bys = (options[:order_by] || 'username').split(',').collect{|ob| ob.strip.split(' ')}
138
+ order_bys = (options[:order_by] || 'username').split(',')
139
+ .collect{|ob| ob.strip.split(' ')}
134
140
 
135
141
  # Toss out bad input, provide default direction
136
142
  order_bys = order_bys.collect do |order_by|
@@ -151,25 +157,26 @@ module OpenStax
151
157
 
152
158
  # Make the ordering call
153
159
  order_bys.each do |order_by|
154
- users = users.order(order_by)
160
+ accounts = accounts.order(order_by)
155
161
  end
156
162
 
157
163
  # Translate to routine outputs
158
164
 
159
- outputs[:users] = users
165
+ outputs[:accounts] = accounts
160
166
  outputs[:query] = query
161
167
  outputs[:per_page] = per_page
162
168
  outputs[:page] = page
163
- outputs[:order_by] = order_bys.join(', ') # convert back to one string
164
- outputs[:num_matching_users] = users.except(:offset, :limit, :order).count
169
+ outputs[:order_by] = order_bys.join(', ') # Convert back to String
170
+ outputs[:num_matching_accounts] = accounts
171
+ .except(:offset, :limit, :order).count
165
172
 
166
173
  end
167
174
 
168
175
  # Return no results if query exceeds maximum allowed number of matches
169
- max_users = options[:max_matching_users] || \
170
- OpenStax::Accounts.configuration.max_matching_users
171
- outputs[:users] = OpenStax::Accounts::User.where('0=1') \
172
- if outputs[:num_matching_users] > max_users
176
+ max_accounts = options[:max_matching_accounts] || \
177
+ OpenStax::Accounts.configuration.max_matching_accounts
178
+ outputs[:accounts] = OpenStax::Accounts::Account.where('0=1') \
179
+ if outputs[:num_matching_accounts] > max_accounts
173
180
 
174
181
  end
175
182
 
@@ -180,7 +187,9 @@ module OpenStax
180
187
  end
181
188
 
182
189
  def prep_usernames(usernames)
183
- usernames.collect{|username| username.gsub(OpenStax::Accounts::User::USERNAME_DISCARDED_CHAR_REGEX, '').downcase + '%'}
190
+ usernames.collect{|username| username.gsub(
191
+ OpenStax::Accounts::Account::USERNAME_DISCARDED_CHAR_REGEX, '')
192
+ .downcase + '%'}
184
193
  end
185
194
 
186
195
  end
@@ -0,0 +1,47 @@
1
+ # Routine for getting account updates from the Accounts server
2
+ #
3
+ # Should be scheduled to run regularly
4
+
5
+ module OpenStax
6
+ module Accounts
7
+
8
+ class SyncAccounts
9
+
10
+ SYNC_ATTRIBUTES = ['username', 'first_name', 'last_name',
11
+ 'full_name', 'title']
12
+
13
+ lev_routine transaction: :no_transaction
14
+
15
+ protected
16
+
17
+ def exec(options={})
18
+
19
+ return if OpenStax::Accounts.configuration.enable_stubbing?
20
+
21
+ response = OpenStax::Accounts.get_application_account_updates
22
+
23
+ app_accounts = []
24
+ app_accounts_rep = OpenStax::Accounts::Api::V1::ApplicationAccountsRepresenter
25
+ .new(app_accounts)
26
+ app_accounts_rep.from_json(response.body)
27
+
28
+ return if app_accounts.empty?
29
+
30
+ app_accounts_hash = {}
31
+ app_accounts.each do |app_account|
32
+ account = OpenStax::Accounts::Account.where(
33
+ :openstax_uid => app_account.account.openstax_uid).first
34
+ account.syncing_with_accounts = true
35
+ next unless account.update_attributes(
36
+ app_account.account.attributes.slice(*SYNC_ATTRIBUTES))
37
+ app_accounts_hash[app_account.id] = app_account.unread_updates
38
+ end
39
+
40
+ OpenStax::Accounts.mark_updates_as_read(app_accounts_hash)
41
+
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
@@ -1,13 +1,13 @@
1
1
  <%
2
2
  page = @handler_result.outputs[:page]
3
- num_users = @handler_result.outputs[:num_matching_users]
3
+ num_accounts = @handler_result.outputs[:num_matching_accounts]
4
4
  per_page = @handler_result.outputs[:per_page]
5
- pages = (num_users * 1.0 / per_page).ceil
6
- users = @handler_result.outputs[:users]
5
+ pages = (num_accounts * 1.0 / per_page).ceil
6
+ accounts = @handler_result.outputs[:accounts]
7
7
  %>
8
8
 
9
9
  <div id='search-results-pagination'>
10
- <%= pluralize(num_users, 'user') %> found.
10
+ <%= pluralize(num_accounts, 'user') %> found.
11
11
 
12
12
  <% if pages > 0 %>
13
13
  Page:
@@ -25,25 +25,25 @@
25
25
  <% linked_page_numbers.each do |lpn| %>
26
26
  <%= link_to_unless lpn == page + 1,
27
27
  lpn,
28
- dev_users_path(search: {terms: @handler_result.outputs[:query], page: lpn-1, per_page: per_page}), remote: true %>
28
+ dev_accounts_path(search: {terms: @handler_result.outputs[:query], page: lpn-1, per_page: per_page}), remote: true %>
29
29
  <% end %>
30
30
  <% end %>
31
31
  </div>
32
32
 
33
33
  <%= osu.action_list(
34
- records: users,
34
+ records: accounts,
35
35
  list: {
36
36
  headings: ['Username', 'First Name', 'Last Name', ''],
37
37
  widths: ['25%', '25%', '25%', '25%'],
38
38
  data_procs:
39
39
  [
40
- Proc.new { |user| user.username },
41
- Proc.new { |user| user.first_name || '---' },
42
- Proc.new { |user| user.last_name || '---' },
43
- Proc.new { |user|
44
- link_to 'Sign in as',
45
- become_dev_user_path(user),
46
- method: :post
40
+ Proc.new { |account| account.username },
41
+ Proc.new { |account| account.first_name || '---' },
42
+ Proc.new { |account| account.last_name || '---' },
43
+ Proc.new { |account|
44
+ link_to 'Sign in as',
45
+ with_interceptor { become_dev_account_path(account) },
46
+ method: :post
47
47
  }
48
48
  ]
49
49
  }
@@ -9,9 +9,9 @@
9
9
  <p>You need to login, but we're not connected to the Accounts server.
10
10
  Search for a user below and click the sign in link next to him or her.</p>
11
11
 
12
- <%= render 'openstax/accounts/shared/users/index',
13
- :search_action_path => openstax_accounts.dev_users_path,
14
- :remote => true %>
12
+ <%= with_interceptor { render 'openstax/accounts/shared/accounts/index',
13
+ :search_action_path => openstax_accounts.dev_accounts_path,
14
+ :remote => true } %>
15
15
 
16
16
  <% end %>
17
17
 
@@ -1,3 +1,3 @@
1
1
  <%= unless_errors alerts_html_id: 'dialog-local-alerts' do %>
2
- $("#search-results-list").html("<%= j(render 'openstax/accounts/dev/users/search_results') %>");
2
+ $("#search-results-list").html("<%= j(render 'openstax/accounts/dev/accounts/search_results') %>");
3
3
  <% end %>
@@ -1,6 +1,8 @@
1
1
  <%
2
2
  # Clients of this partial can override the following variables:
3
3
  search_action_path ||= nil
4
+ results_list_id ||= 'search-results-list'
5
+ method ||= :post
4
6
  remote ||= false
5
7
  form_html ||= {id: 'search-form',
6
8
  class: 'form-inline'}
@@ -10,6 +12,7 @@
10
12
  <%= lev_form_for :search,
11
13
  url: search_action_path,
12
14
  remote: remote,
15
+ method: method,
13
16
  html: form_html do |f| %>
14
17
 
15
18
  Search for
@@ -21,4 +24,4 @@
21
24
 
22
25
  <% end %>
23
26
 
24
- <div id="search-results-list"></div>
27
+ <div id=<%= results_list_id %>></div>
@@ -0,0 +1,14 @@
1
+ ActionInterceptor.configure do
2
+
3
+ interceptor :authenticate_user! do
4
+ account = current_account
5
+
6
+ return if account && !account.is_anonymous?
7
+
8
+ respond_to do |format|
9
+ format.html { redirect_to registration_path }
10
+ format.json { head(:forbidden) }
11
+ end
12
+ end
13
+
14
+ end
data/config/routes.rb CHANGED
@@ -1,26 +1,29 @@
1
1
  OpenStax::Accounts::Engine.routes.draw do
2
- get '/auth/openstax/callback', to: 'sessions#omniauth_authenticated' #omniauth route
2
+
3
+ # Redirect here if we don't know what to do (theoretically should not happen)
4
+ root :to => 'sessions#new'
5
+
6
+ # Shortcut to OmniAuth route that redirects to the Accounts server
7
+ # This is provided by OmniAuth and is not in the SessionsController
3
8
  get '/auth/openstax', :as => 'openstax_login'
4
9
 
5
- get 'sessions/new', :as => 'login'
6
- # See https://github.com/plataformatec/devise/commit/f3385e96abf50e80d2ae282e1fb9bdad87a83d3c
7
- match 'sessions/destroy', :as => 'logout',
8
- :via => OpenStax::Accounts.configuration.logout_via
10
+ # OmniAuth local routes (SessionsController)
11
+ resource :session, :only => [], :path => '', :as => '' do
12
+ get 'callback', :path => 'auth/:provider/callback' # Authentication success
13
+ get 'failure', :path => 'auth/failure' # Authentication failure
14
+
15
+ get 'login', :to => :new # Redirects to /auth/openstax or stub
16
+ match 'logout', :to => :destroy, # Redirects to logout path or stub
17
+ :via => OpenStax::Accounts.configuration.logout_via
18
+ end
9
19
 
10
20
  if OpenStax::Accounts.configuration.enable_stubbing?
11
21
  namespace :dev do
12
- resources :users, :only => [:index] do
13
- collection do
14
- get 'login'
15
- post 'index'
16
- end
17
-
22
+ resources :accounts, :only => [:index] do
23
+ post 'index', :on => :collection
18
24
  post 'become', :on => :member
19
25
  end
20
26
  end
21
27
  end
22
- end
23
28
 
24
- hh = OpenStax::Accounts::Engine.routes.url_helpers
25
-
26
- OpenStax::Accounts::RouteHelper.register_path(:login, hh.openstax_login_path) { hh.login_dev_users_path }
29
+ end
@@ -0,0 +1,22 @@
1
+ class CreateOpenStaxAccountsAccounts < ActiveRecord::Migration
2
+ def change
3
+ create_table :openstax_accounts_accounts do |t|
4
+ t.integer :openstax_uid, :null => false
5
+ t.string :username, :null => false
6
+ t.string :access_token
7
+ t.string :first_name
8
+ t.string :last_name
9
+ t.string :full_name
10
+ t.string :title
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :openstax_accounts_accounts, :openstax_uid, :unique => true
16
+ add_index :openstax_accounts_accounts, :username, :unique => true
17
+ add_index :openstax_accounts_accounts, :access_token, :unique => true
18
+ add_index :openstax_accounts_accounts, :first_name
19
+ add_index :openstax_accounts_accounts, :last_name
20
+ add_index :openstax_accounts_accounts, :full_name
21
+ end
22
+ end
@@ -1,5 +1,5 @@
1
1
  Description:
2
- Creates a "whenever" task that checks for updates from Accounts.
2
+ Creates a "whenever" task that checks for updates from the Accounts server.
3
3
 
4
4
  Example:
5
5
  rails generate openstax:accounts:schedule
@@ -1,3 +1,3 @@
1
1
  every 5.minutes do
2
- runner "OpenStax::Accounts::SyncUsers.call"
2
+ runner "OpenStax::Accounts::SyncAccounts.call"
3
3
  end
@@ -2,102 +2,111 @@ module OpenStax
2
2
  module Accounts
3
3
  class CurrentUserManager
4
4
 
5
- # References:
6
- # http://railscasts.com/episodes/356-dangers-of-session-hijacking
7
-
8
5
  def initialize(request, session, cookies)
9
6
  @request = request
10
7
  @session = session
11
8
  @cookies = cookies
12
9
  end
13
10
 
14
- # Returns the current app user
11
+ # Returns the current account
12
+ def current_account
13
+ load_session
14
+ @current_account
15
+ end
16
+
17
+ # Returns the current user
15
18
  def current_user
16
- load_current_users
17
- @app_current_user
19
+ load_session
20
+ @current_user
18
21
  end
19
22
 
20
- # Signs in the given user; the argument can be either an accounts user or
21
- # an app user
22
- def sign_in(user)
23
- user.is_a?(User) ?
24
- self.accounts_current_user = user :
23
+ # Signs in the given user or account
24
+ def sign_in!(user)
25
+ user.is_a?(Account) ?
26
+ self.current_account = user :
25
27
  self.current_user = user
26
28
  end
27
29
 
28
- # Signs out the user
30
+ alias_method :sign_in, :sign_in!
31
+
32
+ # Signs out the currently signed in user
29
33
  def sign_out!
30
- sign_in(OpenStax::Accounts::User.anonymous)
34
+ self.current_account = AnonymousAccount.instance
31
35
  end
32
36
 
37
+ alias_method :sign_out, :sign_out!
38
+
33
39
  # Returns true iff there is a user signed in
34
40
  def signed_in?
35
- !accounts_current_user.is_anonymous?
41
+ !current_account.is_anonymous?
36
42
  end
37
43
 
38
- # Returns the current accounts user
39
- def accounts_current_user
40
- load_current_users
41
- @accounts_current_user
42
- end
43
-
44
- protected
45
-
46
- # If they are nil (unset), sets the current users based on the session state
47
- def load_current_users
48
- return if !@accounts_current_user.nil?
44
+ protected
49
45
 
50
- if @request.ssl? && @cookies.signed[:secure_user_id] != "secure#{@session[:user_id]}"
51
- sign_out! # hijacked
46
+ # Sets the session state based on the given account
47
+ def set_session(account)
48
+ if account.is_anonymous?
49
+ @session[:account_id] = nil
50
+ @cookies.delete(:secure_account_id)
52
51
  else
53
- # If there is a session user_id, load up that user, otherwise set the anonymous user.
54
-
55
- if @session[:user_id]
56
- @accounts_current_user = User.where(id: @session[:user_id]).first
57
-
58
- # It could happen (normally in development) that there is a session
59
- # user_id that doesn't map to a User in the db.
60
- # In such a case, sign_out! to reset the state
61
- if @accounts_current_user.nil?
62
- sign_out!
63
- return
64
- end
65
- else
66
- @accounts_current_user = User.anonymous
67
- end
68
-
69
- # Bring the app user inline with the accounts user
70
- @app_current_user = user_provider.accounts_user_to_app_user(@accounts_current_user)
52
+ @session[:account_id] = account.id
53
+ @cookies.signed[:secure_account_id] = { secure: true,
54
+ httponly: true, value: "secure#{account.id}" }
71
55
  end
72
56
  end
73
57
 
74
- # Sets (signs in) the provided app user.
75
- def current_user=(user)
76
- self.accounts_current_user = user_provider.app_user_to_accounts_user(user)
77
- @app_current_user
78
- end
79
-
80
- # Sets the current accounts user, updates the app user, and also updates
81
- # the session and cookie state.
82
- def accounts_current_user=(user)
83
- @accounts_current_user = user || User.anonymous
84
- @app_current_user = user_provider.accounts_user_to_app_user(@accounts_current_user)
58
+ # If not already loaded, sets the current user and current account
59
+ # based on the session state
60
+ def load_session
61
+ return unless @current_account.nil?
62
+
63
+ # Sign the user out to reset the session if the request is SSL
64
+ # and the signed secure ID doesn't match the unsecure ID
65
+ # http://railscasts.com/episodes/356-dangers-of-session-hijacking
66
+ if @request.ssl? && \
67
+ @cookies.signed[:secure_account_id] != "secure#{@session[:account_id]}"
68
+ sign_out!
69
+ return
70
+ end
85
71
 
86
- if @accounts_current_user.is_anonymous?
87
- @session[:user_id] = nil
88
- @cookies.delete(:secure_user_id)
72
+ # If there is a session account_id, load up that account,
73
+ # otherwise set the anonymous account.
74
+ if @session[:account_id]
75
+ @current_account = Account.where(id: @session[:account_id]).first
76
+
77
+ # It could happen (normally in development) that there is a session
78
+ # account_id that doesn't map to an Account in the db.
79
+ # In such a case, sign_out! to reset the state
80
+ if @current_account.nil?
81
+ sign_out!
82
+ return
83
+ end
89
84
  else
90
- @session[:user_id] = @accounts_current_user.id
91
- @cookies.signed[:secure_user_id] = {secure: true, value: "secure#{@accounts_current_user.id}"}
85
+ @current_account = AnonymousAccount.instance
92
86
  end
93
87
 
94
- @accounts_current_user
88
+ # Bring the user inline with the account
89
+ @current_user = account_user_mapper.account_to_user(@current_account)
90
+ end
91
+
92
+ # Sets the current account, updates the session and loads it
93
+ def current_account=(account)
94
+ set_session(account)
95
+ @current_user = account_user_mapper.account_to_user(account)
96
+ @current_account = account
97
+ end
98
+
99
+ # Sets (signs in) the provided user, as above
100
+ def current_user=(user)
101
+ @current_account = account_user_mapper.user_to_account(user)
102
+ set_session(@current_account)
103
+ @current_user = user
95
104
  end
96
105
 
97
- def user_provider
98
- OpenStax::Accounts.configuration.user_provider
106
+ def account_user_mapper
107
+ OpenStax::Accounts.configuration.account_user_mapper
99
108
  end
100
109
 
101
110
  end
102
111
  end
103
- end
112
+ end
@@ -0,0 +1,15 @@
1
+ module OpenStax
2
+ module Accounts
3
+ class DefaultAccountUserMapper
4
+
5
+ def self.account_to_user(account)
6
+ account
7
+ end
8
+
9
+ def self.user_to_account(user)
10
+ user
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -5,6 +5,8 @@ require 'roar/decorator'
5
5
  require 'roar/representer/json'
6
6
  require 'keyword_search'
7
7
  require 'squeel'
8
+ require 'action_interceptor'
9
+ require 'openstax/accounts/extend_builtins'
8
10
 
9
11
  ActiveSupport::Inflector.inflections do |inflect|
10
12
  inflect.acronym 'OpenStax'