hullio 0.1.0

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YzVkZjA3YzQ3OTA5MTA3NGJiZWFhOTA3NmZjMWE0ZDc4YmNjMTI3NA==
5
+ data.tar.gz: !binary |-
6
+ NTk3ZDA3NzVhZDg4ODk1Yzk0NzU3ZWJkNTA2OWI1NmU0MDE5ZmRjMg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MTRmM2YzNDY5YTk0YjlhYmZjYzdjN2VhZmI2ZTMxMjNjYjVmYjZhMzFhZDFj
10
+ ZThhZmE1MWIyZGMxM2NkYmViMmJhNjhkMzQzZTZkMzAwNTc3MDdkZjVmNThh
11
+ ZmQ0NmIyOTkzZGE2OWExNzUyNjNmMjRiZTliZDdhNGFmYzVhNzc=
12
+ data.tar.gz: !binary |-
13
+ ZDI0NjA5OTgyMjM4MTNlNTA4YmM0MWViOWJhMDcxY2ZiYzAzYTdmOWE5NTc1
14
+ NjhhNzA2NzA2MGNiZDI5NTY3MGVjZTkzMDQwZWYzNjQ2YzNkMjBkY2JjOWE2
15
+ MjljYjgyZWI1NDVhOGQ2ZTdkZTc3Y2U3MTdiZjg3YWZjOGU2OGM=
@@ -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 hullio.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Hull.io
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,74 @@
1
+ # Hull Ruby client
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'hullio'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install hullio
18
+
19
+ ## Usage
20
+
21
+ ### Configuration
22
+
23
+ Hull.configure do |c|
24
+ c.app_id = "your-app-id"
25
+ c.app_secret = "your-app-secret"
26
+ c.endpoint = "http://ORG-NAMESPACE.hullapp.io"
27
+ end
28
+
29
+ ### Making API Calls
30
+
31
+ `get`, `put`, `post` and `delete` methods are directly available on Hull.
32
+
33
+ examples:
34
+
35
+ # To get the current app
36
+ Hull.get('app')
37
+
38
+ # To get the a list of comments on the current app (with pagination)
39
+ Hull.get('app/comments', limit: 10, page: 2)
40
+
41
+ # To update an existing object
42
+ Hull.put('app', { name: 'My Super App' })
43
+
44
+ with Hull entities :
45
+
46
+ Hull.get('entity', { uid: 'http://example.com' })
47
+ Hull.put('entity', { uid: 'http://example.com', name: 'My super Page' })
48
+ Hull.delete('entity', { uid: 'http://example.com' })
49
+
50
+
51
+ ### Bring your own users
52
+
53
+ In addition to providing multiple social login options, Hull allows you to create and authenticate users that are registered within your own app.
54
+
55
+ To use this feature, you just have to add a `userHash` key at the initialization of hull.js :
56
+
57
+ In you view :
58
+
59
+ <script>
60
+ Hull.init({
61
+ appId: "<%= Hull.app_id %>",
62
+ orgUrl: "<%= Hull.endpoint %>",
63
+ userHash: "<%= Hull.user_hash({ id: "123", email: "bill@hullapp.io", name: "Bill Evans" }) %>"
64
+ });
65
+ </script>
66
+
67
+
68
+ ## Contributing
69
+
70
+ 1. Fork it
71
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
72
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
73
+ 4. Push to the branch (`git push origin my-new-feature`)
74
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/hull/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Stephane Bellity", "Hull"]
6
+ gem.email = ["stephane@hull.io"]
7
+ gem.description = %q{Hull Ruby Client}
8
+ gem.summary = %q{Hull Ruby Client}
9
+ gem.homepage = "http://hull.io"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "hullio"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Hull::VERSION
17
+
18
+ # Dependencies
19
+ gem.add_dependency 'faraday', '~> 0.8'
20
+ gem.add_dependency 'faraday_middleware', '~> 0.9'
21
+ gem.add_dependency 'multi_json'
22
+ gem.add_dependency 'mime-types'
23
+
24
+ # Development Dependencies
25
+ gem.add_development_dependency 'activesupport', ['>= 2.3.9', '< 4']
26
+
27
+ end
@@ -0,0 +1,30 @@
1
+ require 'hull/core_ext/hash'
2
+ require 'hull/client'
3
+ require 'hull/config'
4
+
5
+ module Hull
6
+ extend Config
7
+ class << self
8
+ # Alias for Hull::Client.new
9
+ #
10
+ # @return [Hull::Client]
11
+ def new(options={})
12
+ Hull::Client.new(options)
13
+ end
14
+
15
+ # Delegate to hull::Client
16
+ def method_missing(method, *args, &block)
17
+ return super unless new.respond_to?(method)
18
+ new.send(method, *args, &block)
19
+ end
20
+
21
+ def respond_to?(method, include_private=false)
22
+ new.respond_to?(method, include_private) || super(method, include_private)
23
+ end
24
+
25
+ def log msg, level=:debug
26
+ Hull.logger.send(level.to_sym, "[hull:#{Hull.domain}] #{msg}") if Hull.logger && Hull.logger.respond_to?(level.to_sym)
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,69 @@
1
+ require 'hull/config'
2
+ require 'hull/connection'
3
+ require 'hull/request'
4
+ require 'base64'
5
+ require 'openssl'
6
+
7
+ module Hull
8
+ class Client
9
+
10
+ attr_accessor *Config::VALID_OPTIONS_KEYS
11
+
12
+ include Hull::Connection
13
+ include Hull::Request
14
+
15
+ # Initializes a new API object
16
+ #
17
+ # @param attrs [Hash]
18
+ # @return [Hull::Client]
19
+ def initialize(attrs={})
20
+ attrs = Hull.options.merge(attrs)
21
+ Config::VALID_OPTIONS_KEYS.each do |key|
22
+ instance_variable_set("@#{key}".to_sym, attrs[key])
23
+ end
24
+ end
25
+
26
+ def credentials
27
+ {
28
+ :app_id => app_id,
29
+ :app_secret => app_secret
30
+ }
31
+ end
32
+
33
+ def app
34
+ return unless app_id
35
+ @app ||= get("/app", :app_id => app_id)
36
+ end
37
+
38
+
39
+ def read_cookie str
40
+ return if str.nil? || str.length == 0
41
+ JSON.parse(Base64.decode64(str)) rescue nil
42
+ end
43
+
44
+ def current_user_id user_id, user_sig
45
+ return unless user_id && user_sig
46
+ time, signature = user_sig.split(".")
47
+ data = [time, user_id].join("-")
48
+ digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha1'), self.app_secret, data)
49
+ return user_id if digest == signature
50
+ end
51
+
52
+ def authenticate_user env
53
+ require 'rack/request'
54
+ request = Rack::Request.new(env)
55
+ cookie = request.cookies["hull_#{self.app_id}"]
56
+ user_auth = read_cookie(cookie)
57
+ return unless user_auth
58
+ current_user_id(user_auth['Hull-User-Id'], user_auth['Hull-User-Sig'])
59
+ end
60
+
61
+ def user_hash user_infos
62
+ timestamp = Time.now.to_i.to_s
63
+ message = Base64.encode64(user_infos.to_json).gsub("\n", "")
64
+ sig = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha1'), app_secret, [message, timestamp].join(" "))
65
+ [message, sig, timestamp].join(" ")
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,85 @@
1
+ require 'hull/version'
2
+
3
+ module Hull
4
+ # Defines constants and methods related to configuration
5
+ module Config
6
+
7
+ # The HTTP connection adapter that will be used to connect if none is set
8
+ DEFAULT_ADAPTER = :net_http
9
+
10
+ # The Faraday connection options if none is set
11
+ DEFAULT_CONNECTION_OPTIONS = {}
12
+
13
+
14
+ # The client ID if none is set
15
+ DEFAULT_APP_SECRET = ENV['HULL_APP_SECRET']
16
+ DEFAULT_APP_ID = ENV['HULL_APP_ID']
17
+
18
+
19
+ # The endpoint that will be used to connect if none is set
20
+ #
21
+ DEFAULT_ENDPOINT = ENV['HULL_ORG_URL']
22
+
23
+ DEFAULT_CACHE_STORE = nil
24
+
25
+ DEFAULT_PROXY = nil
26
+
27
+ # The value sent in the 'User-Agent' header if none is set
28
+ DEFAULT_USER_AGENT = "Hull Ruby Gem #{Hull::VERSION}"
29
+
30
+ DEFAULT_LOGGER = nil
31
+
32
+ # An array of valid keys in the options hash when configuring a {Hull::Client}
33
+ VALID_OPTIONS_KEYS = [
34
+ :proxy,
35
+ :adapter,
36
+ :connection_options,
37
+ :app_id,
38
+ :app_secret,
39
+ :endpoint,
40
+ :user_agent,
41
+ :cache_store,
42
+ :logger
43
+ ]
44
+
45
+ attr_accessor *VALID_OPTIONS_KEYS
46
+
47
+ def domain
48
+ @domain ||= URI.parse(endpoint).host unless endpoint.nil?
49
+ end
50
+
51
+ # When this module is extended, set all configuration options to their default values
52
+ def self.extended(base)
53
+ base.reset
54
+ end
55
+
56
+ # Convenience method to allow configuration options to be set in a block
57
+ def configure
58
+ yield self
59
+ self
60
+ end
61
+
62
+ # Create a hash of options and their values
63
+ def options
64
+ options = {}
65
+ VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
66
+ options
67
+ end
68
+
69
+ # Reset all configuration options to defaults
70
+ def reset
71
+ @domain = nil
72
+ self.proxy = DEFAULT_PROXY
73
+ self.logger = DEFAULT_LOGGER
74
+ self.adapter = DEFAULT_ADAPTER
75
+ self.connection_options = DEFAULT_CONNECTION_OPTIONS
76
+ self.app_id = DEFAULT_APP_ID
77
+ self.app_secret = DEFAULT_APP_SECRET
78
+ self.endpoint = DEFAULT_ENDPOINT
79
+ self.user_agent = DEFAULT_USER_AGENT
80
+ self.cache_store = DEFAULT_CACHE_STORE
81
+ self
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,36 @@
1
+ require 'faraday'
2
+ require 'hull/request/auth'
3
+ require 'faraday_middleware/response/parse_json'
4
+ require 'faraday_middleware/response/caching'
5
+
6
+ module Hull
7
+ module Connection
8
+ private
9
+
10
+ # Returns a Faraday::Connection object
11
+ #
12
+ # @param options [Hash] A hash of options
13
+ # @return [Faraday::Connection]
14
+ def connection(options={})
15
+ default_options = {
16
+ :headers => {
17
+ :accept => 'application/json',
18
+ :user_agent => user_agent,
19
+ },
20
+ :ssl => {:verify => false},
21
+ :url => options.fetch(:endpoint, endpoint),
22
+ :timeout => 10,
23
+ :proxy => options.fetch(:proxy, proxy),
24
+ :open_timeout => 10
25
+ }
26
+ @connection ||= Faraday.new(default_options.deep_merge(connection_options)) do |builder|
27
+ builder.use Hull::Request::Auth, credentials
28
+ builder.use Faraday::Request::UrlEncoded
29
+ builder.use FaradayMiddleware::Caching, cache_store unless cache_store.nil?
30
+ builder.use FaradayMiddleware::ParseJson
31
+ builder.use Faraday::Response::RaiseError
32
+ builder.adapter(adapter)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ class Hash
2
+
3
+ # Merges self with another hash, recursively
4
+ #
5
+ # @param hash [Hash] The hash to merge
6
+ # @return [Hash]
7
+ def deep_merge(hash)
8
+ target = self.dup
9
+ hash.keys.each do |key|
10
+ if hash[key].is_a?(Hash) && self[key].is_a?(Hash)
11
+ target[key] = target[key].deep_merge(hash[key])
12
+ next
13
+ end
14
+ target[key] = hash[key]
15
+ end
16
+ target
17
+ end
18
+
19
+ end
@@ -0,0 +1,127 @@
1
+ require 'json'
2
+
3
+ module Hull
4
+
5
+ class Paywall
6
+
7
+
8
+ class Request
9
+
10
+ attr_reader :user_id, :authorized_contents
11
+
12
+ def initialize env, secret
13
+ @env = env
14
+ @secret = secret
15
+ @request = Rack::Request.new(env)
16
+ @user_id = Hull.authenticate_user(env)
17
+ @cookie_name = "_hull_p#{Hull.app_id}"
18
+ raw_cookie = @request.cookies[@cookie_name]
19
+ if raw_cookie
20
+ decoded_cookie = Base64.decode64(raw_cookie) rescue nil
21
+ sig, val = JSON.parse(decoded_cookie) rescue []
22
+ @authorized_contents = check_signature(sig, val) ? val : []
23
+ end
24
+ @authorized_contents ||= []
25
+ end
26
+
27
+ def sign val
28
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha1'), @secret, val)
29
+ end
30
+
31
+ def check_signature sig, val
32
+ return false unless @user_id
33
+ return false if sig.nil? || val.nil?
34
+ sig == sign(val.to_json)
35
+ end
36
+
37
+ def fetch_authorized_contents
38
+ return [] if @user_id.nil?
39
+ badges = Hull.get("#{user_id}/badges") || []
40
+ @authorized_contents = badges.map do |badge|
41
+ if badge['data'] && badge['data']['transactions']
42
+ badge['data']['transactions'].map do |k,t|
43
+ t['permalink']
44
+ end
45
+ end
46
+ end.compact.flatten.uniq.sort
47
+ @authorized_contents
48
+ end
49
+
50
+ def check_authorization_for key
51
+ return false unless @user_id
52
+ @authorized_contents.include?(key) or fetch_authorized_contents.include?(key)
53
+ end
54
+
55
+ def set_cookie headers
56
+ if !@user_id.nil? && @authorized_contents.length > 0
57
+ signed_cookie = Base64.encode64([sign(@authorized_contents.to_json), @authorized_contents].to_json)
58
+ Rack::Utils.set_cookie_header!(headers, @cookie_name, {
59
+ :value => signed_cookie,
60
+ :path => "/"
61
+ })
62
+ else
63
+ Rack::Utils.delete_cookie_header!(headers, @cookie_name, {
64
+ :path => "/"
65
+ })
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ def initialize app, options={}
72
+ @app = app
73
+ @options = options
74
+ Hull.configure do |config|
75
+ config.app_id = @options[:app_id] || ENV['HULL_APP_ID']
76
+ config.app_secret = @options[:app_secret] || ENV['HULL_APP_SECRET']
77
+ config.endpoint = @options[:endpoint] || ENV['HULL_ORG_URL']
78
+ end
79
+ @paths = @options[:paths].map { |k,v| [Regexp.new(k), v] }
80
+ end
81
+
82
+ def secure_content env, rule
83
+ paywall = Hull::Paywall::Request.new(env, Hull.app_secret)
84
+ if paywall.check_authorization_for(rule[:permalink])
85
+ status, headers, body = @app.call(env)
86
+ paywall.set_cookie(headers)
87
+ [status, headers, body]
88
+ else
89
+ status = 302
90
+ redirect_to = rule[:redirect] || '/'
91
+ headers = { 'Content-Type' => 'text/html' }
92
+ body = ''
93
+ if env['PATH_INFO'] != redirect_to
94
+ headers['Location'] = redirect_to
95
+ else
96
+ status = 401
97
+ body = "Access Denied..."
98
+ end
99
+ paywall.set_cookie(headers)
100
+ [status, headers, [body]]
101
+ end
102
+
103
+ end
104
+
105
+ def content_rule_for(path)
106
+ ret = false
107
+ @paths.map do |p|
108
+ match, rule = p
109
+ break if ret
110
+ ret = rule if match && match =~ path
111
+ end
112
+ ret
113
+ end
114
+
115
+ def call env
116
+ rule = content_rule_for(env['PATH_INFO'])
117
+
118
+ if rule
119
+ secure_content(env, rule)
120
+ else
121
+ @app.call(env)
122
+ end
123
+ end
124
+
125
+ end
126
+
127
+ end
@@ -0,0 +1,52 @@
1
+ module Hull
2
+ # Defines HTTP request methods
3
+ module Request
4
+
5
+ # Perform an HTTP DELETE request
6
+ def delete(path, params={}, options={})
7
+ request(:delete, api_path(path), params, options)
8
+ end
9
+
10
+ # Perform an HTTP GET request
11
+ def get(path, params={}, options={})
12
+ request(:get, api_path(path), params, options)
13
+ end
14
+
15
+ # Perform an HTTP POST request
16
+ def post(path, params={}, options={})
17
+ request(:post, api_path(path), params, options)
18
+ end
19
+
20
+ # Perform an HTTP PUT request
21
+ def put(path, params={}, options={})
22
+ request(:put, api_path(path), params, options)
23
+ end
24
+
25
+ private
26
+
27
+ def api_path path
28
+ if path =~ /^\//
29
+ path.to_s
30
+ else
31
+ "/api/v1/#{path.to_s.gsub(/^\//, '')}"
32
+ end
33
+ end
34
+
35
+ # Perform an HTTP request
36
+ def request(method, path, params={}, options={})
37
+ Hull.log("#{method.upcase} #{path} - params: #{params.to_json}")
38
+ response = connection(options).run_request(method, nil, nil, nil) do |request|
39
+ request.options[:raw] = true if options[:raw]
40
+ case method.to_sym
41
+ when :delete, :get
42
+ request.url(path, params)
43
+ when :post, :put
44
+ request.path = path
45
+ request.body = params unless params.empty?
46
+ end
47
+ end
48
+ options[:raw] ? response : response.body
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,19 @@
1
+ require 'digest/md5'
2
+
3
+ module Hull
4
+ module Request
5
+ class Auth < Faraday::Middleware
6
+
7
+ def call(env)
8
+ env[:request_headers]["Hull-Access-Token"] = @credentials[:app_secret]
9
+ env[:request_headers]["Hull-App-id"] = @credentials[:app_id]
10
+ @app.call(env)
11
+ end
12
+
13
+ def initialize(app, credentials)
14
+ @app, @credentials = app, credentials
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Hull
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1 @@
1
+ require 'hull'
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hullio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Stephane Bellity
8
+ - Hull
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '0.8'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '0.8'
28
+ - !ruby/object:Gem::Dependency
29
+ name: faraday_middleware
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '0.9'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '0.9'
42
+ - !ruby/object:Gem::Dependency
43
+ name: multi_json
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: mime-types
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: activesupport
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: 2.3.9
77
+ - - <
78
+ - !ruby/object:Gem::Version
79
+ version: '4'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: 2.3.9
87
+ - - <
88
+ - !ruby/object:Gem::Version
89
+ version: '4'
90
+ description: Hull Ruby Client
91
+ email:
92
+ - stephane@hull.io
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files: []
96
+ files:
97
+ - .gitignore
98
+ - Gemfile
99
+ - LICENSE
100
+ - README.md
101
+ - Rakefile
102
+ - hullio.gemspec
103
+ - lib/hull.rb
104
+ - lib/hull/client.rb
105
+ - lib/hull/config.rb
106
+ - lib/hull/connection.rb
107
+ - lib/hull/core_ext/hash.rb
108
+ - lib/hull/paywall.rb
109
+ - lib/hull/request.rb
110
+ - lib/hull/request/auth.rb
111
+ - lib/hull/version.rb
112
+ - lib/hullio.rb
113
+ homepage: http://hull.io
114
+ licenses: []
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 2.0.3
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: Hull Ruby Client
136
+ test_files: []