hullio 0.3.3 → 0.4.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5134dd78b1ec380b06cb7b2eded06f3d25e11a77
4
+ data.tar.gz: bfe1fdc35d805dab9189fb0bb05d034ba5c21a5d
5
+ SHA512:
6
+ metadata.gz: 40811b930da961adaccc6685d7578b9ab59c89bed446d837c55b809b8aa95ecc08c8b21026947dc1eed0cbb82a4ae12a511df549eff3ab9cd875c6c542cf3c9e
7
+ data.tar.gz: b5f2bf57375f6bd160ca0e9882cb40af60037745c606f6327199164c58f8fdbef86bc5801ce5dd8ee0e5a4fee1ca6512da4063e36ff567352f24594674721564
@@ -0,0 +1,13 @@
1
+ ; EditorConfig helps developers define and maintain consistent
2
+ ; coding styles between different editors and IDEs
3
+ ; editorconfig.org
4
+
5
+ root = true
6
+
7
+ [*]
8
+ indent_style = space
9
+ indent_size = 2
10
+ end_of_line = lf
11
+ charset = utf-8
12
+ trim_trailing_whitespace = true
13
+ insert_final_newline = true
@@ -0,0 +1,6 @@
1
+ # 0.4.0
2
+
3
+ * Add support for JWTs
4
+ * Add helpers for Entities `Hull::Entity.encode` and `Hull::Entity.decode`
5
+
6
+
data/Gemfile CHANGED
@@ -1,22 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'faraday', '0.8.9'
4
-
5
- group :development, :test do
6
- gem 'rake'
7
- gem 'guard', '~> 2.6'
8
- gem 'guard-rspec', '~> 4', require: false
9
- gem 'typhoeus' unless defined? JRUBY_VERSION
10
- gem 'pry-debugger'
11
- end
12
-
13
- group :test do
14
- gem 'rspec', '~> 3.0'
15
- gem 'webmock'
16
- end
17
-
18
- gem 'jruby-openssl' if defined? JRUBY_VERSION
19
-
3
+ # Specify your gem's dependencies in hullio.gemspec
20
4
  gemspec
21
-
22
-
data/README.md CHANGED
@@ -18,7 +18,7 @@ Or install it yourself as:
18
18
 
19
19
  ### Configuration
20
20
 
21
- ```rb
21
+ ```ruby
22
22
  Hull.configure do |c|
23
23
  c.app_id = "your-app-id"
24
24
  c.app_secret = "your-app-secret"
@@ -35,25 +35,32 @@ In Rails, you can include this in an initializer.
35
35
  examples:
36
36
 
37
37
  ```rb
38
- # To get the current app
38
+ # Get the current app
39
39
  Hull.get('app')
40
40
 
41
- # To get the a list of comments on the current app (with pagination)
41
+ # Get the a list of comments on the current app (with pagination)
42
42
  Hull.get('app/comments', limit: 10, page: 2)
43
43
 
44
- # To update an existing object
44
+ # Update an existing object
45
45
  Hull.put('app', { name: 'My Super App' })
46
46
  ```
47
47
 
48
48
  with Hull entities :
49
49
 
50
50
  ```rb
51
- Hull.get('entity', { uid: 'http://example.com' })
52
- Hull.put('entity', { uid: 'http://example.com', name: 'My super Page' })
53
- Hull.delete('entity', { uid: 'http://example.com' })
51
+ entityId = Hull::Entity.encode('http://example.com')
52
+ #=>"~aHR0cDovL2V4YW1wbGUuY29t"
53
+
54
+ Hull.get(entityId)
55
+ Hull.put(entityId)
56
+ Hull.delete(entityId)
54
57
 
55
58
  # Get comments on the Entity identified by 'http://example.com'
56
- Hull.get('entity/comments', { uid: 'http://example.com' })
59
+ Hull.get(entityId+'/comments')
60
+
61
+ # Decoding an encoded entity:
62
+ Hull::Entity.decode(entityId)
63
+ #=>'http://example.com'
57
64
  ```
58
65
 
59
66
  ### Making API calls as as a User
@@ -62,72 +69,57 @@ Hull.get('entity/comments', { uid: 'http://example.com' })
62
69
  # From its user ID
63
70
  Hull.as('51fa7afd09e50d11f1000002').get('me')
64
71
 
