openstax_accounts 2.0.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +1 -0
- data/Rakefile +6 -6
- data/app/models/openstax/accounts/account.rb +34 -24
- data/app/models/openstax/accounts/application_group.rb +7 -0
- data/app/models/openstax/accounts/group.rb +132 -0
- data/app/models/openstax/accounts/group_member.rb +40 -0
- data/app/models/openstax/accounts/group_nesting.rb +62 -0
- data/app/models/openstax/accounts/group_owner.rb +40 -0
- data/app/representers/openstax/accounts/api/v1/application_group_representer.rb +25 -0
- data/app/representers/openstax/accounts/api/v1/application_groups_representer.rb +16 -0
- data/app/representers/openstax/accounts/api/v1/group_nesting_representer.rb +18 -0
- data/app/representers/openstax/accounts/api/v1/group_representer.rb +50 -0
- data/app/representers/openstax/accounts/api/v1/group_user_representer.rb +21 -0
- data/app/routines/openstax/accounts/search_accounts.rb +7 -14
- data/app/routines/openstax/accounts/sync_accounts.rb +32 -18
- data/app/routines/openstax/accounts/sync_groups.rb +61 -0
- data/app/routines/openstax/accounts/update_group_caches.rb +27 -0
- data/app/views/openstax/accounts/shared/accounts/_index.html.erb +0 -3
- data/config/initializers/action_interceptor.rb +1 -1
- data/db/migrate/20140811182433_create_openstax_accounts_groups.rb +16 -0
- data/db/migrate/20140811182505_create_openstax_accounts_group_members.rb +13 -0
- data/db/migrate/20140811182527_create_openstax_accounts_group_owners.rb +13 -0
- data/db/migrate/20140811182553_create_openstax_accounts_group_nestings.rb +13 -0
- data/lib/generators/openstax/accounts/schedule/templates/schedule.rb +1 -0
- data/lib/openstax/accounts/current_user_manager.rb +2 -2
- data/lib/openstax/accounts/has_many_through_groups.rb +45 -0
- data/lib/openstax/accounts/version.rb +1 -1
- data/lib/openstax_accounts.rb +165 -11
- data/spec/controllers/openstax/accounts/dev/accounts_controller_spec.rb +1 -1
- data/spec/controllers/openstax/accounts/sessions_controller_spec.rb +1 -1
- data/spec/dummy/app/controllers/api/application_groups_controller.rb +11 -0
- data/spec/dummy/app/controllers/api/dummy_controller.rb +2 -1
- data/spec/dummy/app/controllers/api/group_members_controller.rb +11 -0
- data/spec/dummy/app/controllers/api/group_nestings_controller.rb +11 -0
- data/spec/dummy/app/controllers/api/group_owners_controller.rb +11 -0
- data/spec/dummy/app/controllers/api/groups_controller.rb +15 -0
- data/spec/dummy/app/controllers/api/users_controller.rb +4 -0
- data/spec/dummy/app/models/ownership.rb +7 -0
- data/spec/dummy/app/models/user.rb +11 -8
- data/spec/dummy/config/application.rb +0 -33
- data/spec/dummy/config/boot.rb +4 -9
- data/spec/dummy/config/database.yml +8 -8
- data/spec/dummy/config/environment.rb +3 -3
- data/spec/dummy/config/environments/development.rb +20 -12
- data/spec/dummy/config/environments/production.rb +42 -29
- data/spec/dummy/config/environments/test.rb +16 -12
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +6 -5
- data/spec/dummy/config/initializers/mime_types.rb +0 -1
- data/spec/dummy/config/initializers/session_store.rb +1 -6
- data/spec/dummy/config/initializers/wrap_parameters.rb +6 -6
- data/spec/dummy/config/routes.rb +23 -0
- data/spec/dummy/config/secrets.yml +8 -0
- data/spec/dummy/db/migrate/1_create_users.rb +2 -2
- data/spec/dummy/db/migrate/2_create_ownerships.rb +11 -0
- data/spec/dummy/db/schema.rb +72 -20
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +186 -0
- data/spec/dummy/log/test.log +2078 -0
- data/spec/factories/openstax_accounts_account.rb +3 -2
- data/spec/factories/openstax_accounts_group.rb +7 -0
- data/spec/factories/openstax_accounts_group_member.rb +6 -0
- data/spec/factories/openstax_accounts_group_nesting.rb +6 -0
- data/spec/factories/openstax_accounts_group_owner.rb +6 -0
- data/spec/lib/openstax/accounts/current_user_manager_spec.rb +9 -3
- data/spec/lib/openstax/accounts/has_many_through_groups_spec.rb +53 -0
- data/spec/lib/openstax_accounts_spec.rb +189 -25
- data/spec/models/openstax/accounts/account_spec.rb +16 -1
- data/spec/models/openstax/accounts/anonymous_account_spec.rb +1 -1
- data/spec/models/openstax/accounts/group_spec.rb +20 -0
- data/spec/routines/openstax/accounts/sync_accounts_spec.rb +70 -0
- data/spec/routines/openstax/accounts/sync_groups_spec.rb +125 -0
- metadata +73 -56
- data/spec/dummy/config/initializers/secret_token.rb +0 -7
data/lib/openstax_accounts.rb
CHANGED
@@ -2,6 +2,7 @@ require 'openstax/accounts/version'
|
|
2
2
|
require 'openstax/accounts/engine'
|
3
3
|
require 'openstax/accounts/default_account_user_mapper'
|
4
4
|
require 'openstax/accounts/current_user_manager'
|
5
|
+
require 'openstax/accounts/has_many_through_groups'
|
5
6
|
require 'openstax_utilities'
|
6
7
|
|
7
8
|
require 'oauth2'
|
@@ -14,6 +15,8 @@ module OpenStax
|
|
14
15
|
|
15
16
|
class << self
|
16
17
|
|
18
|
+
mattr_accessor :syncing
|
19
|
+
|
17
20
|
###########################################################################
|
18
21
|
#
|
19
22
|
# Configuration machinery.
|
@@ -143,6 +146,20 @@ module OpenStax
|
|
143
146
|
api_call(:get, 'users', options)
|
144
147
|
end
|
145
148
|
|
149
|
+
# Updates a user account in the Accounts server.
|
150
|
+
# The account is determined by the OAuth access token.
|
151
|
+
# Also takes an optional API version parameter.
|
152
|
+
# API version currently defaults to :v1 (may change in the future).
|
153
|
+
# On failure, throws an Exception, just like api_call.
|
154
|
+
# On success, returns an OAuth2::Response object.
|
155
|
+
def update_account(account, version = DEFAULT_API_VERSION)
|
156
|
+
options = {:access_token => account.access_token,
|
157
|
+
:api_version => version,
|
158
|
+
:body => account.attributes.slice('username', 'first_name',
|
159
|
+
'last_name', 'full_name', 'title').to_json}
|
160
|
+
api_call(:put, 'user', options)
|
161
|
+
end
|
162
|
+
|
146
163
|
# Performs an account search in the Accounts server.
|
147
164
|
# Results are limited to accounts that have used the current app.
|
148
165
|
# Takes a query parameter and an optional API version parameter.
|
@@ -166,29 +183,166 @@ module OpenStax
|
|
166
183
|
end
|
167
184
|
|
168
185
|
# Marks account updates as "read".
|
169
|
-
# The
|
170
|
-
#
|
171
|
-
#
|
186
|
+
# The application_users parameter is an array of hashes.
|
187
|
+
# Each hash has 2 required fields: 'id', which should contain the
|
188
|
+
# application_user's id, and 'read_updates', which should contain
|
189
|
+
# the last received value of unread_updates for that application_user.
|
190
|
+
# Can only be called for application_users that belong to the current app.
|
172
191
|
# On failure, throws an Exception, just like api_call.
|
173
192
|
# On success, returns an OAuth2::Response object.
|
174
|
-
def
|
193
|
+
def mark_account_updates_as_read(application_users, version = DEFAULT_API_VERSION)
|
175
194
|
options = {:api_version => version,
|
176
|
-
:body =>
|
195
|
+
:body => application_users.to_json}
|
177
196
|
api_call(:put, 'application_users/updated', options)
|
178
197
|
end
|
179
198
|
|
180
|
-
#
|
181
|
-
#
|
199
|
+
# Retrieves information about groups that have been
|
200
|
+
# recently updated.
|
201
|
+
# Results are limited to groups that users of the current app have access to.
|
202
|
+
# On failure, throws an Exception, just like api_call.
|
203
|
+
# On success, returns an OAuth2::Response object.
|
204
|
+
def get_application_group_updates(version = DEFAULT_API_VERSION)
|
205
|
+
options = {:api_version => version}
|
206
|
+
api_call(:get, 'application_groups/updates', options)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Marks group updates as "read".
|
210
|
+
# The application_groups parameter is an array of hashes.
|
211
|
+
# Each hash has 2 required fields: 'id', which should contain the
|
212
|
+
# application_group's id, and 'read_updates', which should contain
|
213
|
+
# the last received value of unread_updates for that application_group.
|
214
|
+
# Can only be called for application_groups that belong to the current app.
|
215
|
+
# On failure, throws an Exception, just like api_call.
|
216
|
+
# On success, returns an OAuth2::Response object.
|
217
|
+
def mark_group_updates_as_read(application_groups, version = DEFAULT_API_VERSION)
|
218
|
+
options = {:api_version => version,
|
219
|
+
:body => application_groups.to_json}
|
220
|
+
api_call(:put, 'application_groups/updated', options)
|
221
|
+
end
|
222
|
+
|
223
|
+
# Creates a group in the Accounts server.
|
224
|
+
# The given account will be the owner of the group.
|
182
225
|
# Also takes an optional API version parameter.
|
183
226
|
# API version currently defaults to :v1 (may change in the future).
|
184
227
|
# On failure, throws an Exception, just like api_call.
|
185
228
|
# On success, returns an OAuth2::Response object.
|
186
|
-
def
|
229
|
+
def create_group(account, group, version = DEFAULT_API_VERSION)
|
187
230
|
options = {:access_token => account.access_token,
|
188
231
|
:api_version => version,
|
189
|
-
:body =>
|
190
|
-
|
191
|
-
|
232
|
+
:body => group.attributes.slice('name', 'is_public').to_json}
|
233
|
+
response = ActiveSupport::JSON.decode(api_call(
|
234
|
+
:post, 'groups', options).body)
|
235
|
+
group.openstax_uid = response['id']
|
236
|
+
response
|
237
|
+
end
|
238
|
+
|
239
|
+
# Updates a group in the Accounts server.
|
240
|
+
# The given account must own the group.
|
241
|
+
# Also takes an optional API version parameter.
|
242
|
+
# API version currently defaults to :v1 (may change in the future).
|
243
|
+
# On failure, throws an Exception, just like api_call.
|
244
|
+
# On success, returns an OAuth2::Response object.
|
245
|
+
def update_group(account, group, version = DEFAULT_API_VERSION)
|
246
|
+
options = {:access_token => account.access_token,
|
247
|
+
:api_version => version,
|
248
|
+
:body => group.attributes.slice('name', 'is_public').to_json}
|
249
|
+
api_call(:put, "groups/#{group.openstax_uid}", options)
|
250
|
+
end
|
251
|
+
|
252
|
+
# Deletes a group from the Accounts server.
|
253
|
+
# The given account must own the group.
|
254
|
+
# Also takes an optional API version parameter.
|
255
|
+
# API version currently defaults to :v1 (may change in the future).
|
256
|
+
# On failure, throws an Exception, just like api_call.
|
257
|
+
# On success, returns an OAuth2::Response object.
|
258
|
+
def destroy_group(account, group, version = DEFAULT_API_VERSION)
|
259
|
+
options = {:access_token => account.access_token,
|
260
|
+
:api_version => version}
|
261
|
+
api_call(:delete, "groups/#{group.openstax_uid}", options)
|
262
|
+
end
|
263
|
+
|
264
|
+
# Creates a group_member in the Accounts server.
|
265
|
+
# The given account must own the group.
|
266
|
+
# Also takes an optional API version parameter.
|
267
|
+
# API version currently defaults to :v1 (may change in the future).
|
268
|
+
# On failure, throws an Exception, just like api_call.
|
269
|
+
# On success, returns an OAuth2::Response object.
|
270
|
+
def create_group_member(account, group_member, version = DEFAULT_API_VERSION)
|
271
|
+
options = {:access_token => account.access_token,
|
272
|
+
:api_version => version}
|
273
|
+
api_call(:post,
|
274
|
+
"groups/#{group_member.group_id}/members/#{group_member.user_id}",
|
275
|
+
options)
|
276
|
+
end
|
277
|
+
|
278
|
+
# Deletes a group_member from the Accounts server.
|
279
|
+
# The given account must own the group.
|
280
|
+
# Also takes an optional API version parameter.
|
281
|
+
# API version currently defaults to :v1 (may change in the future).
|
282
|
+
# On failure, throws an Exception, just like api_call.
|
283
|
+
# On success, returns an OAuth2::Response object.
|
284
|
+
def destroy_group_member(account, group_member, version = DEFAULT_API_VERSION)
|
285
|
+
options = {:access_token => account.access_token,
|
286
|
+
:api_version => version}
|
287
|
+
api_call(:delete,
|
288
|
+
"groups/#{group_member.group_id}/members/#{group_member.user_id}",
|
289
|
+
options)
|
290
|
+
end
|
291
|
+
|
292
|
+
# Creates a group_owner in the Accounts server.
|
293
|
+
# The given account must own the group.
|
294
|
+
# Also takes an optional API version parameter.
|
295
|
+
# API version currently defaults to :v1 (may change in the future).
|
296
|
+
# On failure, throws an Exception, just like api_call.
|
297
|
+
# On success, returns an OAuth2::Response object.
|
298
|
+
def create_group_owner(account, group_owner, version = DEFAULT_API_VERSION)
|
299
|
+
options = {:access_token => account.access_token,
|
300
|
+
:api_version => version}
|
301
|
+
api_call(:post,
|
302
|
+
"groups/#{group_owner.group_id}/owners/#{group_owner.user_id}",
|
303
|
+
options)
|
304
|
+
end
|
305
|
+
|
306
|
+
# Deletes a group_owner from the Accounts server.
|
307
|
+
# The given account must own the group.
|
308
|
+
# Also takes an optional API version parameter.
|
309
|
+
# API version currently defaults to :v1 (may change in the future).
|
310
|
+
# On failure, throws an Exception, just like api_call.
|
311
|
+
# On success, returns an OAuth2::Response object.
|
312
|
+
def destroy_group_owner(account, group_owner, version = DEFAULT_API_VERSION)
|
313
|
+
options = {:access_token => account.access_token,
|
314
|
+
:api_version => version}
|
315
|
+
api_call(:delete,
|
316
|
+
"groups/#{group_owner.group_id}/owners/#{group_owner.user_id}",
|
317
|
+
options)
|
318
|
+
end
|
319
|
+
|
320
|
+
# Creates a group_nesting in the Accounts server.
|
321
|
+
# The given account must own both groups.
|
322
|
+
# Also takes an optional API version parameter.
|
323
|
+
# API version currently defaults to :v1 (may change in the future).
|
324
|
+
# On failure, throws an Exception, just like api_call.
|
325
|
+
# On success, returns an OAuth2::Response object.
|
326
|
+
def create_group_nesting(account, group_nesting, version = DEFAULT_API_VERSION)
|
327
|
+
options = {:access_token => account.access_token,
|
328
|
+
:api_version => version}
|
329
|
+
api_call(:post,
|
330
|
+
"groups/#{group_nesting.container_group_id}/nestings/#{group_nesting.member_group_id}",
|
331
|
+
options)
|
332
|
+
end
|
333
|
+
|
334
|
+
# Deletes a group_nesting from the Accounts server.
|
335
|
+
# The given account must own either group.
|
336
|
+
# Also takes an optional API version parameter.
|
337
|
+
# API version currently defaults to :v1 (may change in the future).
|
338
|
+
# On failure, throws an Exception, just like api_call.
|
339
|
+
# On success, returns an OAuth2::Response object.
|
340
|
+
def destroy_group_nesting(account, group_nesting, version = DEFAULT_API_VERSION)
|
341
|
+
options = {:access_token => account.access_token,
|
342
|
+
:api_version => version}
|
343
|
+
api_call(:delete,
|
344
|
+
"groups/#{group_nesting.container_group_id}/nestings/#{group_nesting.member_group_id}",
|
345
|
+
options)
|
192
346
|
end
|
193
347
|
|
194
348
|
protected
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module Api
|
2
2
|
class DummyController < ApplicationController
|
3
|
-
class << self; attr_accessor :last_action, :last_params end
|
3
|
+
class << self; attr_accessor :last_action, :last_params, :last_json end
|
4
4
|
|
5
5
|
def dummy(action_name = :dummy)
|
6
6
|
self.class.last_action = action_name
|
7
7
|
self.class.last_params = params
|
8
|
+
self.class.last_json = ActiveSupport::JSON.decode(request.body.read) rescue nil
|
8
9
|
render :json => { :head => :no_content }
|
9
10
|
end
|
10
11
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
|
3
|
+
belongs_to :account,
|
4
|
+
class_name: "OpenStax::Accounts::Account"
|
5
|
+
has_many :groups_as_member, through: :account
|
6
|
+
has_many_through_groups :groups_as_member, :ownerships,
|
7
|
+
as: :owner, dependent: :destroy
|
5
8
|
|
6
9
|
delegate :username, :first_name, :last_name, :full_name, :title,
|
7
|
-
:name, :casual_name, to: :
|
10
|
+
:name, :casual_name, to: :account
|
8
11
|
|
9
12
|
def is_anonymous?
|
10
13
|
false
|
@@ -12,15 +15,15 @@ class User < ActiveRecord::Base
|
|
12
15
|
|
13
16
|
# OpenStax Accounts "account_user_mapper" methods
|
14
17
|
|
15
|
-
def self.account_to_user(
|
16
|
-
|
18
|
+
def self.account_to_user(acc)
|
19
|
+
acc.is_anonymous? ? \
|
17
20
|
AnonymousUser.instance : \
|
18
|
-
User.where(:
|
21
|
+
User.where(:account_id => acc.id).first
|
19
22
|
end
|
20
23
|
|
21
24
|
def self.user_to_account(user)
|
22
25
|
user.is_anonymous? ? \
|
23
26
|
AnonymousAccount.instance : \
|
24
|
-
user.
|
27
|
+
user.account
|
25
28
|
end
|
26
29
|
end
|
@@ -11,16 +11,6 @@ module Dummy
|
|
11
11
|
# Application configuration should go into files in config/initializers
|
12
12
|
# -- all .rb files in that directory are automatically loaded.
|
13
13
|
|
14
|
-
# Custom directories with classes and modules you want to be autoloadable.
|
15
|
-
# config.autoload_paths += %W(#{config.root}/extras)
|
16
|
-
|
17
|
-
# Only load the plugins named here, in the order given (default is alphabetical).
|
18
|
-
# :all can be used as a placeholder for all plugins not explicitly named.
|
19
|
-
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
20
|
-
|
21
|
-
# Activate observers that should always be running.
|
22
|
-
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
23
|
-
|
24
14
|
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
25
15
|
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
26
16
|
# config.time_zone = 'Central Time (US & Canada)'
|
@@ -28,29 +18,6 @@ module Dummy
|
|
28
18
|
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
29
19
|
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
30
20
|
# config.i18n.default_locale = :de
|
31
|
-
|
32
|
-
# Configure the default encoding used in templates for Ruby 1.9.
|
33
|
-
config.encoding = "utf-8"
|
34
|
-
|
35
|
-
# Configure sensitive parameters which will be filtered from the log file.
|
36
|
-
config.filter_parameters += [:password]
|
37
|
-
|
38
|
-
# Enable escaping HTML in JSON.
|
39
|
-
config.active_support.escape_html_entities_in_json = true
|
40
|
-
|
41
|
-
# Use SQL instead of Active Record's schema dumper when creating the database.
|
42
|
-
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
43
|
-
# like if you have constraints or database-specific column types
|
44
|
-
# config.active_record.schema_format = :sql
|
45
|
-
|
46
|
-
# Enable the asset pipeline
|
47
|
-
config.assets.enabled = true
|
48
|
-
|
49
|
-
# Version of your assets, change this if you want to expire all your assets
|
50
|
-
config.assets.version = '1.0'
|
51
|
-
|
52
|
-
# Suppress warning
|
53
|
-
config.i18n.enforce_available_locales = true
|
54
21
|
end
|
55
22
|
end
|
56
23
|
|
data/spec/dummy/config/boot.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Set up gems listed in the Gemfile.
|
2
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
|
3
3
|
|
4
|
-
if File.exist?(
|
5
|
-
|
6
|
-
require 'bundler'
|
7
|
-
Bundler.setup
|
8
|
-
end
|
9
|
-
|
10
|
-
$:.unshift File.expand_path('../../../../lib', __FILE__)
|
4
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
5
|
+
$LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
|