openstax_accounts 0.1.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 (74) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +123 -0
  3. data/Rakefile +22 -0
  4. data/app/assets/javascripts/openstax/accounts/application.js +15 -0
  5. data/app/assets/stylesheets/openstax/accounts/application.css +13 -0
  6. data/app/assets/stylesheets/openstax/accounts/dev.css.scss +31 -0
  7. data/app/controllers/openstax/accounts/application_controller.rb +24 -0
  8. data/app/controllers/openstax/accounts/dev/dev_controller.rb +13 -0
  9. data/app/controllers/openstax/accounts/dev/users_controller.rb +21 -0
  10. data/app/controllers/openstax/accounts/sessions_controller.rb +41 -0
  11. data/app/handlers/openstax/accounts/dev/users_search.rb +38 -0
  12. data/app/handlers/openstax/accounts/sessions_omniauth_authenticated.rb +47 -0
  13. data/app/helpers/openstax/accounts/application_helper.rb +20 -0
  14. data/app/models/openstax/accounts/user.rb +42 -0
  15. data/app/routines/openstax/accounts/dev/create_user.rb +37 -0
  16. data/app/routines/openstax/accounts/search_users.rb +47 -0
  17. data/app/views/layouts/openstax/accounts/application.html.erb +14 -0
  18. data/app/views/openstax/accounts/dev/users/login.html.erb +17 -0
  19. data/app/views/openstax/accounts/dev/users/search.js.erb +21 -0
  20. data/app/views/openstax/accounts/shared/_attention.html.erb +3 -0
  21. data/app/views/openstax/accounts/users/_action_create_form.html.erb +9 -0
  22. data/app/views/openstax/accounts/users/_action_dialog.html.erb +10 -0
  23. data/app/views/openstax/accounts/users/_action_list.html.erb +33 -0
  24. data/app/views/openstax/accounts/users/_action_search.html.erb +25 -0
  25. data/app/views/openstax/accounts/users/action_search.js.erb +8 -0
  26. data/config/initializers/extend_builtins.rb +42 -0
  27. data/config/routes.rb +25 -0
  28. data/db/migrate/0_create_openstax_accounts_users.rb +18 -0
  29. data/lib/omniauth/strategies/openstax.rb +39 -0
  30. data/lib/openstax/accounts/action_list.rb +42 -0
  31. data/lib/openstax/accounts/current_user_manager.rb +103 -0
  32. data/lib/openstax/accounts/engine.rb +35 -0
  33. data/lib/openstax/accounts/route_helper.rb +34 -0
  34. data/lib/openstax/accounts/user_provider.rb +15 -0
  35. data/lib/openstax/accounts/version.rb +5 -0
  36. data/lib/openstax_accounts.rb +130 -0
  37. data/spec/controllers/openstax/accounts/dev/users_controller_spec.rb +20 -0
  38. data/spec/controllers/openstax/accounts/sessions_controller_spec.rb +29 -0
  39. data/spec/dummy/README.md +1 -0
  40. data/spec/dummy/Rakefile +7 -0
  41. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  42. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  43. data/spec/dummy/app/controllers/api/application_users_controller.rb +7 -0
  44. data/spec/dummy/app/controllers/api/dummy_controller.rb +11 -0
  45. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  46. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  47. data/spec/dummy/config/application.rb +53 -0
  48. data/spec/dummy/config/boot.rb +10 -0
  49. data/spec/dummy/config/database.yml +25 -0
  50. data/spec/dummy/config/environment.rb +5 -0
  51. data/spec/dummy/config/environments/development.rb +29 -0
  52. data/spec/dummy/config/environments/production.rb +69 -0
  53. data/spec/dummy/config/environments/test.rb +35 -0
  54. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  55. data/spec/dummy/config/initializers/inflections.rb +15 -0
  56. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  57. data/spec/dummy/config/initializers/openstax_accounts.rb +11 -0
  58. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  59. data/spec/dummy/config/initializers/session_store.rb +8 -0
  60. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  61. data/spec/dummy/config/locales/en.yml +5 -0
  62. data/spec/dummy/config/routes.rb +11 -0
  63. data/spec/dummy/config.ru +4 -0
  64. data/spec/dummy/db/schema.rb +31 -0
  65. data/spec/dummy/public/404.html +26 -0
  66. data/spec/dummy/public/422.html +26 -0
  67. data/spec/dummy/public/500.html +25 -0
  68. data/spec/dummy/public/favicon.ico +0 -0
  69. data/spec/dummy/script/rails +6 -0
  70. data/spec/factories/openstax_accounts_user.rb +6 -0
  71. data/spec/lib/openstax_accounts_spec.rb +24 -0
  72. data/spec/models/openstax/accounts/user_spec.rb +13 -0
  73. data/spec/spec_helper.rb +41 -0
  74. metadata +401 -0