65
- # From a user UID
72
+ # Find a User based on his identity from an external service:
73
+
74
+ # Find user from his Twitter handle:
66
75
  Hull.as('twitter:hull').get('me')
76
+
77
+ # Find user from his Faceboo ID
78
+ Hull.as('facebook:fb_uid').get('me')
79
+
80
+ # Find user from his ID in your app (BYOU)
67
81
  Hull.as('external:3637').get('me')
82
+
83
+ # From a User in your database, with lazy creation (Checkout [Bring your own Users Documentation](http://hull.io/docs/users/byou))
84
+ userHash = {external_id:'1234', name:'Romain', email:'user@host.com'}
85
+ Hull.as(userHash).get('me')
68
86
  ```
69
87
 
70
88
  ### Getting the current User
71
89
 
72
- `Hull.authenticate_user` allows you to get the current User's ID.
90
+ `Hull.authenticate_user` allows you to retrieve the current User's ID.
73
91
 
74
92
  #### Rails
75
93
 
76
94
  ```rb
77
95
  class MyController < ApplicationController
96
+ def current_hull_user_id
97
+ @current_hull_user_id ||= Hull.authenticate_user(request.env)
98
+ end
99
+
78
100
  def current_hull_user
79
101
  # You probably should cache this or record this information in a session
80
102
  # to avoid making calls to Hull's API on each request
81
103
  @current_hull_user ||= Hull.get(current_hull_user_id)
82
104
  end
83
105
 
84
- def current_hull_user_id
85
- @current_hull_user_id ||= Hull.authenticate_user(request.env)
86
- end
87
106
  end
88
107
  ```
89
108
 
90
- ### Compiling widgets and templates with Rails' Assets Pipeline
91
-
92
- Load `handlebars_assets` in your Gemfile as part of the assets group
93
-
94
- ```rb
95
- group :assets do
96
- gem 'handlebars_assets'
97
- end
98
- ```
99
-
100
- Place your widgets inside the `app/assets/javascripts` dir.
101
-
102
- app
103
- ├── assets
104
- │   ├── javascripts
105
- │   │   ├── application.js
106
- │   │   └── hello
107
- │   │   ├── hello.hbs
108
- │   │   └── main.js
109
-
110
- And require the in your `application.js` file :
111
-
112
- ```js
113
- //= require handlebars
114
- //= require_tree .
115
- ```
116
109
 
117
110
  ### Bring your own users
118
111
 
119
- In addition to providing multiple social login options, Hull allows you to create and authenticate users that are registered within your own app.
120
-
121
- To use this feature, you just have to add a `userHash` key at the initialization of hull.js :
112
+ Using JWT, you can use Hull with Users from your system.
113
+ To use this feature, you just have to add a `accessToken` key at the initialization of hull.js. Read more at http://hull.io/docs/users/byou
122
114
 
123
- In you view :
115
+ In your view :
124
116
 
125
117
  ```html
126
118
  <script>
127
119
  Hull.init({
128
120
  appId: "<%= Hull.app_id %>",
129
121
  orgUrl: "<%= Hull.org_url %>",
130
- userHash: "<%= Hull.user_hash({ id: "123", email: "bill@hullapp.io", name: "Bill Evans" }) %>"
122
+ accessToken: "<%= Hull.user_token({external_id: "123", email: "bill@hullapp.io", name: "Bill Evans" }) %>"
131
123
  });
132
124
  </script>
