Skip to content

Commit

Permalink
[spaceship] add update method to ConnectAPI::User
Browse files Browse the repository at this point in the history
  • Loading branch information
nekrich committed Jan 13, 2023
1 parent 19ab9fa commit e830684
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 2 deletions.
24 changes: 24 additions & 0 deletions spaceship/lib/spaceship/connect_api/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,30 @@ def self.find(client: nil, email: nil, includes: ESSENTIAL_INCLUDES)
return all(client: client, filter: { email: email }, includes: includes)
end

# @param client [ConnectAPI] ConnectAPI client.
# @param all_apps_visible [Boolean] If all apps must be visible to a user. true - if a user must see all apps, you must not provide visible_app_ids, `false` - a user must see only a limited list of apps, and you must provide visible_app_ids. nil if no change is needed.
# @param provisioning_allowed [Bool] If a user with a Developer or App Manager role must have access to Certificates, Identifiers & Profiles. true - if a user must be able to create new certificates and provisioning profiles, `false` - otherwise. nil if no change is needed.
# @param roles [Array] Array of strings describing user roles. Possible values: https://developer.apple.com/documentation/appstoreconnectapi/userrole.nil if no change is needed.
# @param visible_app_ids [Array] Array of strings with application identifiers user needs have access to. nil if no apps change is needed or user must have access to all apps.
# @return (User) Modified user.
def update(client: nil, all_apps_visible: nil, provisioning_allowed: nil, roles: nil, visible_app_ids: nil)
client ||= Spaceship::ConnectAPI

all_apps_visible = all_apps_visible.nil? ? self.all_apps_visible : all_apps_visible
provisioning_allowed = provisioning_allowed.nil? ? self.provisioning_allowed : provisioning_allowed
roles ||= self.roles
visible_app_ids ||= self.visible_apps.map(&:id)

resp = client.patch_user(
user_id: self.id,
all_apps_visible: all_apps_visible,
provisioning_allowed: provisioning_allowed,
roles: roles,
visible_app_ids: visible_app_ids
)
return resp.to_models.first
end

def delete!(client: nil)
client ||= Spaceship::ConnectAPI
client.delete_user(user_id: id)
Expand Down
4 changes: 2 additions & 2 deletions spaceship/lib/spaceship/connect_api/models/user_invitation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def self.find(client: nil, email: nil, includes: ESSENTIAL_INCLUDES)
# Create and post user invitation
# App Store Connect allows for the following combinations of `all_apps_visible` and `visible_app_ids`:
# - if `all_apps_visible` is `nil`, you don't have to provide values for `visible_app_ids`
# - if `all_apps_visible` is true, you must provide values for `visible_app_ids`.
# - if `all_apps_visible` is false, you must not provide values for `visible_app_ids`.
# - if `all_apps_visible` is false, you must provide values for `visible_app_ids`.
# - if `all_apps_visible` is true, you must not provide values for `visible_app_ids`.
def self.create(client: nil, email: nil, first_name: nil, last_name: nil, roles: [], provisioning_allowed: nil, all_apps_visible: nil, visible_app_ids: [])
client ||= Spaceship::ConnectAPI
resp = client.post_user_invitation(
Expand Down
34 changes: 34 additions & 0 deletions spaceship/lib/spaceship/connect_api/users/users.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,36 @@ def delete_user(user_id: nil)
users_request_client.delete("users/#{user_id}")
end

# Update existing user
def patch_user(user_id:, all_apps_visible:, provisioning_allowed:, roles:, visible_app_ids:)
body = {
data: {
type: 'users',
id: user_id,
attributes: {
allAppsVisible: all_apps_visible,
provisioningAllowed: provisioning_allowed,
roles: roles
},
relationships: {
visibleApps: {
data: visible_app_ids.map do |app_id|
{
type: "apps",
id: app_id
}
end
}
}
}
}

# Avoid API error: You cannot set visible apps for this user because the user's roles give them access to all apps.
body[:data].delete(:relationships) if all_apps_visible

users_request_client.patch("users/#{user_id}", body)
end

# Add app permissions for user
# @deprecated Use {#post_user_visible_apps} instead.
def add_user_visible_apps(user_id: nil, app_ids: nil)
Expand Down Expand Up @@ -116,6 +146,10 @@ def post_user_invitation(email: nil, first_name: nil, last_name: nil, roles: [],
}
}
}

# Avoid API error: You cannot set visible apps for this user because the user's roles give them access to all apps.
body[:data].delete(:relationships) if all_apps_visible

users_request_client.post("userInvitations", body)
end

Expand Down
52 changes: 52 additions & 0 deletions spaceship/spec/connect_api/users/user_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,58 @@ def test_request(url)
end
end

context 'patch_user' do
let(:user_id) { "123" }
let(:all_apps_visible) { false }
let(:provisioning_allowed) { true }
let(:roles) { ["ADMIN"] }
let(:path) { "users/#{user_id}" }
let(:app_ids) { ["456", "789"] }
let(:body) do
{
data: {
type: 'users',
id: user_id,
attributes: {
allAppsVisible: all_apps_visible,
provisioningAllowed: provisioning_allowed,
roles: roles
},
relationships: {
visibleApps: {
data: app_ids.map do |app_id|
{
type: "apps",
id: app_id
}
end
}
}
}
}
end

it 'succeeds_with_list_of_apps' do
url = path
req_mock = test_request_body(url, body)

expect(client).to receive(:request).with(:patch).and_yield(req_mock).and_return(req_mock)
client.patch_user(user_id: user_id, all_apps_visible: all_apps_visible, provisioning_allowed: provisioning_allowed, roles: roles, visible_app_ids: app_ids)
end

it 'succeeds_with_all_apps' do
body_all_apps = body.clone
body_all_apps[:data][:attributes][:allAppsVisible] = true
body_all_apps[:data].delete(:relationships)

url = path
req_mock = test_request_body(url, body_all_apps)

expect(client).to receive(:request).with(:patch).and_yield(req_mock).and_return(req_mock)
client.patch_user(user_id: user_id, all_apps_visible: true, provisioning_allowed: provisioning_allowed, roles: roles, visible_app_ids: app_ids)
end
end

context 'delete_user' do
let(:user_id) { "123" }
let(:path) { "users/#{user_id}" }
Expand Down

0 comments on commit e830684

Please sign in to comment.