databasedotcom-oauth2 0.1.9 → 0.2.0

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