aws_agcod 0.0.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.
- checksums.yaml +15 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/lib/aws_agcod.rb +33 -0
- data/lib/aws_agcod/cancel_gift_card.rb +13 -0
- data/lib/aws_agcod/create_gift_card.rb +30 -0
- data/lib/aws_agcod/request.rb +52 -0
- data/lib/aws_agcod/response.rb +25 -0
- data/lib/aws_agcod/signature.rb +96 -0
- data/lib/aws_agcod/version.rb +3 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZTJiYjU2ZTg4ZjBlNTQ2YjZmOWQ0MWQ2MTVhN2E1NzllYjkyY2YxZg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MGE1MGUxMTNiMjhmODMwMjQ1ZDdjNWIyYmQ4MzQ0NWMyODY4NDljOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NThjZDBiOTMwZTc3YTI0MTZmNjVjY2U3MDI3YWY3NjgwZjQ1Yzk2OWFlMzIx
|
10
|
+
OGUzYmI3OWMxMjM2YjJjYWQxMjhhZTM0MDEzNjgyMmQ2NDZmMTI5ODJhZWRk
|
11
|
+
ZmIwNTI4NDFmYzRkNjhlYWJjZTIxMzg0NDIzNThjNTVlNmZjN2Q=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MzNkOGQ4ZTY5NjdhYzQ5YTBhN2NjOTJkM2ZiODgyODczODEwZGY3MzIxNGRk
|
14
|
+
OTMyNjAxMTJhNTQxY2E0NTVhODIwMzM0ZGM4MDdjNjE2ZWUxYTViZDlmZDcw
|
15
|
+
NjFjMThkMGExZTMyNThmZjJjNmNiNGI0ZjI5ZjlhN2E2MTFlMTA=
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 TODO: Write your name
|
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,31 @@
|
|
1
|
+
# AwsAgcod
|
2
|
+
|
3
|
+
Amazon Gift Code On Demand (AGCOD) API v2 implementation for distribute Amazon gift cards (gift codes) instantly in any denomination.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'aws_agcod'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install aws_agcod
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it ( https://github.com/[my-github-username]/aws_agcod/fork )
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/aws_agcod.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "aws_agcod/version"
|
2
|
+
require "aws_agcod/create_gift_card"
|
3
|
+
require "aws_agcod/cancel_gift_card"
|
4
|
+
|
5
|
+
module AwsAgcod
|
6
|
+
ROOT_PATH = if defined?(Rails)
|
7
|
+
Rails.root
|
8
|
+
else
|
9
|
+
Pathname.new(__FILE__).join("../..").expand_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.env
|
13
|
+
if defined?(Rails)
|
14
|
+
Rails.env
|
15
|
+
else
|
16
|
+
@enviroment || "development"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.env=(enviroment)
|
21
|
+
@enviroment = enviroment
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.config_file
|
25
|
+
@config_file || ROOT_PATH.join("config/agcod.yml")
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.config_file=(file_path)
|
29
|
+
if ROOT_PATH.join(file_path).exist?
|
30
|
+
@config_file = ROOT_PATH.join(file_path)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "aws_agcod/request"
|
2
|
+
|
3
|
+
module AwsAgcod
|
4
|
+
class CancelGiftCard
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :@response, :success?, :error_message
|
8
|
+
|
9
|
+
def initialize(request_id, gc_id)
|
10
|
+
@response = Request.new("CancelGiftCard", request_id, "gcId" => gc_id).response
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "aws_agcod/request"
|
2
|
+
|
3
|
+
module AwsAgcod
|
4
|
+
class CreateGiftCard
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :@response, :success?, :error_message
|
8
|
+
|
9
|
+
def initialize(request_id, amount)
|
10
|
+
@response = Request.new("CreateGiftCard", request_id,
|
11
|
+
"value" => {
|
12
|
+
"currencyCode" => "USD",
|
13
|
+
"amount" => amount
|
14
|
+
}
|
15
|
+
).response
|
16
|
+
end
|
17
|
+
|
18
|
+
def claim_code
|
19
|
+
@response.payload["gcClaimCode"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def gc_id
|
23
|
+
@response.payload["gcId"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def request_id
|
27
|
+
@response.payload["creationRequestId"]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "aws_agcod/signature"
|
2
|
+
require "aws_agcod/response"
|
3
|
+
require "httparty"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
module AwsAgcod
|
7
|
+
class Request
|
8
|
+
TIME_FORMAT = "%Y%m%dT%H%M%SZ"
|
9
|
+
|
10
|
+
attr_reader :response
|
11
|
+
|
12
|
+
def initialize(action, request_id, params)
|
13
|
+
@action = action
|
14
|
+
@request_id = request_id
|
15
|
+
@params = params
|
16
|
+
|
17
|
+
@response = Response.new(HTTParty.post(uri, body: body, headers: signed_headers, timeout: 30).body)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def signed_headers
|
23
|
+
time = Time.now.utc
|
24
|
+
|
25
|
+
headers = {
|
26
|
+
"content-type" => "application/json",
|
27
|
+
"x-amz-date" => time.strftime(TIME_FORMAT),
|
28
|
+
"accept" => "application/json",
|
29
|
+
"host" => uri.host,
|
30
|
+
"x-amz-target" => "com.amazonaws.agcod.AGCODService.#{@action}",
|
31
|
+
"date" => time.to_s
|
32
|
+
}
|
33
|
+
|
34
|
+
Signature.new(config).sign(uri, headers, body)
|
35
|
+
end
|
36
|
+
|
37
|
+
def config
|
38
|
+
@config ||= YAML.load_file(AwsAgcod.config_file)[AwsAgcod.env]
|
39
|
+
end
|
40
|
+
|
41
|
+
def uri
|
42
|
+
@uri ||= URI("#{config["uri"]}/#{@action}")
|
43
|
+
end
|
44
|
+
|
45
|
+
def body
|
46
|
+
@body ||= @params.merge(
|
47
|
+
"partnerId" => config["partner_id"],
|
48
|
+
"creationRequestId" => "#{config["partner_id"]}#{@request_id}"
|
49
|
+
).to_json
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module AwsAgcod
|
4
|
+
class Response
|
5
|
+
attr_reader :status, :payload
|
6
|
+
|
7
|
+
def initialize(raw_json)
|
8
|
+
@payload = JSON.parse(raw_json)
|
9
|
+
|
10
|
+
# All status:
|
11
|
+
# SUCCESS -- Operation succeeded
|
12
|
+
# FAILURE -- Operation failed
|
13
|
+
# RESEND -- A temporary/recoverable system failure that can be resolved by the partner retrying the request
|
14
|
+
@status = payload["status"] ? payload["status"] : payload["agcodResponse"]["status"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def success?
|
18
|
+
status == "SUCCESS"
|
19
|
+
end
|
20
|
+
|
21
|
+
def error_message
|
22
|
+
"#{payload["errorCode"]} #{payload["errorType"]} - #{payload["message"]}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# Currently AGCOD v2 uses v4 Signature for it's authentication,
|
2
|
+
# this class generates signed headers for making proper request to AGCOD service.
|
3
|
+
#
|
4
|
+
# Based on https://github.com/ifeelgoods/aws4/blob/master/lib/aws4/signer.rb
|
5
|
+
require "openssl"
|
6
|
+
require "uri"
|
7
|
+
require "pathname"
|
8
|
+
|
9
|
+
module AwsAgcod
|
10
|
+
class Signature
|
11
|
+
SERVICE = "AGCODService"
|
12
|
+
DEFAULT_REGION = "us-east-1"
|
13
|
+
|
14
|
+
def initialize(credentials)
|
15
|
+
@access_key = credentials["access_key"]
|
16
|
+
@secret_key = credentials["secret_key"]
|
17
|
+
@region = credentials["region"] || DEFAULT_REGION
|
18
|
+
end
|
19
|
+
|
20
|
+
def sign(uri, headers, body = "")
|
21
|
+
@uri = uri
|
22
|
+
@headers = headers
|
23
|
+
@body = body
|
24
|
+
@date = headers["x-amz-date"]
|
25
|
+
|
26
|
+
signed_headers = headers.dup
|
27
|
+
signed_headers["Authorization"] = authorization
|
28
|
+
|
29
|
+
signed_headers
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def authorization
|
35
|
+
[
|
36
|
+
"AWS4-HMAC-SHA256 Credential=#{@access_key}/#{credential_string}",
|
37
|
+
"SignedHeaders=#{@headers.keys.map(&:downcase).sort.join(";")}",
|
38
|
+
"Signature=#{signature}"
|
39
|
+
].join(", ")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Reference http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
|
43
|
+
def signature
|
44
|
+
k_date = hmac("AWS4" + @secret_key, @date[0, 8])
|
45
|
+
k_region = hmac(k_date, @region)
|
46
|
+
k_service = hmac(k_region, SERVICE)
|
47
|
+
k_credentials = hmac(k_service, "aws4_request")
|
48
|
+
hexhmac(k_credentials, string_to_sign)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Reference http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
|
52
|
+
def string_to_sign
|
53
|
+
@string_to_sign ||= [
|
54
|
+
"AWS4-HMAC-SHA256", # Algorithm
|
55
|
+
@date, # RequestDate
|
56
|
+
credential_string, # CredentialScope
|
57
|
+
hexdigest(canonical_request) # HashedCanonicalRequest
|
58
|
+
].join("\n")
|
59
|
+
end
|
60
|
+
|
61
|
+
def credential_string
|
62
|
+
@credential_string ||= [@date[0, 8], @region, SERVICE, "aws4_request"].join("/")
|
63
|
+
end
|
64
|
+
|
65
|
+
# Reference http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
66
|
+
def canonical_request
|
67
|
+
@canonical_request ||= [
|
68
|
+
"POST", # HTTPRequestMethod
|
69
|
+
Pathname.new(@uri.path).cleanpath.to_s, # CanonicalURI
|
70
|
+
@uri.query, # CanonicalQueryString
|
71
|
+
@headers.sort.map { |k, v| [k.downcase, v.strip].join(":") }.join("\n") + "\n", # CanonicalHeaders
|
72
|
+
@headers.sort.map { |k, v| k.downcase }.join(";"), # SignedHeaders
|
73
|
+
hexdigest(@body) # HexEncode(Hash(RequestPayload))
|
74
|
+
].join("\n")
|
75
|
+
end
|
76
|
+
|
77
|
+
# Hexdigest simply produces an ascii safe way
|
78
|
+
# to view the bytes produced from the hash algorithm.
|
79
|
+
# It takes the hex representation of each byte
|
80
|
+
# and concatenates them together to produce a string
|
81
|
+
def hexdigest(value)
|
82
|
+
Digest::SHA256.new.update(value).hexdigest
|
83
|
+
end
|
84
|
+
|
85
|
+
# Hash-based message authentication code (HMAC)
|
86
|
+
# is a mechanism for calculating a message authentication code
|
87
|
+
# involving a hash function in combination with a secret key
|
88
|
+
def hmac(key, value)
|
89
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new("sha256"), key, value)
|
90
|
+
end
|
91
|
+
|
92
|
+
def hexhmac(key, value)
|
93
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new("sha256"), key, value)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aws_agcod
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Xenor Chang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.13'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.1'
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 3.1.0
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ~>
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '3.1'
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 3.1.0
|
75
|
+
description: ! "Amazon Gift Code On Demand (AGCOD) API v2 implementation for\n distribute
|
76
|
+
Amazon gift cards (gift codes) instantly in any denomination"
|
77
|
+
email:
|
78
|
+
- xenor@listia.com
|
79
|
+
executables: []
|
80
|
+
extensions: []
|
81
|
+
extra_rdoc_files: []
|
82
|
+
files:
|
83
|
+
- LICENSE.txt
|
84
|
+
- README.md
|
85
|
+
- Rakefile
|
86
|
+
- lib/aws_agcod.rb
|
87
|
+
- lib/aws_agcod/cancel_gift_card.rb
|
88
|
+
- lib/aws_agcod/create_gift_card.rb
|
89
|
+
- lib/aws_agcod/request.rb
|
90
|
+
- lib/aws_agcod/response.rb
|
91
|
+
- lib/aws_agcod/signature.rb
|
92
|
+
- lib/aws_agcod/version.rb
|
93
|
+
homepage: https://github.com/listia/aws-agcod
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.4.5
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: AWS AGCOD API v2 endpoints implementation
|
117
|
+
test_files: []
|