# encoding: utf-8
module PassaporteWeb
# Represents the membership of an Identity within a ServiceAccount on PassaporteWeb.
class ServiceAccountMember
attr_accessor :roles
attr_reader :service_account, :identity
attr_reader :errors
# Instanciates a new ServiceAccountMember to represent the membership of the supplied Identity in
# the supplied ServiceAccount. The roles attribute should be an array of strings. Any
# value is accepted, only 'owner' is reserved. By default uses only the value of 'user'.
def initialize(service_account, identity, roles=['user'])
@service_account = service_account
@identity = identity
@roles = roles
@membership_details_url = nil
@errors = {}
end
# Finds the membership relation between the supplied Identity in the supplied ServiceAccount and returns
# an instance of ServiceAccountMember representing it.
#
# Raises a RestClient::ResourceNotFound exception if the supplied Identity does not have a
# membership within the supplied ServiceAccount, or if any of the supplied objects is invalid or
# not existent.
#
# API method: GET /organizations/api/accounts/:uuid/members/:member_uuid/
#
# API documentation: https://app.passaporteweb.com.br/static/docs/account_manager.html#get-organizations-api-accounts-uuid-members-member-uuid
def self.find(service_account, identity)
response = Http.get("/organizations/api/accounts/#{service_account.uuid}/members/#{identity.uuid}/")
raise "unexpected response: #{response.code} - #{response.body}" unless response.code == 200
attributes_hash = MultiJson.decode(response.body)
member = self.new(service_account, identity, attributes_hash['roles'])
member.instance_variable_set(:@persisted, true)
member.instance_variable_set(:@destroyed, false)
member
end
# Returns true if the ServiceAccountMember was loaded from PassaporteWeb or saved there successfully.
def persisted?
@persisted == true
end
# Returns true if the ServiceAccountMember object has been destroyed (and thus represents a membership
# no more valid on PassaporteWeb)
def destroyed?
@destroyed == true
end
def membership_details_url # :nodoc:
return @membership_details_url if @membership_details_url
"/organizations/api/accounts/#{self.service_account.uuid}/members/#{self.identity.uuid}/" if persisted?
end
# Creates or updates the ServiceAccountMember object on PassaporteWeb. Returns true if successful and false
# (along with the reason for failure in the #errors method) otherwise.
#
# On update, the only attribute that can be changed is the roles. This can be set to anything,
# including 'owner', on update (on create, the 'owner' role is not allowed.)
#
# API methods:
# * POST /organizations/api/accounts/:uuid/members/ (on create)
# * PUT /organizations/api/accounts/:uuid/members/:member_uuid/ (on update)
#
# API documentation:
# * https://app.passaporteweb.com.br/static/docs/account_manager.html#post-organizations-api-accounts-uuid-members
# * https://app.passaporteweb.com.br/static/docs/account_manager.html#put-organizations-api-accounts-uuid-members-member-uuid
def save
self.persisted? ? update : create
end
# Destroys the membership relation between a Identity and a ServiceAccount, e.g. the Identity no longer will be a
# member of the ServiceAccount. Returns true if successful of false (along with the reason for failure in the #errors
# method) otherwise.
#
# If the member has a 'owner' role, than the membership can not be destroyed.
#
# API method: DELETE /organizations/api/accounts/:uuid/members/:member_uuid/
#
# API documentation: https://app.passaporteweb.com.br/static/docs/account_manager.html#delete-organizations-api-accounts-uuid-members-member-uuid
def destroy
return false unless self.persisted?
response = Http.delete(self.membership_details_url)
raise "unexpected response: #{response.code} - #{response.body}" unless response.code == 204
@errors = {}
@persisted = false
@destroyed = true
true
rescue *[RestClient::NotAcceptable] => e
@errors = MultiJson.decode(e.response.body)
@persisted = true
@destroyed = false
false
end
private
def create
response = Http.post(
"/organizations/api/accounts/#{self.service_account.uuid}/members/",
{identity: self.identity.uuid, roles: self.roles}
)
raise "unexpected response: #{response.code} - #{response.body}" unless [200,201].include?(response.code)
attributes_hash = MultiJson.decode(response.body)
@membership_details_url = attributes_hash['membership_details_url']
@errors = {}
@persisted = true
true
rescue *[RestClient::Conflict, RestClient::BadRequest, RestClient::NotAcceptable] => e
@errors = MultiJson.decode(e.response.body)
@persisted = false
false
end
def update
response = Http.put(
self.membership_details_url,
{roles: self.roles}
)
raise "unexpected response: #{response.code} - #{response.body}" unless response.code == 200
attributes_hash = MultiJson.decode(response.body)
@errors = {}
@persisted = true
true
rescue *[RestClient::BadRequest, RestClient::NotAcceptable] => e
@errors = MultiJson.decode(e.response.body)
@persisted = true
false
end
end
end