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.
- 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'
|