passaporteweb-client 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|