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.
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module OpenStax
2
2
  module Accounts
3
- VERSION = "1.0.0"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
@@ -1,11 +1,9 @@
1
1
  require 'openstax/accounts/version'
2
2
  require 'openstax/accounts/engine'
3
- require 'openstax/accounts/route_helper'
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
- # See the "user_provider" discussion in the README
72
- attr_accessor :user_provider
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
- # The maximum number of users that can be returned in a call to SearchUsers
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 SearchUsers
77
- attr_accessor :max_matching_users
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
- @user_provider = OpenStax::Accounts::UserProvider
96
- @max_matching_users = 10
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!({ 'Accept' => "application/vnd.accounts.openstax.#{version.to_s}" })
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 ApplicationUser search in Accounts for the configured app.
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 application_users_index(query, version = DEFAULT_API_VERSION)
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 ApplicationUsers that have been recently updated.
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 application_users_updates(version = DEFAULT_API_VERSION)
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 ApplicationUser updates as "read".
150
- # The app_users parameter is a hash that maps ApplicationUser
151
- # openstax_uid's to the value of the last received unread_updates.
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 application_users_updated(app_users, version = DEFAULT_API_VERSION)
174
+ def mark_updates_as_read(uid_map, version = DEFAULT_API_VERSION)
155
175
  options = {:api_version => version,
156
- :body => {:application_users => app_users}}
176
+ :body => {:application_users => uid_map}}
157
177
  api_call(:put, 'application_users/updated', options)
158
178
  end
159
179
 
160
- # Updates an OpenStax::Accounts::User in Accounts for the configured app.
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 user_update(user, version = DEFAULT_API_VERSION)
166
- options = {:access_token => user.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 => user.attributes.slice('username', 'first_name',
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 { OpenStax::Accounts::Engine.routes }
5
+ routes { Engine.routes }
6
6
 
7
- let!(:user) { OpenStax::Accounts::User.create(username: 'some_user',
8
- openstax_uid: 1) }
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 RouteHelper.get_path(:login)
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 user
22
- expect(controller.current_user).to eq(user)
23
- expect(controller.current_user.is_anonymous?).to eq(false)
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.current_user).to eq(OpenStax::Accounts::User.anonymous)
26
- expect(controller.current_user.is_anonymous?).to eq(true)
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
@@ -4,10 +4,6 @@ module Api
4
4
  dummy(:index)
5
5
  end
6
6
 
7
- def create
8
- dummy(:create)
9
- end
10
-
11
7
  def updates
12
8
  dummy(:updates)
13
9
  end
@@ -0,0 +1,7 @@
1
+ module Api
2
+ class UsersController < DummyController
3
+ def index
4
+ dummy(:index)
5
+ end
6
+ end
7
+ 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.max_matching_users = 47
12
- end
12
+ config.max_matching_accounts = 47
13
+ end
@@ -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 :application_users, :only => [:index, :create] do
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
@@ -0,0 +1,11 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :users do |t|
4
+ t.integer :openstax_accounts_account_id
5
+
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :users, :openstax_accounts_account_id, :unique => true
10
+ end
11
+ end
@@ -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 => 0) do
14
+ ActiveRecord::Schema.define(:version => 1) do
15
15
 
16
- create_table "openstax_accounts_users", :force => true do |t|
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 "openstax_accounts_users", ["openstax_uid"], :name => "index_openstax_accounts_users_on_openstax_uid", :unique => true
29
- add_index "openstax_accounts_users", ["username"], :name => "index_openstax_accounts_users_on_username", :unique => true
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,6 @@
1
+ FactoryGirl.define do
2
+ factory :openstax_accounts_account, :class => OpenStax::Accounts::Account do
3
+ sequence(:openstax_uid) { -SecureRandom.hex.to_i(16) }
4
+ sequence(:username) { SecureRandom.hex }
5
+ end
6
+ 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!(:user) { OpenStax::Accounts::User.create(username: 'some_user',
4
- openstax_uid: 1,
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 application_user index' do
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.application_users_index('sth')
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 application_user updates' do
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.application_users_updates
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 application_user updated' do
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.application_users_updated({1 => 1})
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
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ module OpenStax::Accounts
4
+ describe Account do
5
+ it 'is not anonymous' do
6
+ expect(Account.new.is_anonymous?).to be_false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ module OpenStax::Accounts
4
+ describe AnonymousAccount do
5
+ it 'is anonymous' do
6
+ expect(AnonymousAccount.instance.is_anonymous?).to be_true
7
+ end
8
+ end
9
+ end