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.
Files changed (77) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +1 -0
  3. data/Rakefile +6 -6
  4. data/app/models/openstax/accounts/account.rb +34 -24
  5. data/app/models/openstax/accounts/application_group.rb +7 -0
  6. data/app/models/openstax/accounts/group.rb +132 -0
  7. data/app/models/openstax/accounts/group_member.rb +40 -0
  8. data/app/models/openstax/accounts/group_nesting.rb +62 -0
  9. data/app/models/openstax/accounts/group_owner.rb +40 -0
  10. data/app/representers/openstax/accounts/api/v1/application_group_representer.rb +25 -0
  11. data/app/representers/openstax/accounts/api/v1/application_groups_representer.rb +16 -0
  12. data/app/representers/openstax/accounts/api/v1/group_nesting_representer.rb +18 -0
  13. data/app/representers/openstax/accounts/api/v1/group_representer.rb +50 -0
  14. data/app/representers/openstax/accounts/api/v1/group_user_representer.rb +21 -0
  15. data/app/routines/openstax/accounts/search_accounts.rb +7 -14
  16. data/app/routines/openstax/accounts/sync_accounts.rb +32 -18
  17. data/app/routines/openstax/accounts/sync_groups.rb +61 -0
  18. data/app/routines/openstax/accounts/update_group_caches.rb +27 -0
  19. data/app/views/openstax/accounts/shared/accounts/_index.html.erb +0 -3
  20. data/config/initializers/action_interceptor.rb +1 -1
  21. data/db/migrate/20140811182433_create_openstax_accounts_groups.rb +16 -0
  22. data/db/migrate/20140811182505_create_openstax_accounts_group_members.rb +13 -0
  23. data/db/migrate/20140811182527_create_openstax_accounts_group_owners.rb +13 -0
  24. data/db/migrate/20140811182553_create_openstax_accounts_group_nestings.rb +13 -0
  25. data/lib/generators/openstax/accounts/schedule/templates/schedule.rb +1 -0
  26. data/lib/openstax/accounts/current_user_manager.rb +2 -2
  27. data/lib/openstax/accounts/has_many_through_groups.rb +45 -0
  28. data/lib/openstax/accounts/version.rb +1 -1
  29. data/lib/openstax_accounts.rb +165 -11
  30. data/spec/controllers/openstax/accounts/dev/accounts_controller_spec.rb +1 -1
  31. data/spec/controllers/openstax/accounts/sessions_controller_spec.rb +1 -1
  32. data/spec/dummy/app/controllers/api/application_groups_controller.rb +11 -0
  33. data/spec/dummy/app/controllers/api/dummy_controller.rb +2 -1
  34. data/spec/dummy/app/controllers/api/group_members_controller.rb +11 -0
  35. data/spec/dummy/app/controllers/api/group_nestings_controller.rb +11 -0
  36. data/spec/dummy/app/controllers/api/group_owners_controller.rb +11 -0
  37. data/spec/dummy/app/controllers/api/groups_controller.rb +15 -0
  38. data/spec/dummy/app/controllers/api/users_controller.rb +4 -0
  39. data/spec/dummy/app/models/ownership.rb +7 -0
  40. data/spec/dummy/app/models/user.rb +11 -8
  41. data/spec/dummy/config/application.rb +0 -33
  42. data/spec/dummy/config/boot.rb +4 -9
  43. data/spec/dummy/config/database.yml +8 -8
  44. data/spec/dummy/config/environment.rb +3 -3
  45. data/spec/dummy/config/environments/development.rb +20 -12
  46. data/spec/dummy/config/environments/production.rb +42 -29
  47. data/spec/dummy/config/environments/test.rb +16 -12
  48. data/spec/dummy/config/initializers/assets.rb +8 -0
  49. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  50. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  51. data/spec/dummy/config/initializers/inflections.rb +6 -5
  52. data/spec/dummy/config/initializers/mime_types.rb +0 -1
  53. data/spec/dummy/config/initializers/session_store.rb +1 -6
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +6 -6
  55. data/spec/dummy/config/routes.rb +23 -0
  56. data/spec/dummy/config/secrets.yml +8 -0
  57. data/spec/dummy/db/migrate/1_create_users.rb +2 -2
  58. data/spec/dummy/db/migrate/2_create_ownerships.rb +11 -0
  59. data/spec/dummy/db/schema.rb +72 -20
  60. data/spec/dummy/db/test.sqlite3 +0 -0
  61. data/spec/dummy/log/development.log +186 -0
  62. data/spec/dummy/log/test.log +2078 -0
  63. data/spec/factories/openstax_accounts_account.rb +3 -2
  64. data/spec/factories/openstax_accounts_group.rb +7 -0
  65. data/spec/factories/openstax_accounts_group_member.rb +6 -0
  66. data/spec/factories/openstax_accounts_group_nesting.rb +6 -0
  67. data/spec/factories/openstax_accounts_group_owner.rb +6 -0
  68. data/spec/lib/openstax/accounts/current_user_manager_spec.rb +9 -3
  69. data/spec/lib/openstax/accounts/has_many_through_groups_spec.rb +53 -0
  70. data/spec/lib/openstax_accounts_spec.rb +189 -25
  71. data/spec/models/openstax/accounts/account_spec.rb +16 -1
  72. data/spec/models/openstax/accounts/anonymous_account_spec.rb +1 -1
  73. data/spec/models/openstax/accounts/group_spec.rb +20 -0
  74. data/spec/routines/openstax/accounts/sync_accounts_spec.rb +70 -0
  75. data/spec/routines/openstax/accounts/sync_groups_spec.rb +125 -0
  76. metadata +73 -56
  77. data/spec/dummy/config/initializers/secret_token.rb +0 -7
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZmE5M2NiMTk1MWUzMTg1OTY1MDA5MzVjMGExNzEwMmVlMDY2NTFiMA==
4
+ MjM3YTQ1MzUyNzQ1ZDcxY2U4OWJhMTEzNzlhOTZhMDAwNDk5YzI1Ng==
5
5
  data.tar.gz: !binary |-
