code42 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +203 -0
- data/README.md +182 -0
- data/Rakefile +1 -0
- data/code42.gemspec +26 -0
- data/examples/Gemfile +6 -0
- data/examples/computers.rb +88 -0
- data/examples/diagnostic.rb +82 -0
- data/examples/orgs.rb +88 -0
- data/examples/parser.rb +51 -0
- data/examples/parser_test.rb +64 -0
- data/examples/users.rb +88 -0
- data/lib/code42.rb +46 -0
- data/lib/code42/attribute.rb +13 -0
- data/lib/code42/attribute_serializer.rb +129 -0
- data/lib/code42/client.rb +301 -0
- data/lib/code42/computer.rb +15 -0
- data/lib/code42/connection.rb +124 -0
- data/lib/code42/diagnostic.rb +8 -0
- data/lib/code42/error.rb +21 -0
- data/lib/code42/org.rb +38 -0
- data/lib/code42/ping.rb +14 -0
- data/lib/code42/resource.rb +58 -0
- data/lib/code42/role.rb +26 -0
- data/lib/code42/role_collection.rb +35 -0
- data/lib/code42/settings.rb +42 -0
- data/lib/code42/token.rb +31 -0
- data/lib/code42/token_validation.rb +10 -0
- data/lib/code42/user.rb +40 -0
- data/lib/code42/version.rb +3 -0
- data/spec/cassettes/Code42_Client/_create_org/returns_created_org.yml +47 -0
- data/spec/cassettes/Code42_Client/_create_user/returns_created_user.yml +44 -0
- data/spec/cassettes/Code42_Client/_create_user/when_sending_an_invalid_email/raises_an_exception.yml +37 -0
- data/spec/cassettes/Code42_Client/_find_org_by_name/returns_the_org_with_the_specified_name.yml +101 -0
- data/spec/cassettes/Code42_Client/_get_token/returns_valid_tokens.yml +38 -0
- data/spec/cassettes/Code42_Client/_get_token/when_providing_invalid_credentials/should_raise_an_exception.yml +37 -0
- data/spec/cassettes/Code42_Client/_org/when_ID_is_not_passed/returns_my_org.yml +54 -0
- data/spec/cassettes/Code42_Client/_org/when_ID_is_passed_in/returns_a_specific_org.yml +54 -0
- data/spec/cassettes/Code42_Client/_ping/returns_a_ping.yml +48 -0
- data/spec/cassettes/Code42_Client/_user/when_ID_is_not_passed/returns_my_user.yml +53 -0
- data/spec/cassettes/Code42_Client/_user/when_ID_is_passed_in/returns_a_specific_user.yml +53 -0
- data/spec/cassettes/Code42_Client/_user_roles/returns_an_enumerable.yml +50 -0
- data/spec/cassettes/Code42_Client/_validate_token/returns_a_valid_response.yml +83 -0
- data/spec/cassettes/Crashplan_Client/_create_org/returns_created_org.yml +47 -0
- data/spec/cassettes/Crashplan_Client/_create_user/returns_created_user.yml +44 -0
- data/spec/cassettes/Crashplan_Client/_create_user/when_sending_an_invalid_email/raises_an_exception.yml +37 -0
- data/spec/cassettes/Crashplan_Client/_find_org_by_name/returns_the_org_with_the_specified_name.yml +55 -0
- data/spec/cassettes/Crashplan_Client/_get_token/returns_valid_tokens.yml +38 -0
- data/spec/cassettes/Crashplan_Client/_get_token/when_providing_invalid_credentials/should_raise_an_exception.yml +37 -0
- data/spec/cassettes/Crashplan_Client/_org/when_ID_is_not_passed/returns_my_org.yml +54 -0
- data/spec/cassettes/Crashplan_Client/_org/when_ID_is_passed_in/returns_a_specific_org.yml +54 -0
- data/spec/cassettes/Crashplan_Client/_ping/returns_a_ping.yml +48 -0
- data/spec/cassettes/Crashplan_Client/_user/when_ID_is_not_passed/returns_my_user.yml +99 -0
- data/spec/cassettes/Crashplan_Client/_user/when_ID_is_passed_in/returns_a_specific_user.yml +53 -0
- data/spec/cassettes/Crashplan_Client/_user_roles/returns_an_enumerable.yml +50 -0
- data/spec/cassettes/Crashplan_Client/_validate_token/returns_a_valid_response.yml +128 -0
- data/spec/crashplan/client_spec.rb +135 -0
- data/spec/crashplan/connection_spec.rb +45 -0
- data/spec/crashplan/org_spec.rb +63 -0
- data/spec/crashplan/ping_spec.rb +14 -0
- data/spec/crashplan/resource_spec.rb +56 -0
- data/spec/crashplan/role_spec.rb +28 -0
- data/spec/crashplan/settings_spec.rb +118 -0
- data/spec/crashplan/token_spec.rb +33 -0
- data/spec/crashplan/user_spec.rb +21 -0
- data/spec/fixtures/auth/bad_password.json +1 -0
- data/spec/fixtures/authToken.json +10 -0
- data/spec/fixtures/org.1.json +36 -0
- data/spec/fixtures/org.create.json +36 -0
- data/spec/fixtures/org.my.json +36 -0
- data/spec/fixtures/ping.json +7 -0
- data/spec/fixtures/user.1.json +27 -0
- data/spec/fixtures/user.create.json +27 -0
- data/spec/fixtures/user.my.json +27 -0
- data/spec/fixtures/user_roles.json +32 -0
- data/spec/fixtures/validate_token.json +10 -0
- data/spec/spec_helper.rb +67 -0
- metadata +268 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require 'logger'
|
4
|
+
require 'code42/error'
|
5
|
+
|
6
|
+
module Code42
|
7
|
+
class Connection
|
8
|
+
attr_accessor :host, :port, :scheme, :path_prefix, :username, :password, :adapter, :token, :verify_https, :logger
|
9
|
+
def initialize(options = {})
|
10
|
+
self.host = options[:host]
|
11
|
+
self.port = options[:port]
|
12
|
+
self.scheme = options[:scheme]
|
13
|
+
self.path_prefix = options[:path_prefix]
|
14
|
+
self.username = options[:username]
|
15
|
+
self.password = options[:password]
|
16
|
+
self.token = options[:token] if options[:token]
|
17
|
+
self.verify_https = !options[:verify_https].nil? ? options[:verify_https] : true
|
18
|
+
|
19
|
+
adapter.host = host
|
20
|
+
adapter.port = port
|
21
|
+
adapter.scheme = scheme
|
22
|
+
adapter.path_prefix = path_prefix
|
23
|
+
adapter.ssl[:verify] = verify_https
|
24
|
+
end
|
25
|
+
|
26
|
+
def logger
|
27
|
+
@logger ||= Logger.new(STDOUT)
|
28
|
+
end
|
29
|
+
|
30
|
+
def adapter
|
31
|
+
if !@adapter
|
32
|
+
@adapter = Faraday.new
|
33
|
+
@adapter.response :json
|
34
|
+
end
|
35
|
+
@adapter
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_valid_credentials?
|
39
|
+
username && password
|
40
|
+
end
|
41
|
+
|
42
|
+
def token=(token)
|
43
|
+
@token = token
|
44
|
+
adapter.headers['Authorization-Challenge'] = "false"
|
45
|
+
adapter.headers['Authorization'] = "TOKEN #{token}"
|
46
|
+
@token
|
47
|
+
end
|
48
|
+
|
49
|
+
def username=(username)
|
50
|
+
@username = username
|
51
|
+
adapter.basic_auth(username, password) if has_valid_credentials?
|
52
|
+
end
|
53
|
+
|
54
|
+
def password=(password)
|
55
|
+
@password = password
|
56
|
+
adapter.basic_auth(username, password) if has_valid_credentials?
|
57
|
+
end
|
58
|
+
|
59
|
+
def make_request(method, *args)
|
60
|
+
begin
|
61
|
+
response = self.send(method, *args)
|
62
|
+
rescue Faraday::Error::ConnectionFailed
|
63
|
+
raise Code42::Error::ConnectionFailed
|
64
|
+
end
|
65
|
+
check_for_errors(response)
|
66
|
+
response.body
|
67
|
+
end
|
68
|
+
|
69
|
+
def get(path, data)
|
70
|
+
adapter.get(path, data)
|
71
|
+
end
|
72
|
+
|
73
|
+
def put(path, data)
|
74
|
+
adapter.headers['Content-Type'] = 'application/json'
|
75
|
+
adapter.put path, data.to_json
|
76
|
+
end
|
77
|
+
|
78
|
+
def post(path, data)
|
79
|
+
adapter.headers['Content-Type'] = 'application/json'
|
80
|
+
adapter.post path, data.to_json
|
81
|
+
end
|
82
|
+
|
83
|
+
def delete(path, data)
|
84
|
+
adapter.delete(path, data)
|
85
|
+
end
|
86
|
+
|
87
|
+
def respond_to?(method_name, include_private = false)
|
88
|
+
adapter.respond_to?(method_name, include_private) || super
|
89
|
+
end if RUBY_VERSION < "1.9"
|
90
|
+
|
91
|
+
def respond_to_missing?(method_name, include_private = false)
|
92
|
+
adapter.respond_to?(method_name, include_private) || super
|
93
|
+
end if RUBY_VERSION >= "1.9"
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def check_for_errors(response)
|
98
|
+
if response.status == 401
|
99
|
+
raise Code42::Error::AuthenticationError.new(nil, response.status)
|
100
|
+
elsif response.status == 404
|
101
|
+
raise Code42::Error::ResourceNotFound.new(nil, response.status)
|
102
|
+
elsif response.status >= 400 && response.status < 600
|
103
|
+
body = response.body.is_a?(Array) ? response.body.first : response.body
|
104
|
+
raise exception_from_body(body, response.status)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def exception_from_body(body, status = nil)
|
109
|
+
return Code42::Error.new("Status: #{status}") if body.nil? || !body.has_key?('name')
|
110
|
+
exception_name = body['name'].downcase.camelize
|
111
|
+
if Code42::Error.const_defined?(exception_name)
|
112
|
+
klass = Code42::Error.const_get(exception_name)
|
113
|
+
else
|
114
|
+
klass = Code42::Error
|
115
|
+
end
|
116
|
+
klass.new(body['description'], status)
|
117
|
+
end
|
118
|
+
|
119
|
+
def method_missing(method_name, *args, &block)
|
120
|
+
return super unless adapter.respond_to?(method_name)
|
121
|
+
adapter.send(method_name, *args, &block)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
data/lib/code42/error.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Code42
|
2
|
+
class Error < StandardError;
|
3
|
+
attr_reader :status
|
4
|
+
def initialize(message = nil, status = nil)
|
5
|
+
super(message)
|
6
|
+
@status = status
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Error::AuthenticationError < Error; end
|
11
|
+
class Error::UsernameNotEmail < Error; end
|
12
|
+
class Error::EmailInvalid < Error; end
|
13
|
+
class Error::InvalidUsername < Error; end
|
14
|
+
class Error::OrgNameMissing < Error; end
|
15
|
+
class Error::OrgDuplicate < Error; end
|
16
|
+
class Error::ParentOrgBlocked < Error; end
|
17
|
+
class Error::ParentOrgNotActive < Error; end
|
18
|
+
class Error::OrgNameTooShort < Error; end
|
19
|
+
class Error::ConnectionFailed < Error; end
|
20
|
+
class Error::ResourceNotFound < Error; end
|
21
|
+
end
|
data/lib/code42/org.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'date'
|
2
|
+
module Code42
|
3
|
+
class Org < Resource
|
4
|
+
|
5
|
+
attribute :id, :from => 'orgId'
|
6
|
+
attribute :uid, :from => 'orgUid'
|
7
|
+
attribute :name, :from => 'orgName'
|
8
|
+
attribute :parent_id, :from => 'parentOrgId'
|
9
|
+
attribute :created_at, :from => 'creationDate', :as => DateTime
|
10
|
+
attribute :updated_at, :from => 'modificationDate', :as => DateTime
|
11
|
+
attribute :customer_id
|
12
|
+
|
13
|
+
def self.create(attrs = {})
|
14
|
+
client.create_org(attrs)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find_by_name(name)
|
18
|
+
client.find_org_by_name(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def users
|
22
|
+
client.users(org_id: id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def update(attrs = {})
|
26
|
+
client.update_org(id, attrs)
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete
|
30
|
+
client.delete_org(id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_user(attrs = {})
|
34
|
+
attrs.merge!(org_id: id)
|
35
|
+
client.create_user(attrs)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/code42/ping.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Code42
|
2
|
+
class Resource
|
3
|
+
alias_method :inspect, :to_s
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def from_response(response, client = nil)
|
7
|
+
deserialize_and_initialize(response, client)
|
8
|
+
end
|
9
|
+
|
10
|
+
def deserialize_and_initialize(data, client = nil)
|
11
|
+
new deserialize(data), client
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialize(data)
|
15
|
+
data.inject({}) { |o, ary| o.merge! serializer.serialize(*ary) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def deserialize(data)
|
19
|
+
data.inject({}) { |o, ary| o.merge! serializer.deserialize(*ary) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def serializer
|
23
|
+
@serializer ||= Code42::AttributeSerializer.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def attribute(*args)
|
27
|
+
options = args.extract_options!
|
28
|
+
args.each do |name|
|
29
|
+
serializer << Attribute.new(name, options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def collection_from_response(array)
|
34
|
+
array.map { |element| self.deserialize_and_initialize(element, self) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
attr_accessor :client, :attributes
|
38
|
+
|
39
|
+
def initialize(data = {}, client = nil)
|
40
|
+
self.client = client || Code42.client
|
41
|
+
self.attributes = {}
|
42
|
+
data.each do |key, value|
|
43
|
+
unless self.respond_to?("#{key}=".to_sym)
|
44
|
+
self.class.instance_eval { attr_writer key.to_sym }
|
45
|
+
end
|
46
|
+
unless self.respond_to?("#{key}".to_sym)
|
47
|
+
self.class.instance_eval { attr_reader key.to_sym }
|
48
|
+
end
|
49
|
+
self.send("#{key}=", value)
|
50
|
+
attributes[key.to_sym] = send(key.to_sym)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def serialize
|
55
|
+
self.class.serialize attributes
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/code42/role.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Code42
|
2
|
+
class Role < Resource
|
3
|
+
|
4
|
+
# @!attribute [rw] id
|
5
|
+
# @return [Fixnum] The id of the role
|
6
|
+
# @!attribute [rw] name
|
7
|
+
# @return [String] The name of the role
|
8
|
+
# @!attribute [rw] permissions
|
9
|
+
# @return [Array] A list of permissions for this role
|
10
|
+
# @!attribute [rw] created_at
|
11
|
+
# @return [DateTime] The timestamp for the time the role was assigned
|
12
|
+
# @!attribute [rw] updated_at
|
13
|
+
# @return [DateTime] The timestamp for the time the role was updated
|
14
|
+
|
15
|
+
attribute :user_id
|
16
|
+
attribute :id, :from => :roleId
|
17
|
+
attribute :name, :from => :roleName
|
18
|
+
attribute :created_at, :from => :creationDate, :as => DateTime
|
19
|
+
attribute :updated_at, :from => :modificationDate, :as => DateTime
|
20
|
+
attribute :permissions
|
21
|
+
|
22
|
+
def permissions=(permissions = [])
|
23
|
+
@permissions = permissions.map { |p| p['permission'] }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Code42
|
2
|
+
class RoleCollection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(roles = [])
|
6
|
+
@roles = roles
|
7
|
+
end
|
8
|
+
|
9
|
+
def each(&block)
|
10
|
+
@roles.each do |role|
|
11
|
+
if block_given?
|
12
|
+
block.call role
|
13
|
+
else
|
14
|
+
yield role
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes
|
20
|
+
map(&:attributes)
|
21
|
+
end
|
22
|
+
|
23
|
+
def serialize
|
24
|
+
map(&:serialize)
|
25
|
+
end
|
26
|
+
|
27
|
+
def includes_id?(id)
|
28
|
+
map(&:id).include? id
|
29
|
+
end
|
30
|
+
|
31
|
+
def includes_name?(name)
|
32
|
+
map(&:name).include? name
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Code42
|
2
|
+
class Settings
|
3
|
+
attr_accessor :host, :port, :https, :api_root, :username, :password, :token, :verify_https, :debug
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
options.symbolize_keys!
|
7
|
+
self.host = options[:host]
|
8
|
+
self.port = options[:port]
|
9
|
+
self.https = !options[:https].nil? ? options[:https] : true
|
10
|
+
self.verify_https = !options[:verify_https].nil? ? options[:verify_https] : true
|
11
|
+
self.api_root = options[:api_root] || '/api'
|
12
|
+
self.username = options[:username]
|
13
|
+
self.password = options[:password]
|
14
|
+
self.token = options[:token]
|
15
|
+
self.debug = options[:debug]
|
16
|
+
end
|
17
|
+
|
18
|
+
def all
|
19
|
+
settings = {}
|
20
|
+
settings[:host] = host
|
21
|
+
settings[:port] = port
|
22
|
+
settings[:https] = https
|
23
|
+
settings[:api_root] = api_root
|
24
|
+
settings[:username] = username
|
25
|
+
settings[:password] = password
|
26
|
+
settings
|
27
|
+
end
|
28
|
+
|
29
|
+
def scheme
|
30
|
+
https ? 'https' : 'http'
|
31
|
+
end
|
32
|
+
|
33
|
+
def base_url
|
34
|
+
raise Error unless valid?
|
35
|
+
"#{scheme}://#{host}:#{port}#{api_root}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def valid?
|
39
|
+
host && port && api_root
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/code42/token.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'code42/resource'
|
2
|
+
|
3
|
+
module Code42
|
4
|
+
class Token < Resource
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def from_string(token_string)
|
8
|
+
tokens = token_string.split('-')
|
9
|
+
new(cookie_token: tokens[0],
|
10
|
+
url_token: tokens[1])
|
11
|
+
end
|
12
|
+
|
13
|
+
def deserialize(data)
|
14
|
+
result = {}
|
15
|
+
result[:cookie_token] = data[0]
|
16
|
+
result[:url_token] = data[1]
|
17
|
+
result
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
alias inspect to_s
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
token_string
|
25
|
+
end
|
26
|
+
|
27
|
+
def token_string
|
28
|
+
[cookie_token, url_token].join('-')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/code42/user.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Code42
|
4
|
+
class User < Resource
|
5
|
+
|
6
|
+
attribute :id, :from => 'userId'
|
7
|
+
attribute :uid, :from => 'userUid'
|
8
|
+
attribute :org_id
|
9
|
+
attribute :updated_at, :from => 'modificationDate', :as => DateTime
|
10
|
+
attribute :created_at, :from => 'creationDate', :as => DateTime
|
11
|
+
attribute :status, :username, :email, :first_name, :last_name, :quota_in_bytes, :org_id, :org_uid, :org_name, :active, :blocked, :email_promo, :invited, :org_type, :username_is_an_email, :customer_id
|
12
|
+
|
13
|
+
def self.create(attributes)
|
14
|
+
client.create_user(attributes)
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete
|
18
|
+
client.delete_user(id)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the org associated with this user
|
22
|
+
# @return [Code42::User]
|
23
|
+
def org
|
24
|
+
client.org(org_id)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the roles associated with this user
|
28
|
+
# @return [Code42::RoleCollection]
|
29
|
+
def roles
|
30
|
+
client.user_roles(id)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Assigns a role to this user
|
34
|
+
# @return [Code42::Role]
|
35
|
+
def assign_role(attrs = {})
|
36
|
+
attrs.merge!(user_id: id)
|
37
|
+
client.assign_role(attrs)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|