kojn 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 +7 -0
- data/.gitignore +25 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +1 -0
- data/kojn.gemspec +26 -0
- data/lib/app.rb +12 -0
- data/lib/kojn.rb +83 -0
- data/lib/kojn/collection.rb +44 -0
- data/lib/kojn/crypto.rb +50 -0
- data/lib/kojn/invoice.rb +32 -0
- data/lib/kojn/ipn.rb +51 -0
- data/lib/kojn/model.rb +27 -0
- data/lib/kojn/net.rb +56 -0
- data/lib/kojn/net_old.rb +58 -0
- data/lib/kojn/transaction.rb +80 -0
- data/lib/kojn/version.rb +3 -0
- data/spec/.rspec +2 -0
- data/spec/collection_spec.rb +24 -0
- data/spec/inflector_spec.rb +14 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/transaction_spec.rb +25 -0
- metadata +144 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a72ee15ab939bdb4881738fb56d50f50438277a4
|
4
|
+
data.tar.gz: 46f9903f44872e54333e120aef379dff9ce830b7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b9dc30c12210444747397261b19241ca81d080417a765479ce8c6c5c0deaa0b88d1215b63aa4f763eac0c0057514e848ae43220c5ba44337627a646b9ec3cb08
|
7
|
+
data.tar.gz: 55c4a138a8b81c0f52eca848939c34484358339213fd17241eb02ec26fb162d967b4078447acbadacc3e6101fff6bf4eff1d5ce7203ae7aee6b7583b7078fa99
|
data/.gitignore
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
coverage
|
12
|
+
InstalledFiles
|
13
|
+
lib/bundler/man
|
14
|
+
pkg
|
15
|
+
rdoc
|
16
|
+
spec/reports
|
17
|
+
test/tmp
|
18
|
+
test/version_tmp
|
19
|
+
tmp
|
20
|
+
# YARD artifacts
|
21
|
+
.yardoc
|
22
|
+
_yardoc
|
23
|
+
doc/
|
24
|
+
*/**/*un~
|
25
|
+
.*un~
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Kojn
|
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,33 @@
|
|
1
|
+
# Kojn
|
2
|
+
|
3
|
+
Kojn's ruby API library.
|
4
|
+
|
5
|
+
Feel free to fork, modify & redistribute under the MIT license.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'kojn'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install kojn
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
(TODO: Write inline docs)
|
24
|
+
|
25
|
+
Latest docs can be found here: https://kojn.nl/developer/docs/ruby_setup
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/kojn.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'kojn/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "kojn"
|
8
|
+
spec.version = Kojn::VERSION
|
9
|
+
spec.authors = ["Jeffrey Wilcke", "Maran Hidskes"]
|
10
|
+
spec.email = ["maran.hidskes@gmail.com", "jeff.wilcke@gmail.com"]
|
11
|
+
spec.description = %q{Ruby gem for communicating with the kojn.nl API. Allows you to create and managed invoices.}
|
12
|
+
spec.summary = %q{Ruby gem for communicating with the kojn.nl API.}
|
13
|
+
spec.homepage = "https://kojn.nl"
|
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_runtime_dependency "activemodel"
|
22
|
+
spec.add_runtime_dependency "activesupport"
|
23
|
+
spec.add_runtime_dependency 'curb', '> 0.8.1'
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
data/lib/app.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require './kojn.rb'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
Kojn.setup do |config|
|
5
|
+
config.api_key = "09367d4b49ae1f1d9ee0a326bd3619f1"
|
6
|
+
config.host = "localhost"
|
7
|
+
config.port = 3000
|
8
|
+
config.ssl = false
|
9
|
+
end
|
10
|
+
|
11
|
+
pp Kojn.invoices.all
|
12
|
+
pp Kojn.invoices.create(amount_in_euro: 1, currency: 'btc', description: 'Test')
|
data/lib/kojn.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
require 'active_model'
|
4
|
+
require 'curb'
|
5
|
+
|
6
|
+
String.send(:include, ActiveSupport::Inflector)
|
7
|
+
|
8
|
+
require 'base64'
|
9
|
+
require 'openssl'
|
10
|
+
require 'digest/sha2'
|
11
|
+
require 'json'
|
12
|
+
require 'net/http'
|
13
|
+
require 'uri'
|
14
|
+
|
15
|
+
require './kojn/model'
|
16
|
+
require './kojn/collection'
|
17
|
+
|
18
|
+
require './kojn/crypto'
|
19
|
+
require './kojn/net'
|
20
|
+
require './kojn/invoice'
|
21
|
+
require './kojn/ipn'
|
22
|
+
|
23
|
+
module Kojn
|
24
|
+
# Api key
|
25
|
+
mattr_accessor :api_key
|
26
|
+
|
27
|
+
# The crypto module
|
28
|
+
mattr_accessor :crypto
|
29
|
+
|
30
|
+
# The transactios module
|
31
|
+
mattr_accessor :invoices
|
32
|
+
|
33
|
+
# Type of ipn security
|
34
|
+
mattr_accessor :ipn_sec
|
35
|
+
@@ipn_sec = :integrity
|
36
|
+
|
37
|
+
# Host
|
38
|
+
mattr_accessor :host
|
39
|
+
@@host = "kojn.nl"
|
40
|
+
# Port
|
41
|
+
mattr_accessor :port
|
42
|
+
@@port = 80
|
43
|
+
# SSL
|
44
|
+
mattr_accessor :ssl
|
45
|
+
@@ssl = true
|
46
|
+
|
47
|
+
def self.crypto
|
48
|
+
raise MissingConfigExecption.new("API key not set") unless self.api_key
|
49
|
+
|
50
|
+
@@crypto ||= Kojn::Crypto.new
|
51
|
+
|
52
|
+
return @@crypto
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.invoices
|
56
|
+
raise MissingConfigExecption.new("API key not set") unless self.api_key
|
57
|
+
|
58
|
+
@@transacions ||= Kojn::Invoices.new
|
59
|
+
|
60
|
+
return @@transacions
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.ipn(params)
|
64
|
+
raise MissingConfigExecption.new("API key not set") unless self.api_key
|
65
|
+
|
66
|
+
return Kojn::Ipn.new(params)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Config setters/getters
|
70
|
+
def self.[](key)
|
71
|
+
self.send(key)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.[]=(key, value)
|
75
|
+
self.send("#{key}=", value)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.setup
|
79
|
+
yield self
|
80
|
+
end
|
81
|
+
|
82
|
+
class MissingConfigExecption<Exception;end;
|
83
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Kojn
|
2
|
+
class Collection
|
3
|
+
attr_accessor :access_token, :module, :name, :model, :path
|
4
|
+
|
5
|
+
def initialize(api_prefix="/api")
|
6
|
+
self.access_token = Kojn.api_key
|
7
|
+
|
8
|
+
self.module = self.class.to_s.singularize.underscore
|
9
|
+
self.name = self.module.split('/').last
|
10
|
+
self.model = self.module.camelize.constantize
|
11
|
+
self.path = "#{api_prefix}/#{self.name.pluralize}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def all(options = {})
|
15
|
+
parse_objects! Kojn::Net::get(self.path).body_str, self.model
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(options = {})
|
19
|
+
parse_object! Kojn::Net::post(self.path, {invoice: options}).body_str, self.model
|
20
|
+
end
|
21
|
+
|
22
|
+
def find(id, options = {})
|
23
|
+
parse_object! Kojn::Net::get("#{self.path}/#{id}").body_str, self.model
|
24
|
+
end
|
25
|
+
|
26
|
+
def update(id, options = {})
|
27
|
+
parse_object! Kojn::Net::patch("#{self.path}/#{id}", options).body_str, self.model
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
def parse_objects!(string, klass)
|
32
|
+
objects = JSON.parse(string)
|
33
|
+
objects.collect do |t_json|
|
34
|
+
parse_object!(t_json, klass)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_object!(object, klass)
|
39
|
+
object = JSON.parse(object) if object.is_a? String
|
40
|
+
|
41
|
+
klass.new(object)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/kojn/crypto.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module Kojn
|
2
|
+
class Crypto
|
3
|
+
protected
|
4
|
+
attr_writer :access_token, :crypt_method, :aes
|
5
|
+
|
6
|
+
public
|
7
|
+
attr_reader :access_token, :crypt_method, :aes
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.access_token = Kojn.api_key
|
11
|
+
self.crypt_method = 'AES-256-CFB'
|
12
|
+
|
13
|
+
self.aes = OpenSSL::Cipher.new(self.crypt_method)
|
14
|
+
end
|
15
|
+
|
16
|
+
def decrypt_params(params)
|
17
|
+
return self.decrypt(Base64.decode64(params['payload']), params['iv'])
|
18
|
+
end
|
19
|
+
|
20
|
+
def decrypt(data, iv)
|
21
|
+
self.aes.decrypt
|
22
|
+
self.aes.key = @access_token
|
23
|
+
self.aes.iv = iv
|
24
|
+
|
25
|
+
JSON.parse(aes.update(data) + aes.final)
|
26
|
+
end
|
27
|
+
|
28
|
+
def encrypt_params(params, key)
|
29
|
+
iv = rand.to_s[0..15]
|
30
|
+
|
31
|
+
return {iv: iv, payload: Base64.encode64(encrypt(params, iv, key))}
|
32
|
+
end
|
33
|
+
|
34
|
+
def encrypt(data, iv, key)
|
35
|
+
@aes.encrypt
|
36
|
+
@aes.key = key
|
37
|
+
@aes.iv = iv
|
38
|
+
|
39
|
+
@aes.update(data.to_json) + @aes.final
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.encrypt(key, data)
|
43
|
+
Kojn::Crypto.new(key).encrypt_params(data)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.decrypt(key, data)
|
47
|
+
Kojn::Crypto.new(key).decrypt_params(data)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/kojn/invoice.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Kojn
|
2
|
+
class Invoices < Kojn::Collection
|
3
|
+
end
|
4
|
+
|
5
|
+
class Invoice < Kojn::Model
|
6
|
+
UNCONFIRMED = 1
|
7
|
+
INSUFFICIENT = 2
|
8
|
+
SEEN = 3
|
9
|
+
CANCELLED = 4
|
10
|
+
|
11
|
+
attr_accessor :internal_id, :external_id, :address, :currency, :amount, :amount_in_euro, :exchange_rate, :status, :received_amount, :description, :seen, :received_amount_in_euro
|
12
|
+
attr_accessor :paid, :amount_left, :redirect_uri
|
13
|
+
attr_accessor :error, :message, :errors
|
14
|
+
|
15
|
+
def save
|
16
|
+
# Uses the invoices helper class to create and update
|
17
|
+
# Copies the returned invoices' attributes over to its own.
|
18
|
+
if self.new_record?
|
19
|
+
self.attributes = Kojn.invoices.create(self.attributes).attributes
|
20
|
+
else
|
21
|
+
self.attributes = Kojn.invoices.update(self.internal_id, self.attributes).attributes
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns whether this 'record' is new. Inspired by rails :)
|
26
|
+
# TODO Make sure if a newly initialized object's internal_id is actually set to nil.
|
27
|
+
def new_record?
|
28
|
+
self.internal_id == nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
data/lib/kojn/ipn.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Kojn
|
2
|
+
class Ipn
|
3
|
+
ENCRYPTION = 1
|
4
|
+
INTEGRITY = 2
|
5
|
+
|
6
|
+
attr_accessor :mode, :content, :invoice, :token
|
7
|
+
|
8
|
+
def initialize params
|
9
|
+
self.content = params
|
10
|
+
|
11
|
+
self.ensure_secure(params)
|
12
|
+
|
13
|
+
if params['token']
|
14
|
+
self.mode = Kojn::Ipn::INTEGRITY
|
15
|
+
self.invoice = params['invoice']
|
16
|
+
self.token = params['token']
|
17
|
+
|
18
|
+
raise AuthenticityException.new("ERROR -*- IPN Could not be verified. Please notify Kojn authors. This message has been fabricated. -*- ERROR") unless self.authentic?
|
19
|
+
elsif params['iv']
|
20
|
+
self.mode = Kojn::Ipn::ENCRYPTION
|
21
|
+
self.decrypt
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create a real object.
|
25
|
+
self.invoice = Kojn::Invoice.new(self.invoice)
|
26
|
+
end
|
27
|
+
|
28
|
+
def authentic?
|
29
|
+
raise AuthenticityException.new("Checking if message is authentic while mode is set to Encryption") unless self.mode == Kojn::Ipn::INTEGRITY
|
30
|
+
|
31
|
+
sha = Digest::SHA2.hexdigest "#{Kojn.api_key}#{self.invoice['internal_id']}#{self.invoice['received_amount']}"
|
32
|
+
Rails.logger.info "sha: #{sha} tokne: #{self.token}"
|
33
|
+
|
34
|
+
sha == self.token
|
35
|
+
end
|
36
|
+
|
37
|
+
def decrypt
|
38
|
+
self.invoice = Kojn::crypto.decrypt_params(self.content)
|
39
|
+
end
|
40
|
+
|
41
|
+
def ensure_secure(params)
|
42
|
+
if (params['token'] && Kojn.ipn_sec == :integrity) || (params['iv'] && Kojn.ipn_sec == :encryption)
|
43
|
+
true
|
44
|
+
else
|
45
|
+
raise Kojn::AuthenticityException.new("ERROR -*- IPN security expected: #{Kojn.ipn_sec}. Opposite was found. -*- ERROR")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class AuthenticityException<Exception;end
|
51
|
+
end
|
data/lib/kojn/model.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Kojn
|
2
|
+
class Model
|
3
|
+
if ActiveModel::VERSION::MAJOR <= 3
|
4
|
+
include ActiveModel::Validations
|
5
|
+
include ActiveModel::Conversion
|
6
|
+
extend ActiveModel::Naming
|
7
|
+
|
8
|
+
def initialize(attributes = {})
|
9
|
+
self.attributes = attributes
|
10
|
+
end
|
11
|
+
else
|
12
|
+
include ActiveModel::Model
|
13
|
+
end
|
14
|
+
|
15
|
+
# Set the attributes based on the given hash
|
16
|
+
def attributes=(attributes = {})
|
17
|
+
attributes.each do |name, value|
|
18
|
+
send("#{name}=", value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a hash with the current instance variables
|
23
|
+
def attributes
|
24
|
+
Hash[instance_variables.map { |name| [name, instance_variable_get(name)] }]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/kojn/net.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
module Kojn
|
2
|
+
module Net
|
3
|
+
def self.to_uri(path)
|
4
|
+
return "http#{Kojn.ssl ? "s" : ""}://#{Kojn.host}:#{Kojn.port}#{path}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.curl(verb, path, options={})
|
8
|
+
verb = verb.upcase.to_sym
|
9
|
+
|
10
|
+
c = Curl::Easy.new(self.to_uri(path))
|
11
|
+
c.http(verb)
|
12
|
+
|
13
|
+
if verb != :GET
|
14
|
+
c.post_body = options.to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
c.headers['Content-Type'] = 'application/json'
|
18
|
+
c.http_auth_types = :basic
|
19
|
+
c.username = Kojn.api_key
|
20
|
+
|
21
|
+
return c
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.get(path, options={})
|
25
|
+
request = self.curl(:GET, path, options)
|
26
|
+
|
27
|
+
request.perform
|
28
|
+
|
29
|
+
return request
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.post(path, options={})
|
33
|
+
request = self.curl(:POST, path, options)
|
34
|
+
|
35
|
+
request.perform
|
36
|
+
|
37
|
+
return request
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.patch(path, options={})
|
41
|
+
request = self.curl(:PATCH, path, options)
|
42
|
+
|
43
|
+
request.perform
|
44
|
+
|
45
|
+
return request
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.delete(path, options={})
|
49
|
+
request = self.curl(:DELETE, path, options)
|
50
|
+
|
51
|
+
request.perform
|
52
|
+
|
53
|
+
return request
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/kojn/net_old.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Kojn
|
2
|
+
module Net
|
3
|
+
def self.http
|
4
|
+
if defined?(Rails) && Rails.env == 'development'
|
5
|
+
http = ::Net::HTTP.new('localhost', 3000)
|
6
|
+
else
|
7
|
+
http = ::Net::HTTP.new('kojn.nl', 443)
|
8
|
+
|
9
|
+
http.use_ssl = true
|
10
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
return http
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get(uri, options={})
|
18
|
+
request = ::Net::HTTP::Get.new(uri)
|
19
|
+
|
20
|
+
request.content_type = 'application/json'
|
21
|
+
request.basic_auth Kojn.api_key, ''
|
22
|
+
request.body = options.to_json
|
23
|
+
|
24
|
+
self.http.request(request)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.post(uri, options={})
|
28
|
+
request = ::Net::HTTP::Post.new(uri)
|
29
|
+
|
30
|
+
request.content_type = 'application/json'
|
31
|
+
request.basic_auth Kojn.api_key, ''
|
32
|
+
request.body = options.to_json
|
33
|
+
|
34
|
+
self.http.request(request)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.patch(uri, options={})
|
38
|
+
request = ::Net::HTTP::Patch.new(uri)
|
39
|
+
|
40
|
+
request.content_type = 'application/json'
|
41
|
+
request.basic_auth Kojn.api_key, ''
|
42
|
+
request.body = options.to_json
|
43
|
+
|
44
|
+
self.http.request(request)
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.delete(uri, options={})
|
49
|
+
request = ::Net::HTTP::Delete.new(uri)
|
50
|
+
|
51
|
+
request.content_type = 'application/json'
|
52
|
+
request.basic_auth Kojn.api_key, ''
|
53
|
+
request.body = options.to_json
|
54
|
+
|
55
|
+
self.http.request(request)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Kojn
|
2
|
+
def self.parse_objects!(string, klass)
|
3
|
+
objects = JSON.parse(string)
|
4
|
+
objects.collect do |t_json|
|
5
|
+
Kojn.parse_object!(t_json, klass)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.parse_object!(object, klass)
|
10
|
+
object = JSON.parse(object) if object.is_a? String
|
11
|
+
|
12
|
+
klass.new(object)
|
13
|
+
end
|
14
|
+
|
15
|
+
class Transactions
|
16
|
+
attr_accessor :access_token
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
self.access_token = Kojn.api_key
|
20
|
+
end
|
21
|
+
|
22
|
+
def all(options = {})
|
23
|
+
Kojn.parse_objects! Kojn::Net::get('/api/transactions').read_body, Kojn::Tx
|
24
|
+
end
|
25
|
+
|
26
|
+
def create(options = {})
|
27
|
+
Kojn.parse_object! Kojn::Net::post('/api/transactions', {transaction: options}).read_body, Kojn::Tx
|
28
|
+
end
|
29
|
+
|
30
|
+
def find(id, options = {})
|
31
|
+
Kojn.parse_object! Kojn::Net::get("/api/transactions/#{id}").read_body, Kojn::Tx
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(id, options = {})
|
35
|
+
Kojn.parse_object! Kojn::Net::patch("/api/transactions/#{id}", options).read_body, Kojn::Tx
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Tx
|
40
|
+
UNCONFIRMED = 1
|
41
|
+
INSUFFICIENT = 2
|
42
|
+
SEEN = 3
|
43
|
+
CANCELLED = 4
|
44
|
+
|
45
|
+
if ActiveModel::VERSION::MAJOR <= 3
|
46
|
+
include ActiveModel::Validations
|
47
|
+
include ActiveModel::Conversion
|
48
|
+
extend ActiveModel::Naming
|
49
|
+
|
50
|
+
def initialize(attributes = {})
|
51
|
+
self.attributes = attributes
|
52
|
+
end
|
53
|
+
else
|
54
|
+
include ActiveModel::Model
|
55
|
+
end
|
56
|
+
|
57
|
+
include Kojn::Model
|
58
|
+
|
59
|
+
attr_accessor :internal_id, :external_id, :address, :currency, :amount, :amount_in_euro, :exchange_rate, :status, :received_amount, :description, :seen, :received_amount_in_euro, :confirmed
|
60
|
+
attr_accessor :paid, :amount_left, :redirect_uri
|
61
|
+
attr_accessor :error, :message, :errors
|
62
|
+
|
63
|
+
def save
|
64
|
+
# Uses the transactions helper class to create and update
|
65
|
+
# Copies the returned transactions' attributes over to its own.
|
66
|
+
if self.new_record?
|
67
|
+
self.attributes = Kojn.transactions.create(self.attributes).attributes
|
68
|
+
else
|
69
|
+
self.attributes = Kojn.transactions.update(self.internal_id, self.attributes).attributes
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns whether this 'record' is new. Inspired by rails :)
|
74
|
+
# TODO Make sure if a newly initialized object's internal_id is actually set to nil.
|
75
|
+
def new_record?
|
76
|
+
self.internal_id == nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
data/lib/kojn/version.rb
ADDED
data/spec/.rspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Kojn::Coin < Kojn::Model;end
|
4
|
+
class Kojn::Coins < Kojn::Collection;end
|
5
|
+
|
6
|
+
describe Kojn::Coins do
|
7
|
+
let(:kojns) { Kojn::Coins.new }
|
8
|
+
|
9
|
+
it 'should have a name representing the class his name but not modules' do
|
10
|
+
kojns.name.should eq 'coin'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'module should reflect a singular form' do
|
14
|
+
kojns.module.should eq "kojn/coin"
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should have a model' do
|
18
|
+
kojns.model.should be Kojn::Coin
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should have an api end point' do
|
22
|
+
kojns.path.should eq "/api/coins"
|
23
|
+
end
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require './lib/kojn'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
config.filter_run :focus
|
13
|
+
|
14
|
+
# Run specs in random order to surface order dependencies. If you find an
|
15
|
+
# order dependency and want to debug it, you can fix the order by providing
|
16
|
+
# the seed, which is printed after each run.
|
17
|
+
# --seed 1234
|
18
|
+
config.order = 'random'
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Move this
|
4
|
+
def stub_http(response)
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
http = double('http')
|
8
|
+
# TODO We need some real data here
|
9
|
+
http.stub(:read_body).and_return(response.to_json)
|
10
|
+
http.stub(:"use_ssl=")
|
11
|
+
http.stub(:"verify_mode=")
|
12
|
+
http.stub(:"request").and_return(http)
|
13
|
+
|
14
|
+
::Net::HTTP.stub!(:new).and_return(http)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Kojn::Invoice do
|
18
|
+
before :each do
|
19
|
+
stub_http({test: 'stuff'})
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should not fail' do
|
23
|
+
Kojn::Net.get('/bullshit').read_body.should eq "{\"test\":\"stuff\"}"
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kojn
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeffrey Wilcke
|
8
|
+
- Maran Hidskes
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activemodel
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: activesupport
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: curb
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>'
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.8.1
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>'
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.8.1
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: bundler
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.3'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.3'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rake
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
description: Ruby gem for communicating with the kojn.nl API. Allows you to create
|
85
|
+
and managed invoices.
|
86
|
+
email:
|
87
|
+
- maran.hidskes@gmail.com
|
88
|
+
- jeff.wilcke@gmail.com
|
89
|
+
executables: []
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- .gitignore
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- kojn.gemspec
|
99
|
+
- lib/app.rb
|
100
|
+
- lib/kojn.rb
|
101
|
+
- lib/kojn/collection.rb
|
102
|
+
- lib/kojn/crypto.rb
|
103
|
+
- lib/kojn/invoice.rb
|
104
|
+
- lib/kojn/ipn.rb
|
105
|
+
- lib/kojn/model.rb
|
106
|
+
- lib/kojn/net.rb
|
107
|
+
- lib/kojn/net_old.rb
|
108
|
+
- lib/kojn/transaction.rb
|
109
|
+
- lib/kojn/version.rb
|
110
|
+
- spec/.rspec
|
111
|
+
- spec/collection_spec.rb
|
112
|
+
- spec/inflector_spec.rb
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
- spec/transaction_spec.rb
|
115
|
+
homepage: https://kojn.nl
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 2.0.3
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: Ruby gem for communicating with the kojn.nl API.
|
139
|
+
test_files:
|
140
|
+
- spec/.rspec
|
141
|
+
- spec/collection_spec.rb
|
142
|
+
- spec/inflector_spec.rb
|
143
|
+
- spec/spec_helper.rb
|
144
|
+
- spec/transaction_spec.rb
|