hullio 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: