code42 0.1.2

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