openstax_connect 0.0.10 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/README.md +26 -9
  2. data/Rakefile +12 -39
  3. data/app/controllers/openstax/connect/application_controller.rb +15 -4
  4. data/app/controllers/openstax/connect/dev/dev_controller.rb +1 -4
  5. data/app/controllers/openstax/connect/dev/users_controller.rb +5 -0
  6. data/app/controllers/openstax/connect/sessions_controller.rb +9 -19
  7. data/app/handlers/openstax/connect/sessions_omniauth_authenticated.rb +4 -1
  8. data/app/views/openstax/connect/dev/users/login.html.erb +2 -2
  9. data/app/views/openstax/connect/dev/users/search.js.erb +1 -1
  10. data/config/initializers/{02_extend_builtins.rb → extend_builtins.rb} +0 -0
  11. data/config/routes.rb +11 -6
  12. data/db/migrate/20140410194004_add_fields_to_openstax_connect_users.rb +7 -0
  13. data/lib/omniauth/strategies/openstax.rb +15 -6
  14. data/lib/openstax/connect/current_user_manager.rb +3 -3
  15. data/lib/openstax/connect/engine.rb +1 -4
  16. data/lib/openstax/connect/inflections.rb +3 -0
  17. data/lib/openstax/connect/version.rb +1 -1
  18. data/lib/openstax_connect.rb +52 -6
  19. data/spec/controllers/openstax/connect/dev/users_controller_spec.rb +20 -0
  20. data/spec/controllers/openstax/connect/sessions_controller_spec.rb +21 -7
  21. data/spec/dummy/README.md +1 -0
  22. data/spec/dummy/Rakefile +7 -0
  23. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  24. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  25. data/spec/dummy/app/controllers/api/application_users_controller.rb +7 -0
  26. data/spec/dummy/app/controllers/api/dummy_controller.rb +11 -0
  27. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  28. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  29. data/spec/dummy/config.ru +4 -0
  30. data/spec/dummy/config/application.rb +53 -0
  31. data/spec/dummy/config/boot.rb +10 -0
  32. data/spec/dummy/config/database.yml +25 -0
  33. data/spec/dummy/config/environment.rb +5 -0
  34. data/spec/dummy/config/environments/development.rb +29 -0
  35. data/spec/dummy/config/environments/production.rb +69 -0
  36. data/spec/dummy/config/environments/test.rb +35 -0
  37. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  38. data/spec/dummy/config/initializers/inflections.rb +15 -0
  39. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  40. data/spec/dummy/config/initializers/openstax_connect.rb +11 -0
  41. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  42. data/spec/dummy/config/initializers/session_store.rb +8 -0
  43. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  44. data/spec/dummy/config/locales/en.yml +5 -0
  45. data/spec/dummy/config/routes.rb +11 -0
  46. data/spec/dummy/db/schema.rb +31 -0
  47. data/spec/dummy/public/404.html +26 -0
  48. data/spec/dummy/public/422.html +26 -0
  49. data/spec/dummy/public/500.html +25 -0
  50. data/spec/dummy/public/favicon.ico +0 -0
  51. data/spec/dummy/script/rails +6 -0
  52. data/spec/lib/openstax_connect_spec.rb +24 -0
  53. data/spec/models/openstax/connect/user_spec.rb +7 -1
  54. data/spec/spec_helper.rb +7 -4
  55. metadata +109 -17
  56. data/app/assets/javascripts/openstax/connect/sessions.js +0 -2
  57. data/app/assets/stylesheets/openstax/connect/sessions.css +0 -4
  58. data/app/helpers/openstax/connect/sessions_helper.rb +0 -4
  59. data/config/initializers/01_requires.rb +0 -1
  60. data/lib/openstax/connect/exceptions.rb +0 -3
  61. data/lib/tasks/connect-rails_tasks.rake +0 -4
  62. data/spec/helpers/openstax/connect/sessions_helper_spec.rb +0 -17
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  connect-rails
2
2
  =============
3
3
 
4
- A rails engine for interfacing with OpenStax's common services server.
4
+ A rails engine for interfacing with OpenStax's common accounts server.
5
5
 