133
125
  ```
data/Rakefile CHANGED
@@ -1,9 +1,2 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
3
-
4
- require 'rspec/core/rake_task'
5
- RSpec::Core::RakeTask.new(:spec)
6
-
7
- task :test => :spec
8
-
9
- task :default => [:spec]
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -14,13 +14,18 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "hullio"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Hull::VERSION
17
+ gem.licenses = ['MIT']
17
18
 
18
19
  # Dependencies
19
- gem.add_dependency 'faraday', '>= 0.8'
20
- gem.add_dependency 'faraday_middleware'
21
- gem.add_dependency 'multi_json'
22
- gem.add_dependency 'mime-types'
20
+ gem.add_dependency 'faraday', ['>= 0.7', '< 0.10']
21
+ gem.add_dependency 'faraday_middleware', ['>= 0.7', '< 0.10']
22
+ gem.add_dependency 'multi_json', '~> 1.0'
23
+ gem.add_dependency 'mime-types', '~> 2.0'
24
+ gem.add_dependency 'jwt', '~> 1.0'
25
+ gem.add_dependency 'addressable', '~> 2.3'
26
+ gem.add_dependency 'postrank-uri', '~> 1.0'
23
27
 
24
28
  # Development Dependencies
25
29
  gem.add_development_dependency 'activesupport', ['>= 2.3.9', '< 4']
30
+
26
31
  end
@@ -1,6 +1,7 @@
1
1
  require 'hull/core_ext/hash'
2
2
  require 'hull/client'
3
3
  require 'hull/config'
4
+ require 'hull/entity'
4
5
 
5
6
  module Hull
6
7
  extend Config
@@ -12,8 +13,12 @@ module Hull
12
13
  Hull::Client.new(options)
13
14
  end
14
15
 
15
- def as(user_id)
16
- Hull::Client.new({ user_id: user_id })
16
+ def as(user)
17
+ if user.is_a?(String)
18
+ Hull::Client.new({ user_id: user })
19
+ else
20
+ Hull::Client.new({ access_token: self.user_token(user) })
21
+ end
17
22
  end
18
23
 
19
24
  # Delegate to Hull::Client
@@ -3,6 +3,7 @@ require 'hull/connection'
3
3
  require 'hull/request'
4
4
  require 'base64'
5
5
  require 'openssl'
6
+ require 'jwt'
6
7
 
7
8
  module Hull
8
9
  class Client
@@ -25,12 +26,13 @@ module Hull
25
26
 
26
27
  def credentials
27
28
  {
28
- :app_id => @app_id,
29
- :app_secret => @app_secret,
30
- :user_id => @user_id,
29
+ :app_id => @app_id,
30
+ :app_secret => @app_secret,
31
+ :user_id => @user_id,
32
+ :access_token => @access_token
31
33
  }
32
34
  end
33
-
35
+
34
36
  def app
35
37
  return unless app_id
36
38
  @app ||= get("/app", :app_id => app_id)
@@ -51,7 +53,7 @@ module Hull
51
53
  end
52
54
 
53
55
  def authenticate_user env
54
- require 'rack/request'
56
+ require 'rack/request'
55
57
  request = Rack::Request.new(env)
56
58
  cookie = request.cookies["hull_#{self.app_id}"]
57
59
  user_auth = read_cookie(cookie)
@@ -65,6 +67,19 @@ module Hull
65
67
  sig = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha1'), app_secret, [message, timestamp].join(" "))
66
68
  [message, sig, timestamp].join(" ")
67
69
  end
68
-
70
+
71
+ def user_token user, claims={}
72
+ claims = claims.inject({}) { |c,(k,v)| c.merge(k.to_sym => v) }
73
+ if user.is_a?(String)
74
+ claims[:sub] = user
75
+ else
76
+ claims[:'io.hull.user'] = user
77
+ end
78
+ claims = claims.merge({ iat: Time.now.to_i, iss: app_id })
79
+ claims[:nbf] = claims[:nbf].to_i if claims[:nbf]
80
+ claims[:exp] = claims[:exp].to_i if claims[:exp]
81
+ JWT.encode(claims, app_secret)
82
+ end
83
+
69
84
  end
70
- end
85
+ end
@@ -15,7 +15,7 @@ module Hull
15
15
  DEFAULT_APP_SECRET = ENV['HULL_APP_SECRET']
16
16
  DEFAULT_APP_ID = ENV['HULL_APP_ID']
17
17
 
18
-
18
+
19
19
  # The ORG_URL that will be used to connect if none is set
20
20
  #
21
21
  DEFAULT_ORG_URL = ENV['HULL_ORG_URL']
@@ -24,7 +24,7 @@ module Hull
24
24
  DEFAULT_CACHE_STORE = nil
25
25
 
26
26
  DEFAULT_PROXY = nil
27
-
27
+
28
28
  # The value sent in the 'User-Agent' header if none is set
29
29
  DEFAULT_USER_AGENT = "Hull Ruby Gem #{Hull::VERSION}"
30
30
 
@@ -44,7 +44,8 @@ module Hull
44
44
  :cache_store,
45
45
  :logger,
46
46
  :current_user,
47
- :user_id,
47
+ :user_id,
48
+ :access_token,
48
49
  :authenticate_users,
49
50
  :user_attributes,
50
51
  :js_url
@@ -0,0 +1,43 @@
1
+ require 'addressable/uri'
2
+ require 'postrank-uri'
3
+
4
+ class Hull::Entity
5
+
6
+ class InvalidUID < StandardError; end
7
+
8
+ def self.valid_uri?(uri)
9
+ Addressable::URI.parse(uri).domain
10
+ rescue Addressable::URI::InvalidURIError
11
+ false
12
+ end
13
+
14
+ def self.decode uid
15
+ raise(InvalidUID, uid) unless uid.is_a?(String)
16
+ if uid =~ /^~[a-z0-9_\-\+\/\=]+$/i && (uid.length - 1) % 4 == 0
17
+ uid = uid.gsub(/^~/, '')
18
+ begin
19
+ if uid =~ /\/\+/
20
+ uid = Base64.decode64(uid)
21
+ else
22
+ uid = Base64.urlsafe_decode64(uid)
23
+ end
24
+ rescue => err
25
+ raise InvalidUID, err.message
26
+ end
27
+ end
28
+
29
+ if valid_uri?(uid)
30
+ uid = PostRank::URI.clean(uid)
31
+ end
32
+
33
+ begin
34
+ uid.encode(Encoding::UTF_8)
35
+ rescue => err
36
+ raise InvalidUID, err.message
37
+ end
38
+ end
39
+
40
+ def self.encode uid
41
+ "~#{Base64.urlsafe_encode64(uid)}"
42
+ end
43
+ end
@@ -5,9 +5,13 @@ module Hull
5
5
  class Auth < Faraday::Middleware
6
6
 
7
7
  def call(env)
8
- env[:request_headers]["Hull-Access-Token"] = @credentials[:app_secret]
9
8
  env[:request_headers]["Hull-App-Id"] = @credentials[:app_id]
10
- env[:request_headers]["Hull-User-Id"] = @credentials[:user_id] if @credentials[:user_id]
9
+ if !@credentials[:access_token].nil?
10
+ env[:request_headers]["Hull-Access-Token"] = @credentials[:access_token]
11
+ else
12
+ env[:request_headers]["Hull-Access-Token"] = @credentials[:app_secret]
13
+ env[:request_headers]["Hull-User-Id"] = @credentials[:user_id] if @credentials[:user_id]
14
+ end
11
15
  @app.call(env)
12
16
  end
13
17
 
@@ -17,4 +21,4 @@ module Hull
17
21
 
18
22
  end
19
23
  end
20
- end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Hull
2
- VERSION = "0.3.3"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hullio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
5
- prerelease:
4
+ version: 0.4.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Stephane Bellity
@@ -10,94 +9,138 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2014-06-05 00:00:00.000000000 Z
12
+ date: 2014-09-25 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: faraday
17
16
  requirement: !ruby/object:Gem::Requirement
18
17
  requirements:
19
- - - ! '>='
18
+ - - ">="
20
19
  - !ruby/object:Gem::Version
21
- version: '0.8'
22
- none: false
23
- prerelease: false
20
+ version: '0.7'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '0.10'
24
24
  type: :runtime
25
+ prerelease: false
25
26
  version_requirements: !ruby/object:Gem::Requirement
26
27
  requirements:
27
- - - ! '>='
28
+ - - ">="
28
29
  - !ruby/object:Gem::Version
29
- version: '0.8'
30
- none: false
30
+ version: '0.7'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.10'
31
34
  - !ruby/object:Gem::Dependency
32
35
  name: faraday_middleware
33
36
  requirement: !ruby/object:Gem::Requirement
34
37
  requirements:
35
- - - ! '>='
38
+ - - ">="
36
39
  - !ruby/object:Gem::Version
37
- version: '0'
38
- none: false
39
- prerelease: false
40
+ version: '0.7'
41
+ - - "<"
42
+ - !ruby/object:Gem::Version
43
+ version: '0.10'
40
44
  type: :runtime
45
+ prerelease: false
41
46
  version_requirements: !ruby/object:Gem::Requirement
42
47
  requirements:
43
- - - ! '>='
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0.7'
51
+ - - "<"
44
52
  - !ruby/object:Gem::Version
45
- version: '0'
46
- none: false
53
+ version: '0.10'
47
54
  - !ruby/object:Gem::Dependency
48
55
  name: multi_json
49
56
  requirement: !ruby/object:Gem::Requirement
50
57
  requirements:
51
- - - ! '>='
58
+ - - "~>"
52
59
  - !ruby/object:Gem::Version
53
- version: '0'
54
- none: false
55
- prerelease: false
60
+ version: '1.0'
56
61
  type: :runtime
62
+ prerelease: false
57
63
  version_requirements: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - ! '>='
65
+ - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '0'
62
- none: false
67
+ version: '1.0'
63
68
  - !ruby/object:Gem::Dependency
64
69
  name: mime-types
65
70
  requirement: !ruby/object:Gem::Requirement
66
71
  requirements:
67
- - - ! '>='
72
+ - - "~>"
68
73
  - !ruby/object:Gem::Version
69
- version: '0'
70
- none: false
74
+ version: '2.0'
75
+ type: :runtime
71
76
  prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: jwt
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.0'
72
89
  type: :runtime
90
+ prerelease: false
73
91
  version_requirements: !ruby/object:Gem::Requirement
74
92
  requirements:
75
- - - ! '>='
93
+ - - "~>"
76
94
  - !ruby/object:Gem::Version
77
- version: '0'
78
- none: false
95
+ version: '1.0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: addressable
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.3'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '2.3'
110
+ - !ruby/object:Gem::Dependency
111
+ name: postrank-uri
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.0'
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '1.0'
79
124
  - !ruby/object:Gem::Dependency
80
125
  name: activesupport
81
126
  requirement: !ruby/object:Gem::Requirement
82
127
  requirements:
83
- - - ! '>='
128
+ - - ">="
84
129
  - !ruby/object:Gem::Version
85
130
  version: 2.3.9
86
- - - <
131
+ - - "<"
87
132
  - !ruby/object:Gem::Version
88
133
  version: '4'
89
- none: false
90
- prerelease: false
91
134
  type: :development
135
+ prerelease: false
92
136
  version_requirements: !ruby/object:Gem::Requirement
93
137
  requirements:
94
- - - ! '>='
138
+ - - ">="
95
139
  - !ruby/object:Gem::Version
96
140
  version: 2.3.9
97
- - - <
141
+ - - "<"
98
142
  - !ruby/object:Gem::Version
99
143
  version: '4'
100
- none: false
101
144
  description: Hull Ruby Client
102
145
  email:
103
146
  - stephane@hull.io
@@ -105,7 +148,9 @@ executables: []
105
148
  extensions: []
106
149
  extra_rdoc_files: []
107
150
  files:
108
- - .gitignore
151
+ - ".editorconfig"
152
+ - ".gitignore"
153
+ - CHANGELOG
109
154
  - Gemfile
110
155
  - LICENSE
111
156
  - README.md
@@ -116,6 +161,7 @@ files:
116
161
  - lib/hull/config.rb
117
162
  - lib/hull/connection.rb
118
163
  - lib/hull/core_ext/hash.rb
164
+ - lib/hull/entity.rb
119
165
  - lib/hull/middlewares/hook.rb
120
166
  - lib/hull/paywall.rb
121
167
  - lib/hull/request.rb
@@ -124,28 +170,27 @@ files:
124
170
  - lib/hull/version.rb
125
171
  - lib/hullio.rb
126
172
  homepage: http://hull.io
127
- licenses: []
173
+ licenses:
174
+ - MIT
175
+ metadata: {}
128
176
  post_install_message:
129
177
  rdoc_options: []
130
178
  require_paths:
131
179
  - lib
132
180
  required_ruby_version: !ruby/object:Gem::Requirement
133
181
  requirements:
134
- - - ! '>='
182
+ - - ">="
135
183
  - !ruby/object:Gem::Version
136
184
  version: '0'
137
- none: false
138
185
  required_rubygems_version: !ruby/object:Gem::Requirement
139
186
  requirements:
140
- - - ! '>='
187
+ - - ">="
141
188
  - !ruby/object:Gem::Version
142
189
  version: '0'
143
- none: false
144
190
  requirements: []
145
191
  rubyforge_project:
146
- rubygems_version: 1.8.25
192
+ rubygems_version: 2.2.2
147
193
  signing_key:
148
- specification_version: 3
194
+ specification_version: 4
149
195
  summary: Hull Ruby Client
150
196
  test_files: []
151
- has_rdoc: