openstax_accounts 0.3.0 → 1.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 +15 -0
- data/README.md +20 -0
- data/app/controllers/openstax/accounts/dev/base_controller.rb +19 -0
- data/app/controllers/openstax/accounts/dev/users_controller.rb +10 -9
- data/app/handlers/openstax/accounts/dev/users_index.rb +39 -0
- data/app/handlers/openstax/accounts/sessions_omniauth_authenticated.rb +2 -1
- data/app/models/openstax/accounts/application_user.rb +7 -0
- data/app/models/openstax/accounts/user.rb +15 -3
- data/app/representers/openstax/accounts/api/v1/application_user_representer.rb +5 -1
- data/app/representers/openstax/accounts/api/v1/application_user_search_representer.rb +19 -0
- data/app/representers/openstax/accounts/api/v1/application_users_representer.rb +16 -0
- data/app/representers/openstax/accounts/api/v1/user_representer.rb +2 -6
- data/app/routines/openstax/accounts/dev/create_user.rb +4 -4
- data/app/routines/openstax/accounts/dev/search_users.rb +27 -0
- data/app/routines/openstax/accounts/search_users.rb +174 -32
- data/app/routines/openstax/accounts/sync_users.rb +44 -0
- data/app/views/openstax/accounts/dev/users/_search_results.html.erb +50 -0
- data/app/views/openstax/accounts/dev/users/index.js.erb +3 -0
- data/app/views/openstax/accounts/dev/users/login.html.erb +6 -5
- data/app/views/openstax/accounts/shared/_attention.html.erb +1 -1
- data/app/views/openstax/accounts/shared/users/_index.html.erb +24 -0
- data/config/routes.rb +5 -4
- data/lib/generators/openstax/accounts/schedule/USAGE +8 -0
- data/lib/generators/openstax/accounts/schedule/schedule_generator.rb +18 -0
- data/lib/generators/openstax/accounts/schedule/templates/schedule.rb +3 -0
- data/lib/omniauth/strategies/openstax.rb +1 -1
- data/lib/openstax/accounts/engine.rb +2 -0
- data/lib/openstax/accounts/version.rb +1 -1
- data/lib/openstax_accounts.rb +69 -26
- data/spec/controllers/openstax/accounts/dev/users_controller_spec.rb +4 -3
- data/spec/dummy/app/controllers/api/application_users_controller.rb +12 -0
- data/spec/dummy/config/application.rb +3 -0
- data/spec/dummy/config/initializers/openstax_accounts.rb +1 -0
- data/spec/dummy/config/routes.rb +5 -4
- data/spec/lib/openstax_accounts_spec.rb +19 -11
- data/spec/routines/openstax/accounts/dev/create_user_spec.rb +26 -0
- data/spec/routines/openstax/accounts/search_users_spec.rb +129 -0
- metadata +47 -68
- data/app/controllers/openstax/accounts/dev/dev_controller.rb +0 -13
- data/app/handlers/openstax/accounts/dev/users_search.rb +0 -38
- data/app/representers/openstax/accounts/api/v1/contact_info_representer.rb +0 -23
- data/app/representers/openstax/accounts/api/v1/email_address_representer.rb +0 -9
- data/app/views/openstax/accounts/dev/users/search.js.erb +0 -21
- data/app/views/openstax/accounts/users/_action_create_form.html.erb +0 -9
- data/app/views/openstax/accounts/users/_action_dialog.html.erb +0 -10
- data/app/views/openstax/accounts/users/_action_list.html.erb +0 -33
- data/app/views/openstax/accounts/users/_action_search.html.erb +0 -25
- data/app/views/openstax/accounts/users/action_search.js.erb +0 -8
- data/spec/dummy/app/controllers/api/users_controller.rb +0 -7
@@ -0,0 +1,44 @@
|
|
1
|
+
# Routine for getting user updates from Accounts
|
2
|
+
#
|
3
|
+
# Should be scheduled to run regularly
|
4
|
+
|
5
|
+
module OpenStax
|
6
|
+
module Accounts
|
7
|
+
|
8
|
+
class SyncUsers
|
9
|
+
|
10
|
+
SYNC_ATTRIBUTES = ['username', 'first_name', 'last_name',
|
11
|
+
'full_name', 'title']
|
12
|
+
|
13
|
+
lev_routine transaction: :no_transaction
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def exec(options={})
|
18
|
+
|
19
|
+
return if OpenStax::Accounts.configuration.enable_stubbing?
|
20
|
+
|
21
|
+
response = OpenStax::Accounts.application_users_updates
|
22
|
+
|
23
|
+
app_users = []
|
24
|
+
app_users_rep = OpenStax::Accounts::Api::V1::ApplicationUsersRepresenter.new(app_users)
|
25
|
+
app_users_rep.from_json(response.body)
|
26
|
+
|
27
|
+
return if app_users.empty?
|
28
|
+
|
29
|
+
app_users_hash = {}
|
30
|
+
app_users.each do |app_user|
|
31
|
+
user = OpenStax::Accounts::User.where(:openstax_uid => app_user.user.openstax_uid).first
|
32
|
+
user.updating_from_accounts = true
|
33
|
+
next unless user.update_attributes(app_user.user.attributes.slice(*SYNC_ATTRIBUTES))
|
34
|
+
app_users_hash[app_user.id] = app_user.unread_updates
|
35
|
+
end
|
36
|
+
|
37
|
+
OpenStax::Accounts.application_users_updated(app_users_hash)
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<%
|
2
|
+
page = @handler_result.outputs[:page]
|
3
|
+
num_users = @handler_result.outputs[:num_matching_users]
|
4
|
+
per_page = @handler_result.outputs[:per_page]
|
5
|
+
pages = (num_users * 1.0 / per_page).ceil
|
6
|
+
users = @handler_result.outputs[:users]
|
7
|
+
%>
|
8
|
+
|
9
|
+
<div id='search-results-pagination'>
|
10
|
+
<%= pluralize(num_users, 'user') %> found.
|
11
|
+
|
12
|
+
<% if pages > 0 %>
|
13
|
+
Page:
|
14
|
+
|
15
|
+
<%
|
16
|
+
linked_page_numbers = [page+1]
|
17
|
+
linked_page_numbers.push(1)
|
18
|
+
linked_page_numbers.push(pages)
|
19
|
+
linked_page_numbers.push(page+1-1, page+1-2, page+1+1, page+1+2)
|
20
|
+
linked_page_numbers.reject!{|pp| pp < 1 || pp > pages}
|
21
|
+
linked_page_numbers.uniq!
|
22
|
+
linked_page_numbers.sort!
|
23
|
+
%>
|
24
|
+
|
25
|
+
<% linked_page_numbers.each do |lpn| %>
|
26
|
+
<%= link_to_unless lpn == page + 1,
|
27
|
+
lpn,
|
28
|
+
dev_users_path(search: {terms: @handler_result.outputs[:query], page: lpn-1, per_page: per_page}), remote: true %>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<%= osu.action_list(
|
34
|
+
records: users,
|
35
|
+
list: {
|
36
|
+
headings: ['Username', 'First Name', 'Last Name', ''],
|
37
|
+
widths: ['25%', '25%', '25%', '25%'],
|
38
|
+
data_procs:
|
39
|
+
[
|
40
|
+
Proc.new { |user| user.username },
|
41
|
+
Proc.new { |user| user.first_name || '---' },
|
42
|
+
Proc.new { |user| user.last_name || '---' },
|
43
|
+
Proc.new { |user|
|
44
|
+
link_to 'Sign in as',
|
45
|
+
become_dev_user_path(user),
|
46
|
+
method: :post
|
47
|
+
}
|
48
|
+
]
|
49
|
+
}
|
50
|
+
) %>
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
<div class="openstax-accounts development-login">
|
3
2
|
|
4
3
|
<% handler_errors.each do |error| %>
|
@@ -7,11 +6,13 @@
|
|
7
6
|
|
8
7
|
<%= osu.section_block "Development Login" do %>
|
9
8
|
|
10
|
-
<p>You need to login, but we're not connected to the Accounts server.
|
11
|
-
|
9
|
+
<p>You need to login, but we're not connected to the Accounts server.
|
10
|
+
Search for a user below and click the sign in link next to him or her.</p>
|
12
11
|
|
13
|
-
<%= render 'openstax/accounts/users/
|
12
|
+
<%= render 'openstax/accounts/shared/users/index',
|
13
|
+
:search_action_path => openstax_accounts.dev_users_path,
|
14
|
+
:remote => true %>
|
14
15
|
|
15
16
|
<% end %>
|
16
17
|
|
17
|
-
</div>
|
18
|
+
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%
|
2
|
+
# Clients of this partial can override the following variables:
|
3
|
+
search_action_path ||= nil
|
4
|
+
remote ||= false
|
5
|
+
form_html ||= {id: 'search-form',
|
6
|
+
class: 'form-inline'}
|
7
|
+
search_types ||= ['Any', 'Username', 'Email']
|
8
|
+
%>
|
9
|
+
|
10
|
+
<%= lev_form_for :search,
|
11
|
+
url: search_action_path,
|
12
|
+
remote: remote,
|
13
|
+
html: form_html do |f| %>
|
14
|
+
|
15
|
+
Search for
|
16
|
+
<%= f.search_field :terms, style: 'width:300px' %>
|
17
|
+
in
|
18
|
+
<%= f.select :type, search_types, {}, {style: 'width: 150px'} %>
|
19
|
+
|
20
|
+
<%= f.submit 'Search', class: 'btn btn-primary' %>
|
21
|
+
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<div id="search-results-list"></div>
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
OpenStax::Accounts::Engine.routes.draw do
|
2
|
-
|
2
|
+
get '/auth/openstax/callback', to: 'sessions#omniauth_authenticated' #omniauth route
|
3
3
|
get '/auth/openstax', :as => 'openstax_login'
|
4
4
|
|
5
5
|
get 'sessions/new', :as => 'login'
|
@@ -9,12 +9,13 @@ OpenStax::Accounts::Engine.routes.draw do
|
|
9
9
|
|
10
10
|
if OpenStax::Accounts.configuration.enable_stubbing?
|
11
11
|
namespace :dev do
|
12
|
-
resources :users, :only => [] do
|
12
|
+
resources :users, :only => [:index] do
|
13
13
|
collection do
|
14
14
|
get 'login'
|
15
|
-
post '
|
16
|
-
post 'become'
|
15
|
+
post 'index'
|
17
16
|
end
|
17
|
+
|
18
|
+
post 'become', :on => :member
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Can't use OpenStax. See https://github.com/rails/rails/issues/13856
|
2
|
+
module Openstax
|
3
|
+
module Accounts
|
4
|
+
class ScheduleGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
6
|
+
|
7
|
+
def generate_schedule
|
8
|
+
if File.exists?(File.expand_path('config/schedule.rb'))
|
9
|
+
File.open(File.expand_path('../templates/schedule.rb', __FILE__)) do |file|
|
10
|
+
append_file 'config/schedule.rb', file.read
|
11
|
+
end
|
12
|
+
else
|
13
|
+
copy_file 'schedule.rb', 'config/schedule.rb'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/openstax_accounts.rb
CHANGED
@@ -6,12 +6,14 @@ require 'openstax/accounts/user_provider'
|
|
6
6
|
require 'openstax/accounts/current_user_manager'
|
7
7
|
|
8
8
|
require 'openstax_utilities'
|
9
|
-
require 'uri'
|
10
9
|
require 'oauth2'
|
10
|
+
require 'uri'
|
11
11
|
|
12
12
|
module OpenStax
|
13
13
|
module Accounts
|
14
14
|
|
15
|
+
DEFAULT_API_VERSION = :v1
|
16
|
+
|
15
17
|
class << self
|
16
18
|
|
17
19
|
###########################################################################
|
@@ -27,9 +29,6 @@ module OpenStax
|
|
27
29
|
# ...
|
28
30
|
# end
|
29
31
|
#
|
30
|
-
# Set enable_stubbing to true iff you want this engine to fake all
|
31
|
-
# interaction with the accounts site.
|
32
|
-
#
|
33
32
|
|
34
33
|
def configure
|
35
34
|
yield configuration
|
@@ -40,26 +39,50 @@ module OpenStax
|
|
40
39
|
end
|
41
40
|
|
42
41
|
class Configuration
|
42
|
+
# openstax_accounts_url
|
43
|
+
# Base URL for OpenStax Accounts
|
44
|
+
attr_reader :openstax_accounts_url
|
45
|
+
|
46
|
+
# openstax_application_id
|
47
|
+
# OAuth client_id received from OpenStax Accounts
|
43
48
|
attr_accessor :openstax_application_id
|
49
|
+
|
50
|
+
# openstax_application_secret
|
51
|
+
# OAuth client_secret received from OpenStax Accounts
|
44
52
|
attr_accessor :openstax_application_secret
|
53
|
+
|
54
|
+
# enable_stubbing
|
55
|
+
# Set to true if you want this engine to fake all
|
56
|
+
# interaction with the accounts site.
|
45
57
|
attr_accessor :enable_stubbing
|
46
|
-
|
58
|
+
|
59
|
+
# logout_via
|
60
|
+
# HTTP method to accept for logout requests
|
47
61
|
attr_accessor :logout_via
|
62
|
+
|
48
63
|
attr_accessor :default_errors_partial
|
49
64
|
attr_accessor :default_errors_html_id
|
50
65
|
attr_accessor :default_errors_added_trigger
|
66
|
+
|
67
|
+
# security_transgression_exception
|
68
|
+
# Class to be used for security transgression exceptions
|
51
69
|
attr_accessor :security_transgression_exception
|
52
70
|
|
53
|
-
# See the "user_provider" discussion in the README
|
71
|
+
# See the "user_provider" discussion in the README
|
54
72
|
attr_accessor :user_provider
|
55
73
|
|
74
|
+
# The maximum number of users that can be returned in a call to SearchUsers
|
75
|
+
# 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
|
+
|
56
79
|
def openstax_accounts_url=(url)
|
57
80
|
url.gsub!(/https|http/,'https') if !(url =~ /localhost/)
|
58
81
|
url = url + "/" if url[url.size-1] != '/'
|
59
82
|
@openstax_accounts_url = url
|
60
83
|
end
|
61
84
|
|
62
|
-
def initialize
|
85
|
+
def initialize
|
63
86
|
@openstax_application_id = 'SET ME!'
|
64
87
|
@openstax_application_secret = 'SET ME!'
|
65
88
|
@openstax_accounts_url = 'https://accounts.openstax.org/'
|
@@ -70,6 +93,7 @@ module OpenStax
|
|
70
93
|
@default_errors_added_trigger = 'openstax-accounts-errors-added'
|
71
94
|
@security_transgression_exception = SecurityTransgression
|
72
95
|
@user_provider = OpenStax::Accounts::UserProvider
|
96
|
+
@max_matching_users = 10
|
73
97
|
super
|
74
98
|
end
|
75
99
|
|
@@ -96,43 +120,62 @@ module OpenStax
|
|
96
120
|
|
97
121
|
token_string = options.delete(:access_token)
|
98
122
|
token = token_string.blank? ? client.client_credentials.get_token :
|
99
|
-
|
123
|
+
OAuth2::AccessToken.new(client, token_string)
|
100
124
|
|
101
125
|
api_url = URI.join(configuration.openstax_accounts_url, 'api/', url)
|
102
126
|
|
103
127
|
token.request(http_method, api_url, options)
|
104
128
|
end
|
105
129
|
|
106
|
-
#
|
107
|
-
# and
|
108
|
-
#
|
130
|
+
# Performs an ApplicationUser search in Accounts for the configured app.
|
131
|
+
# Takes a query parameter and an optional API version parameter.
|
132
|
+
# API version currently defaults to :v1 (may change in the future).
|
109
133
|
# On failure, throws an Exception, just like api_call.
|
110
134
|
# On success, returns an OAuth2::Response object.
|
111
|
-
def
|
112
|
-
options = {:
|
135
|
+
def application_users_index(query, version = DEFAULT_API_VERSION)
|
136
|
+
options = {:params => {:q => query},
|
113
137
|
:api_version => version}
|
114
|
-
api_call(:
|
138
|
+
api_call(:get, 'application_users', options)
|
115
139
|
end
|
116
140
|
|
117
|
-
#
|
118
|
-
# Takes a query parameter and an optional API version parameter.
|
119
|
-
# API version currently defaults to :v1.
|
141
|
+
# Retrieves information about ApplicationUsers that have been recently updated.
|
120
142
|
# On failure, throws an Exception, just like api_call.
|
121
143
|
# On success, returns an OAuth2::Response object.
|
122
|
-
def
|
123
|
-
options = {:
|
124
|
-
|
125
|
-
|
144
|
+
def application_users_updates(version = DEFAULT_API_VERSION)
|
145
|
+
options = {:api_version => version}
|
146
|
+
api_call(:get, 'application_users/updates', options)
|
147
|
+
end
|
148
|
+
|
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.
|
152
|
+
# On failure, throws an Exception, just like api_call.
|
153
|
+
# On success, returns an OAuth2::Response object.
|
154
|
+
def application_users_updated(app_users, version = DEFAULT_API_VERSION)
|
155
|
+
options = {:api_version => version,
|
156
|
+
:body => {:application_users => app_users}}
|
157
|
+
api_call(:put, 'application_users/updated', options)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Updates an OpenStax::Accounts::User in Accounts for the configured app.
|
161
|
+
# Also takes an optional API version parameter.
|
162
|
+
# API version currently defaults to :v1 (may change in the future).
|
163
|
+
# On failure, throws an Exception, just like api_call.
|
164
|
+
# On success, returns an OAuth2::Response object.
|
165
|
+
def user_update(user, version = DEFAULT_API_VERSION)
|
166
|
+
options = {:access_token => user.access_token,
|
167
|
+
:api_version => version,
|
168
|
+
:body => user.attributes.slice('username', 'first_name',
|
169
|
+
'last_name', 'full_name', 'title').to_json}
|
170
|
+
api_call(:put, 'user', options)
|
126
171
|
end
|
127
172
|
|
128
|
-
|
173
|
+
protected
|
129
174
|
|
130
175
|
def client
|
131
|
-
@client ||= OAuth2::Client.new(
|
132
|
-
configuration.openstax_application_id,
|
176
|
+
@client ||= OAuth2::Client.new(configuration.openstax_application_id,
|
133
177
|
configuration.openstax_application_secret,
|
134
|
-
:site => configuration.openstax_accounts_url
|
135
|
-
)
|
178
|
+
:site => configuration.openstax_accounts_url)
|
136
179
|
end
|
137
180
|
|
138
181
|
end
|
@@ -5,13 +5,14 @@ module OpenStax::Accounts
|
|
5
5
|
describe UsersController do
|
6
6
|
routes { OpenStax::Accounts::Engine.routes }
|
7
7
|
|
8
|
-
let!(:user) {
|
9
|
-
|
8
|
+
let!(:user) { user = FactoryGirl.create :openstax_accounts_user,
|
9
|
+
username: 'some_user',
|
10
|
+
openstax_uid: 10 }
|
10
11
|
|
11
12
|
it 'should allow users not in production to become other users' do
|
12
13
|
expect(controller.current_user).to eq(OpenStax::Accounts::User.anonymous)
|
13
14
|
expect(controller.current_user.is_anonymous?).to eq(true)
|
14
|
-
|
15
|
+
post :become, id: user.id
|
15
16
|
expect(controller.current_user).to eq(user)
|
16
17
|
expect(controller.current_user.is_anonymous?).to eq(false)
|
17
18
|
end
|