openstax_accounts 8.1.1 → 9.0.4

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/openstax/accounts/application_controller.rb +0 -4
  3. data/app/controllers/openstax/accounts/dev/accounts_controller.rb +16 -10
  4. data/app/controllers/openstax/accounts/dev/base_controller.rb +1 -5
  5. data/app/controllers/openstax/accounts/sessions_controller.rb +2 -5
  6. data/app/handlers/openstax/accounts/accounts_search.rb +3 -5
  7. data/app/handlers/openstax/accounts/dev/accounts_create.rb +1 -7
  8. data/app/handlers/openstax/accounts/dev/accounts_search.rb +0 -2
  9. data/app/handlers/openstax/accounts/sessions_callback.rb +3 -4
  10. data/app/models/openstax/accounts/account.rb +27 -23
  11. data/app/models/openstax/accounts/anonymous_account.rb +1 -2
  12. data/app/representers/openstax/accounts/api/v1/account_representer.rb +19 -6
  13. data/app/routines/openstax/accounts/dev/create_account.rb +25 -21
  14. data/app/routines/openstax/accounts/find_or_create_account.rb +11 -19
  15. data/app/routines/openstax/accounts/find_or_create_from_sso.rb +2 -8
  16. data/app/routines/openstax/accounts/sync_accounts.rb +1 -7
  17. data/app/views/layouts/openstax/accounts/application.html.erb +2 -2
  18. data/app/views/openstax/accounts/dev/accounts/_search_results.html.erb +9 -10
  19. data/app/views/openstax/accounts/dev/accounts/index.html.erb +7 -10
  20. data/app/views/openstax/accounts/dev/accounts/{search.js.erb → index.js.erb} +0 -0
  21. data/app/views/openstax/accounts/shared/_attention.html.erb +9 -1
  22. data/app/views/openstax/accounts/shared/accounts/_search.html.erb +12 -8
  23. data/config/routes.rb +2 -5
  24. data/db/migrate/14_drop_openstax_uid_and_username_uniqueness.rb +9 -0
  25. data/db/migrate/15_drop_accounts_groups.rb +42 -0
  26. data/db/migrate/16_add_is_kip_to_openstax_accounts_accounts.rb +5 -0
  27. data/db/migrate/17_add_school_location_to_openstax_accounts_accounts.rb +5 -0
  28. data/lib/omniauth/strategies/openstax.rb +1 -1
  29. data/lib/openstax/accounts/api.rb +0 -149
  30. data/lib/openstax/accounts/current_user_manager.rb +1 -5
  31. data/lib/openstax/accounts/engine.rb +1 -1
  32. data/lib/openstax/accounts/version.rb +1 -1
  33. data/lib/tasks/sync.rake +0 -8
  34. data/spec/factories/openstax_accounts_account.rb +1 -0
  35. metadata +8 -23
  36. data/app/models/openstax/accounts/application_group.rb +0 -7
  37. data/app/models/openstax/accounts/group.rb +0 -169
  38. data/app/models/openstax/accounts/group_member.rb +0 -37
  39. data/app/models/openstax/accounts/group_nesting.rb +0 -55
  40. data/app/models/openstax/accounts/group_owner.rb +0 -37
  41. data/app/representers/openstax/accounts/api/v1/application_group_representer.rb +0 -48
  42. data/app/representers/openstax/accounts/api/v1/application_groups_representer.rb +0 -20
  43. data/app/representers/openstax/accounts/api/v1/group_nesting_representer.rb +0 -31
  44. data/app/representers/openstax/accounts/api/v1/group_representer.rb +0 -71
  45. data/app/representers/openstax/accounts/api/v1/group_user_representer.rb +0 -34
  46. data/app/routines/openstax/accounts/create_group.rb +0 -26
  47. data/app/routines/openstax/accounts/sync_groups.rb +0 -67
  48. data/app/routines/openstax/accounts/update_group_caches.rb +0 -27
  49. data/lib/openstax/accounts/has_many_through_groups/active_record/base.rb +0 -51
  50. data/spec/factories/openstax_accounts_group.rb +0 -7
  51. data/spec/factories/openstax_accounts_group_member.rb +0 -6
  52. data/spec/factories/openstax_accounts_group_nesting.rb +0 -6
  53. data/spec/factories/openstax_accounts_group_owner.rb +0 -6
