code42 0.1.2
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/.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
|