6
- MmMwMGI2MTRkYTkzZDg2NTlhZmE2Njc5NjZjOTgyMTUyNDJkZDU5MA==
6
+ ZTQ1NjI3MTRiMTk0YjQ0N2M4OTRhZmMzYTg2YjNjODYyMWViMjFmMA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NmZhOWE1OTA5Y2U5M2ViZTJlNzQzMjNjYmUwM2FkMmFlNTczNDU5ZDVmZmEz
10
- NjFmNmI4NGU4OGRiNDE2OTI2ZDRhYTdiNjFlMjc1NTA3ZWFiM2E4NWM4OTY3
11
- YTZhZTVlYjVjODhkY2YzMmYxZGRhZWQxNmM1YmUyNzE0MmJhOGE=
9
+ YTJiNWU0ZmVlYzI4NjhmMjY4YjNlYjhjMTk0NjNjM2MwYmU5YTcyMDRkYTQ4
10
+ MzEyN2YyMTFlMDM3MTBhYTEwYmVmMTZlOTkxNWY2MDhmYmU2NGZiMTQ0MmQz
11
+ ZTkyNmJjMDNjMGI5ZGExZjM5YTBlNjQzMmE3N2E4YmI3NWQ5MWM=
12
12
  data.tar.gz: !binary |-
