hdcore 0.0.1

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 ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hdcore.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ethan Pemble
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Hdcore
2
+
3
+ A basic wrapper for HostDime's customer portal 'Core' API.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'hdcore'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install hdcore
18
+
19
+ ## Usage
20
+
21
+ https://api.hostdime.com/
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/hdcore.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hdcore/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hdcore"
8
+ spec.version = Hdcore::VERSION
9
+ spec.authors = ["Ethan Pemble"]
10
+ spec.email = ["ethan.p@hostdime.com"]
11
+ spec.description = "A basic wrapper for HostDime's customer portal 'Core' API"
12
+ spec.summary = ""
13
+ spec.homepage = "https://github.com/hostdime/hdcore"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 2.13"
24
+ spec.add_dependency "httparty", "~> 0.11"
25
+ end
@@ -0,0 +1,60 @@
1
+ #
2
+ module Hdcore
3
+ @log = Logger.new(STDOUT)
4
+
5
+ # Default configuration values
6
+ @config = {
7
+ api_endpoint: 'core.hostdime.com/api/v1',
8
+ public_key: nil,
9
+ private_key: nil
10
+ }
11
+ @valid_config_keys = @config.keys
12
+
13
+ class << self
14
+ # Configure HDCore with an options hash.
15
+ # @param [Hash] opts Configuration options hash
16
+ # @option opts [String] :api_endpoint ('core.hostdime.com/api/v1') The HDCore API endpoint URI
17
+ # @option opts [String] :public_key Your HDCore public key
18
+ # @option opts [String] :private_key Your HDCore private key
19
+ def configure opts = {}
20
+ opts.each do |key, val|
21
+ config[key.to_sym] = val if @valid_config_keys.include? key.to_sym
22
+ end
23
+ end
24
+
25
+ # Configure HDCore with an external yaml config file.
26
+ # @param [String] path_to_yaml_file Absolute path to yaml config file
27
+ def configure_with path_to_yaml_file
28
+ begin
29
+ config = YAML::load(IO.read(path_to_yaml_file))
30
+ rescue Errno::ENOENT
31
+ log.warn "YAML config file not found: using defaults instead"; return
32
+ rescue Psych::SyntaxError
33
+ log.warn "YAML config file has invalid syntax: using defaults instead"; return
34
+ end
35
+
36
+ configure(config)
37
+ end
38
+
39
+ # Current configuration hash
40
+ def config
41
+ @config
42
+ end
43
+
44
+ # For logging purposes
45
+ def log
46
+ @log
47
+ end
48
+
49
+ # @return [Bool] True if there are configuration keys that have no assigned value.
50
+ def missing_config_values?
51
+ config.values.include? nil
52
+ end
53
+
54
+ # @return [Array] Configuration keys that have no assigned value.
55
+ def missing_config_values
56
+ config.select{|k,v| v.nil?}.keys
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,75 @@
1
+ #
2
+ module Hdcore
3
+ class Request
4
+ include HTTParty
5
+
6
+ class << self
7
+
8
+ # Initializes the request: throws exception if there are configs missing (requires public and private keys)
9
+ # @param [String] action The full API action
10
+ def init
11
+ # Make sure required config values are set
12
+ if Hdcore.missing_config_values?
13
+ msg = "Hdcore is not yet properly configured: Missing #{Hdcore.missing_config_values}"
14
+
15
+ Hdcore.log.error(msg)
16
+ raise Exception, msg, caller
17
+ end
18
+
19
+ # set base uri for HTTParty request
20
+ base_uri Hdcore.config[:api_endpoint]
21
+ end
22
+
23
+ # @return [String] public key established in configuration
24
+ def public_key
25
+ Hdcore.config[:public_key]
26
+ end
27
+
28
+ # @return [String] private key established in configuration
29
+ def private_key
30
+ Hdcore.config[:private_key]
31
+ end
32
+
33
+ # @param [String] action The full API action
34
+ # @param [Hash] params The given action parameters
35
+ # @return [HTTParty::Response]
36
+ def send(action, params = {})
37
+ init()
38
+ self.get("/call/api_action/#{action}/format/json/", query_string(action, params))
39
+ end
40
+
41
+ # @param [Hash] params The given action parameters
42
+ # @return [Hash] Full set of parameters, including generated api parameters
43
+ def query_string(action, params = {})
44
+ params.merge generate_api_params(action, params)
45
+ end
46
+
47
+ # @param [Hash] action_params The given action parameters
48
+ # @return [Hash] required api parameters: [api_key, api_unique, api_timestamp, api_hash]
49
+ def generate_api_params(action, params = {})
50
+ {
51
+ api_key: public_key,
52
+ api_unique: uuid = generate_uuid,
53
+ api_timestamp: timestamp = Time.now.to_i,
54
+ api_hash: generate_hash( timestamp,
55
+ uuid,
56
+ private_key,
57
+ action,
58
+ params.to_json )
59
+ }
60
+ end
61
+
62
+ # @return [String] SHA256 hash of all the arguments "joined:with:colons"
63
+ def generate_hash(*args)
64
+ (Digest::SHA2.new << args.join(':')).to_s
65
+ end
66
+
67
+ # @return [String] Version 4 UUID
68
+ # More: http://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29
69
+ def generate_uuid
70
+ SecureRandom.uuid
71
+ end
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ module Hdcore
2
+ VERSION = "0.0.1"
3
+ end
data/lib/hdcore.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'hdcore/version'
2
+ require 'httparty'
3
+ require 'logger'
4
+ require 'yaml'
5
+ require 'json'
6
+ require 'digest/sha2' # to generate SHA256 hash
7
+ require 'securerandom' # to generate v4 UUID
8
+
9
+ Dir[File.dirname(__FILE__) + '/hdcore/*.rb'].each do |file|
10
+ require file
11
+ end
@@ -0,0 +1,71 @@
1
+ require_relative '../../../lib/hdcore'
2
+
3
+ describe Hdcore do
4
+
5
+ describe '.config' do
6
+ it 'returns hash with expected keys [:api_endpoint, :public_key, :private_key]' do
7
+ Hdcore.config.keys.should == [:api_endpoint, :public_key, :private_key]
8
+ end
9
+
10
+ it 'returns default [:api_endpoint] => "core.hostdime.com/api/v1"' do
11
+ Hdcore.config[:api_endpoint].should == 'core.hostdime.com/api/v1'
12
+ end
13
+
14
+ it 'returns default [:public_key] => nil' do
15
+ Hdcore.config[:public_key].should == nil
16
+ end
17
+
18
+ it 'returns default [:private_key] => nil' do
19
+ Hdcore.config[:private_key].should == nil
20
+ end
21
+ end
22
+
23
+ describe '.configure' do
24
+ it 'assigns value if the key is valid' do
25
+ # public_key is known to be a valid config key
26
+ Hdcore.configure(public_key: 'some_value')
27
+ Hdcore.config[:public_key].should == 'some_value'
28
+ end
29
+
30
+ it 'does nothing for invalid keys' do
31
+ Hdcore.configure(bogus_key: 'some_value')
32
+ Hdcore.config[:bogus_key].should be_nil
33
+ end
34
+
35
+ after do
36
+ # reset to expected nil values
37
+ Hdcore.configure({
38
+ public_key: nil,
39
+ private_key: nil
40
+ })
41
+ end
42
+ end
43
+
44
+ describe '.missing_config_values?' do
45
+ it 'returns true by default, due to uninitialized config values' do
46
+ Hdcore.missing_config_values?.should be_true
47
+ end
48
+
49
+ it 'returns true when a config value is nil' do
50
+ Hdcore.stub(:config).and_return(some: nil)
51
+ Hdcore.missing_config_values?.should be_true
52
+ end
53
+
54
+ it 'returns false when config values are not nil' do
55
+ Hdcore.stub(:config).and_return(some: 'not_nil')
56
+ Hdcore.missing_config_values?.should be_false
57
+ end
58
+ end
59
+
60
+ describe '.missing_config_values' do
61
+ it 'returns default [:public_key, :private_key]' do
62
+ Hdcore.missing_config_values.should == [:public_key, :private_key]
63
+ end
64
+
65
+ it 'returns keys that have nil values' do
66
+ Hdcore.stub(:config).and_return(empty_config_key: nil, not_empty: 'value')
67
+ Hdcore.missing_config_values.should == [:empty_config_key]
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,86 @@
1
+ require_relative '../../../lib/hdcore'
2
+
3
+ describe Hdcore::Request do
4
+
5
+ describe '.send' do
6
+ it 'initializes and sends GET request to API endpoint' do
7
+ test_action = 'some.action'
8
+ Hdcore::Request.stub(:query_string).and_return(params = {some: 'params'})
9
+ Hdcore::Request.should_receive(:init)
10
+ Hdcore::Request.should_receive(:get).with("/call/api_action/#{test_action}/format/json/", params)
11
+ Hdcore::Request.send(test_action, {})
12
+ end
13
+ end
14
+
15
+
16
+ describe '.query_string' do
17
+ it 'returns parameters merged with generated api parameters' do
18
+ Hdcore::Request.stub(:generate_api_params).and_return(api_params = {some: 'api_params'})
19
+ actual = Hdcore::Request.query_string('some.action', params = {some_other: 'params'})
20
+ actual.should == params.merge(api_params)
21
+ end
22
+ end
23
+
24
+
25
+ describe '.generate_api_params' do
26
+ it 'returns hash with four valid param keys' do
27
+ actual = Hdcore::Request.generate_api_params("", {})
28
+ actual.keys.should == [:api_key, :api_unique, :api_timestamp, :api_hash]
29
+ end
30
+
31
+ it 'returns [:api_key] => public key' do
32
+ Hdcore::Request.stub(:public_key).and_return(key = 'some_public_key')
33
+ actual = Hdcore::Request.generate_api_params("", {})
34
+ actual[:api_key].should == key
35
+ end
36
+
37
+ it 'returns [:api_unique] => generated uuid' do
38
+ Hdcore::Request.stub(:generate_uuid).and_return(uuid = 'some_uuid')
39
+ actual = Hdcore::Request.generate_api_params("", {})
40
+ actual[:api_unique].should == uuid
41
+ end
42
+
43
+ it 'returns [:api_timestamp] => time of execution' do
44
+ timestamp = Time.now.to_i
45
+ actual = Hdcore::Request.generate_api_params("", {})
46
+ actual[:api_timestamp].should == timestamp
47
+ end
48
+
49
+ it 'returns [:api_hash] => generated hash' do
50
+ Hdcore::Request.stub(:generate_hash).and_return(hash = 'some_hash')
51
+ actual = Hdcore::Request.generate_api_params("", {})
52
+ actual[:api_hash].should == hash
53
+ end
54
+
55
+
56
+ it 'generated hash formed with the correct elements: [timestamp, uuid, pkey, action, json-ified params]' do
57
+ Hdcore::Request.stub(:generate_uuid).and_return(uuid = 'some_uuid')
58
+ Hdcore::Request.stub(:private_key).and_return(private_key = 'some_private_key')
59
+
60
+ Hdcore::Request.should_receive(:generate_hash).with(Time.now.to_i,
61
+ uuid,
62
+ private_key,
63
+ action = 'some.action',
64
+ (params = {some: 'optional_params'}).to_json
65
+ )
66
+
67
+ Hdcore::Request.generate_api_params(action, params)
68
+ end
69
+ end
70
+
71
+
72
+ describe '.generate_hash' do
73
+ it 'uses the SHA256 algorithm, and joins parameters with colons' do
74
+ args = %w[one two three 4 five seven 8]
75
+ hash = (Digest::SHA2.new << args.join(':')).to_s
76
+ Hdcore::Request.generate_hash(*args).should == hash
77
+ end
78
+ end
79
+
80
+ describe '.generate_uuid' do
81
+ it 'uses Version 4 UUID' do
82
+ SecureRandom.should_receive(:uuid).and_return(uuid = 'some_uuid')
83
+ Hdcore::Request.generate_uuid.should == uuid
84
+ end
85
+ end
86
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hdcore
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ethan Pemble
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-05-08 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bundler
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 9
29
+ segments:
30
+ - 1
31
+ - 3
32
+ version: "1.3"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rake
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ hash: 25
58
+ segments:
59
+ - 2
60
+ - 13
61
+ version: "2.13"
62
+ type: :development
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: httparty
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ~>
71
+ - !ruby/object:Gem::Version
72
+ hash: 29
73
+ segments:
74
+ - 0
75
+ - 11
76
+ version: "0.11"
77
+ type: :runtime
78
+ version_requirements: *id004
79
+ description: A basic wrapper for HostDime's customer portal 'Core' API
80
+ email:
81
+ - ethan.p@hostdime.com
82
+ executables: []
83
+
84
+ extensions: []
85
+
86
+ extra_rdoc_files: []
87
+
88
+ files:
89
+ - .gitignore
90
+ - Gemfile
91
+ - LICENSE.txt
92
+ - README.md
93
+ - Rakefile
94
+ - hdcore.gemspec
95
+ - lib/hdcore.rb
96
+ - lib/hdcore/hdcore.rb
97
+ - lib/hdcore/request.rb
98
+ - lib/hdcore/version.rb
99
+ - spec/lib/hdcore/hdcore_spec.rb
100
+ - spec/lib/hdcore/request_spec.rb
101
+ homepage: https://github.com/hostdime/hdcore
102
+ licenses:
103
+ - MIT
104
+ post_install_message:
105
+ rdoc_options: []
106
+
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ hash: 3
124
+ segments:
125
+ - 0
126
+ version: "0"
127
+ requirements: []
128
+
129
+ rubyforge_project:
130
+ rubygems_version: 1.8.24
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: ""
134
+ test_files:
135
+ - spec/lib/hdcore/hdcore_spec.rb
136
+ - spec/lib/hdcore/request_spec.rb