passaporteweb-client 0.0.10
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.
- data/.coveralls.yml +1 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +72 -0
- data/LICENSE +202 -0
- data/README.rdoc +127 -0
- data/Rakefile +16 -0
- data/lib/passaporte_web.rb +26 -0
- data/lib/passaporte_web/attributable.rb +17 -0
- data/lib/passaporte_web/configuration.rb +41 -0
- data/lib/passaporte_web/helpers.rb +67 -0
- data/lib/passaporte_web/http.rb +70 -0
- data/lib/passaporte_web/identity.rb +216 -0
- data/lib/passaporte_web/identity_service_account.rb +91 -0
- data/lib/passaporte_web/service_account.rb +118 -0
- data/lib/passaporte_web/service_account_member.rb +136 -0
- data/lib/passaporte_web/version.rb +4 -0
- data/passaporteweb-client.gemspec +40 -0
- data/spec/passaporte_web/configuration_spec.rb +55 -0
- data/spec/passaporte_web/helpers_spec.rb +34 -0
- data/spec/passaporte_web/http_spec.rb +114 -0
- data/spec/passaporte_web/identity_service_account_spec.rb +136 -0
- data/spec/passaporte_web/identity_spec.rb +290 -0
- data/spec/passaporte_web/service_account_member_spec.rb +150 -0
- data/spec/passaporte_web/service_account_spec.rb +163 -0
- data/spec/passaporte_web_spec.rb +32 -0
- data/spec/spec_helper.rb +37 -0
- metadata +302 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rest_client'
|
4
|
+
require 'multi_json'
|
5
|
+
|
6
|
+
require "passaporte_web/version"
|
7
|
+
require "passaporte_web/configuration"
|
8
|
+
require "passaporte_web/http"
|
9
|
+
require "passaporte_web/helpers"
|
10
|
+
require "passaporte_web/attributable"
|
11
|
+
require "passaporte_web/identity"
|
12
|
+
require "passaporte_web/service_account"
|
13
|
+
require "passaporte_web/service_account_member"
|
14
|
+
require "passaporte_web/identity_service_account"
|
15
|
+
|
16
|
+
module PassaporteWeb
|
17
|
+
|
18
|
+
def self.configuration
|
19
|
+
@configuration ||= Configuration.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.configure
|
23
|
+
yield(configuration) if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module PassaporteWeb
|
3
|
+
|
4
|
+
module Attributable
|
5
|
+
|
6
|
+
def set_attributes(hash)
|
7
|
+
self.class::ATTRIBUTES.each do |attribute|
|
8
|
+
value = hash[attribute.to_s] if hash.has_key?(attribute.to_s)
|
9
|
+
value = hash[attribute.to_sym] if hash.has_key?(attribute.to_sym)
|
10
|
+
instance_variable_set("@#{attribute}".to_sym, value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
private :set_attributes
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'base64'
|
3
|
+
module PassaporteWeb
|
4
|
+
|
5
|
+
class Configuration
|
6
|
+
attr_accessor :url, :user_agent, :application_token, :application_secret, :user_token
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@url = 'https://app.passaporteweb.com.br'
|
10
|
+
@user_agent = "PassaporteWeb Ruby Client v#{PassaporteWeb::VERSION}"
|
11
|
+
@application_token = nil
|
12
|
+
@application_secret = nil
|
13
|
+
@user_token = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def application_credentials
|
17
|
+
check_tokens! :application_token, :application_secret
|
18
|
+
base64_credential('application', @application_token, @application_secret)
|
19
|
+
end
|
20
|
+
|
21
|
+
def user_credentials
|
22
|
+
check_tokens! :user_token
|
23
|
+
base64_credential('user', @user_token)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def check_tokens!(*tokens)
|
29
|
+
tokens.each do |token|
|
30
|
+
value = instance_variable_get("@#{token}".to_sym)
|
31
|
+
raise ArgumentError, "#{token} not set" if value.nil? || value.to_s.strip == ''
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def base64_credential(type, user, password=nil)
|
36
|
+
return "Basic #{::Base64.strict_encode64("#{user}:#{password}")}" if type.eql? 'application'
|
37
|
+
return "Basic #{::Base64.strict_encode64(":#{user}")}" if type.eql? 'user'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ostruct'
|
3
|
+
module PassaporteWeb
|
4
|
+
|
5
|
+
class Helpers
|
6
|
+
|
7
|
+
# Converts pagination information from a Link header in a HTTP response to a Hash
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# link_header = "<http://sandbox.app.passaporteweb.com.br/organizations/api/accounts/?page=3&limit=3>; rel=next, <http://sandbox.app.passaporteweb.com.br/organizations/api/accounts/?page=1&limit=3>; rel=prev, <http://sandbox.app.passaporteweb.com.br/organizations/api/accounts/?page=5&limit=3>; rel=last, <http://sandbox.app.passaporteweb.com.br/organizations/api/accounts/?page=1&limit=3>; rel=first"
|
11
|
+
# PassaporteWeb::Helpers.meta_links_from_header(link_header)
|
12
|
+
# => {limit: 3, next_page: 3, prev_page: 1, first_page: 1, last_page: 5}
|
13
|
+
def self.meta_links_from_header(link_header)
|
14
|
+
hash = {limit: nil, next_page: nil, prev_page: nil, first_page: nil, last_page: nil}
|
15
|
+
links = link_header.split(',').map(&:strip)
|
16
|
+
|
17
|
+
if link_header.match(/limit\=([0-9]+)/)
|
18
|
+
hash[:limit] = Integer($1)
|
19
|
+
end
|
20
|
+
|
21
|
+
links.each do |link|
|
22
|
+
if link.match(/page\=([0-9]+).*rel\=([a-z]+)/)
|
23
|
+
case $2
|
24
|
+
when 'next'
|
25
|
+
hash[:next_page] = Integer($1)
|
26
|
+
when 'prev'
|
27
|
+
hash[:prev_page] = Integer($1)
|
28
|
+
when 'first'
|
29
|
+
hash[:first_page] = Integer($1)
|
30
|
+
when 'last'
|
31
|
+
hash[:last_page] = Integer($1)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
|
39
|
+
# Converts a Hash recursevely to a OpenStruct object.
|
40
|
+
#
|
41
|
+
# Example:
|
42
|
+
# hash = {a: 1, b: {c: 3, d: 4, e: {f: 6, g: 7}}}
|
43
|
+
# os = PassaporteWeb::Helpers.convert_to_ostruct_recursive(hash)
|
44
|
+
# os.a # => 1
|
45
|
+
# os.b # => {c: 3, d: 4, e: {f: 6, g: 7}}
|
46
|
+
# os.b.c # => 3
|
47
|
+
# os.b.d # => 4
|
48
|
+
# os.b.e # => {f: 6, g: 7}
|
49
|
+
# os.b.e.f # => 6
|
50
|
+
# os.b.e.g # => 7
|
51
|
+
def self.convert_to_ostruct_recursive(obj, options={})
|
52
|
+
result = obj
|
53
|
+
if result.is_a? Hash
|
54
|
+
result = result.dup
|
55
|
+
result.each do |key, val|
|
56
|
+
result[key] = convert_to_ostruct_recursive(val, options) unless (!options[:exclude].nil? && options[:exclude].include?(key))
|
57
|
+
end
|
58
|
+
result = OpenStruct.new result
|
59
|
+
elsif result.is_a? Array
|
60
|
+
result = result.map { |r| convert_to_ostruct_recursive(r, options) }
|
61
|
+
end
|
62
|
+
return result
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'base64'
|
3
|
+
module PassaporteWeb
|
4
|
+
|
5
|
+
class Http # :nodoc:
|
6
|
+
|
7
|
+
def self.get(path='/', params={}, type='application')
|
8
|
+
get_or_delete(:get, path, params, type)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.put(path='/', body={}, params={}, type='application')
|
12
|
+
put_or_post(:put, path, body, params, type)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.post(path='/', body={}, params={}, type='application')
|
16
|
+
put_or_post(:post, path, body, params, type)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.delete(path='/', params={}, type='application')
|
20
|
+
get_or_delete(:delete, path, params, type)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.custom_auth_get(user, password, path='/', params={})
|
24
|
+
credentials = "Basic #{::Base64.strict_encode64("#{user}:#{password}")}"
|
25
|
+
custom_params = common_params('application').merge({authorization: credentials})
|
26
|
+
RestClient.get(
|
27
|
+
pw_url(path),
|
28
|
+
{params: params}.merge(custom_params)
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def self.put_or_post(method, path, body, params, type)
|
35
|
+
RestClient.send(
|
36
|
+
method,
|
37
|
+
pw_url(path),
|
38
|
+
encoded_body(body),
|
39
|
+
{params: params}.merge(common_params(type))
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.get_or_delete(method, path, params, type)
|
44
|
+
RestClient.send(
|
45
|
+
method,
|
46
|
+
pw_url(path),
|
47
|
+
{params: params}.merge(common_params(type))
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.pw_url(path)
|
52
|
+
"#{PassaporteWeb.configuration.url}#{path}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.common_params(type)
|
56
|
+
{
|
57
|
+
authorization: (type == 'application' ? PassaporteWeb.configuration.application_credentials : PassaporteWeb.configuration.user_credentials),
|
58
|
+
content_type: :json,
|
59
|
+
accept: :json,
|
60
|
+
user_agent: PassaporteWeb.configuration.user_agent
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.encoded_body(body)
|
65
|
+
body.is_a?(Hash) ? MultiJson.encode(body) : body
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,216 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module PassaporteWeb
|
3
|
+
|
4
|
+
# Represents an Identity on PassaporteWeb, i.e. a person. When you sign up for PassaporteWeb, your 'account'
|
5
|
+
# there is an Identity.
|
6
|
+
class Identity
|
7
|
+
include Attributable
|
8
|
+
|
9
|
+
ATTRIBUTES = [:accounts, :birth_date, :country, :cpf, :email, :first_name, :gender, :is_active, :language, :last_name, :nickname, :notifications, :send_myfreecomm_news, :send_partner_news, :services, :timezone, :update_info_url, :uuid, :password, :password2, :must_change_password, :inhibit_activation_message, :tos]
|
10
|
+
UPDATABLE_ATTRIBUTES = [:first_name, :last_name, :nickname, :cpf, :birth_date, :gender, :send_myfreecomm_news, :send_partner_news, :country, :language, :timezone]
|
11
|
+
CREATABLE_ATTRIBUTES = *(UPDATABLE_ATTRIBUTES + [:email, :password, :password2, :must_change_password, :tos])
|
12
|
+
|
13
|
+
attr_accessor *UPDATABLE_ATTRIBUTES
|
14
|
+
attr_reader *(ATTRIBUTES - UPDATABLE_ATTRIBUTES)
|
15
|
+
attr_reader :errors
|
16
|
+
|
17
|
+
# Finds an Identity by it's UUID. Returns the Identity instance with all fields set if successful.
|
18
|
+
# Raises a <tt>RestClient::ResourceNotFound</tt> exception if no Identity exists with the supplied
|
19
|
+
# UUID.
|
20
|
+
#
|
21
|
+
# If <tt>include_expired_accounts</tt> is passed as <tt>true</tt>, brings information about all
|
22
|
+
# accounts the Identity is related, regardless of the account's expiration date.
|
23
|
+
#
|
24
|
+
# If <tt>include_other_services</tt> is passed as <tt>true</tt>, brings information about accounts
|
25
|
+
# of all services the Identity is related to (not just the current logged in service / application).
|
26
|
+
#
|
27
|
+
# API method: <tt>/accounts/api/identities/:uuid/</tt>
|
28
|
+
#
|
29
|
+
# API documentation: https://app.passaporteweb.com.br/static/docs/usuarios.html#get-accounts-api-identities-uuid
|
30
|
+
def self.find(uuid, include_expired_accounts=false, include_other_services=false)
|
31
|
+
response = Http.get(
|
32
|
+
"/accounts/api/identities/#{uuid}/",
|
33
|
+
{include_expired_accounts: include_expired_accounts, include_other_services: include_other_services}
|
34
|
+
)
|
35
|
+
attributes_hash = MultiJson.decode(response.body)
|
36
|
+
load_identity(attributes_hash)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Finds an Identity by it's email (emails are unique on PassaporteWeb). Returns the Identity instance
|
40
|
+
# with all fields set if successful. Raises a <tt>RestClient::ResourceNotFound</tt> exception if no
|
41
|
+
# Identity exists with the supplied email.
|
42
|
+
#
|
43
|
+
# If <tt>include_expired_accounts</tt> is passed as <tt>true</tt>, brings information about all
|
44
|
+
# accounts the Identity is related, regardless of the account's expiration date.
|
45
|
+
#
|
46
|
+
# If <tt>include_other_services</tt> is passed as <tt>true</tt>, brings information about accounts
|
47
|
+
# of all services the Identity is related to (not just the current logged in service / application).
|
48
|
+
#
|
49
|
+
# API method: <tt>GET /accounts/api/identities/?email=:email</tt>
|
50
|
+
#
|
51
|
+
# API documentation: https://app.passaporteweb.com.br/static/docs/usuarios.html#get-accounts-api-identities-email-email
|
52
|
+
def self.find_by_email(email, include_expired_accounts=false, include_other_services=false)
|
53
|
+
response = Http.get(
|
54
|
+
"/accounts/api/identities/",
|
55
|
+
{email: email, include_expired_accounts: include_expired_accounts, include_other_services: include_other_services}
|
56
|
+
)
|
57
|
+
attributes_hash = MultiJson.decode(response.body)
|
58
|
+
load_identity(attributes_hash)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Checks if an Identity exists on PassaporteWeb and if the password is correct. Returns an instance of
|
62
|
+
# Identity for the supplied email if the password is correct (although with only basic attributes set).
|
63
|
+
# Returns <tt>false</tt> if the password is wrong or if no Identity exists on PassaporteWeb with
|
64
|
+
# the supplied email. Use it to validate that a user is who he says he is.
|
65
|
+
#
|
66
|
+
# API method: <tt>GET /accounts/api/auth/</tt>
|
67
|
+
#
|
68
|
+
# API documentation: https://app.passaporteweb.com.br/static/docs/usuarios.html#get-accounts-api-auth
|
69
|
+
def self.authenticate(email, password)
|
70
|
+
response = Http.custom_auth_get(
|
71
|
+
email,
|
72
|
+
password,
|
73
|
+
"/accounts/api/auth/"
|
74
|
+
)
|
75
|
+
raise "unexpected response: #{response.code} - #{response.body}" unless response.code == 200
|
76
|
+
attributes_hash = MultiJson.decode(response.body)
|
77
|
+
load_identity(attributes_hash)
|
78
|
+
rescue *[RestClient::Unauthorized] => e
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
# Checks if the supplied password is correct for the current Identity. Returns <tt>true</tt> if the
|
83
|
+
# password matches or <tt>false</tt> if the password is wrong. Use it to validate that a user is who
|
84
|
+
# he says he is.
|
85
|
+
#
|
86
|
+
# API method: <tt>GET /accounts/api/auth/</tt>
|
87
|
+
#
|
88
|
+
# API documentation: https://app.passaporteweb.com.br/static/docs/usuarios.html#get-accounts-api-auth
|
89
|
+
def authenticate(password)
|
90
|
+
raise ArgumentError, "email must be set" if (self.email.nil? || self.email.to_s.empty?)
|
91
|
+
response = Http.custom_auth_get(
|
92
|
+
self.email,
|
93
|
+
password,
|
94
|
+
"/accounts/api/auth/"
|
95
|
+
)
|
96
|
+
raise "unexpected response: #{response.code} - #{response.body}" unless response.code == 200
|
97
|
+
true
|
98
|
+
rescue *[RestClient::Unauthorized] => e
|
99
|
+
false
|
100
|
+
end
|
101
|
+
|
102
|
+
# Instanciates a new Identity with the supplied attributes. Only the attributes listed
|
103
|
+
# on <tt>Identity::CREATABLE_ATTRIBUTES</tt> are used when creating an Identity and
|
104
|
+
# on <tt>Identity::UPDATABLE_ATTRIBUTES</tt> are used when updating an Identity.
|
105
|
+
#
|
106
|
+
# Example:
|
107
|
+
#
|
108
|
+
# identity = PassaporteWeb::Identity.new(
|
109
|
+
# email: 'fulano@detal.com.br',
|
110
|
+
# password: '123456',
|
111
|
+
# password2: '123456',
|
112
|
+
# must_change_password: false,
|
113
|
+
# tos: true,
|
114
|
+
# first_name: 'Fulano',
|
115
|
+
# last_name: 'de Tal',
|
116
|
+
# nickname: 'Fulaninho',
|
117
|
+
# cpf: '342.766.570-40',
|
118
|
+
# birth_date: '1983-04-19',
|
119
|
+
# gender: 'M',
|
120
|
+
# send_myfreecomm_news: true,
|
121
|
+
# send_partner_news: false,
|
122
|
+
# country: 'Brasil',
|
123
|
+
# language: 'pt_BR',
|
124
|
+
# timezone: 'GMT-3'
|
125
|
+
# )
|
126
|
+
def initialize(attributes={})
|
127
|
+
set_attributes(attributes)
|
128
|
+
@errors = {}
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns a hash with all attribures of the identity.
|
132
|
+
def attributes
|
133
|
+
ATTRIBUTES.inject({}) do |hash, attribute|
|
134
|
+
hash[attribute] = self.send(attribute)
|
135
|
+
hash
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Compares one Identity with another, returns true if they have the same UUID.
|
140
|
+
def ==(other)
|
141
|
+
self.uuid == other.uuid
|
142
|
+
end
|
143
|
+
|
144
|
+
# Returns true if both Identity are the same object.
|
145
|
+
def ===(other)
|
146
|
+
self.object_id == other.object_id
|
147
|
+
end
|
148
|
+
|
149
|
+
# Saves the Identity on PassaporteWeb, creating it if new or updating it if existing. Returns true
|
150
|
+
# if successfull or false if not. In case of failure, it will fill the <tt>errors</tt> attribute
|
151
|
+
# with the reason for the failure to save the object.
|
152
|
+
#
|
153
|
+
# The attributes <tt>first_name</tt>, <tt>last_name</tt>, <tt>cpf</tt> and <tt>inhibit_activation_message</tt>
|
154
|
+
# are optional. <tt>password2</tt> and <tt>password</tt> fields are required even if the parameter
|
155
|
+
# <tt>must_change_password</tt> is used.
|
156
|
+
#
|
157
|
+
# API methods:
|
158
|
+
# * <tt>POST /accounts/api/create/</tt> (on create)
|
159
|
+
# * <tt>PUT /accounts/api/identities/:uuid/</tt> (on update)
|
160
|
+
#
|
161
|
+
# API documentation:
|
162
|
+
# * https://app.passaporteweb.com.br/static/docs/usuarios.html#post-accounts-api-create
|
163
|
+
# * https://app.passaporteweb.com.br/static/docs/usuarios.html#get-accounts-api-identities-email-email
|
164
|
+
#
|
165
|
+
# Example:
|
166
|
+
#
|
167
|
+
# identity = Identity.find_by_email('foo@bar.com')
|
168
|
+
# identity.save # => true
|
169
|
+
# identity.cpf = '12'
|
170
|
+
# identity.save # => false
|
171
|
+
# identity.errors # => {"cpf" => ["Certifique-se de que o valor tenha no mínimo 11 caracteres (ele possui 2)."]}
|
172
|
+
def save
|
173
|
+
# TODO validar atributos?
|
174
|
+
response = (persisted? ? update : create)
|
175
|
+
raise "unexpected response: #{response.code} - #{response.body}" unless response.code == 200
|
176
|
+
attributes_hash = MultiJson.decode(response.body)
|
177
|
+
set_attributes(attributes_hash)
|
178
|
+
@persisted = true
|
179
|
+
@errors = {}
|
180
|
+
true
|
181
|
+
rescue *[RestClient::Conflict, RestClient::BadRequest] => e
|
182
|
+
@errors = MultiJson.decode(e.response.body)
|
183
|
+
false
|
184
|
+
end
|
185
|
+
|
186
|
+
def persisted?
|
187
|
+
!self.uuid.nil? && @persisted == true
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def self.load_identity(attributes)
|
193
|
+
identity = self.new(attributes)
|
194
|
+
identity.instance_variable_set(:@persisted, true)
|
195
|
+
identity
|
196
|
+
end
|
197
|
+
|
198
|
+
def create
|
199
|
+
Http.post("/accounts/api/create/", create_body)
|
200
|
+
end
|
201
|
+
|
202
|
+
def update
|
203
|
+
Http.put("/accounts/api/identities/#{self.uuid}/", update_body)
|
204
|
+
end
|
205
|
+
|
206
|
+
def update_body
|
207
|
+
self.attributes.select { |key, value| UPDATABLE_ATTRIBUTES.include?(key) && !value.nil? }
|
208
|
+
end
|
209
|
+
|
210
|
+
def create_body
|
211
|
+
self.attributes.select { |key, value| CREATABLE_ATTRIBUTES.include?(key) && !value.nil? }
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module PassaporteWeb
|
3
|
+
|
4
|
+
# Also represents a ServiceAccount, but uses diffetent API endpoints to list and create them
|
5
|
+
# from a existing Identity.
|
6
|
+
class IdentityServiceAccount
|
7
|
+
include Attributable
|
8
|
+
|
9
|
+
ATTRIBUTES = [:membership_details_url, :plan_slug, :roles, :url, :expiration, :service_data, :account_data, :add_member_url, :name, :uuid]
|
10
|
+
CREATABLE_ATTRIBUTES = [:plan_slug, :expiration, :name, :uuid]
|
11
|
+
|
12
|
+
attr_accessor *CREATABLE_ATTRIBUTES
|
13
|
+
attr_reader *(ATTRIBUTES - CREATABLE_ATTRIBUTES)
|
14
|
+
attr_reader :identity, :errors
|
15
|
+
|
16
|
+
# Finds all service accounts of the supplied Identity on the current authenticated application.
|
17
|
+
# Returns an array of IdentityServiceAccount.
|
18
|
+
#
|
19
|
+
# API method: <tt>GET /organizations/api/identities/:uuid/accounts/</tt>
|
20
|
+
#
|
21
|
+
# API documentation: https://app.passaporteweb.com.br/static/docs/account_manager.html#get-organizations-api-identities-uuid-accounts
|
22
|
+
def self.find_all(identity, include_expired_accounts=false, role=nil)
|
23
|
+
params = {include_expired_accounts: include_expired_accounts}
|
24
|
+
params[:role] = role unless (role.nil? || role.to_s.empty?)
|
25
|
+
response = Http.get("/organizations/api/identities/#{identity.uuid}/accounts/", params)
|
26
|
+
raw_accounts = MultiJson.decode(response.body)
|
27
|
+
raw_accounts.map { |raw_account| load_identity_service_account(identity, raw_account) }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Instanciates a new ServiceAccount to be created for the supplied Identity on the current
|
31
|
+
# authenticated application. See #save
|
32
|
+
def initialize(identity, attributes={})
|
33
|
+
set_attributes(attributes)
|
34
|
+
@identity = identity
|
35
|
+
@persisted = false
|
36
|
+
@errors = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
# Creates a new ServiceAccount for the supplied Identity on the current authenticated application.
|
40
|
+
# The supplied Identity will be the ServiceAccount's owner. You should supply either the <tt>name</tt>
|
41
|
+
# or the (service account's) <tt>uuid</tt> attribute. If the latter is supplied, the supplied Identity
|
42
|
+
# must already be owner of at least one other ServiceAccount on the same group / organization.
|
43
|
+
#
|
44
|
+
# Returns true in case of success, false otherwise (along with failure reasons on #errors).
|
45
|
+
#
|
46
|
+
# API method: <tt>POST /organizations/api/identities/:uuid/accounts/</tt>
|
47
|
+
#
|
48
|
+
# API documentation: https://app.passaporteweb.com.br/static/docs/account_manager.html#post-organizations-api-identities-uuid-accounts
|
49
|
+
def save
|
50
|
+
# TODO validar atributos?
|
51
|
+
response = Http.post("/organizations/api/identities/#{self.identity.uuid}/accounts/", create_body)
|
52
|
+
raise "unexpected response: #{response.code} - #{response.body}" unless response.code == 201
|
53
|
+
attributes_hash = MultiJson.decode(response.body)
|
54
|
+
set_attributes(attributes_hash)
|
55
|
+
@persisted = true
|
56
|
+
@errors = {}
|
57
|
+
true
|
58
|
+
rescue *[RestClient::BadRequest] => e
|
59
|
+
@persisted = false
|
60
|
+
@errors = MultiJson.decode(e.response.body)
|
61
|
+
false
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns true if the IdentityServiceAccount exists on PassaporteWeb
|
65
|
+
def persisted?
|
66
|
+
@persisted == true
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns a hash with all attribures of the IdentityServiceAccount
|
70
|
+
def attributes
|
71
|
+
ATTRIBUTES.inject({}) do |hash, attribute|
|
72
|
+
hash[attribute] = self.send(attribute)
|
73
|
+
hash
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def create_body
|
80
|
+
self.attributes.select { |key, value| CREATABLE_ATTRIBUTES.include?(key) && !value.nil? }
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.load_identity_service_account(identity, attributes={})
|
84
|
+
isa = self.new(identity, attributes)
|
85
|
+
isa.instance_variable_set(:@persisted, true)
|
86
|
+
isa
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|