inkdit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.swp
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
6
+ .yardoc
7
+ doc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in inkdit.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Inkdit API Client Library #
2
+
3
+ ## Obtaining an API Key ##
4
+
5
+ To use the Inkdit API you need to [register your application](https://developer.inkdit.com/apps/register).
6
+ Once your application is registered, you'll be given an API key and a shared secret.
7
+
8
+ Inkdit::Config['api_key'] = '...'
9
+ Inkdit::Config['secret'] = '...'
10
+
11
+ ## Obtaining an Access Token ##
12
+
13
+ Accessing the API requires an [OAuth 2](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1) access token.
14
+ This means the user needs to give your application authorization to access their account.
15
+
16
+ First, you redirect the user to the authorization code URL:
17
+
18
+ redirect_to Inkdit.authorization_code_url(scopes, redirect_uri)
19
+
20
+ `scopes` is the list of permissions that your application needs (see https://developer.inkdit.com/docs/read/Home).
21
+ When the user authorizes your application (or denies authorization), their browser will be redirected to `redirect_uri`.
22
+
23
+ If the authorization is successfully, a `code` parameter will be included when the user is redirected.
24
+
25
+ access_token = Inkdit.get_token(params[:code], redirect_uri)
26
+
27
+ You should store this token somewhere.
28
+
29
+ some_storage_function(current_user, access_token.token, access_token.refresh_token, access_token.expires_at)
30
+
31
+ For the full details (including what a client needs to do for security and error
32
+ handling), read the [OAuth 2 spec](htjp://tools.ietf.org/html/draft-ietf-oauth-v2-22).
33
+
34
+ ## Using the API ##
35
+
36
+ At last, we're ready to go! Once everything is set up, you can create an `Inkdit::Client` using the access token you stored:
37
+
38
+ client = Inkdit::Client.new(:access_token => ..., :expires_at => ..., :refresh_token => ...)
39
+
40
+ The first thing to do is find out who this access token belongs to:
41
+
42
+ entity = client.get_entity
43
+
44
+ Then you might want to take a look at that entity's contracts:
45
+
46
+ entity.get_contracts
47
+
48
+ or create a new contract:
49
+
50
+ params = { :name => '...', :content => '...' }
51
+ contract = Inkdit::Contract.create(client, entity, params)
52
+
53
+ Given an `Inkdit::Contract`, you can list the signature fields:
54
+
55
+ contract.fetch!
56
+ contract.signatures
57
+
58
+ and sign an unsigned field:
59
+
60
+ signature_field.sign!
61
+
62
+ If you know the URL of a form contract, you can sign it:
63
+
64
+ form_contract = Inkdit::FormContract.new client, form_contract_url
65
+ form_contract.fetch!
66
+ form_contract.sign!
67
+
68
+ ## Running the Specs ##
69
+
70
+ To run the specs you need a config.yml file containing your API key, shared secret, and access token.
71
+ Once you've obtained an API key, there's a demo application that can be used to obtain an access token:
72
+
73
+ ./script/get_access_token.rb
74
+
75
+ Then visit http://localhost:4567/ in your browser.
76
+
77
+ Once you've entered your API key and shared scret, you will be prompted to log
78
+ into Inkdit and authorize the application. When the application is authorized, it will produce a file that you can copy and paste into config.yml.
79
+
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ require 'yard'
6
+ require 'yard/rake/yardoc_task'
7
+
8
+ RSpec::Core::RakeTask.new('spec')
9
+ YARD::Rake::YardocTask.new
data/inkdit.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "inkdit/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "inkdit"
7
+ s.version = Inkdit::VERSION
8
+ s.authors = ["Brendan Taylor"]
9
+ s.email = ["brendan@inkdit.com"]
10
+ s.homepage = "https://developer.inkdit.com/"
11
+ s.summary = %q{A library for using the Inkdit API to sign, share and store contracts}
12
+ s.description = %q{This is both a working Ruby gem and a code sample that other client implementations can work from.}
13
+
14
+ s.rubyforge_project = "inkdit"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "oauth2"
22
+
23
+ # documentation
24
+ s.add_development_dependency "yard"
25
+
26
+ # test dependencies
27
+ s.add_development_dependency "rspec"
28
+ s.add_development_dependency "vcr"
29
+
30
+ # dependencies for our access token getter
31
+ s.add_development_dependency "sinatra"
32
+ s.add_development_dependency "haml"
33
+ end
data/lib/inkdit.rb ADDED
@@ -0,0 +1,64 @@
1
+ require "inkdit/version"
2
+
3
+ require "inkdit/client"
4
+ require "inkdit/resource"
5
+
6
+ require "inkdit/entity"
7
+
8
+ require "inkdit/contract"
9
+ require "inkdit/form_contract"
10
+
11
+ require "inkdit/signature"
12
+ require "inkdit/signature_field"
13
+
14
+ require "oauth2"
15
+
16
+ module Inkdit
17
+ # global configuration for the client.
18
+ # this has to be set up for anything to work. It must have the keys:
19
+ #
20
+ # +api_key+:: your application's API key, obtained from https://developer.inkdit.com/
21
+ # +secret+:: your application's shared secret, obtained from https://developer.inkdit.com/
22
+ #
23
+ # It can optionally have the key:
24
+ #
25
+ # +debug+:: +true+ if you want HTTP requests and responses printed to stdout.
26
+ Config = {}
27
+
28
+ # @param [Array<String,Symbol>] scopes an Array of the permissions that your application needs (see https://developer.inkdit.com/docs/read/Home)
29
+ # @param [String] redirect_uri the URL that the user should be redirected to after the authorization code is obtained (OAuth 2 section 4.1.2)
30
+ #
31
+ # @return [String] the URL that the user should be sent to to obtain an authorization code. (OAuth 2 section 4.1.1)
32
+ def self.authorization_code_url(scopes, redirect_uri)
33
+ scopes = scopes.join('%20')
34
+ "https://inkdit.com/oauth?response_type=code&client_id=#{Config['api_key']}&scope=#{scopes}&redirect_uri=#{redirect_uri}"
35
+ end
36
+
37
+ # you probably don't want to call this.
38
+ #
39
+ # @return [OAuth2::Client]
40
+ def self.oauth_client # :nodoc:
41
+ api_key = Inkdit::Config['api_key']
42
+ secret = Inkdit::Config['secret']
43
+
44
+ opts = { :site => 'https://api.inkdit.com/',
45
+ :token_url => '/token',
46
+ :raise_errors => false
47
+ }
48
+
49
+ OAuth2::Client.new(api_key, secret, opts)
50
+ end
51
+
52
+ # requests an access token using an authorization code (OAuth 2 section 4.1.3/4.1.4)
53
+ #
54
+ # @param [String] authorization_code the authorization code Inkdit passed to your application
55
+ # @param [String] redirect_uri the redirect URI you used when requesting the authorization code
56
+ #
57
+ # @return [OAuth2::AccessToken]
58
+ def self.get_token(authorization_code, redirect_uri)
59
+ self.oauth_client.auth_code.get_token(authorization_code, :redirect_uri => redirect_uri)
60
+ end
61
+
62
+ # an exception that's raised when a request fails due to an invalid access token
63
+ class Unauthorized < Exception; end
64
+ end
@@ -0,0 +1,87 @@
1
+ module Inkdit
2
+ # a client that can issue authenticated HTTP requests to Inkdit's API.
3
+ class Client
4
+ # +token+ is a Hash containing the details of the access token returned by {Inkdit.get_token}.
5
+ # The keys +access_token+, +refresh_token+, and +expires_at+ are required.
6
+ def initialize(token)
7
+ # AccessToken#from_hash modifies the hash it's passed.
8
+ @access_token = OAuth2::AccessToken.from_hash(oauth_client, token.clone)
9
+ end
10
+
11
+ # @return [Entity] the entity that this access token belongs to
12
+ def get_entity
13
+ response = get '/v1/'
14
+
15
+ entity = response.parsed["entities"].first
16
+ Entity.new(self, entity)
17
+ end
18
+
19
+ # issue an HTTP +GET+.
20
+ # @return [OAuth2::Response]
21
+ def get(path)
22
+ request(:get, path, {})
23
+ end
24
+
25
+ # issue an HTTP +POST+.
26
+ # @return [OAuth2::Response]
27
+ def post(path, params)
28
+ request(:post, path, params)
29
+ end
30
+
31
+ # issue an HTTP +PUT+.
32
+ # @return [OAuth2::Response]
33
+ def put(path, params)
34
+ request(:put, path, params)
35
+ end
36
+
37
+ # issue an HTTP +DELETE+.
38
+ # @return [OAuth2::Response]
39
+ def delete(path, params)
40
+ request(:delete, path, {})
41
+ end
42
+
43
+ private
44
+
45
+ def oauth_client
46
+ @_oauth_client ||= Inkdit.oauth_client
47
+ end
48
+
49
+ def when_debugging
50
+ yield if Inkdit::Config['debug']
51
+ end
52
+
53
+ # issue an HTTP request.
54
+ # @return [OAuth2::Response]
55
+ def request(method, path, params)
56
+ when_debugging do
57
+ puts '---'
58
+ puts "#{method.to_s.upcase} #{path}"
59
+ puts params.inspect
60
+ puts
61
+ end
62
+
63
+ response = @access_token.send(method, path, params)
64
+
65
+ when_debugging do
66
+ puts response.status
67
+ puts response.body
68
+ puts
69
+ end
70
+
71
+ checked_response(response)
72
+ end
73
+
74
+ # raises {Inkdit::Unauthorized} if the response indicates an invalid access token.
75
+ # @return [OAuth2::Response]
76
+ def checked_response(response)
77
+ if response.status == 401 and response.headers['www-authenticate'].match /invalid_token/
78
+ # wrong access token or the user rescinded the app's access.
79
+ # TODO: properly parse the header
80
+ # Bearer realm="api.inkdit.com", error="invalid_token"
81
+ raise Inkdit::Unauthorized
82
+ end
83
+
84
+ response
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,72 @@
1
+ module Inkdit
2
+ # Represents an {https://developer.inkdit.com/docs/read/Contract_Description Inkdit Contract}.
3
+ class Contract < Resource
4
+ # create a new contract.
5
+ #
6
+ # @param [Client] client the client to create this contract with
7
+ # @param [Entity] owner the entity that will own this contract
8
+ # @param [Hash] params the details of the new contract.
9
+ # this should include the basic details required in a
10
+ # {https://developer.inkdit.com/docs/read/Contract_Description Contract Description}.
11
+ #
12
+ # @return [Contract] contract the newly created contract
13
+ def self.create(client, owner, params)
14
+ response = client.post owner.contracts_link, { :body => params.to_json, :headers => { 'Content-Type' => 'application/json' } }
15
+ self.new(client, response.parsed)
16
+ end
17
+
18
+ # @return [String] a human-readable name for the contract
19
+ def name
20
+ @params['name']
21
+ end
22
+
23
+ # @return [String] the contract's content
24
+ def content
25
+ @params['content']
26
+ end
27
+
28
+ # whether the cantract is a test contract or not
29
+ def test?
30
+ @params['test']
31
+ end
32
+
33
+ # the URL of this contract's HTML representation.
34
+ def html_link
35
+ @params['links']['html']
36
+ end
37
+
38
+ def sharing_link
39
+ @params['links']['shared-with']
40
+ end
41
+
42
+ # an opaque string indicating the version of the contract's content
43
+ def content_updated_at
44
+ @params['content_updated_at']
45
+ end
46
+
47
+ # @return [Array<Signature,SignatureField>] this contract's signatures and unsigned signature fields
48
+ def signatures
49
+ @params['signatures'].map do |s|
50
+ if s['signed_by']
51
+ Inkdit::Signature.new(@client, s)
52
+ else
53
+ Inkdit::SignatureField.new(@client, self, s)
54
+ end
55
+ end
56
+ end
57
+
58
+ # @param [Entity] individual the individual who should be connected to the contract
59
+ # @param [Entity] entity the entity that the individual should be connected to the contract through
60
+ def share_with(individual, entity)
61
+ params = {
62
+ :individual => {
63
+ :url => individual
64
+ },
65
+ :entity => {
66
+ :url => entity
67
+ }
68
+ }
69
+ @client.post self.sharing_link, { :body => params.to_json, :headers => { 'Content-Type' => 'application/json' } }
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,37 @@
1
+ module Inkdit
2
+ # Represents an {https://developer.inkdit.com/docs/read/Entity_Description Inkdit Entity}.
3
+ class Entity < Resource
4
+ # this entity's type. +'individual'+ or +'organization'+.
5
+ def type
6
+ @params['type']
7
+ end
8
+
9
+ # this entity's human-readable name.
10
+ def label
11
+ @params['label']
12
+ end
13
+
14
+ # the URL of this entity's HTML representation.
15
+ def html_link
16
+ @params['links']['html']
17
+ end
18
+
19
+ # the URL of this entity's Contract Collection
20
+ def contracts_link
21
+ @params['links']['contracts']
22
+ end
23
+
24
+ # retrieves this entity's Contract Collection
25
+ # @return [Array<Contract>] the contracts in this entity's Contract Collection
26
+ def get_contracts
27
+ response = @client.get(contracts_link)
28
+ response.parsed['resources'].map do |contract_params|
29
+ Contract.new @client, contract_params
30
+ end
31
+ end
32
+
33
+ def inspect
34
+ "#<Inkdit::Entity type=#{type} label=#{label}>"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ module Inkdit
2
+ # represents a form contract on Inkdit
3
+ class FormContract < Resource
4
+ # @return [String] a human-readable name for the contract
5
+ def name
6
+ @params['name']
7
+ end
8
+
9
+ # @return [String] the contract's content
10
+ def content
11
+ @params['content']
12
+ end
13
+
14
+ def signatures_link
15
+ @params['links']['signatures']
16
+ end
17
+
18
+ # an opaque string indicating the version of the form contract's content
19
+ def content_updated_at
20
+ @params['content_updated_at']
21
+ end
22
+
23
+ # sign this field as the user and entity associated with the current access token.
24
+ # @return [Signature] the newly-created signature
25
+ def sign!
26
+ params = { :if_updated_at => self.content_updated_at }
27
+ response = @client.post self.signatures_link, { :body => params.to_json, :headers => { 'Content-Type' => 'application/json' } }
28
+
29
+ Inkdit::Signature.new(@client, response.parsed)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,41 @@
1
+ module Inkdit
2
+ # some resource (in the REST sense) in the system
3
+ class Resource
4
+ # the URL of this resource
5
+ attr_reader :url
6
+
7
+ # @param [Client] client the client to use this resource with
8
+ # @param [String,Hash] opts either the resource's URL, or a hash describing the resource
9
+ def initialize(client, opts)
10
+ @client = client
11
+
12
+ if opts.is_a? String
13
+ @url = opts
14
+ @params = []
15
+ else
16
+ self.params = opts
17
+ end
18
+ end
19
+
20
+ # retrieve this resource using its URL.
21
+ def fetch!
22
+ response = @client.get(self.url)
23
+ @params = response.parsed
24
+ end
25
+
26
+ def ==(other_resource)
27
+ self.url == other_resource.url
28
+ end
29
+
30
+ def inspect
31
+ "#<#{self.class.inspect} params=#{@params}>"
32
+ end
33
+
34
+ private
35
+
36
+ def params=(params)
37
+ @params = params
38
+ @url = params['url']
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,34 @@
1
+ module Inkdit
2
+ # Represents a signed {https://developer.inkdit.com/docs/read/Signature_Description signature placeholder}.
3
+ class Signature
4
+ def initialize(client, params)
5
+ @client = client
6
+ @params = params
7
+ end
8
+
9
+ # @return [Entity] the individual who signed this field
10
+ def signed_by
11
+ Inkdit::Entity.new(@client, @params['signed_by'])
12
+ end
13
+
14
+ # @return [Entity] the entity this field was signed on behalf of
15
+ def on_behalf_of
16
+ Inkdit::Entity.new(@client, @params['on_behalf_of'])
17
+ end
18
+
19
+ # @return [Time] when this field was signed
20
+ def signed_at
21
+ Time.parse(params['signed_at'])
22
+ end
23
+
24
+ # @return [Contract] the contract this field is part of
25
+ def contract
26
+ return unless @params['contract']
27
+ Inkdit::Contract.new @client, @params['contract']
28
+ end
29
+
30
+ def inspect
31
+ "#<#{self.class.inspect} params=#{@params}>"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ module Inkdit
2
+ # Represents an unsigned {https://developer.inkdit.com/docs/read/Signature_Description signature placeholder}.
3
+ class SignatureField
4
+ def initialize(client, contract, params)
5
+ @client = client
6
+ @contract = contract
7
+ @params = params
8
+ end
9
+
10
+ # @return [String] the URL of this signature field
11
+ def url
12
+ @params['url']
13
+ end
14
+
15
+ # sign this field as the user and entity associated with the current access token.
16
+ # @return [Signature] the newly-created signature
17
+ def sign!
18
+ params = {
19
+ :if_updated_at => @contract.content_updated_at
20
+ }
21
+
22
+ response = @client.put self.url, { :body => params.to_json, :headers => { 'Content-Type' => 'application/json' } }
23
+
24
+ Inkdit::Signature.new(@client, response.parsed)
25
+ end
26
+
27
+ def inspect
28
+ "#<#{self.class.inspect} params=#{@params}>"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Inkdit
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'inkdit'
6
+
7
+ require 'sinatra'
8
+ require 'haml'
9
+
10
+ get '/' do
11
+ haml <<END
12
+ %div
13
+ %form{:action => '/get-auth-code'}
14
+ %p First, I need your details for accessing the Inkdit API:
15
+ %label
16
+ API Key:
17
+ %input{:name => 'api_key'}
18
+ %br
19
+ %label
20
+ Secret:
21
+ %input{:name => 'secret'}
22
+ %br
23
+ %input{:type => 'submit'}
24
+ END
25
+ end
26
+
27
+ get '/get-auth-code' do
28
+ Inkdit::Config['api_key'] = params[:api_key]
29
+ Inkdit::Config['secret'] = params[:secret]
30
+
31
+ redirect_url = url('/got-auth-code')
32
+ auth_code_url = Inkdit.authorization_code_url([:read, :write, :sign], redirect_url)
33
+
34
+ redirect auth_code_url
35
+ end
36
+
37
+ get '/got-auth-code' do
38
+ auth_code = params[:code]
39
+
40
+ @access_token = Inkdit.get_token(params[:code], url('/got-auth-code'))
41
+
42
+ config = {
43
+ 'api_key' => Inkdit::Config['api_key'],
44
+ 'secret' => Inkdit::Config['secret'],
45
+ 'access_token' => {
46
+ 'access_token' => @access_token.token,
47
+ 'refresh_token' => @access_token.refresh_token,
48
+ 'expires_at' => @access_token.expires_at
49
+ }
50
+ }
51
+
52
+ <<END
53
+ <p>
54
+ Ok, we've got a thing for you! Save the below as config.yml.
55
+ </p>
56
+
57
+ <pre>
58
+ #{config.to_yaml}
59
+ </pre>
60
+ END
61
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Inkdit::Client do
4
+ before do
5
+ @client = Inkdit::Client.new(Inkdit::Config['access_token'])
6
+ end
7
+
8
+ it 'gives you information about the entity the client is authorized to access' do
9
+ entity = @client.get_entity
10
+
11
+ entity.type.should == 'individual'
12
+ entity.label.should == 'API Test'
13
+
14
+ entity.html_link.should_not be_nil
15
+ entity.contracts_link.should_not be_nil
16
+ end
17
+ end
@@ -0,0 +1,50 @@
1
+ require 'time'
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Inkdit::Contract do
6
+ before do
7
+ @client = Inkdit::Client.new(Inkdit::Config['access_token'])
8
+ end
9
+
10
+ it 'allows you to manipulate a contract' do
11
+ entity = @client.get_entity
12
+
13
+ contract_name = "API Test #{Time.now.iso8601}"
14
+
15
+ params = {
16
+ :name => contract_name,
17
+ :content => "<contract> <signature id='1' /></contract>",
18
+ :test => true
19
+ }
20
+
21
+ contract = Inkdit::Contract.create @client, entity, params
22
+
23
+ # the new contract should have the attributes we asked for
24
+ contract.name.should == contract_name
25
+ contract.should be_test
26
+
27
+ contract.html_link.should_not be_nil
28
+ contract.sharing_link.should_not be_nil
29
+
30
+ # the new contract should appear in the list of contracts
31
+ contracts = entity.get_contracts
32
+ contracts.find { |c| c.name == contract_name }.should_not be_nil
33
+
34
+ # the new contract can be signed
35
+ #
36
+ # first we need to fetch the full representation of the contract
37
+ # (since the other representation doesn't include signatures)
38
+ contract.fetch!
39
+
40
+ contract.signatures.length.should == 1
41
+ signature_field = contract.signatures.first
42
+
43
+ signature = signature_field.sign!
44
+
45
+ signature.signed_by.should == entity
46
+ signature.on_behalf_of.should == entity
47
+ end
48
+
49
+ pending 'sharing a contract (this is tough to do because it requires an entity URL)'
50
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Inkdit::FormContract do
4
+ before do
5
+ @client = Inkdit::Client.new(Inkdit::Config['access_token'])
6
+ end
7
+
8
+ it 'allows you to sign a form contract' do
9
+ # this is the path of the Web 2.0 Information Superhighway API Demo
10
+ form_contract_path = '/v1/offers/x53c396c3de147b54'
11
+
12
+ form_contract = Inkdit::FormContract.new @client, form_contract_path
13
+ form_contract.fetch!
14
+
15
+ form_contract.name.should == 'Web 2.0 Information Superhighway API Demo'
16
+ form_contract.signatures_link.should_not be_nil
17
+
18
+ signature = form_contract.sign!
19
+
20
+ signature.signed_by.should_not be_nil
21
+ signature.on_behalf_of.should_not be_nil
22
+
23
+ signature.contract.name.should == 'Web 2.0 Information Superhighway API Demo'
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'inkdit'
5
+
6
+ Inkdit::Config.merge! YAML.load_file('config.yml')
7
+
8
+ RSpec.configure do |config|
9
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inkdit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brendan Taylor
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: oauth2
16
+ requirement: &9892260 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *9892260
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ requirement: &9891720 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *9891720
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &9888300 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *9888300
47
+ - !ruby/object:Gem::Dependency
48
+ name: vcr
49
+ requirement: &9887800 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *9887800
58
+ - !ruby/object:Gem::Dependency
59
+ name: sinatra
60
+ requirement: &9887080 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *9887080
69
+ - !ruby/object:Gem::Dependency
70
+ name: haml
71
+ requirement: &9886460 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *9886460
80
+ description: This is both a working Ruby gem and a code sample that other client implementations
81
+ can work from.
82
+ email:
83
+ - brendan@inkdit.com
84
+ executables: []
85
+ extensions: []
86
+ extra_rdoc_files: []
87
+ files:
88
+ - .gitignore
89
+ - Gemfile
90
+ - Gemfile.lock
91
+ - README.md
92
+ - Rakefile
93
+ - inkdit.gemspec
94
+ - lib/inkdit.rb
95
+ - lib/inkdit/client.rb
96
+ - lib/inkdit/contract.rb
97
+ - lib/inkdit/entity.rb
98
+ - lib/inkdit/form_contract.rb
99
+ - lib/inkdit/resource.rb
100
+ - lib/inkdit/signature.rb
101
+ - lib/inkdit/signature_field.rb
102
+ - lib/inkdit/version.rb
103
+ - script/get_access_token.rb
104
+ - spec/client_spec.rb
105
+ - spec/contract_spec.rb
106
+ - spec/form_contract_spec.rb
107
+ - spec/spec_helper.rb
108
+ homepage: https://developer.inkdit.com/
109
+ licenses: []
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project: inkdit
128
+ rubygems_version: 1.8.10
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: A library for using the Inkdit API to sign, share and store contracts
132
+ test_files: []