databasedotcom-oauth2 0.1.9 → 0.2.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.
@@ -7,70 +7,28 @@ require "gibberish"
7
7
  require "databasedotcom"
8
8
  require "oauth2"
9
9
 
10
- module OAuth2
11
- class AccessToken
12
- attr_accessor :client
13
- end
14
- end
15
-
16
10
  module Databasedotcom
17
11
 
18
- def self.parse_domain(url = nil)
19
- unless url.nil?
20
- url = "https://" + url if (url =~ /http[s]?:\/\//).nil?
21
- begin
22
- url = Addressable::URI.parse(url)
23
- rescue Addressable::URI::InvalidURIError
24
- url = nil
25
- end
26
- url = url.host unless url.nil?
27
- url.strip! unless url.nil?
28
- end
29
- url = nil if url && url.strip.empty?
30
- url
31
- end
32
-
33
12
  class Client
34
- def self.from_token(token, api_version)
35
- client = nil
36
- unless token.nil?
37
- client = self.new({
38
- :client_id => token.client.id,
39
- :client_secret => token.client.secret,
40
- :host => Databasedotcom.parse_domain(token.client.site)
41
- })
42
- m = token["id"].match(/\/id\/([^\/]+)\/([^\/]+)$/)
43
- client.org_id = m[1] rescue nil
44
- client.user_id = m[2] rescue nil
45
- client.version = api_version
46
- client.instance_url = token.client.site
47
- client.oauth_token = token.token
48
- client.refresh_token = token.refresh_token
49
- end
50
- client
51
- end
52
-
53
- def org_id=(val)
54
- @org_id = val
55
- end
56
-
57
- def user_id=(val)
58
- @user_id = val
13
+
14
+ attr_accessor :org_id
15
+ attr_accessor :user_id
16
+ attr_accessor :endpoint
17
+ attr_accessor :last_seen
18
+ attr_accessor :logout_flag
19
+
20
+ def logout
21
+ @logout_flag = true
59
22
  end
60
23
 
61
24
  end
62
25
 
63
26
  module OAuth2
64
- TOKEN_KEY = "databasedotcom.token"
65
27
  CLIENT_KEY = "databasedotcom.client"
66
28
 
67
29
  module Helpers
68
30
  def client
69
- env['databasedotcom.client']
70
- end
71
-
72
- def token
73
- env['databasedotcom.token']
31
+ env[CLIENT_KEY]
74
32
  end
75
33
 
76
34
  def unauthenticated?
@@ -83,7 +41,6 @@ module Databasedotcom
83
41
 
84
42
  def me
85
43
  @me ||= ::Hashie::Mash.new(Databasedotcom::Chatter::User.find(client, "me").raw_hash)
86
- #@me.organization_id
87
44
  end
88
45
  end
89
46
 
@@ -102,7 +59,7 @@ module Databasedotcom
102
59
  @scope = options[:scope]
103
60
  @display_override = options[:display_override] || false
104
61
  @immediate_override = options[:immediate_override] || false
105
- @prompt_override = options[:prompt_override] || false
62
+ @prompt_override = options[:prompt_override] || false
106
63
  @scope_override = options[:scope_override] || false
107
64
  @api_version = options[:api_version] || "25.0"
108
65
  @debugging = options[:debugging] || false
@@ -136,7 +93,6 @@ module Databasedotcom
136
93
  begin
137
94
  return authorize_call if on_authorize_path?
138
95
  return callback_call if on_callback_path?
139
- materialize_token_and_client_from_session_if_present
140
96
  rescue Exception => e
141
97
  self.class._log_exception(e)
142
98
  if @on_failure.nil?
@@ -147,7 +103,10 @@ module Databasedotcom
147
103
  return @on_failure.call(env,e)
148
104
  end
149
105
  end
150
- @app.call(env)
106
+ @env[CLIENT_KEY] = retrieve_client_from_session
107
+ status, headers, body = @app.call(env)
108
+ save_client_to_session(@env[CLIENT_KEY])
109
+ [status, headers, body]
151
110
  end
152
111
 
153
112
  private
@@ -170,7 +129,7 @@ module Databasedotcom
170
129
  state.query_values={} unless state.query_values
171
130
  state.query_values= state.query_values.merge({:endpoint => endpoint})
172
131
 
173
- puts "endpoint: #{endpoint}\nmydomain: #{mydomain}\nstate: #{state.to_str}" if @debugging
132
+ puts "(1) endpoint: #{endpoint}\n(2) mydomain: #{mydomain}\n(3) state: #{state.to_str}" if @debugging
174
133
 
175
134
  #build params hash to be passed to ouath2 authorize redirect url
176
135
  auth_params = {
@@ -186,7 +145,10 @@ module Databasedotcom
186
145
  overrides = {}
187
146
  overrides[:display] = request.params["display"] unless !@display_override || request.params["display"].nil?
188
147
  overrides[:immediate] = request.params["immediate"] unless !@immediate_override || request.params["immediate"].nil?
189
- overrides[:prompt] = request.params["prompt"] unless !@prompt_override || request.params["prompt"].nil?
148
+ if @prompt_override
149
+ prompt = (self.class.param_repeated(request.url, :prompt) || []).join(" ")
150
+ overrides[:prompt] = prompt unless prompt.nil? || prompt.strip.empty?
151
+ end
190
152
  if @scope_override
191
153
  scope = (self.class.param_repeated(request.url, :scope) || []).join(" ")
192
154
  overrides[:scope] = scope unless scope.nil? || scope.strip.empty?
@@ -195,7 +157,7 @@ module Databasedotcom
195
157
 
196
158
  #do redirect
197
159
  redirect_url = client(mydomain || endpoint, keys[:key], keys[:secret]).auth_code.authorize_url(auth_params)
198
- puts "redirecting to #{redirect_url}..." if @debugging
160
+ puts "(4) redirecting to #{redirect_url}..." if @debugging
199
161
  redirect redirect_url
200
162
  end
201
163
 
@@ -220,55 +182,85 @@ module Databasedotcom
220
182
  state_params = state.query_values.dup
221
183
  endpoint = state_params.delete("endpoint")
222
184
  keys = @endpoints[endpoint]
223
- puts "endpoint #{endpoint}"
224
- puts "keys #{keys}"
185
+ puts "(1) endpoint #{endpoint}" if @debugging
186
+ puts "(2) keys #{keys}" if @debugging
225
187
  state.query_values= state_params
226
188
  state = state.to_s
227
189
  state.sub!(/\?$/,"") unless state.nil?
228
- puts "endpoint: #{endpoint}\nstate: #{state.to_str}\nretrieving token" if @debugging
190
+ puts "(3) endpoint: #{endpoint}\nstate: #{state.to_str}\nretrieving token" if @debugging
229
191
 
230
192
  #do callout to retrieve token
231
193
  access_token = client(endpoint, keys[:key], keys[:secret]).auth_code.get_token(code,
232
194
  :redirect_uri => "#{full_host}#{@path_prefix}/callback")
233
- puts "access_token immediatly post get token call #{access_token.inspect}" if @debugging
234
- access_token.options[:mode] = :query
235
- access_token.options[:param_name] = :oauth_token
236
- access_token.options[:endpoint] = endpoint
237
- access_token.client = nil
238
- puts "access_token pre marshal-encrypt-cookiewrite #{access_token.inspect}" if @debugging
195
+ puts "(4) access_token immediatly post get token call #{access_token.inspect}" if @debugging
239
196
 
240
- #populate session with serialized, encrypted token
241
- #will be used later to materialize actual token and databasedotcom client handle
242
- set_session_token(encrypt(access_token))
243
- puts "session_token \n#{session_token}" if @debugging
197
+ client = self.class.client_from_oauth_token(access_token)
198
+ client.endpoint = endpoint
199
+ puts "(5) client from token: #{client.inspect}" if @debugging
200
+ save_client_to_session(client)
201
+ puts "(6) session_client \n#{session_client}" if @debugging
244
202
  redirect state.to_str
245
203
  end
246
204
 
247
- def materialize_token_and_client_from_session_if_present
248
- puts "==========================\nmaterialize intercept\n==========================\n" if @debugging
249
- access_token = nil
250
- puts "session_token \n#{session_token}" if @debugging
205
+ def save_client_to_session(client)
206
+ puts "==========================\nsave_client_to_session\n==========================\n" if @debugging
207
+ puts "(1) client as stored in session \n#{session_client}" if @debugging
208
+ puts "(2) client to save: #{client.inspect}" if @debugging
209
+ unless client.nil?
210
+ new_session_client = nil
211
+ unless client.logout_flag
212
+ # Zero out client id and secret; will re-populate later when client
213
+ # is reloaded. Should be safe to store client id and secret inside
214
+ # encrypted client; however, out of an abundance of caution (and b/c
215
+ # it just makes sense), client id and secret will never be written
216
+ # to session but only stored via @endpoints variable server side.
217
+ client.client_id = nil
218
+ client.client_secret = nil
219
+ client.version = nil
220
+ client.debugging = nil
221
+ client.last_seen = Time.now
222
+ new_session_client = Gibberish::AES.new(@token_encryption_key).encrypt(Marshal.dump(client))
223
+ end
224
+ if new_session_client != session_client
225
+ session_client_put(new_session_client)
226
+ end
227
+ end
228
+ puts "(3) client as stored in session \n#{session_client}" if @debugging
229
+
230
+ end
231
+
232
+ def retrieve_client_from_session
233
+ puts "==========================\nretrieve_client_from_session\n==========================\n" if @debugging
234
+ puts "(1) session_client \n#{session_client}" if @debugging
235
+ client = nil
251
236
  begin
252
- access_token = decrypt(session_token) unless session_token.nil?
237
+ client = Marshal.load(Gibberish::AES.new(@token_encryption_key).decrypt(session_client)) unless session_client.nil?
253
238
  rescue Exception => e
254
239
  puts "Exception FYI"
255
240
  self.class._log_exception(e)
256
241
  end
257
- unless access_token.nil?
258
- puts "access_token post cookieread-decrypt-marshal #{access_token.inspect}" if @debugging
259
- instance_url = access_token.params["instance_url"]
260
- endpoint = access_token.options[:endpoint]
261
- keys = @endpoints[endpoint]
262
- puts "endpoint #{endpoint}\nkeys #{keys}" if @debugging
263
- access_token.client = client(instance_url, keys[:key], keys[:secret])
264
- unless keys.nil?
265
- @env[TOKEN_KEY] = access_token #::OAuth2::AccessToken.from_hash(client(instance_url, keys[:key], keys[:secret]),access_token_hash.dup)
266
- @env[CLIENT_KEY] = ::Databasedotcom::Client.from_token(@env[TOKEN_KEY],@api_version)
267
- @env[CLIENT_KEY].debugging = @debugging
242
+ unless client.nil?
243
+ keys = @endpoints[client.endpoint]
244
+ if @debugging
245
+ puts "(2) client #{client.inspect}"
246
+ puts "(3) client.endpoint #{client.endpoint}"
247
+ puts "(4) keys #{keys}"
248
+ end
249
+ if keys.nil?
250
+ client = nil
251
+ else
252
+ client.client_id = keys[:key]
253
+ client.client_secret = keys[:secret]
254
+ client.version = @api_version
255
+ client.debugging = @debugging
268
256
  end
269
- puts "materialized token: #{@env[TOKEN_KEY].inspect}" if @debugging
270
- puts "materialized client: #{@env[CLIENT_KEY].inspect}" if @debugging
257
+ puts "(5) client #{client.inspect}" if @debugging
271
258
  end
259
+ client
260
+ end
261
+
262
+ def request
263
+ @request ||= Rack::Request.new(@env)
272
264
  end
273
265
 
274
266
  def session
@@ -276,24 +268,12 @@ module Databasedotcom
276
268
  @env["rack.session"]
277
269
  end
278
270
 
279
- def session_token
280
- session[TOKEN_KEY]
281
- end
282
-
283
- def set_session_token(value)
284
- session[TOKEN_KEY] = value
285
- end
286
-
287
- def aes
288
- Gibberish::AES.new(@token_encryption_key)
271
+ def session_client
272
+ session[CLIENT_KEY]
289
273
  end
290
274
 
291
- def encrypt(data)
292
- aes.encrypt(Marshal.dump(data))
293
- end
294
-
295
- def decrypt(data)
296
- Marshal.load(aes.decrypt(data))
275
+ def session_client_put(value)
276
+ session[CLIENT_KEY] = value
297
277
  end
298
278
 
299
279
  def on_path?(path)
@@ -304,14 +284,6 @@ module Databasedotcom
304
284
  request.path_info.downcase.sub(/\/$/,'')
305
285
  end
306
286
 
307
- def query_string
308
- request.query_string.empty? ? "" : "?#{request.query_string}"
309
- end
310
-
311
- def request
312
- @request ||= Rack::Request.new(@env)
313
- end
314
-
315
287
  def full_host
316
288
  full_host = ENV['ORIGIN']
317
289
  if full_host.nil? || full_host.strip.empty?
@@ -328,7 +300,7 @@ module Databasedotcom
328
300
  ::OAuth2::Client.new(
329
301
  client_id,
330
302
  client_secret,
331
- :site => "https://#{Databasedotcom.parse_domain(site)}",
303
+ :site => "https://#{self.class.parse_domain(site)}",
332
304
  :authorize_url => '/services/oauth2/authorize',
333
305
  :token_url => '/services/oauth2/token'
334
306
  )
@@ -343,6 +315,36 @@ module Databasedotcom
343
315
 
344
316
  class << self
345
317
 
318
+ def parse_domain(url = nil)
319
+ unless url.nil?
320
+ url = "https://" + url if (url =~ /http[s]?:\/\//).nil?
321
+ begin
322
+ url = Addressable::URI.parse(url)
323
+ rescue Addressable::URI::InvalidURIError
324
+ url = nil
325
+ end
326
+ url = url.host unless url.nil?
327
+ url.strip! unless url.nil?
328
+ end
329
+ url = nil if url && url.strip.empty?
330
+ url
331
+ end
332
+
333
+ def client_from_oauth_token(token)
334
+ c = nil
335
+ unless token.nil?
336
+ c = Databasedotcom::Client.new
337
+ m = token["id"].match(/\/id\/([^\/]+)\/([^\/]+)$/)
338
+ c.org_id = m[1] rescue nil
339
+ c.user_id = m[2] rescue nil
340
+ c.instance_url = token.params["instance_url"]
341
+ c.host = parse_domain(c.instance_url)
342
+ c.oauth_token = token.token
343
+ c.refresh_token = token.refresh_token
344
+ end
345
+ c
346
+ end
347
+
346
348
  def _log_exception(exception)
347
349
  STDERR.puts "\n\n#{exception.class} (#{exception.message}):\n " +
348
350
  exception.backtrace.join("\n ") +
@@ -350,7 +352,7 @@ module Databasedotcom
350
352
  end
351
353
 
352
354
  def sanitize_mydomain(mydomain)
353
- mydomain = Databasedotcom.parse_domain(mydomain)
355
+ mydomain = parse_domain(mydomain)
354
356
  mydomain = nil unless mydomain.nil? || !mydomain.strip.empty?
355
357
  mydomain = mydomain.split(/\.my\.salesforce\.com/).first + ".my.salesforce.com" unless mydomain.nil?
356
358
  mydomain
@@ -1,5 +1,5 @@
1
1
  module Databasedotcom
2
2
  module OAuth2
3
- VERSION = "0.1.9"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: databasedotcom-oauth2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-01 00:00:00.000000000 Z
12
+ date: 2012-07-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable