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.
Files changed (80) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +203 -0
  5. data/README.md +182 -0
  6. data/Rakefile +1 -0
  7. data/code42.gemspec +26 -0
  8. data/examples/Gemfile +6 -0
  9. data/examples/computers.rb +88 -0
  10. data/examples/diagnostic.rb +82 -0
  11. data/examples/orgs.rb +88 -0
  12. data/examples/parser.rb +51 -0
  13. data/examples/parser_test.rb +64 -0
  14. data/examples/users.rb +88 -0
  15. data/lib/code42.rb +46 -0
  16. data/lib/code42/attribute.rb +13 -0
  17. data/lib/code42/attribute_serializer.rb +129 -0
  18. data/lib/code42/client.rb +301 -0
  19. data/lib/code42/computer.rb +15 -0
  20. data/lib/code42/connection.rb +124 -0
  21. data/lib/code42/diagnostic.rb +8 -0
  22. data/lib/code42/error.rb +21 -0
  23. data/lib/code42/org.rb +38 -0
  24. data/lib/code42/ping.rb +14 -0
  25. data/lib/code42/resource.rb +58 -0
  26. data/lib/code42/role.rb +26 -0
  27. data/lib/code42/role_collection.rb +35 -0
  28. data/lib/code42/settings.rb +42 -0
  29. data/lib/code42/token.rb +31 -0
  30. data/lib/code42/token_validation.rb +10 -0
  31. data/lib/code42/user.rb +40 -0
  32. data/lib/code42/version.rb +3 -0
  33. data/spec/cassettes/Code42_Client/_create_org/returns_created_org.yml +47 -0
  34. data/spec/cassettes/Code42_Client/_create_user/returns_created_user.yml +44 -0
  35. data/spec/cassettes/Code42_Client/_create_user/when_sending_an_invalid_email/raises_an_exception.yml +37 -0
  36. data/spec/cassettes/Code42_Client/_find_org_by_name/returns_the_org_with_the_specified_name.yml +101 -0
  37. data/spec/cassettes/Code42_Client/_get_token/returns_valid_tokens.yml +38 -0
  38. data/spec/cassettes/Code42_Client/_get_token/when_providing_invalid_credentials/should_raise_an_exception.yml +37 -0
  39. data/spec/cassettes/Code42_Client/_org/when_ID_is_not_passed/returns_my_org.yml +54 -0
  40. data/spec/cassettes/Code42_Client/_org/when_ID_is_passed_in/returns_a_specific_org.yml +54 -0
  41. data/spec/cassettes/Code42_Client/_ping/returns_a_ping.yml +48 -0
  42. data/spec/cassettes/Code42_Client/_user/when_ID_is_not_passed/returns_my_user.yml +53 -0
  43. data/spec/cassettes/Code42_Client/_user/when_ID_is_passed_in/returns_a_specific_user.yml +53 -0
  44. data/spec/cassettes/Code42_Client/_user_roles/returns_an_enumerable.yml +50 -0
  45. data/spec/cassettes/Code42_Client/_validate_token/returns_a_valid_response.yml +83 -0
  46. data/spec/cassettes/Crashplan_Client/_create_org/returns_created_org.yml +47 -0
  47. data/spec/cassettes/Crashplan_Client/_create_user/returns_created_user.yml +44 -0
  48. data/spec/cassettes/Crashplan_Client/_create_user/when_sending_an_invalid_email/raises_an_exception.yml +37 -0
  49. data/spec/cassettes/Crashplan_Client/_find_org_by_name/returns_the_org_with_the_specified_name.yml +55 -0
  50. data/spec/cassettes/Crashplan_Client/_get_token/returns_valid_tokens.yml +38 -0
  51. data/spec/cassettes/Crashplan_Client/_get_token/when_providing_invalid_credentials/should_raise_an_exception.yml +37 -0
  52. data/spec/cassettes/Crashplan_Client/_org/when_ID_is_not_passed/returns_my_org.yml +54 -0
  53. data/spec/cassettes/Crashplan_Client/_org/when_ID_is_passed_in/returns_a_specific_org.yml +54 -0
  54. data/spec/cassettes/Crashplan_Client/_ping/returns_a_ping.yml +48 -0
  55. data/spec/cassettes/Crashplan_Client/_user/when_ID_is_not_passed/returns_my_user.yml +99 -0
  56. data/spec/cassettes/Crashplan_Client/_user/when_ID_is_passed_in/returns_a_specific_user.yml +53 -0
  57. data/spec/cassettes/Crashplan_Client/_user_roles/returns_an_enumerable.yml +50 -0
  58. data/spec/cassettes/Crashplan_Client/_validate_token/returns_a_valid_response.yml +128 -0
  59. data/spec/crashplan/client_spec.rb +135 -0
  60. data/spec/crashplan/connection_spec.rb +45 -0
  61. data/spec/crashplan/org_spec.rb +63 -0
  62. data/spec/crashplan/ping_spec.rb +14 -0
  63. data/spec/crashplan/resource_spec.rb +56 -0
  64. data/spec/crashplan/role_spec.rb +28 -0
  65. data/spec/crashplan/settings_spec.rb +118 -0
  66. data/spec/crashplan/token_spec.rb +33 -0
  67. data/spec/crashplan/user_spec.rb +21 -0
  68. data/spec/fixtures/auth/bad_password.json +1 -0
  69. data/spec/fixtures/authToken.json +10 -0
  70. data/spec/fixtures/org.1.json +36 -0
  71. data/spec/fixtures/org.create.json +36 -0
  72. data/spec/fixtures/org.my.json +36 -0
  73. data/spec/fixtures/ping.json +7 -0
  74. data/spec/fixtures/user.1.json +27 -0
  75. data/spec/fixtures/user.create.json +27 -0
  76. data/spec/fixtures/user.my.json +27 -0
  77. data/spec/fixtures/user_roles.json +32 -0
  78. data/spec/fixtures/validate_token.json +10 -0
  79. data/spec/spec_helper.rb +67 -0
  80. metadata +268 -0
@@ -0,0 +1,15 @@
1
+ module Code42
2
+ class Computer < Resource
3
+
4
+ attribute :id, :from => 'computerId'
5
+
6
+ def unblock
7
+ client.unblock_computer(id)
8
+ end
9
+
10
+ def block
11
+ client.block_computer(id)
12
+ end
13
+
14
+ end
15
+ end
@@ -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
@@ -0,0 +1,8 @@
1
+ module Code42
2
+ class Diagnostic < Resource
3
+ attribute :timestamp, :from => 'diagnosticTimestamp', :as => DateTime
4
+ attribute :db_ok
5
+ attribute :volumes
6
+ attribute :system_alerts
7
+ end
8
+ end
@@ -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
@@ -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
@@ -0,0 +1,14 @@
1
+ module Code42
2
+ class Ping < Resource
3
+
4
+ attribute :success
5
+
6
+ def to_s
7
+ success?
8
+ end
9
+
10
+ def success?
11
+ self.success
12
+ end
13
+ end
14
+ end
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,10 @@
1
+ module Code42
2
+ class TokenValidation < Resource
3
+
4
+ attribute :valid, :username
5
+
6
+ def valid?
7
+ valid
8
+ end
9
+ end
10
+ end
@@ -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