@@ -0,0 +1,33 @@
1
+ <%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
2
+ License version 3 or later. See the COPYRIGHT file for details. %>
3
+
4
+ <%
5
+ users ||= []
6
+ %>
7
+
8
+ <% if list.num_columns > 0 %>
9
+ <table class="list" width="100%">
10
+ <% if list.has_headings? %>
11
+ <tr>
12
+ <% for ii in 0..list.num_columns - 1 %>
13
+ <th><%= list.get_heading(ii) %></th>
14
+ <% end %>
15
+ </tr>
16
+ <% end %>
17
+
18
+ <% if users.empty? %>
19
+ <tr>
20
+ <td colspan="<%= list.num_columns %>">No results</td>
21
+ </tr>
22
+ <% else %>
23
+ <% users.all.each_with_index do |user, uu| %>
24
+ <tr>
25
+ <% for cc in 0..list.num_columns - 1 %>
26
+ <% width = uu == 0 ? list.get_width(cc) : nil %>
27
+ <td <%= "width=#{width}" if width %>><%= list.get_data(cc, user) %></td>
28
+ <% end %>
29
+ </tr>
30
+ <% end %>
31
+ <% end %>
32
+ </table>
33
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
2
+ License version 3 or later. See the COPYRIGHT file for details. %>
3
+
4
+ <%
5
+ # Clients of this partial must supply the following variables:
6
+ # action_search_path
7
+ %>
8
+
9
+ <div id="action-search-errors"></div>
10
+
11
+ <%= lev_form_for :search,
12
+ url: action_search_path,
13
+ html: {id: 'action-search-form'},
14
+ remote: true do |f| %>
15
+
16
+ Search for
17
+ <%= f.text_field :search_terms, style: 'width:300px' %>
18
+ in
19
+ <%= f.select :search_type, options_for_select(['Any', 'Name', 'Username']) %>
20
+
21
+ <%= submit_tag 'Search' %>
22
+
23
+ <% end %>
24
+
25
+ <div id="action-search-results-list"></div>
@@ -0,0 +1,8 @@
1
+ <%= unless_errors errors_html_id: (errors_html_id ||= 'action-search-errors') do %>
2
+ <% contents = render 'openstax/accounts/users/action_list',
3
+ users: users,
4
+ list: list %>
5
+
6
+ $("#action-search-results-list").html("<%= j(contents) %>");
7
+ <% end %>
8
+
@@ -0,0 +1,42 @@
1
+ class ActionController::Base
2
+
3
+ # Returns the current app user
4
+ def current_user
5
+ current_user_manager.current_user
6
+ end
7
+
8
+ # Signs in the given user; the argument can be either an accounts user or
9
+ # an app user
10
+ def sign_in(user)
11
+ current_user_manager.sign_in(user)
12
+ end
13
+
14
+ # Signs out the current user
15
+ def sign_out!
16
+ current_user_manager.sign_out!
17
+ end
18
+
19
+ # Returns true iff there is a user signed in
20
+ def signed_in?
21
+ current_user_manager.signed_in?
22
+ end
23
+
24
+ # Useful in before_filters
25
+ def authenticate_user!
26
+ return if signed_in?
27
+ session[:return_to] = "#{request.protocol}#{request.host_with_port}#{request.fullpath}"
28
+ redirect_to openstax_accounts.login_path
29
+ end
30
+
31
+ protected
32
+
33
+ helper_method :current_user, :signed_in?
34
+
35
+ def current_user_manager
36
+ @current_user_manager ||= OpenStax::Accounts::CurrentUserManager.new(request,
37
+ session,
38
+ cookies)
39
+ end
40
+
41
+ end
42
+
data/config/routes.rb ADDED
@@ -0,0 +1,25 @@
1
+ OpenStax::Accounts::Engine.routes.draw do
2
+ match '/auth/openstax/callback', to: 'sessions#omniauth_authenticated' #omniauth route
3
+ get '/auth/openstax', :as => 'openstax_login'
4
+
5
+ get 'sessions/new', :as => 'login'
6
+ # See https://github.com/plataformatec/devise/commit/f3385e96abf50e80d2ae282e1fb9bdad87a83d3c
7
+ match 'sessions/destroy', :as => 'logout',
8
+ :via => OpenStax::Accounts.configuration.logout_via
9
+
10
+ if OpenStax::Accounts.configuration.enable_stubbing?
11
+ namespace :dev do
12
+ resources :users, :only => [] do
13
+ collection do
14
+ get 'login'
15
+ post 'search'
16
+ post 'become'
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ hh = OpenStax::Accounts::Engine.routes.url_helpers
24
+
25
+ OpenStax::Accounts::RouteHelper.register_path(:login, hh.openstax_login_path) { hh.login_dev_users_path }
@@ -0,0 +1,18 @@
1
+ class CreateOpenStaxAccountsUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :openstax_accounts_users do |t|
4
+ t.integer :openstax_uid
5
+ t.string :username
6
+ t.string :first_name
7
+ t.string :last_name
8
+ t.string :full_name
9
+ t.string :title
10
+ t.string :access_token
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :openstax_accounts_users, :openstax_uid, :unique => true
16
+ add_index :openstax_accounts_users, :username, :unique => true
17
+ end
18
+ end
@@ -0,0 +1,39 @@
1
+ require 'omniauth'
2
+ require 'omniauth-oauth2'
3
+
4
+ module OmniAuth
5
+ module Strategies
6
+ class Openstax < OAuth2
7
+ option :name, "openstax"
8
+
9
+ option :client_options, {
10
+ :site => "http://accounts.openstax.org",
11
+ :authorize_url => "/oauth/authorize"
12
+ }
13
+
14
+ uid { raw_info["id"] }
15
+
16
+ info do
17
+ username = raw_info["username"]
18
+ title = raw_info["title"]
19
+ first_name = raw_info["first_name"]
20
+ last_name = raw_info["last_name"]
21
+ full_name = raw_info["full_name"] || "#{first_name} #{last_name}"
22
+ full_name = username if full_name.blank?
23
+
24
+ # Changed to conform to the omniauth schema
25
+ {
26
+ name: full_name,
27
+ nickname: username,
28
+ first_name: first_name,
29
+ last_name: last_name,
30
+ title: title
31
+ }
32
+ end
33
+
34
+ def raw_info
35
+ @raw_info ||= access_token.get('/api/users/me.json').parsed
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,42 @@
1
+ module OpenStax
2
+ module Accounts
3
+ class ActionList
4
+
5
+ def initialize(options={})
6
+ @options = options
7
+
8
+ raise IllegalArgument, "must supply data procs" if options[:data_procs].nil?
9
+
10
+ if options[:headings].present? && options[:data_procs].size != options[:headings].size
11
+ raise IllegalArgument, "if you supply headings, you must supply one for each column"
12
+ end
13
+
14
+ if options[:widths].present? && options[:data_procs].size != options[:widths].size
15
+ raise IllegalArgument, "if you supply widths, you must supply one for each column"
16
+ end
17
+
18
+ end
19
+
20
+ def num_columns
21
+ @options[:data_procs].size
22
+ end
23
+
24
+ def has_headings?
25
+ @options[:headings].present?
26
+ end
27
+
28
+ def get_heading(column)
29
+ @options[:headings].nil? ? nil : @options[:headings][column]
30
+ end
31
+
32
+ def get_width(column)
33
+ @options[:widths].nil? ? nil : @options[:widths][column]
34
+ end
35
+
36
+ def get_data(column, *args)
37
+ @options[:data_procs][column].call(*args)
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,103 @@
1
+ module OpenStax
2
+ module Accounts
3
+ class CurrentUserManager
4
+
5
+ # References:
6
+ # http://railscasts.com/episodes/356-dangers-of-session-hijacking
7
+
8
+ def initialize(request, session, cookies)
9
+ @request = request
10
+ @session = session
11
+ @cookies = cookies
12
+ end
13
+
14
+ # Returns the current app user
15
+ def current_user
16
+ load_current_users
17
+ @app_current_user
18
+ end
19
+
20
+ # Signs in the given user; the argument can be either an accounts user or
21
+ # an app user
22
+ def sign_in(user)
23
+ user.is_a?(User) ?
24
+ self.accounts_current_user = user :
25
+ self.current_user = user
26
+ end
27
+
28
+ # Signs out the user
29
+ def sign_out!
30
+ sign_in(OpenStax::Accounts::User.anonymous)
31
+ end
32
+
33
+ # Returns true iff there is a user signed in
34
+ def signed_in?
35
+ !accounts_current_user.is_anonymous?
36
+ end
37
+
38
+ # Returns the current accounts user
39
+ def accounts_current_user
40
+ load_current_users
41
+ @accounts_current_user
42
+ end
43
+
44
+ protected
45
+
46
+ # If they are nil (unset), sets the current users based on the session state
47
+ def load_current_users
48
+ return if !@accounts_current_user.nil?
49
+
50
+ if @request.ssl? && @cookies.signed[:secure_user_id] != "secure#{@session[:user_id]}"
51
+ sign_out! # hijacked
52
+ else
53
+ # If there is a session user_id, load up that user, otherwise set the anonymous user.
54
+
55
+ if @session[:user_id]
56
+ @accounts_current_user = User.where(id: @session[:user_id]).first
57
+
58
+ # It could happen (normally in development) that there is a session
59
+ # user_id that doesn't map to a User in the db.
60
+ # In such a case, sign_out! to reset the state
61
+ if @accounts_current_user.nil?
62
+ sign_out!
63
+ return
64
+ end
65
+ else
66
+ @accounts_current_user = User.anonymous
67
+ end
68
+
69
+ # Bring the app user inline with the accounts user
70
+ @app_current_user = user_provider.accounts_user_to_app_user(@accounts_current_user)
71
+ end
72
+ end
73
+
74
+ # Sets (signs in) the provided app user.
75
+ def current_user=(user)
76
+ self.accounts_current_user = user_provider.app_user_to_accounts_user(user)
77
+ @app_current_user
78
+ end
79
+
80
+ # Sets the current accounts user, updates the app user, and also updates
81
+ # the session and cookie state.
82
+ def accounts_current_user=(user)
83
+ @accounts_current_user = user || User.anonymous
84
+ @app_current_user = user_provider.accounts_user_to_app_user(@accounts_current_user)
85
+
86
+ if @accounts_current_user.is_anonymous?
87
+ @session[:user_id] = nil
88
+ @cookies.delete(:secure_user_id)
89
+ else
90
+ @session[:user_id] = @accounts_current_user.id
91
+ @cookies.signed[:secure_user_id] = {secure: true, value: "secure#{@accounts_current_user.id}"}
92
+ end
93
+
94
+ @accounts_current_user
95
+ end
96
+
97
+ def user_provider
98
+ OpenStax::Accounts.configuration.user_provider
99
+ end
100
+
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,35 @@
1
+ require 'omniauth'
2
+ require 'omniauth/strategies/openstax'
3
+ require 'lev'
4
+
5
+ ActiveSupport::Inflector.inflections do |inflect|
6
+ inflect.acronym 'OpenStax'
7
+ end
8
+
9
+ module OpenStax
10
+ module Accounts
11
+ class Engine < ::Rails::Engine
12
+ isolate_namespace OpenStax::Accounts
13
+
14
+ config.generators do |g|
15
+ g.test_framework :rspec, :view_specs => false, :fixture => false
16
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
17
+ g.assets false
18
+ g.helper false
19
+ end
20
+
21
+ SETUP_PROC = lambda do |env|
22
+ env['omniauth.strategy'].options[:client_options][:site] = OpenStax::Accounts.configuration.openstax_accounts_url
23
+ end
24
+
25
+ # Doesn't work to put this omniauth code in an engine initializer, instead:
26
+ # https://gist.github.com/pablomarti/5243118
27
+ middleware.use ::OmniAuth::Builder do
28
+ provider :openstax,
29
+ OpenStax::Accounts.configuration.openstax_application_id,
30
+ OpenStax::Accounts.configuration.openstax_application_secret,
31
+ :setup => SETUP_PROC
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,34 @@
1
+ require 'singleton'
2
+
3
+ module OpenStax
4
+ module Accounts
5
+ class RouteHelper
6
+
7
+ include Singleton
8
+
9
+ # Registers a path against a canonical name. An optional
10
+ # block can be provided to give the stubbed path
11
+ def self.register_path(canonical_name, path, &block)
12
+ instance.paths[canonical_name] = path
13
+ if block.present? && OpenStax::Accounts.configuration.enable_stubbing?
14
+ instance.stubbed_paths[canonical_name] = block.call
15
+ end
16
+ end
17
+
18
+ def self.get_path(canonical_name)
19
+ OpenStax::Accounts.configuration.enable_stubbing? ?
20
+ instance.stubbed_paths[canonical_name] :
21
+ instance.paths[canonical_name]
22
+ end
23
+
24
+ def initialize
25
+ self.paths = {}
26
+ self.stubbed_paths = {}
27
+ end
28
+
29
+ attr_accessor :paths
30
+ attr_accessor :stubbed_paths
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ module OpenStax
2
+ module Accounts
3
+ class UserProvider
4
+
5
+ def self.accounts_user_to_app_user(accounts_user)
6
+ accounts_user
7
+ end
8
+
9
+ def self.app_user_to_accounts_user(app_user)
10
+ app_user
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module OpenStax
2
+ module Accounts
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,130 @@
1
+ require 'openstax/accounts/version'
2
+ require 'openstax/accounts/engine'
3
+ require 'openstax/accounts/route_helper'
4
+ require 'openstax/accounts/action_list'
5
+ require 'openstax/accounts/user_provider'
6
+ require 'openstax/accounts/current_user_manager'
7
+
8
+ require 'openstax_utilities'
9
+ require 'uri'
10
+ require 'oauth2'
11
+
12
+ module OpenStax
13
+ module Accounts
14
+
15
+ class << self
16
+
17
+ ###########################################################################
18
+ #
19
+ # Configuration machinery.
20
+ #
21
+ # To configure OpenStax Accounts, put the following code in your
22
+ # application's initialization logic
23
+ # (eg. in the config/initializers in a Rails app)
24
+ #
25
+ # OpenStax::Accounts.configure do |config|
26
+ # config.<parameter name> = <parameter value>
27
+ # ...
28
+ # end
29
+ #
30
+ # Set enable_stubbing to true iff you want this engine to fake all
31
+ # interaction with the accounts site.
32
+ #
33
+
34
+ def configure
35
+ yield configuration
36
+ end
37
+
38
+ def configuration
39
+ @configuration ||= Configuration.new
40
+ end
41
+
42
+ class Configuration
43
+ attr_accessor :openstax_application_id
44
+ attr_accessor :openstax_application_secret
45
+ attr_accessor :enable_stubbing
46
+ attr_reader :openstax_accounts_url
47
+ attr_accessor :logout_via
48
+ attr_accessor :default_errors_partial
49
+ attr_accessor :default_errors_html_id
50
+ attr_accessor :default_errors_added_trigger
51
+ attr_accessor :security_transgression_exception
52
+
53
+ # See the "user_provider" discussion in the README
54
+ attr_accessor :user_provider
55
+
56
+ def openstax_accounts_url=(url)
57
+ url.gsub!(/https|http/,'https') if !(url =~ /localhost/)
58
+ url = url + "/" if url[url.size-1] != '/'
59
+ @openstax_accounts_url = url
60
+ end
61
+
62
+ def initialize
63
+ @openstax_application_id = 'SET ME!'
64
+ @openstax_application_secret = 'SET ME!'
65
+ @openstax_accounts_url = 'https://accounts.openstax.org/'
66
+ @enable_stubbing = true
67
+ @logout_via = :get
68
+ @default_errors_partial = 'openstax/accounts/shared/attention'
69
+ @default_errors_html_id = 'openstax-accounts-attention'
70
+ @default_errors_added_trigger = 'openstax-accounts-errors-added'
71
+ @security_transgression_exception = SecurityTransgression
72
+ @user_provider = OpenStax::Accounts::UserProvider
73
+ super
74
+ end
75
+
76
+ def enable_stubbing?
77
+ !Rails.env.production? && enable_stubbing
78
+ end
79
+ end
80
+
81
+ # Executes an OpenStax Accounts API call, using the given HTTP method,
82
+ # API url and request options.
83
+ # Any options accepted by OAuth2 requests can be used, such as
84
+ # :params, :body, :headers, etc, plus the :access_token option, which can
85
+ # be used to manually specify an OAuth access token.
86
+ # On failure, it can throw Faraday::ConnectionFailed for connection errors
87
+ # or OAuth2::Error if Accounts returns an HTTP 400 error,
88
+ # such as 422 Unprocessable Entity.
89
+ # On success, returns an OAuth2::Response object.
90
+ def api_call(http_method, url, options = {})
91
+ version = options.delete(:api_version)
92
+ unless version.blank?
93
+ options[:headers] ||= {}
94
+ options[:headers].merge!({ 'Accept' => "application/vnd.accounts.openstax.#{version.to_s}" })
95
+ end
96
+
97
+ token_string = options.delete(:access_token)
98
+ token = token_string.blank? ? client.client_credentials.get_token :
99
+ OAuth2::AccessToken.new(client, token_string)
100
+
101
+ api_url = URI.join(configuration.openstax_accounts_url, 'api/', url)
102
+
103
+ token.request(http_method, api_url, options)
104
+ end
105
+
106
+ # Creates an ApplicationUser in Accounts for this app and the given
107
+ # OpenStax::Accounts::User.
108
+ # Also takes an optional API version parameter. Defaults to :v1.
109
+ # On failure, throws an Exception, just like api_call.
110
+ # On success, returns an OAuth2::Response object.
111
+ def create_application_user(user, version = nil)
112
+ options = {:access_token => user.access_token,
113
+ :api_version => (version.nil? ? :v1 : version)}
114
+ api_call(:post, 'application_users', options)
115
+ end
116
+
117
+ protected
118
+
119
+ def client
120
+ @client ||= OAuth2::Client.new(
121
+ configuration.openstax_application_id,
122
+ configuration.openstax_application_secret,
123
+ :site => configuration.openstax_accounts_url
124
+ )
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module OpenStax::Accounts
4
+ module Dev
5
+ describe UsersController do
6
+ routes { OpenStax::Accounts::Engine.routes }
7
+
8
+ let!(:user) { OpenStax::Accounts::User.create(username: 'some_user',
9
+ openstax_uid: 1) }
10
+
11
+ it 'should allow users not in production to become other users' do
12
+ expect(controller.current_user).to eq(OpenStax::Accounts::User.anonymous)
13
+ expect(controller.current_user.is_anonymous?).to eq(true)
14
+ get :become, user_id: user.id
15
+ expect(controller.current_user).to eq(user)
16
+ expect(controller.current_user.is_anonymous?).to eq(false)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ module OpenStax::Accounts
4
+ describe SessionsController do
5
+ routes { OpenStax::Accounts::Engine.routes }
6
+
7
+ let!(:user) { OpenStax::Accounts::User.create(username: 'some_user',
8
+ openstax_uid: 1) }
9
+
10
+ it 'should redirect users to the login path' do
11
+ get :new
12
+ expect(response).to redirect_to RouteHelper.get_path(:login)
13
+ expect(response.code).to eq('302')
14
+ end
15
+
16
+ it 'should authenticate users based on the oauth callback' do
17
+ # TODO
18
+ end
19
+
20
+ 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
+ delete :destroy
25
+ expect(controller.current_user).to eq(OpenStax::Accounts::User.anonymous)
26
+ expect(controller.current_user.is_anonymous?).to eq(true)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1 @@
1
+ Dummy application used to test the OpenStax Accounts engine.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
3
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
+
5
+ require File.expand_path('../config/application', __FILE__)
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,7 @@
1
+ module Api
2
+ class ApplicationUsersController < DummyController
3
+ def create
4
+ dummy(:create)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Api
2
+ class DummyController < ApplicationController
3
+ class << self; attr_accessor :last_action, :last_params end
4
+
5
+ def dummy(action_name = :dummy)
6
+ self.class.last_action = action_name
7
+ self.class.last_params = params
8
+ render :json => { :head => :no_content }
9
+ end
10
+ end
11
+ end