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
@@ -0,0 +1,37 @@
|
|
1
|
+
ActionController::Base.class_exec do
|
2
|
+
|
3
|
+
helper_method :current_user, :signed_in?
|
4
|
+
|
5
|
+
# Returns the current user
|
6
|
+
def current_user
|
7
|
+
current_user_manager.current_user
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns the current account
|
11
|
+
def current_account
|
12
|
+
current_user_manager.current_account
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns true iff there is a user signed in
|
16
|
+
def signed_in?
|
17
|
+
current_user_manager.signed_in?
|
18
|
+
end
|
19
|
+
|
20
|
+
# Signs in the given account or user
|
21
|
+
def sign_in(user)
|
22
|
+
current_user_manager.sign_in(user)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Signs out the current account and user
|
26
|
+
def sign_out!
|
27
|
+
current_user_manager.sign_out!
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def current_user_manager
|
33
|
+
@current_user_manager ||= OpenStax::Accounts::CurrentUserManager.new(
|
34
|
+
request, session, cookies)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/lib/openstax_accounts.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
require 'openstax/accounts/version'
|
2
2
|
require 'openstax/accounts/engine'
|
3
|
-
require 'openstax/accounts/
|
4
|
-
require 'openstax/accounts/action_list'
|
5
|
-
require 'openstax/accounts/user_provider'
|
3
|
+
require 'openstax/accounts/default_account_user_mapper'
|
6
4
|
require 'openstax/accounts/current_user_manager'
|
7
|
-
|
8
5
|
require 'openstax_utilities'
|
6
|
+
|
9
7
|
require 'oauth2'
|
10
8
|
require 'uri'
|
11
9
|
|
@@ -68,13 +66,17 @@ module OpenStax
|
|
68
66
|
# Class to be used for security transgression exceptions
|
69
67
|
attr_accessor :security_transgression_exception
|
70
68
|
|
71
|
-
#
|
72
|
-
|
69
|
+
# account_user_mapper
|
70
|
+
# This class teaches the gem how to convert between accounts and users
|
71
|
+
# See the "account_user_mapper" discussion in the README
|
72
|
+
attr_accessor :account_user_mapper
|
73
73
|
|
74
|
-
#
|
74
|
+
# max_matching_accounts
|
75
|
+
# The maximum number of accounts that can be returned
|
76
|
+
# in a call to SearchAccounts
|
75
77
|
# If more would be returned, the result will be empty instead
|
76
|
-
# Can also be passed directly to
|
77
|
-
attr_accessor :
|
78
|
+
# Can also be passed directly to SearchAccounts
|
79
|
+
attr_accessor :max_matching_accounts
|
78
80
|
|
79
81
|
def openstax_accounts_url=(url)
|
80
82
|
url.gsub!(/https|http/,'https') if !(url =~ /localhost/)
|
@@ -92,8 +94,8 @@ module OpenStax
|
|
92
94
|
@default_errors_html_id = 'openstax-accounts-attention'
|
93
95
|
@default_errors_added_trigger = 'openstax-accounts-errors-added'
|
94
96
|
@security_transgression_exception = SecurityTransgression
|
95
|
-
@
|
96
|
-
@
|
97
|
+
@account_user_mapper = OpenStax::Accounts::DefaultAccountUserMapper
|
98
|
+
@max_matching_accounts = 10
|
97
99
|
super
|
98
100
|
end
|
99
101
|
|
@@ -115,7 +117,9 @@ module OpenStax
|
|
115
117
|
version = options.delete(:api_version)
|
116
118
|
unless version.blank?
|
117
119
|
options[:headers] ||= {}
|
118
|
-
options[:headers].merge!({
|
120
|
+
options[:headers].merge!({
|
121
|
+
'Accept' => "application/vnd.accounts.openstax.#{version.to_s}"
|
122
|
+
})
|
119
123
|
end
|
120
124
|
|
121
125
|
token_string = options.delete(:access_token)
|
@@ -127,45 +131,62 @@ module OpenStax
|
|
127
131
|
token.request(http_method, api_url, options)
|
128
132
|
end
|
129
133
|
|
130
|
-
# Performs an
|
134
|
+
# Performs an account search in the Accounts server.
|
135
|
+
# Results are limited to 10 accounts maximum.
|
136
|
+
# Takes a query parameter and an optional API version parameter.
|
137
|
+
# API version currently defaults to :v1 (may change in the future).
|
138
|
+
# On failure, throws an Exception, just like api_call.
|
139
|
+
# On success, returns an OAuth2::Response object.
|
140
|
+
def search_accounts(query, version = DEFAULT_API_VERSION)
|
141
|
+
options = {:params => {:q => query},
|
142
|
+
:api_version => version}
|
143
|
+
api_call(:get, 'users', options)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Performs an account search in the Accounts server.
|
147
|
+
# Results are limited to accounts that have used the current app.
|
131
148
|
# Takes a query parameter and an optional API version parameter.
|
132
149
|
# API version currently defaults to :v1 (may change in the future).
|
133
150
|
# On failure, throws an Exception, just like api_call.
|
134
151
|
# On success, returns an OAuth2::Response object.
|
135
|
-
def
|
152
|
+
def search_application_accounts(query, version = DEFAULT_API_VERSION)
|
136
153
|
options = {:params => {:q => query},
|
137
154
|
:api_version => version}
|
138
155
|
api_call(:get, 'application_users', options)
|
139
156
|
end
|
140
157
|
|
141
|
-
# Retrieves information about
|
158
|
+
# Retrieves information about accounts that have been
|
159
|
+
# recently updated.
|
160
|
+
# Results are limited to accounts that have used the current app.
|
142
161
|
# On failure, throws an Exception, just like api_call.
|
143
162
|
# On success, returns an OAuth2::Response object.
|
144
|
-
def
|
163
|
+
def get_application_account_updates(version = DEFAULT_API_VERSION)
|
145
164
|
options = {:api_version => version}
|
146
165
|
api_call(:get, 'application_users/updates', options)
|
147
166
|
end
|
148
167
|
|
149
|
-
# Marks
|
150
|
-
# The
|
151
|
-
#
|
168
|
+
# Marks account updates as "read".
|
169
|
+
# The uid_map parameter is a hash that maps account openstax_uid's
|
170
|
+
# to the value of the last received unread_updates for that uid.
|
171
|
+
# Can only be called for accounts that have used the current app.
|
152
172
|
# On failure, throws an Exception, just like api_call.
|
153
173
|
# On success, returns an OAuth2::Response object.
|
154
|
-
def
|
174
|
+
def mark_updates_as_read(uid_map, version = DEFAULT_API_VERSION)
|
155
175
|
options = {:api_version => version,
|
156
|
-
:body => {:application_users =>
|
176
|
+
:body => {:application_users => uid_map}}
|
157
177
|
api_call(:put, 'application_users/updated', options)
|
158
178
|
end
|
159
179
|
|
160
|
-
# Updates
|
180
|
+
# Updates the current account in the Accounts server.
|
181
|
+
# The current account is determined by the OAuth access token.
|
161
182
|
# Also takes an optional API version parameter.
|
162
183
|
# API version currently defaults to :v1 (may change in the future).
|
163
184
|
# On failure, throws an Exception, just like api_call.
|
164
185
|
# On success, returns an OAuth2::Response object.
|
165
|
-
def
|
166
|
-
options = {:access_token =>
|
186
|
+
def update_account(account, version = DEFAULT_API_VERSION)
|
187
|
+
options = {:access_token => account.access_token,
|
167
188
|
:api_version => version,
|
168
|
-
:body =>
|
189
|
+
:body => account.attributes.slice('username', 'first_name',
|
169
190
|
'last_name', 'full_name', 'title').to_json}
|
170
191
|
api_call(:put, 'user', options)
|
171
192
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module OpenStax::Accounts
|
4
|
+
module Dev
|
5
|
+
describe AccountsController do
|
6
|
+
routes { Engine.routes }
|
7
|
+
|
8
|
+
let!(:account) { FactoryGirl.create :openstax_accounts_account,
|
9
|
+
username: 'some_user',
|
10
|
+
openstax_uid: 10 }
|
11
|
+
|
12
|
+
it 'should allow users not in production to become other users' do
|
13
|
+
expect(controller.current_account).to eq(AnonymousAccount.instance)
|
14
|
+
expect(controller.current_account.is_anonymous?).to eq(true)
|
15
|
+
post :become, id: account.id
|
16
|
+
expect(controller.current_account).to eq(account)
|
17
|
+
expect(controller.current_account.is_anonymous?).to eq(false)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,14 +2,17 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module OpenStax::Accounts
|
4
4
|
describe SessionsController do
|
5
|
-
routes {
|
5
|
+
routes { Engine.routes }
|
6
6
|
|
7
|
-
let!(:
|
8
|
-
|
7
|
+
let!(:account) { FactoryGirl.create :openstax_accounts_account,
|
8
|
+
username: 'some_user',
|
9
|
+
openstax_uid: 10 }
|
9
10
|
|
10
11
|
it 'should redirect users to the login path' do
|
12
|
+
c = controller
|
11
13
|
get :new
|
12
|
-
expect(response).to redirect_to
|
14
|
+
expect(response).to redirect_to(
|
15
|
+
c.send(:with_interceptor) { c.dev_accounts_path })
|
13
16
|
expect(response.code).to eq('302')
|
14
17
|
end
|
15
18
|
|
@@ -18,12 +21,12 @@ module OpenStax::Accounts
|
|
18
21
|
end
|
19
22
|
|
20
23
|
it 'should let users logout' do
|
21
|
-
controller.sign_in
|
22
|
-
expect(controller.
|
23
|
-
expect(controller.
|
24
|
+
controller.sign_in account
|
25
|
+
expect(controller.current_account).to eq(account)
|
26
|
+
expect(controller.current_account.is_anonymous?).to eq(false)
|
24
27
|
delete :destroy
|
25
|
-
expect(controller.
|
26
|
-
expect(controller.
|
28
|
+
expect(controller.current_account).to eq(AnonymousAccount.instance)
|
29
|
+
expect(controller.current_account.is_anonymous?).to eq(true)
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
class AnonymousUser
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
def is_admin?
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_anonymous?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def is_human?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_application?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def id
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def authentications
|
27
|
+
[]
|
28
|
+
end
|
29
|
+
|
30
|
+
def identity
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
# Necessary if an anonymous user ever runs into an Exception
|
35
|
+
# or else the developer email doesn't work
|
36
|
+
def username
|
37
|
+
'anonymous'
|
38
|
+
end
|
39
|
+
|
40
|
+
def full_name
|
41
|
+
"Anonymous User"
|
42
|
+
end
|
43
|
+
|
44
|
+
def casual_name
|
45
|
+
full_name
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
belongs_to :openstax_accounts_account,
|
3
|
+
class_name: "OpenStax::Accounts::Account",
|
4
|
+
dependent: :destroy
|
5
|
+
|
6
|
+
delegate :username, :first_name, :last_name, :full_name, :title,
|
7
|
+
:name, :casual_name, to: :openstax_accounts_account
|
8
|
+
|
9
|
+
def is_anonymous?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
# OpenStax Accounts "account_user_mapper" methods
|
14
|
+
|
15
|
+
def self.account_to_user(account)
|
16
|
+
account.is_anonymous? ? \
|
17
|
+
AnonymousUser.instance : \
|
18
|
+
User.where(:openstax_accounts_account_id => account.id).first
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.user_to_account(user)
|
22
|
+
user.is_anonymous? ? \
|
23
|
+
AnonymousAccount.instance : \
|
24
|
+
user.openstax_accounts_account
|
25
|
+
end
|
26
|
+
end
|
@@ -7,6 +7,7 @@ OpenStax::Accounts.configure do |config|
|
|
7
7
|
config.openstax_accounts_url = "http://localhost:#{CAPYBARA_SERVER.port}/"
|
8
8
|
config.openstax_application_id = 'secret'
|
9
9
|
config.openstax_application_secret = 'secret'
|
10
|
+
config.account_user_mapper = User
|
10
11
|
config.logout_via = :delete
|
11
|
-
config.
|
12
|
-
end
|
12
|
+
config.max_matching_accounts = 47
|
13
|
+
end
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
|
+
root :to => 'application#index'
|
3
|
+
|
2
4
|
mount OpenStax::Accounts::Engine => '/accounts'
|
3
5
|
|
4
6
|
post 'oauth/token', :to => 'oauth#token'
|
@@ -6,13 +8,13 @@ Rails.application.routes.draw do
|
|
6
8
|
namespace :api do
|
7
9
|
post 'dummy', :to => 'dummy#dummy'
|
8
10
|
|
9
|
-
resources :
|
11
|
+
resources :users, :only => [:index]
|
12
|
+
|
13
|
+
resources :application_users, :only => [:index] do
|
10
14
|
collection do
|
11
15
|
get 'updates'
|
12
16
|
put 'updated'
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
16
|
-
|
17
|
-
root :to => 'application#index'
|
18
20
|
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -11,11 +11,11 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended to check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(:version =>
|
14
|
+
ActiveRecord::Schema.define(:version => 1) do
|
15
15
|
|
16
|
-
create_table "
|
17
|
-
t.integer "openstax_uid"
|
18
|
-
t.string "username"
|
16
|
+
create_table "openstax_accounts_accounts", :force => true do |t|
|
17
|
+
t.integer "openstax_uid", :null => false
|
18
|
+
t.string "username", :null => false
|
19
19
|
t.string "first_name"
|
20
20
|
t.string "last_name"
|
21
21
|
t.string "full_name"
|
@@ -25,7 +25,19 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
25
25
|
t.datetime "updated_at", :null => false
|
26
26
|
end
|
27
27
|
|
28
|
-
add_index "
|
29
|
-
add_index "
|
28
|
+
add_index "openstax_accounts_accounts", ["access_token"], :name => "index_openstax_accounts_accounts_on_access_token", :unique => true
|
29
|
+
add_index "openstax_accounts_accounts", ["first_name"], :name => "index_openstax_accounts_accounts_on_first_name"
|
30
|
+
add_index "openstax_accounts_accounts", ["full_name"], :name => "index_openstax_accounts_accounts_on_full_name"
|
31
|
+
add_index "openstax_accounts_accounts", ["last_name"], :name => "index_openstax_accounts_accounts_on_last_name"
|
32
|
+
add_index "openstax_accounts_accounts", ["openstax_uid"], :name => "index_openstax_accounts_accounts_on_openstax_uid", :unique => true
|
33
|
+
add_index "openstax_accounts_accounts", ["username"], :name => "index_openstax_accounts_accounts_on_username", :unique => true
|
34
|
+
|
35
|
+
create_table "users", :force => true do |t|
|
36
|
+
t.integer "openstax_accounts_account_id"
|
37
|
+
t.datetime "created_at", :null => false
|
38
|
+
t.datetime "updated_at", :null => false
|
39
|
+
end
|
40
|
+
|
41
|
+
add_index "users", ["openstax_accounts_account_id"], :name => "index_users_on_openstax_accounts_account_id", :unique => true
|
30
42
|
|
31
43
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module OpenStax
|
2
|
+
module Accounts
|
3
|
+
describe CurrentUserManager do
|
4
|
+
let!(:account) { FactoryGirl.create(:openstax_accounts_account,
|
5
|
+
username: 'some_user',
|
6
|
+
openstax_uid: 1) }
|
7
|
+
let!(:user) { User.create(:openstax_accounts_account => account) }
|
8
|
+
|
9
|
+
let!(:request) { double('request',
|
10
|
+
:host => 'localhost',
|
11
|
+
:ssl? => false) }
|
12
|
+
|
13
|
+
let!(:ssl_request) { double('request',
|
14
|
+
:host => 'localhost',
|
15
|
+
:ssl? => true) }
|
16
|
+
|
17
|
+
let!(:session) { {} }
|
18
|
+
|
19
|
+
let!(:cookies) { ActionDispatch::Cookies::CookieJar.new(
|
20
|
+
SecureRandom.hex, 'localhost') }
|
21
|
+
|
22
|
+
let!(:current_user_manager) { CurrentUserManager.new(
|
23
|
+
request, session, cookies) }
|
24
|
+
|
25
|
+
context 'signing in' do
|
26
|
+
|
27
|
+
it 'signs in an account' do
|
28
|
+
expect(current_user_manager.signed_in?).to eq(false)
|
29
|
+
expect(current_user_manager.current_account).to(
|
30
|
+
eq(AnonymousAccount.instance))
|
31
|
+
expect(current_user_manager.current_user).to(
|
32
|
+
eq(AnonymousUser.instance))
|
33
|
+
|
34
|
+
current_user_manager.sign_in!(account)
|
35
|
+
|
36
|
+
expect(current_user_manager.signed_in?).to eq(true)
|
37
|
+
expect(current_user_manager.current_account).to eq(account)
|
38
|
+
expect(current_user_manager.current_user).to eq(user)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'signs in a user' do
|
42
|
+
expect(current_user_manager.signed_in?).to eq(false)
|
43
|
+
expect(current_user_manager.current_account).to(
|
44
|
+
eq(AnonymousAccount.instance))
|
45
|
+
expect(current_user_manager.current_user).to(
|
46
|
+
eq(AnonymousUser.instance))
|
47
|
+
|
48
|
+
current_user_manager.sign_in!(user)
|
49
|
+
|
50
|
+
expect(current_user_manager.signed_in?).to eq(true)
|
51
|
+
expect(current_user_manager.current_account).to eq(account)
|
52
|
+
expect(current_user_manager.current_user).to eq(user)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'from session' do
|
58
|
+
|
59
|
+
before(:each) do
|
60
|
+
current_user_manager.sign_in!(account)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'keeps a legitimate user signed in' do
|
64
|
+
expect(current_user_manager.signed_in?).to eq(true)
|
65
|
+
expect(current_user_manager.current_account).to eq(account)
|
66
|
+
expect(current_user_manager.current_user).to eq(user)
|
67
|
+
|
68
|
+
# Secure cookies are not sent with non-SSL requests
|
69
|
+
unsecure_cookies = ActionDispatch::Cookies::CookieJar.new(
|
70
|
+
SecureRandom.hex, 'localhost')
|
71
|
+
unsecure_cookies[:account_id] = cookies[:account_id]
|
72
|
+
|
73
|
+
current_user_manager = CurrentUserManager.new(
|
74
|
+
request, session, unsecure_cookies)
|
75
|
+
|
76
|
+
expect(current_user_manager.signed_in?).to eq(true)
|
77
|
+
expect(current_user_manager.current_account).to eq(account)
|
78
|
+
expect(current_user_manager.current_user).to eq(user)
|
79
|
+
|
80
|
+
# But they are sent with SSL requests
|
81
|
+
current_user_manager = CurrentUserManager.new(
|
82
|
+
ssl_request, session, cookies)
|
83
|
+
|
84
|
+
expect(current_user_manager.signed_in?).to eq(true)
|
85
|
+
expect(current_user_manager.current_account).to eq(account)
|
86
|
+
expect(current_user_manager.current_user).to eq(user)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'signs out an attacker attempting to hijack the session' do
|
90
|
+
expect(current_user_manager.signed_in?).to eq(true)
|
91
|
+
expect(current_user_manager.current_account).to eq(account)
|
92
|
+
expect(current_user_manager.current_user).to eq(user)
|
93
|
+
|
94
|
+
# The protection relies on the attacker not being
|
95
|
+
# able to get the secure cookies
|
96
|
+
cookies.delete(:secure_account_id)
|
97
|
+
|
98
|
+
# The attacker can still access non-SSL pages
|
99
|
+
current_user_manager = CurrentUserManager.new(
|
100
|
+
request, session, cookies)
|
101
|
+
|
102
|
+
expect(current_user_manager.signed_in?).to eq(true)
|
103
|
+
expect(current_user_manager.current_account).to eq(account)
|
104
|
+
expect(current_user_manager.current_user).to eq(user)
|
105
|
+
|
106
|
+
# But not SSL pages
|
107
|
+
current_user_manager = CurrentUserManager.new(
|
108
|
+
ssl_request, session, cookies)
|
109
|
+
|
110
|
+
expect(current_user_manager.signed_in?).to eq(false)
|
111
|
+
expect(current_user_manager.current_account).to(
|
112
|
+
eq(AnonymousAccount.instance))
|
113
|
+
expect(current_user_manager.current_user).to(
|
114
|
+
eq(AnonymousUser.instance))
|
115
|
+
|
116
|
+
# And after they logout, that's it
|
117
|
+
current_user_manager = CurrentUserManager.new(
|
118
|
+
request, session, cookies)
|
119
|
+
|
120
|
+
expect(current_user_manager.signed_in?).to eq(false)
|
121
|
+
expect(current_user_manager.current_account).to(
|
122
|
+
eq(AnonymousAccount.instance))
|
123
|
+
expect(current_user_manager.current_user).to(
|
124
|
+
eq(AnonymousUser.instance))
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'signing out' do
|
130
|
+
|
131
|
+
before(:each) { current_user_manager.sign_in!(account) }
|
132
|
+
|
133
|
+
it 'signs out users' do
|
134
|
+
expect(current_user_manager.signed_in?).to eq(true)
|
135
|
+
expect(current_user_manager.current_account).to eq(account)
|
136
|
+
expect(current_user_manager.current_user).to eq(user)
|
137
|
+
|
138
|
+
current_user_manager.sign_out!
|
139
|
+
|
140
|
+
expect(current_user_manager.signed_in?).to eq(false)
|
141
|
+
expect(current_user_manager.current_account).to(
|
142
|
+
eq(AnonymousAccount.instance))
|
143
|
+
expect(current_user_manager.current_user).to(
|
144
|
+
eq(AnonymousUser.instance))
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
module OpenStax
|
2
2
|
describe Accounts do
|
3
|
-
let!(:
|
4
|
-
|
5
|
-
access_token: 'secret') }
|
3
|
+
let!(:account) { OpenStax::Accounts::Account.create(username: 'some_user',
|
4
|
+
openstax_uid: 1, access_token: 'secret') }
|
6
5
|
|
7
6
|
it 'makes api calls' do
|
8
7
|
expect(Api::DummyController.last_action).to be_nil
|
@@ -12,26 +11,34 @@ module OpenStax
|
|
12
11
|
expect(Api::DummyController.last_params).to include 'test' => 'true'
|
13
12
|
end
|
14
13
|
|
15
|
-
it 'makes api call to
|
14
|
+
it 'makes api call to accounts (index)' do
|
15
|
+
Api::UsersController.last_action = nil
|
16
|
+
Api::UsersController.last_params = nil
|
17
|
+
Accounts.search_accounts('sth')
|
18
|
+
expect(Api::UsersController.last_action).to eq :index
|
19
|
+
expect(Api::UsersController.last_params).to include :q => 'sth'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'makes api call to application_accounts (index)' do
|
16
23
|
Api::ApplicationUsersController.last_action = nil
|
17
24
|
Api::ApplicationUsersController.last_params = nil
|
18
|
-
Accounts.
|
25
|
+
Accounts.search_application_accounts('sth')
|
19
26
|
expect(Api::ApplicationUsersController.last_action).to eq :index
|
20
27
|
expect(Api::ApplicationUsersController.last_params).to include :q => 'sth'
|
21
28
|
end
|
22
29
|
|
23
|
-
it 'makes api call to
|
30
|
+
it 'makes api call to application_users_updates' do
|
24
31
|
Api::ApplicationUsersController.last_action = nil
|
25
32
|
Api::ApplicationUsersController.last_params = nil
|
26
|
-
Accounts.
|
33
|
+
Accounts.get_application_account_updates
|
27
34
|
expect(Api::ApplicationUsersController.last_action).to eq :updates
|
28
35
|
expect(Api::ApplicationUsersController.last_params).not_to be_nil
|
29
36
|
end
|
30
37
|
|
31
|
-
it 'makes api call to
|
38
|
+
it 'makes api call to application_users_updated' do
|
32
39
|
Api::ApplicationUsersController.last_action = nil
|
33
40
|
Api::ApplicationUsersController.last_params = nil
|
34
|
-
Accounts.
|
41
|
+
Accounts.mark_updates_as_read({1 => 1})
|
35
42
|
expect(Api::ApplicationUsersController.last_action).to eq :updated
|
36
43
|
expect(Api::ApplicationUsersController.last_params[:application_users]).to include '1' => '1'
|
37
44
|
end
|