@@ -1,14 +1,13 @@
1
1
  module OpenStax
2
2
  module Accounts
3
3
  class FindOrCreateAccount
4
-
5
4
  lev_routine
6
5
 
7
6
  protected
8
7
 
9
8
  def exec(email: nil, username: nil, password: nil, first_name: nil, last_name: nil,
10
9
  full_name: nil, title: nil, salesforce_contact_id: nil, faculty_status: nil,
11
- role: nil, school_type: nil, is_test: nil)
10
+ role: nil, school_type: nil, school_location: nil, is_test: nil)
12
11
  raise(
13
12
  ArgumentError,
14
13
  'You must specify either an email address or a username (and an optional password)'
@@ -16,31 +15,27 @@ module OpenStax
16
15
 
17
16
  if OpenStax::Accounts.configuration.enable_stubbing
18
17
  # We can only stub finding by username b/c accounts-rails doesn't persist emails
19
- id = Account.find_by(username: username).try!(:openstax_uid) ||
20
- -SecureRandom.hex(4).to_i(16)/2
21
- uuid = SecureRandom.uuid
18
+ uuid = Account.find_by(username: username)&.uuid || SecureRandom.uuid
19
+ openstax_uid = -SecureRandom.hex(4).to_i(16)/2
22
20
  support_identifier = "cs_#{SecureRandom.hex(4)}"
23
21
  else
24
- response = Api.find_or_create_account(
22
+ response = OpenStax::Accounts::Api.find_or_create_account(
25
23
  email: email, username: username, password: password,
26
24
  first_name: first_name, last_name: last_name, full_name: full_name,
27
25
  salesforce_contact_id: salesforce_contact_id, faculty_status: faculty_status,
28
- role: role, school_type: school_type, is_test: is_test)
26
+ role: role, school_type: school_type, school_location: school_location, is_test: is_test
27
+ )
29
28
  fatal_error(code: :invalid_inputs) unless (200..202).include?(response.status)
30
29
 
31
30
  struct = OpenStruct.new
32
31
  Api::V1::UnclaimedAccountRepresenter.new(struct).from_json(response.body)
33
- id = struct.id
32
+ openstax_uid = struct.id
34
33
  uuid = struct.uuid
35
34
  support_identifier = struct.support_identifier
36
35
  end
37
36
 
38
- account = Account.find_or_initialize_by(openstax_uid: id)
39
-
40
- unless account.persisted?
41
- while username.nil? || Account.where(username: username).exists? do
42
- username = SecureRandom.hex(3).to_s
43
- end
37
+ outputs.account = Account.find_or_create_by(uuid: uuid) do |account|
38
+ account.openstax_uid = openstax_uid
44
39
  account.username = username
45
40
  account.first_name = first_name
46
41
  account.last_name = last_name
@@ -50,16 +45,13 @@ module OpenStax
50
45
  account.faculty_status = faculty_status || :no_faculty_info
51
46
  account.role = role || :unknown_role
52
47
  account.school_type = school_type || :unknown_school_type
53
- account.uuid = uuid
48
+ account.school_location = school_location || :unknown_school_location
54
49
  account.support_identifier = support_identifier
55
50
  account.is_test = is_test
56
- account.save!
57
51
  end
58
52
 
59
- transfer_errors_from(account, {type: :verbatim}, true)
60
- outputs.account = account
53
+ transfer_errors_from outputs.account, { type: :verbatim }, true
61
54
  end
62
-
63
55
  end
64
56
  end
65
57
  end
@@ -1,23 +1,17 @@
1
1
  module OpenStax
2
2
  module Accounts
3
3
  class FindOrCreateFromSso
4
-
5
4
  lev_routine express_output: :account
6
5
 
7
6
  def exec(attrs)
8
7
  attrs.stringify_keys!
9
8
  uid = attrs.delete('id')
10
9
  uuid = attrs.delete('uuid')
11
- account = Account.find_or_initialize_by(
12
- uuid: uuid, openstax_uid: uid
13
- )
14
- account.update_attributes!(
15
- attrs.slice(*Account.column_names)
16
- )
10
+ account = Account.find_or_initialize_by(uuid: uuid)
11
+ account.update_attributes!(attrs.slice(*Account.column_names))
17
12
  transfer_errors_from(account, {type: :verbatim})
18
13
  outputs.account = account
19
14
  end
20
-
21
15
  end
22
16
  end
23
17
  end
@@ -4,15 +4,12 @@
4
4
 
5
5
  module OpenStax
6
6
  module Accounts
7
-
8
7
  class SyncAccounts
9
-
10
8
  lev_routine transaction: :no_transaction
11
9
 
12
10
  protected
13
11
 
14
12
  def exec(options={})
15
-
16
13
  return if OpenStax::Accounts.configuration.enable_stubbing?
17
14
 
18
15
  response = OpenStax::Accounts::Api.get_application_account_updates
@@ -27,7 +24,7 @@ module OpenStax
27
24
  updated_app_accounts = []
28
25
  app_accounts.each do |app_account|
29
26
  account = OpenStax::Accounts::Account.find_by(
30
- openstax_uid: app_account.account.openstax_uid
27
+ uuid: app_account.account.uuid
31
28
  ) || app_account.account
32
29
  account.syncing = true
33
30
 
@@ -45,10 +42,7 @@ module OpenStax
45
42
  end
46
43
 
47
44
  OpenStax::Accounts::Api.mark_account_updates_as_read(updated_app_accounts)
48
-
49
45
  end
50
-
51
46
  end
52
-
53
47
  end
54
48
  end
@@ -2,8 +2,8 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Accounts</title>
5
- <%= stylesheet_link_tag "openstax/accounts/application", :media => "all" %>
6
- <%= javascript_include_tag "openstax/accounts/application" %>
5
+ <%= stylesheet_link_tag 'openstax/accounts/application', media: 'all' %>
6
+ <%= javascript_include_tag 'openstax/accounts/application' %>
7
7
  <%= csrf_meta_tags %>
8
8
  </head>
9
9
  <body>
@@ -1,5 +1,5 @@
1
- <% total_count = @handler_result.outputs[:total_count]
2
- accounts = @handler_result.outputs[:items] %>
1
+ <% total_count = @handler_result.outputs.total_count
2
+ accounts = @handler_result.outputs.items || [] %>
3
3
 
4
4
  <div id='search-results-count'>
5
5
  <%= pluralize(total_count, 'user') %> found.
@@ -9,16 +9,15 @@
9
9
  <%= osu.action_list(
10
10
  records: accounts,
11
11
  list: {
12
- headings: ['UID', 'Username (click to sign in as)', 'Name'],
13
- widths: ['20%', '40%', '40%'],
12
+ headings: ['UID', 'UUID', 'Username (click to sign in as)', 'Name'],
13
+ widths: ['20%', '20%', '30%', '30%'],
14
14
  data_procs: [
15
- lambda { |account| account.openstax_uid },
16
- lambda { |account|
17
- link_to account.username, become_dev_account_path(
18
- account.openstax_uid
19
- ), method: :post
15
+ ->(account) { account.openstax_uid },
16
+ ->(account) { account.uuid },
17
+ ->(account) {
18
+ link_to account.username, become_dev_account_path(account.id), method: :post
20
19
  },
21
- lambda { |account| account.name || '---' }
20
+ ->(account) { account.name || '---' }
22
21
  ]
23
22
  }
24
23
  ) %>
@@ -1,5 +1,4 @@
1
1
  <div class="openstax-accounts development-login">
2
-
3
2
  <%= render partial: 'openstax/accounts/shared/attention' %>
4
3
 
5
4
  <h3>Create an Account</h3>
@@ -11,7 +10,7 @@
11
10
 
12
11
 
13
12
  <div class="form-group">
14
- <%= f.text_field :username, placeholder: "Username" %>&nbsp;
13
+ <%= f.text_field :username, placeholder: 'Username' %>&nbsp;
15
14
  <%= f.select :role, OpenStax::Accounts::Account.roles.keys.map{|rr| [rr, rr]} %>&nbsp;
16
15
  <%= f.submit 'Create', class: 'btn btn-primary' %>
17
16
  </div>
@@ -23,15 +22,13 @@
23
22
  <p>You need to login, but we're not connected to the Accounts server.<br>
24
23
  Search for a user below and click the sign in link next to him or her.</p>
25
24
 
26
- <%= render :partial => 'openstax/accounts/shared/accounts/search',
27
- :locals => {
28
- :search_action_path => openstax_accounts.search_dev_accounts_path,
29
- :remote => true,
30
- :method => :get
25
+ <%= render partial: 'openstax/accounts/shared/accounts/search',
26
+ locals: {
27
+ search_action_path: openstax_accounts.dev_accounts_path,
28
+ search_results_partial: 'openstax/accounts/dev/accounts/search_results',
29
+ remote: true,
30
+ method: :get
31
31
  } %>
32
32
 
33
33
  <br>
34
-
35
- <div id="search-results"></div>
36
-
37
34
  </div>
@@ -1,3 +1,11 @@
1
1
  <% handler_errors.each do |error| %>
2
- <%= error.translate %>
2
+ <div class="error"><%= error.translate %></div>
3
+ <% end %>
4
+
5
+ <% if flash.alert %>
6
+ <div class="alert"><%= flash.alert %></div>
7
+ <% end %>
8
+
9
+ <% if flash.notice %>
10
+ <div class="notice"><%= flash.notice %></div>
3
11
  <% end %>
@@ -1,12 +1,11 @@
1
1
  <%
2
- # Clients of this partial can override the following variables:
3
- search_action_path ||= nil
4
- method ||= :get
5
- remote ||= false
6
- form_html ||= {id: 'search-form',
7
- class: 'form-inline'}
8
- search_types ||= ['Any', 'Username', 'Name',
9
- 'First Name', 'Last Name', 'Email']
2
+ # Clients of this partial can override the following variables:
3
+ search_action_path ||= nil
4
+ search_results_partial ||= nil
5
+ method ||= :get
6
+ remote ||= false
7
+ form_html ||= {id: 'search-form', class: 'form-inline'}
8
+ search_types ||= ['Any', 'Username', 'Name', 'First Name', 'Last Name', 'Email']
10
9
  %>
11
10
 
12
11
  <%= lev_form_for :search,
@@ -26,6 +25,11 @@
26
25
 
27
26
  <% end %>
28
27
 
28
+ <div id="search-results">
29
+ <% unless search_results_partial.blank? %>
30
+ <%= render partial: search_results_partial %>
31
+ <% end %>
32
+ </div>
29
33
 
30
34
  <script>
31
35
  var input = $('input[name="search[query]"]');
@@ -1,18 +1,16 @@
1
1
  OpenStax::Accounts::Engine.routes.draw do
2
-
3
2
  # Redirect here if we don't know what to do (theoretically should not happen)
4
3
  root to: 'sessions#new'
5
4
 
6
5
  # Shortcut to OmniAuth route that redirects to the Accounts server
7
6
  # This is provided by OmniAuth and is not in the SessionsController
8
- get '/auth/openstax', as: 'openstax_login'
7
+ get '/auth/openstax', to: ->(env) { [ 404, {}, [ '' ] ] }, as: 'openstax_login'
9
8
 
10
- # User profile route
11
9
  if OpenStax::Accounts.configuration.enable_stubbing?
10
+ # User profile route
12
11
  namespace :dev do
13
12
  resources :accounts, only: [:index, :create] do
14
13
  post 'become', on: :member
15
- get 'search', on: :collection
16
14
  end
17
15
  end
18
16
  end
@@ -27,5 +25,4 @@ OpenStax::Accounts::Engine.routes.draw do
27
25
  via: OpenStax::Accounts.configuration.logout_via
28
26
  get 'profile', action: :profile # Redirects to profile path or stub
29
27
  end
30
-
31
28
  end
@@ -0,0 +1,9 @@
1
+ class DropOpenStaxUidAndUsernameUniqueness < ActiveRecord::Migration[5.2]
2
+ def change
3
+ remove_index :openstax_accounts_accounts, column: [ :openstax_uid ], unique: true
4
+ remove_index :openstax_accounts_accounts, column: [ :username ], unique: true
5
+
6
+ add_index :openstax_accounts_accounts, :openstax_uid
7
+ add_index :openstax_accounts_accounts, :username
8
+ end
9
+ end
@@ -0,0 +1,42 @@
1
+ class DropAccountsGroups < ActiveRecord::Migration[5.2]
2
+ def change
3
+ drop_table "openstax_accounts_group_members" do |t|
4
+ t.integer "group_id", null: false
5
+ t.integer "user_id", null: false
6
+ t.datetime "created_at", null: false
7
+ t.datetime "updated_at", null: false
8
+ t.index ["group_id", "user_id"], name: "index_openstax_accounts_group_members_on_group_id_and_user_id", unique: true
9
+ t.index ["user_id"], name: "index_openstax_accounts_group_members_on_user_id"
10
+ end
11
+
12
+ drop_table "openstax_accounts_group_nestings" do |t|
13
+ t.integer "member_group_id", null: false
14
+ t.integer "container_group_id", null: false
15
+ t.datetime "created_at", null: false
16
+ t.datetime "updated_at", null: false
17
+ t.index ["container_group_id"], name: "index_openstax_accounts_group_nestings_on_container_group_id"
18
+ t.index ["member_group_id"], name: "index_openstax_accounts_group_nestings_on_member_group_id", unique: true
19
+ end
20
+
21
+ drop_table "openstax_accounts_group_owners" do |t|
22
+ t.integer "group_id", null: false
23
+ t.integer "user_id", null: false
24
+ t.datetime "created_at", null: false
25
+ t.datetime "updated_at", null: false
26
+ t.index ["group_id", "user_id"], name: "index_openstax_accounts_group_owners_on_group_id_and_user_id", unique: true
27
+ t.index ["user_id"], name: "index_openstax_accounts_group_owners_on_user_id"
28
+ end
29
+
30
+ drop_table "openstax_accounts_groups" do |t|
31
+ t.integer "openstax_uid", null: false
32
+ t.boolean "is_public", default: false, null: false
33
+ t.string "name"
34
+ t.text "cached_subtree_group_ids"
35
+ t.text "cached_supertree_group_ids"
36
+ t.datetime "created_at", null: false
37
+ t.datetime "updated_at", null: false
38
+ t.index ["is_public"], name: "index_openstax_accounts_groups_on_is_public"
39
+ t.index ["openstax_uid"], name: "index_openstax_accounts_groups_on_openstax_uid", unique: true
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,5 @@
1
+ class AddIsKipToOpenStaxAccountsAccounts < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :openstax_accounts_accounts, :is_kip, :boolean
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddSchoolLocationToOpenStaxAccountsAccounts < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :openstax_accounts_accounts, :school_location, :integer, default: 0, null: false
4
+ end
5
+ end
@@ -11,7 +11,7 @@ module OmniAuth
11
11
  authorize_url: "/oauth/authorize"
12
12
  }
13
13
 
14
- uid { raw_info[:id] }
14
+ uid { raw_info[:uuid] }
15
15
 
16
16
  info do
17
17
  # Changed to conform to the omniauth schema
@@ -97,155 +97,6 @@ module OpenStax
97
97
  request(:put, 'application_users/updated', options.merge(body: application_users.to_json))
98
98
  end
99
99
 
100
- # Retrieves information about groups that have been
101
- # recently updated.
102
- # Results are limited to groups that users of the current app
103
- # have access to.
104
- # Takes an options hash.
105
- # On failure, throws an Exception, just like the request method.
106
- # On success, returns an OAuth2::Response object.
107
- def self.get_application_group_updates(options = {})
108
- request(:get, 'application_groups/updates', options)
109
- end
110
-
111
- # Marks group updates as "read".
112
- # The application_groups parameter is an array of hashes.
113
- # Each hash has 2 required fields: 'id', which should contain the
114
- # application_group's id, and 'read_updates', which should contain
115
- # the last received value of unread_updates for that application_group.
116
- # Can only be called for application_groups that belong to the current app.
117
- # Also takes an options hash.
118
- # On failure, throws an Exception, just like the request method.
119
- # On success, returns an OAuth2::Response object.
120
- def self.mark_group_updates_as_read(application_groups, options = {})
121
- request(:put, 'application_groups/updated', options.merge(
122
- body: application_groups.to_json
123
- ))
124
- end
125
-
126
- # Creates a group in the Accounts server.
127
- # The given account will be the owner of the group.
128
- # Also takes an options hash.
129
- # On failure, throws an Exception, just like the request method.
130
- # On success, returns a hash containing the group attributes
131
- def self.create_group(account, group, options = {})
132
- response = ActiveSupport::JSON.decode(
133
- request_for_account(account, :post, 'groups', options.merge(
134
- body: group.attributes.slice('name', 'is_public').to_json
135
- )).body
136
- )
137
- group.openstax_uid = response['id']
138
- response
139
- end
140
-
141
- # Updates a group in the Accounts server.
142
- # The given account must own the group.
143
- # Also takes an options hash.
144
- # On failure, throws an Exception, just like the request method.
145
- # On success, returns an OAuth2::Response object.
146
- def self.update_group(account, group, options = {})
147
- request_for_account(account, :put, "groups/#{group.openstax_uid}",
148
- options.merge(
149
- body: group.attributes.slice('name', 'is_public').to_json
150
- )
151
- )
152
- end
153
-
154
- # Deletes a group from the Accounts server.
155
- # The given account must own the group.
156
- # Also takes an options hash.
157
- # On failure, throws an Exception, just like the request method.
158
- # On success, returns an OAuth2::Response object.
159
- def self.destroy_group(account, group, options = {})
160
- request_for_account(account, :delete, "groups/#{group.openstax_uid}", options)
161
- end
162
-
163
- # Creates a group_member in the Accounts server.
164
- # The given account must own the group.
165
- # Also takes an options hash.
166
- # On failure, throws an Exception, just like the request method.
167
- # On success, returns an OAuth2::Response object.
168
- def self.create_group_member(account, group_member, options = {})
169
- request_for_account(
170
- account,
171
- :post,
172
- "groups/#{group_member.group_id}/members/#{group_member.user_id}",
173
- options
174
- )
175
- end
176
-
177
- # Deletes a group_member from the Accounts server.
178
- # The given account must own the group.
179
- # Also takes an options hash.
180
- # On failure, throws an Exception, just like the request method.
181
- # On success, returns an OAuth2::Response object.
182
- def self.destroy_group_member(account, group_member, options = {})
183
- request_for_account(
184
- account,
185
- :delete,
186
- "groups/#{group_member.group_id}/members/#{group_member.user_id}",
187
- options
188
- )
189
- end
190
-
191
- # Creates a group_owner in the Accounts server.
192
- # The given account must own the group.
193
- # Also takes an options hash.
194
- # On failure, throws an Exception, just like the request method.
195
- # On success, returns an OAuth2::Response object.
196
- def self.create_group_owner(account, group_owner, options = {})
197
- request_for_account(
198
- account,
199
- :post,
200
- "groups/#{group_owner.group_id}/owners/#{group_owner.user_id}",
201
- options
202
- )
203
- end
204
-
205
- # Deletes a group_owner from the Accounts server.
206
- # The given account must own the group.
207
- # Also takes an options hash.
208
- # On failure, throws an Exception, just like the request method.
209
- # On success, returns an OAuth2::Response object.
210
- def self.destroy_group_owner(account, group_owner, options = {})
211
- request_for_account(
212
- account,
213
- :delete,
214
- "groups/#{group_owner.group_id}/owners/#{group_owner.user_id}",
215
- options
216
- )
217
- end
218
-
219
- # Creates a group_nesting in the Accounts server.
220
- # The given account must own both groups.
221
- # Also takes an an options hash.
222
- # On failure, throws an Exception, just like the request method.
223
- # On success, returns an OAuth2::Response object.
224
- def self.create_group_nesting(account, group_nesting, options = {})
225
- request_for_account(
226
- account,
227
- :post,
228
- "groups/#{group_nesting.container_group_id}/nestings/#{
229
- group_nesting.member_group_id}",
230
- options
231
- )
232
- end
233
-
234
- # Deletes a group_nesting from the Accounts server.
235
- # The given account must own either group.
236
- # Also takes an options hash.
237
- # On failure, throws an Exception, just like the request method.
238
- # On success, returns an OAuth2::Response object.
239
- def self.destroy_group_nesting(account, group_nesting, options = {})
240
- request_for_account(
241
- account,
242
- :delete,
243
- "groups/#{group_nesting.container_group_id}/nestings/#{
244
- group_nesting.member_group_id}",
245
- options
246
- )
247
- end
248
-
249
100
  # Finds an account matching the provided attributes or creates a new
250
101
  # account. Also takes an options hash.
251
102
  # On failure, throws an Exception, just like the request method.