6
6
  Usage
7
7
  -----
@@ -21,13 +21,13 @@ You can use whatever path you want instead of `/connect`, just make sure to make
21
21
  Create an `openstax_connect.rb` initializer in `config/initializers`, with the following contents:
22
22
 
23
23
  OpenStax::Connect.configure do |config|
24
- config.openstax_application_id = 'value_from_openstax_services_here'
25
- config.openstax_application_secret = 'value_from_openstax_services_here'
24
+ config.openstax_application_id = 'value_from_openstax_accounts_here'
25
+ config.openstax_application_secret = 'value_from_openstax_accounts_here'
26
26
  end
27
27
 
28
- If you're running OpenStax Services in a dev instance on your machine, you can specify that instance's local URL with:
28
+ If you're running OpenStax Accounts in a dev instance on your machine, you can specify that instance's local URL with:
29
29
 
30
- config.openstax_services_url = 'http://localhost:2999/'
30
+ config.openstax_accounts_url = 'http://localhost:2999/'
31
31
 
32
32
  To have users login, direct them to `/connect/sessions/new`. This is also available through the `openstax_connect.login` route helper, e.g. `<%= link_to 'Sign in!', openstax_connect.login_path %>`.
33
33
 
@@ -75,13 +75,30 @@ Make sure to install the engine's migrations:
75
75
 
76
76
  rake openstax_connect:install:migrations
77
77
 
78
+ Accounts API
79
+ ------------
80
+
81
+ OpenStax::Connect provides convenience methods for accessing the OpenStax Accounts API.
82
+
83
+ `OpenStax::Connect.create_application_user(user, version = nil)` takes
84
+ an OpenStax::Connect::User and, optionally, an API version argument, and creates
85
+ an ApplicationUser for the configured application and the given user. Call this method
86
+ when users finish the registration process in your app.
87
+
88
+ `OpenStax::Connect.api_call(http_method, url, options = {})` provides a generic
89
+ convenience method capable of making API calls to Accounts. `http_method` can be
90
+ any valid HTTP method, and `url` is the desired API URL, without the 'api/' prefix.
91
+ Options is a hash that can contain any option that OAuth2 requests accept, such
92
+ as :headers, :params, :body, etc, plus the optional values :api_version (to specify
93
+ an API version) and :access_token (to specify an OAuth access token).
94
+
78
95
  Example Application
79
96
  -------------------
80
97
 
81
98
  There is an example application included in the gem in the `example` folder. Here are steps
82
99
  to follow:
83
100
 
84
- 1. Download (clone) the OpenStax Services site from github.com/openstax/services.
101
+ 1. Download (clone) the OpenStax Accounts site from github.com/openstax/accounts.
85
102
  1. In the site's `config` folder put a `secret_settings.yml` file that has values for the
86
103
  following keys: `facebook_app_id`, `facebook_app_secret`, `twitter_consumer_key`, `twitter_consumer_secret`. If you
87
104
  don't have access to these values, you can always make dummy apps on facebook and twitter.
@@ -89,7 +106,7 @@ don't have access to these values, you can always make dummy apps on facebook an
89
106
  1. Run `bundle install --without production`
90
107
  2. Run `bundle exec rake db:migrate`
91
108
  3. Run `bundle exec rails server`
