openstax_accounts 1.0.0 → 2.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.
- checksums.yaml +8 -8
- data/README.md +89 -58
- data/app/controllers/openstax/accounts/application_controller.rb +3 -12
- data/app/controllers/openstax/accounts/dev/accounts_controller.rb +19 -0
- data/app/controllers/openstax/accounts/dev/base_controller.rb +2 -8
- data/app/controllers/openstax/accounts/sessions_controller.rb +31 -19
- data/app/handlers/openstax/accounts/dev/{users_index.rb → accounts_index.rb} +4 -4
- data/app/handlers/openstax/accounts/sessions_callback.rb +43 -0
- data/app/models/openstax/accounts/{user.rb → account.rb} +7 -22
- data/app/models/openstax/accounts/anonymous_account.rb +24 -0
- data/app/models/openstax/accounts/application_account.rb +7 -0
- data/app/representers/openstax/accounts/api/v1/{user_representer.rb → account_representer.rb} +1 -1
- data/app/representers/openstax/accounts/api/v1/{user_search_representer.rb → account_search_representer.rb} +7 -6
- data/app/representers/openstax/accounts/api/v1/{application_user_representer.rb → application_account_representer.rb} +5 -4
- data/app/representers/openstax/accounts/api/v1/application_account_search_representer.rb +20 -0
- data/app/representers/openstax/accounts/api/v1/{application_users_representer.rb → application_accounts_representer.rb} +3 -3
- data/app/routines/openstax/accounts/dev/{search_users.rb → search_accounts.rb} +5 -5
- data/app/routines/openstax/accounts/{search_users.rb → search_accounts.rb} +55 -46
- data/app/routines/openstax/accounts/sync_accounts.rb +47 -0
- data/app/views/openstax/accounts/dev/{users → accounts}/_search_results.html.erb +13 -13
- data/app/views/openstax/accounts/dev/{users/login.html.erb → accounts/index.html.erb} +3 -3
- data/app/views/openstax/accounts/dev/{users → accounts}/index.js.erb +1 -1
- data/app/views/openstax/accounts/shared/{users → accounts}/_index.html.erb +4 -1
- data/config/initializers/action_interceptor.rb +14 -0
- data/config/routes.rb +18 -15
- data/db/migrate/0_create_openstax_accounts_accounts.rb +22 -0
- data/lib/generators/openstax/accounts/schedule/USAGE +1 -1
- data/lib/generators/openstax/accounts/schedule/templates/schedule.rb +1 -1
- data/lib/openstax/accounts/current_user_manager.rb +74 -65
- data/lib/openstax/accounts/default_account_user_mapper.rb +15 -0
- data/lib/openstax/accounts/engine.rb +2 -0
- data/lib/openstax/accounts/extend_builtins.rb +37 -0
- data/lib/openstax/accounts/version.rb +1 -1
- data/lib/openstax_accounts.rb +46 -25
- data/spec/controllers/openstax/accounts/dev/accounts_controller_spec.rb +21 -0
- data/spec/controllers/openstax/accounts/sessions_controller_spec.rb +12 -9
- data/spec/dummy/app/controllers/api/application_users_controller.rb +0 -4
- data/spec/dummy/app/controllers/api/users_controller.rb +7 -0
- data/spec/dummy/app/models/anonymous_user.rb +48 -0
- data/spec/dummy/app/models/user.rb +26 -0
- data/spec/dummy/config/initializers/openstax_accounts.rb +3 -2
- data/spec/dummy/config/routes.rb +5 -3
- data/spec/dummy/db/migrate/1_create_users.rb +11 -0
- data/spec/dummy/db/schema.rb +18 -6
- data/spec/factories/openstax_accounts_account.rb +6 -0
- data/spec/lib/openstax/accounts/current_user_manager_spec.rb +151 -0
- data/spec/lib/openstax_accounts_spec.rb +16 -9
- data/spec/models/openstax/accounts/account_spec.rb +9 -0
- data/spec/models/openstax/accounts/anonymous_account_spec.rb +9 -0
- data/spec/routines/openstax/accounts/{search_users_spec.rb → search_accounts_spec.rb} +38 -38
- metadata +87 -50
- data/app/controllers/openstax/accounts/dev/users_controller.rb +0 -22
- data/app/handlers/openstax/accounts/sessions_omniauth_authenticated.rb +0 -48
- data/app/models/openstax/accounts/application_user.rb +0 -7
- data/app/representers/openstax/accounts/api/v1/application_user_search_representer.rb +0 -19
- data/app/routines/openstax/accounts/dev/create_user.rb +0 -37
- data/app/routines/openstax/accounts/sync_users.rb +0 -44
- data/config/initializers/extend_builtins.rb +0 -42
- data/db/migrate/0_create_openstax_accounts_users.rb +0 -18
- data/lib/openstax/accounts/action_list.rb +0 -42
- data/lib/openstax/accounts/route_helper.rb +0 -34
- data/lib/openstax/accounts/user_provider.rb +0 -15
- data/spec/controllers/openstax/accounts/dev/users_controller_spec.rb +0 -21
- data/spec/factories/openstax_accounts_user.rb +0 -6
- data/spec/models/openstax/accounts/user_spec.rb +0 -13
- data/spec/routines/openstax/accounts/dev/create_user_spec.rb +0 -26
@@ -1,10 +1,10 @@
|
|
1
|
-
# Routine for searching for
|
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"
|
7
|
-
# "name:John" --> returns
|
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
|
-
# :
|
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
|
-
#
|
28
|
-
#
|
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
|
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.
|
48
|
+
response = OpenStax::Accounts.search_application_accounts(query)
|
49
49
|
|
50
|
-
|
51
|
-
|
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[:
|
56
|
-
|
57
|
-
|
58
|
-
outputs[:query] =
|
59
|
-
outputs[:per_page] =
|
60
|
-
outputs[:page] =
|
61
|
-
outputs[:order_by] =
|
62
|
-
outputs[:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
92
|
-
|
93
|
-
|
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
|
-
|
102
|
+
accounts = accounts.where{openstax_uid.in ids}
|
98
103
|
end
|
99
104
|
|
100
105
|
with.keyword :email do |emails|
|
101
|
-
|
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
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
-
|
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(',')
|
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
|
-
|
160
|
+
accounts = accounts.order(order_by)
|
155
161
|
end
|
156
162
|
|
157
163
|
# Translate to routine outputs
|
158
164
|
|
159
|
-
outputs[:
|
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(', ') #
|
164
|
-
outputs[:
|
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
|
-
|
170
|
-
OpenStax::Accounts.configuration.
|
171
|
-
outputs[:
|
172
|
-
if outputs[:
|
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(
|
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
|
-
|
3
|
+
num_accounts = @handler_result.outputs[:num_matching_accounts]
|
4
4
|
per_page = @handler_result.outputs[:per_page]
|
5
|
-
pages = (
|
6
|
-
|
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(
|
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
|
-
|
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:
|
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 { |
|
41
|
-
Proc.new { |
|
42
|
-
Proc.new { |
|
43
|
-
Proc.new { |
|
44
|
-
link_to 'Sign in as',
|
45
|
-
|
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/
|
13
|
-
:search_action_path => openstax_accounts.
|
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/
|
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
|
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
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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 :
|
13
|
-
collection
|
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
|
-
|
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
|
@@ -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
|
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
|
-
|
17
|
-
@
|
19
|
+
load_session
|
20
|
+
@current_user
|
18
21
|
end
|
19
22
|
|
20
|
-
# Signs in the given user
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
30
|
+
alias_method :sign_in, :sign_in!
|
31
|
+
|
32
|
+
# Signs out the currently signed in user
|
29
33
|
def sign_out!
|
30
|
-
|
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
|
-
!
|
41
|
+
!current_account.is_anonymous?
|
36
42
|
end
|
37
43
|
|
38
|
-
|
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
|
-
|
51
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
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
|
-
#
|
75
|
-
|
76
|
-
|
77
|
-
@
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
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
|
-
@
|
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
|
-
|
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
|
98
|
-
OpenStax::Accounts.configuration.
|
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
|
@@ -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'
|