13
- NmJiODkwZGVjZTRlNzZmNGMwNDJmNWJkMTE1ZTE2MjQzNDc2YWM5YjRmYzlk
14
- MjVjODkyYTNmNDZmMjQ4NTQyMDliY2YxYmY4MWNhMmY4NzA1OTcwMzNlNmFm
15
- YTQwOTQxOWE5Y2NlYzJiMmQ2ZDdjYjBkYTZkOTg1ZTIxZTc2YTU=
13
+ ZGFjNDAwZmU3NGUyNThlMTMwMjI3ZjFiYWQzYzY3MWNiM2RjN2I0NzY4MWYy
14
+ M2NlYWU5MmFlOGJhOGZhZDViZDQzOTMwMTBhNGI2MDA5OGNmOTcyYTgyNDBk
15
+ YmVkYTEzYTZmM2I5YmUzOWVlNjA2ZTFkMDVjMWZlM2U1ZmRhZDg=
data/README.md CHANGED
@@ -3,6 +3,7 @@ accounts-rails
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/openstax_accounts.svg)](http://badge.fury.io/rb/openstax_accounts)
5
5
  [![Build Status](https://travis-ci.org/openstax/accounts-rails.svg?branch=master)](https://travis-ci.org/openstax/accounts-rails)
6
+ [![Code Climate](https://codeclimate.com/github/openstax/accounts-rails/badges/gpa.svg)](https://codeclimate.com/github/openstax/accounts-rails)
6
7
 
7
8
  A rails engine for interfacing with OpenStax's accounts server.
8
9
 
data/Rakefile CHANGED
@@ -11,12 +11,12 @@ load 'rails/tasks/engine.rake'
11
11
 
12
12
  Bundler::GemHelper.install_tasks
13
13
 
14
- Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
14
+ require 'rake/testtask'
15
15
 
16
- require 'rspec/core'
17
- require 'rspec/core/rake_task'
18
-
19
- desc 'Run all specs in spec directory (excluding plugin specs)'
20
- RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
16
+ Rake::TestTask.new(:spec => 'app:db:test:prepare') do |t|
17
+ t.libs << 'spec'
18
+ t.pattern = 'spec/**/*_spec.rb'
19
+ t.verbose = false
20
+ end
21
21
 
22
22
  task :default => :spec
@@ -1,39 +1,49 @@
1
- module OpenStax
2
- module Accounts
1
+ module OpenStax::Accounts
3
2
  class Account < ActiveRecord::Base
4
3
 
5
- USERNAME_DISCARDED_CHAR_REGEX = /[^A-Za-z\d_]/
6
- USERNAME_MAX_LENGTH = 50
4
+ USERNAME_DISCARDED_CHAR_REGEX = /[^A-Za-z\d_]/
5
+ USERNAME_MAX_LENGTH = 50
7
6
 
8
- attr_accessor :syncing_with_accounts
7
+ has_many :group_owners, dependent: :destroy,
8
+ class_name: 'OpenStax::Accounts::GroupOwner',
9
+ primary_key: :openstax_uid, foreign_key: :user_id, inverse_of: :user
10
+ has_many :groups_as_owner, through: :group_owners, source: :group
9
11
 
10
- validates :username, uniqueness: true, presence: true
11
- validates :openstax_uid, uniqueness: true, presence: true
12
- validates :access_token, uniqueness: true, allow_nil: true
12
+ has_many :group_members, dependent: :destroy,
13
+ class_name: 'OpenStax::Accounts::GroupMember',
14
+ primary_key: :openstax_uid, foreign_key: :user_id, inverse_of: :user
15
+ has_many :groups_as_member, through: :group_members, source: :group
13
16
 
14
- attr_accessible :username, :first_name, :last_name, :full_name, :title
17
+ validates :openstax_uid, :presence => true, :uniqueness => true
18
+ validates :username, :presence => true, :uniqueness => true,
19
+ :unless => :syncing_or_stubbing
20
+ validates :access_token, :presence => true, :uniqueness => true,
21
+ :unless => :syncing_or_stubbing
15
22
 
16
- before_update :update_openstax_accounts
23
+ before_update :update_openstax_accounts, :unless => :syncing_or_stubbing
17
24
 
18
- def name
19
- (first_name || last_name) ? [first_name, last_name].compact.join(" ") : username
20
- end
25
+ def name
26
+ (first_name || last_name) ? [first_name, last_name].compact.join(" ") : username
27
+ end
21
28
 
22
- def casual_name
23
- first_name || username
24
- end
29
+ def casual_name
30
+ first_name || username
31
+ end
25
32
 
26
- def is_anonymous?
27
- false
28
- end
33
+ def is_anonymous?
34
+ false
35
+ end
29
36
 
30
- def update_openstax_accounts
31
- return if syncing_with_accounts || \
32
- OpenStax::Accounts.configuration.enable_stubbing?
37
+ protected
33
38
 
34
- OpenStax::Accounts.update_account(self)
35
- end
39
+ def syncing_or_stubbing
40
+ OpenStax::Accounts.syncing ||\
41
+ OpenStax::Accounts.configuration.enable_stubbing?
42
+ end
36
43
 
44
+ def update_openstax_accounts
45
+ OpenStax::Accounts.update_account(self)
37
46
  end
47
+
38
48
  end
39
49
  end
@@ -0,0 +1,7 @@
1
+ module OpenStax
2
+ module Accounts
3
+ class ApplicationGroup
4
+ attr_accessor :id, :application_id, :group, :unread_updates
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,132 @@
1
+ module OpenStax::Accounts
2
+ class Group < ActiveRecord::Base
3
+
4
+ serialize :cached_supertree_group_ids
5
+ serialize :cached_subtree_group_ids
6
+
7
+ attr_accessor :requestor
8
+
9
+ has_many :group_owners, dependent: :destroy,
10
+ class_name: 'OpenStax::Accounts::GroupOwner',
11
+ primary_key: :openstax_uid, inverse_of: :group
12
+ has_many :owners, through: :group_owners, source: :user
13
+
14
+ has_many :group_members, dependent: :destroy,
15
+ class_name: 'OpenStax::Accounts::GroupMember',
16
+ primary_key: :openstax_uid, inverse_of: :group
17
+ has_many :members, through: :group_members, source: :user
18
+
19
+ has_one :container_group_nesting, dependent: :destroy,
20
+ class_name: 'OpenStax::Accounts::GroupNesting', primary_key: :openstax_uid,
21
+ foreign_key: :member_group_id, inverse_of: :member_group
22
+ has_one :container_group, through: :container_group_nesting
23
+
24
+ has_many :member_group_nestings, dependent: :destroy,
25
+ class_name: 'OpenStax::Accounts::GroupNesting', primary_key: :openstax_uid,
26
+ foreign_key: :container_group_id, inverse_of: :container_group
27
+ has_many :member_groups, through: :member_group_nestings
28
+
29
+ validates :openstax_uid, :uniqueness => true, :presence => true
30
+ validates_presence_of :requestor, :unless => :syncing_or_stubbing
31
+ validates_uniqueness_of :name, :allow_nil => true, :unless => :syncing_or_stubbing
32
+
33
+ before_validation :create_openstax_accounts_group,
34
+ :on => :create, :unless => :syncing_or_stubbing
35
+ before_update :update_openstax_accounts_group, :unless => :syncing_or_stubbing
36
+ before_destroy :destroy_openstax_accounts_group, :unless => :syncing_or_stubbing
37
+
38
+ scope :visible_for, lambda { |account|
39
+ next where(is_public: true) unless account.is_a? OpenStax::Accounts::Account
40
+
41
+ includes(:group_members).includes(:group_owners)
42
+ .where{((is_public.eq true) |\
43
+ (group_members.user_id.eq my{account.id}) |\
44
+ (group_owners.user_id.eq my{account.id}))}
45
+ }
46
+
47
+ def has_owner?(account)
48
+ return false unless account.is_a? OpenStax::Accounts::Account
49
+ !group_owners.where(user_id: account.id).first.nil?
50
+ end
51
+
52
+ def has_direct_member?(account)
53
+ return false unless account.is_a? OpenStax::Accounts::Account
54
+ !group_members.where(user_id: account.id).first.nil?
55
+ end
56
+
57
+ def has_member?(account)
58
+ return false unless account.is_a? OpenStax::Accounts::Account
59
+ !account.group_members.where(group_id: subtree_group_ids).first.nil?
60
+ end
61
+
62
+ def add_owner(account)
63
+ return false unless account.is_a? OpenStax::Accounts::Account
64
+ go = GroupOwner.new
65
+ go.group = self
66
+ go.user = account
67
+ return false unless go.valid?
68
+ go.save if persisted?
69
+ group_owners << go
70
+ end
71
+
72
+ def add_member(account)
73
+ return false unless account.is_a? OpenStax::Accounts::Account
74
+ gm = GroupMember.new
75
+ gm.group = self
76
+ gm.user = account
77
+ return false unless gm.valid?
78
+ gm.save if persisted?
79
+ group_members << gm
80
+ end
81
+
82
+ def supertree_group_ids
83
+ return cached_supertree_group_ids unless cached_supertree_group_ids.nil?
84
+ return [] unless persisted?
85
+ reload
86
+
87
+ gids = [id] + (Group.includes(:member_group_nestings)
88
+ .where(member_group_nestings: {member_group_id: openstax_uid})
89
+ .first.try(:supertree_group_ids) || [])
90
+ update_column(:cached_supertree_group_ids, gids.to_yaml)
91
+ self.cached_supertree_group_ids = gids
92
+ end
93
+
94
+ def subtree_group_ids
95
+ return cached_subtree_group_ids unless cached_subtree_group_ids.nil?
96
+ return [] unless persisted?
97
+ reload
98
+
99
+ gids = [id] + Group.includes(:container_group_nesting)
100
+ .where(container_group_nesting: {container_group_id: openstax_uid})
101
+ .collect{|g| g.subtree_group_ids}.flatten
102
+ update_column(:cached_subtree_group_ids, gids.to_yaml)
103
+ self.cached_subtree_group_ids = gids
104
+ end
105
+
106
+ protected
107
+
108
+ def syncing_or_stubbing
109
+ OpenStax::Accounts.syncing ||\
110
+ OpenStax::Accounts.configuration.enable_stubbing?
111
+ end
112
+
113
+ def create_openstax_accounts_group
114
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
115
+
116
+ OpenStax::Accounts.create_group(requestor, self)
117
+ end
118
+
119
+ def update_openstax_accounts_group
120
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
121
+
122
+ OpenStax::Accounts.update_group(requestor, self)
123
+ end
124
+
125
+ def destroy_openstax_accounts_group
126
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
127
+
128
+ OpenStax::Accounts.destroy_group(requestor, self)
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,40 @@
1
+ module OpenStax::Accounts
2
+ class GroupMember < ActiveRecord::Base
3
+
4
+ attr_accessor :requestor
5
+
6
+ belongs_to :group, class_name: 'OpenStax::Accounts::Group',
7
+ primary_key: :openstax_uid, inverse_of: :group_members
8
+ belongs_to :user, class_name: 'OpenStax::Accounts::Account',
9
+ primary_key: :openstax_uid, inverse_of: :group_members
10
+
11
+ validates_presence_of :user_id, :group_id
12
+ validates_uniqueness_of :user_id, scope: :group_id
13
+ validates_presence_of :group, :user, :requestor, :unless => :syncing_or_stubbing
14
+
15
+ before_create :create_openstax_accounts_group_member, :unless => :syncing_or_stubbing
16
+ before_destroy :destroy_openstax_accounts_group_member, :unless => :syncing_or_stubbing
17
+
18
+ protected
19
+
20
+ def syncing_or_stubbing
21
+ OpenStax::Accounts.syncing ||\
22
+ OpenStax::Accounts.configuration.enable_stubbing?
23
+ end
24
+
25
+ def create_openstax_accounts_group_member
26
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
27
+ return false unless requestor
28
+
29
+ OpenStax::Accounts.create_group_member(requestor, self)
30
+ end
31
+
32
+ def destroy_openstax_accounts_group_member
33
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
34
+ return false unless requestor
35
+
36
+ OpenStax::Accounts.destroy_group_member(requestor, self)
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,62 @@
1
+ module OpenStax::Accounts
2
+ class GroupNesting < ActiveRecord::Base
3
+
4
+ attr_accessor :requestor
5
+
6
+ belongs_to :container_group, class_name: 'OpenStax::Accounts::Group',
7
+ primary_key: :openstax_uid, inverse_of: :member_group_nestings
8
+ belongs_to :member_group, class_name: 'OpenStax::Accounts::Group',
9
+ primary_key: :openstax_uid, inverse_of: :container_group_nesting
10
+
11
+ validates_presence_of :container_group_id, :member_group_id
12
+ validates_uniqueness_of :member_group_id
13
+ validates_presence_of :container_group, :member_group, :requestor,
14
+ :unless => :syncing_or_stubbing
15
+ validate :no_loops, :unless => :syncing_or_stubbing
16
+
17
+ before_create :update_group_caches, :unless => :syncing?
18
+ before_destroy :update_group_caches, :unless => :syncing?
19
+
20
+ before_create :create_openstax_accounts_group_nesting,
21
+ :unless => :syncing_or_stubbing
22
+ before_destroy :update_group_caches, :destroy_openstax_accounts_group_nesting,
23
+ :unless => :syncing_or_stubbing
24
+
25
+ protected
26
+
27
+ def syncing?
28
+ OpenStax::Accounts.syncing
29
+ end
30
+
31
+ def syncing_or_stubbing
32
+ syncing? || OpenStax::Accounts.configuration.enable_stubbing?
33
+ end
34
+
35
+ def no_loops
36
+ return if member_group.nil? ||\
37
+ !member_group.subtree_group_ids.include?(container_group_id)
38
+ errors.add(:base, 'would create a loop') if errors[:base].blank?
39
+ false
40
+ end
41
+
42
+ def update_group_caches
43
+ # Returns false if the update fails (aborting the save transaction)
44
+ UpdateGroupCaches.call(self).errors.none?
45
+ end
46
+
47
+ def create_openstax_accounts_group_nesting
48
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
49
+ return false unless requestor
50
+
51
+ OpenStax::Accounts.create_group_nesting(requestor, self)
52
+ end
53
+
54
+ def destroy_openstax_accounts_group_nesting
55
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
56
+ return false unless requestor
57
+
58
+ OpenStax::Accounts.destroy_group_nesting(requestor, self)
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,40 @@
1
+ module OpenStax::Accounts
2
+ class GroupOwner < ActiveRecord::Base
3
+
4
+ attr_accessor :requestor
5
+
6
+ belongs_to :group, class_name: 'OpenStax::Accounts::Group',
7
+ primary_key: :openstax_uid, inverse_of: :group_owners
8
+ belongs_to :user, class_name: 'OpenStax::Accounts::Account',
9
+ primary_key: :openstax_uid, inverse_of: :group_owners
10
+
11
+ validates_presence_of :user_id, :group_id
12
+ validates_uniqueness_of :user_id, scope: :group_id
13
+ validates_presence_of :group, :user, :requestor, :unless => :syncing_or_stubbing
14
+
15
+ before_create :create_openstax_accounts_group_owner, :unless => :syncing_or_stubbing
16
+ before_destroy :destroy_openstax_accounts_group_owner, :unless => :syncing_or_stubbing
17
+
18
+ protected
19
+
20
+ def syncing_or_stubbing
21
+ OpenStax::Accounts.syncing ||\
22
+ OpenStax::Accounts.configuration.enable_stubbing?
23
+ end
24
+
25
+ def create_openstax_accounts_group_owner
26
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
27
+ return false unless requestor
28
+
29
+ OpenStax::Accounts.create_group_owner(requestor, self)
30
+ end
31
+
32
+ def destroy_openstax_accounts_group_owner
33
+ return if OpenStax::Accounts.syncing || OpenStax::Accounts.configuration.enable_stubbing?
34
+ return false unless requestor
35
+
36
+ OpenStax::Accounts.destroy_group_owner(requestor, self)
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,25 @@
1
+ module OpenStax
2
+ module Accounts
3
+ module Api
4
+ module V1
5
+ class ApplicationGroupRepresenter < Roar::Decorator
6
+ include Roar::Representer::JSON
7
+
8
+ property :id,
9
+ type: Integer
10
+
11
+ property :application_id,
12
+ type: Integer
13
+
14
+ property :group,
15
+ class: OpenStax::Accounts::Group,
16
+ decorator: GroupRepresenter
17
+
18
+ property :unread_updates,
19
+ type: Integer
20
+
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ require 'representable/json/collection'
2
+
3
+ module OpenStax
4
+ module Accounts
5
+ module Api
6
+ module V1
7
+ class ApplicationGroupsRepresenter < Roar::Decorator
8
+ include Representable::JSON::Collection
9
+
10
+ items class: OpenStax::Accounts::ApplicationGroup,
11
+ decorator: ApplicationGroupRepresenter
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end