92
- 2. Open this services site in a web browser (defaults to http://localhost:2999)
109
+ 2. Open this accounts site in a web browser (defaults to http://localhost:2999)
93
110
  3. Navigate to http://localhost:2999/oauth/applications
94
111
  4. Click `New application`
95
112
  5. Set the callback URL to `http://localhost:4000/connect/auth/openstax/callback`.
@@ -98,9 +115,9 @@ Port 4000 is where you'll be running the example application.
98
115
  2. Click the `Trusted?` checkbox.
99
116
  3. Click `Submit`.
100
117
  4. Keep this window open so you can copy the application ID and secret into the example app
101
- 5. Leave the services app running
118
+ 5. Leave the accounts app running
102
119
  6. Download (clone) the OpenStax Connect gem from github.com/openstax/connect-rails. The
103
120
  example application is in the `example` folder. In that folder's config folder, create a `secret_settings.yml` file
104
121
  according to the instructions in `secret_settings.yml.example`. Run the example server in the normal way (bundle install..., migrate db, rails server).
105
- 7. Navigate to the home page, http://localhost:4000. Click log in and play around. You can also refresh the services site and see yourself logged in, log out, etc.
122
+ 7. Navigate to the home page, http://localhost:4000. Click log in and play around. You can also refresh the accounts site and see yourself logged in, log out, etc.
106
123
  8. For fun, change example/config/openstax_connect.rb to set `enable_stubbing` to `true`. Now when you click login you'll be taken to a developer-only page where you can login as other users, generate new users, create new users, etc.
data/Rakefile CHANGED
@@ -1,49 +1,22 @@
1
1
  #!/usr/bin/env rake
2
2
 
3
- require 'bundler/gem_tasks'
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
4
8
 
5
- # begin
6
- # require 'bundler/setup'
7
- # rescue LoadError
8
- # puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
9
- # end
10
- # begin
11
- # require 'rdoc/task'
12
- # rescue LoadError
13
- # require 'rdoc/rdoc'
14
- # require 'rake/rdoctask'
15
- # RDoc::Task = Rake::RDocTask
16
- # end
9
+ APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
10
+ load 'rails/tasks/engine.rake'
17
11
 
18
- # RDoc::Task.new(:rdoc) do |rdoc|
19
- # rdoc.rdoc_dir = 'rdoc'
20
- # rdoc.title = 'OpenstaxConnect'
21
- # rdoc.options << '--line-numbers'
22
- # rdoc.rdoc_files.include('README.rdoc')
23
- # rdoc.rdoc_files.include('lib/**/*.rb')
24
- # end
12
+ Bundler::GemHelper.install_tasks
25
13
 
26
- # APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
27
- # load 'rails/tasks/engine.rake'
28
-
29
-
30
-
31
- # Bundler::GemHelper.install_tasks
32
-
33
- # require 'rake/testtask'
34
-
35
- # Rake::TestTask.new(:test) do |t|
36
- # t.libs << 'lib'
37
- # t.libs << 'test'
38
- # t.pattern = 'test/**/*_test.rb'
39
- # t.verbose = false
40
- # end
41
-
42
-
43
- # task :default => :test
14
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
44
15
 
16
+ require 'rspec/core'
45
17
  require 'rspec/core/rake_task'
46
18
 
47
- RSpec::Core::RakeTask.new('spec')
19
+ desc 'Run all specs in spec directory (excluding plugin specs)'
20
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
48
21
 
49
22
  task :default => :spec
@@ -1,12 +1,23 @@
1
- # References:
2
- # http://edgeguides.rubyonrails.org/engines.html#using-a-class-provided-by-the-application
3
-
4
1
  module OpenStax
5
2
  module Connect
6
3
 
7
- # Inherit from the applications ApplicationController to share some methods
8
4
  class ApplicationController < ActionController::Base
9
5
  include Lev::HandleWith
6
+
7
+ # Override current_user to always return an OpenStax::Connect::User
8
+ def current_user
9
+ current_user_manager.connect_current_user
10
+ end
11
+
12
+ protected
13
+
14
+ def return_url(include_referrer=false)
15
+ referrer = include_referrer ? request.referrer : nil
16
+ # Always clear the session
17
+ session_return_to = session.delete(:return_to)
18
+ params[:return_to] || session_return_to || referrer || main_app.root_url
19
+ end
20
+
10
21
  end
11
22
 
12
23
  end
@@ -5,11 +5,8 @@ module OpenStax
5
5
  module Dev
6
6
  class DevController < ApplicationController
7
7
 
8
- skip_before_filter :authenticate_user!
9
-
10
8
  before_filter Proc.new{
11
- raise SecurityTransgression unless !Rails.env.production? ||
12
- current_user.is_administrator?
9
+ raise SecurityTransgression if Rails.env.production?
13
10
  }
14
11
 
15
12
  end
@@ -10,6 +10,11 @@ module OpenStax
10
10
  complete: lambda { render 'search' })
11
11
  end
12
12
 
13
+ def become
14
+ sign_in(User.find(params[:user_id]))
15
+ redirect_to return_url(true)
16
+ end
17
+
13
18
  end
14
19
  end
15
20
  end
@@ -4,29 +4,32 @@ module OpenStax
4
4
  module Connect
5
5
  class SessionsController < ApplicationController
6
6
 
7
- skip_before_filter :authenticate_user!
8
-
9
7
  def new
8
+ session[:return_to] ||= request.referrer
10
9
  redirect_to RouteHelper.get_path(:login)
11
10
  end
12
11
 
13
12
  def omniauth_authenticated
14
13
  handle_with(SessionsOmniauthAuthenticated,
15
- complete: lambda {
14
+ success: lambda {
16
15
  sign_in(@handler_result.outputs[:connect_user_to_sign_in])
17
- redirect_to return_url(true)
16
+ # referrer is in Accounts, so don't include it
17
+ redirect_to return_url
18
+ },
19
+ failure: lambda {
20
+ failure
18
21
  })
19
22
  end
20
23
 
21
24
  def destroy
22
25
  sign_out!
23
26
 
24
- # If we're using the Services server, need to sign out of it so can't
27
+ # If we're using the Accounts server, need to sign out of it so can't
25
28
  # log back in automagically
26
29
  redirect_to OpenStax::Connect.configuration.enable_stubbing? ?
27
30
  return_url :
28
31
  OpenStax::Utilities.generate_url(
29
- OpenStax::Connect.configuration.openstax_services_url + "/logout",
32
+ OpenStax::Connect.configuration.openstax_accounts_url + "/logout",
30
33
  return_to: return_url
31
34
  )
32
35
  end
@@ -35,19 +38,6 @@ module OpenStax
35
38
  redirect_to return_url, alert: "Authentication failed, please try again."
36
39
  end
37
40
 
38
- def become
39
- raise SecurityTransgression unless !Rails.env.production? || current_user.is_administrator?
40
- sign_in(User.find(params[:user_id]))
41
- redirect_to return_url(true)
42
- end
43
-
44
- protected
45
-
46
- def return_url(include_referrer=false)
47
- referrer = include_referrer ? request.referrer : nil
48
- params[:return_to] || session.delete(:return_to) || referrer || main_app.root_url
49
- end
50
-
51
41
  end
52
42
  end
53
43
  end
@@ -28,9 +28,12 @@ module OpenStax::Connect
28
28
 
29
29
  new_user = User.create do |user|
30
30
  user.openstax_uid = @auth_data.uid
31
- user.username = @auth_data.info.username
31
+ user.username = @auth_data.info.nickname
32
32
  user.first_name = @auth_data.info.first_name
33
33
  user.last_name = @auth_data.info.last_name
34
+ user.full_name = @auth_data.info.name
35
+ user.title = @auth_data.info.title
36
+ user.access_token = @auth_data.credentials.token
34
37
  end
35
38
 
36
39
  transfer_errors_from(new_user, {type: :verbatim})
@@ -7,10 +7,10 @@
7
7
 
8
8
  <%= osu.section_block "Development Login" do %>
9
9
 
10
- <p>You need to login, but we're not connected to the Services server. Search for a user below
10
+ <p>You need to login, but we're not connected to the Accounts server. Search for a user below
11
11
  and click the sign in link next to him or her.</p>
12
12
 
13
- <%= render 'openstax/connect/users/action_search', action_search_path: dev_users_search_path %>
13
+ <%= render 'openstax/connect/users/action_search', action_search_path: search_dev_users_path %>
14
14
 
15
15
  <% end %>
16
16
 
@@ -12,7 +12,7 @@
12
12
  Proc.new { |user| user.username },
13
13
  Proc.new { |user|
14
14
  link_to 'Sign in as',
15
- sessions_become_path(:user_id => user.id),
15
+ become_dev_users_path(:user_id => user.id),
16
16
  method: :post
17
17
  }
18
18
  ]
data/config/routes.rb CHANGED
@@ -1,16 +1,21 @@
1
1
  OpenStax::Connect::Engine.routes.draw do
2
2
  match '/auth/openstax/callback', to: 'sessions#omniauth_authenticated' #omniauth route
3
3
  get '/auth/openstax', :as => 'openstax_login'
4
+
4
5
  get 'sessions/new', :as => 'login'
5
- post 'sessions/become'
6
-
7
6
  # See https://github.com/plataformatec/devise/commit/f3385e96abf50e80d2ae282e1fb9bdad87a83d3c
8
- match 'sessions/destroy', :as => 'logout', :via => OpenStax::Connect.configuration.logout_via
7
+ match 'sessions/destroy', :as => 'logout',
8
+ :via => OpenStax::Connect.configuration.logout_via
9
9
 
10
10
  if OpenStax::Connect.configuration.enable_stubbing?
11
11
  namespace :dev do
12
- get 'users/login'
13
- post 'users/search'
12
+ resources :users, :only => [] do
13
+ collection do
14
+ get 'login'
15
+ post 'search'
16
+ post 'become'
17
+ end
18
+ end
14
19
  end
15
20
  end
16
21
  end
@@ -20,7 +25,7 @@ module OpenStax
20
25
  module Connect
21
26
  hh = Engine.routes.url_helpers
22
27
 
23
- RouteHelper.register_path(:login, hh.openstax_login_path) { hh.dev_users_login_path }
28
+ RouteHelper.register_path(:login, hh.openstax_login_path) { hh.login_dev_users_path }
24
29
  end
25
30
  end
26
31
 
@@ -0,0 +1,7 @@
1
+ class AddFieldsToOpenStaxConnectUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :openstax_connect_users, :full_name, :string
4
+ add_column :openstax_connect_users, :title, :string
5
+ add_column :openstax_connect_users, :access_token, :string
6
+ end
7
+ end
@@ -7,18 +7,27 @@ module OmniAuth
7
7
  option :name, "openstax"
8
8
 
9
9
  option :client_options, {
10
- :site => OpenStax::Connect.configuration.openstax_services_url,
10
+ :site => OpenStax::Connect.configuration.openstax_accounts_url,
11
11
  :authorize_url => "/oauth/authorize"
12
12
  }
13
13
 
14
- uid { raw_info["id"] }
14
+ uid { raw_info["id"] }
15
15
 
16
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
17
25
  {
18
- username: raw_info["username"],
19
- first_name: raw_info["first_name"],
20
- last_name: raw_info["last_name"]
21
- # and anything else you want to return to your API consumers
26
+ name: full_name,
27
+ nickname: username,
28
+ first_name: first_name,
29
+ last_name: last_name,
30
+ title: title
22
31
  }
23
32
  end
24
33
 
@@ -34,13 +34,13 @@ module OpenStax::Connect
34
34
  !connect_current_user.is_anonymous?
35
35
  end
36
36
 
37
- protected
38
-
39
37
  # Returns the current connect user
40
38
  def connect_current_user
41
39
  load_current_users
42
40
  @connect_current_user
43
- end
41
+ end
42
+
43
+ protected
44
44
 
45
45
  # If they are nil (unset), sets the current users based on the session state
46
46
  def load_current_users
@@ -1,7 +1,4 @@
1
- ActiveSupport::Inflector.inflections do |inflect|
2
- inflect.acronym 'OpenStax'
3
- end
4
-
1
+ require 'openstax/connect/inflections'
5
2
  require 'omniauth'
6
3
  require 'squeel'
7
4
 
@@ -0,0 +1,3 @@
1
+ ActiveSupport::Inflector.inflections do |inflect|
2
+ inflect.acronym 'OpenStax'
3
+ end
@@ -1,5 +1,5 @@
1
1
  module OpenStax
2
2
  module Connect
3
- VERSION = "0.0.10"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
+ require "lev"
1
2
  require "openstax/connect/version"
2
- require "openstax/connect/exceptions"
3
3
  require "openstax/connect/engine"
4
4
  require "openstax/connect/utilities"
5
5
  require "openstax/connect/route_helper"
@@ -25,7 +25,7 @@ module OpenStax
25
25
  # end
26
26
  #
27
27
  # Set enable_stubbing to true iff you want this engine to fake all
28
- # interaction with the services site.
28
+ # interaction with the accounts site.
29
29
  #
30
30
 
31
31
  def configure
@@ -40,7 +40,7 @@ module OpenStax
40
40
  attr_accessor :openstax_application_id
41
41
  attr_accessor :openstax_application_secret
42
42
  attr_accessor :enable_stubbing
43
- attr_reader :openstax_services_url
43
+ attr_reader :openstax_accounts_url
44
44
  attr_accessor :logout_via
45
45
  attr_accessor :default_errors_partial
46
46
  attr_accessor :default_errors_html_id
@@ -50,16 +50,16 @@ module OpenStax
50
50
  # See the "user_provider" discussion in the README
51
51
  attr_accessor :user_provider
52
52
 
53
- def openstax_services_url=(url)
53
+ def openstax_accounts_url=(url)
54
54
  url.gsub!(/https|http/,'https') if !(url =~ /localhost/)
55
55
  url = url + "/" if url[url.size-1] != '/'
56
- @openstax_services_url = url
56
+ @openstax_accounts_url = url
57
57
  end
58
58
 
59
59
  def initialize
60
60
  @openstax_application_id = 'SET ME!'
61
61
  @openstax_application_secret = 'SET ME!'
62
- @openstax_services_url = 'https://services.openstax.org/'
62
+ @openstax_accounts_url = 'https://accounts.openstax.org/'
63
63
  @enable_stubbing = true
64
64
  @logout_via = :get
65
65
  @default_errors_partial = 'openstax/connect/shared/attention'
@@ -75,6 +75,52 @@ module OpenStax
75
75
  end
76
76
  end
77
77
 
78
+ # Executes an OpenStax Accounts API call, using the given HTTP method,
79
+ # API url and request options.
80
+ # Any options accepted by OAuth2 requests can be used, such as
81
+ # :params, :body, :headers, etc, plus the :access_token option, which can
82
+ # be used to manually specify an OAuth access token.
83
+ # On failure, it can throw Faraday::ConnectionFailed for connection errors
84
+ # or OAuth2::Error if Accounts returns an HTTP 400 error,
85
+ # such as 422 Unprocessable Entity.
86
+ # On success, returns an OAuth2::Response object.
87
+ def api_call(http_method, url, options = {})
88
+ version = options.delete(:api_version)
89
+ unless version.blank?
90
+ options[:headers] ||= {}
91
+ options[:headers].merge!({ 'Accept' => "application/vnd.accounts.openstax.#{version.to_s}" })
92
+ end
93
+
94
+ token_string = options.delete(:access_token)
95
+ token = token_string.blank? ? client.client_credentials.get_token :
96
+ OAuth2::AccessToken.new(client, token_string)
97
+
98
+ api_url = URI.join(configuration.openstax_accounts_url, 'api/', url)
99
+
100
+ token.request(http_method, api_url, options)
101
+ end
102
+
103
+ # Creates an ApplicationUser in Accounts for this app and the given
104
+ # OpenStax::Connect::User.
105
+ # Also takes an optional API version parameter. Defaults to :v1.
106
+ # On failure, throws an Exception, just like api_call.
107
+ # On success, returns an OAuth2::Response object.
108
+ def create_application_user(user, version = nil)
109
+ options = {:access_token => user.access_token,
110
+ :api_version => (version.nil? ? :v1 : version)}
111
+ api_call(:post, 'application_users', options)
112
+ end
113
+
114
+ protected
115
+
116
+ def client
117
+ @client ||= OAuth2::Client.new(
118
+ configuration.openstax_application_id,
119
+ configuration.openstax_application_secret,
120
+ :site => configuration.openstax_accounts_url
121
+ )
122
+ end
123
+
78
124
  end
79
125
 
80
126
  end