Class: Databasedotcom::OAuth2::WebServerFlow

Inherits:
Object
  • Object
show all
Defined in:
lib/databasedotcom-oauth2.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = nil) ⇒ WebServerFlow

Returns a new instance of WebServerFlow.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/databasedotcom-oauth2.rb', line 49

def initialize(app, options = nil)
  @app = app       
  unless options.nil?
    self.class.symbolize_keys!(options)
    @endpoints            = self.class.sanitize_endpoints(options[:endpoints])
    @token_encryption_key = options[:token_encryption_key]
    @path_prefix          = options[:path_prefix]
    @on_failure           = options[:on_failure]
    @display              = options[:display]
    @immediate            = options[:immediate]
    @prompt               = options[:prompt]
    @scope                = options[:scope]
    @display_override     = options[:display_override]   || false
    @immediate_override   = options[:immediate_override] || false
    @prompt_override      = options[:prompt_override]    || false
    @scope_override       = options[:scope_override]     || false
    @api_version          = options[:api_version]        || "25.0"
    @debugging            = options[:debugging]          || false
  end

  fail "\n\ndatabasedotcom-oauth2 initialization error!  :endpoints parameter " \
    + "is invalid.  Do something like this:\n\nuse Databasedotcom::OAuth2::Web" \
    + "ServerFlow, :endpoints => {\"login.salesforce.com\" => { :key => CLIENT" \
    + "_ID_FROM_DATABASEDOTCOM, :secret => CLIENT_SECRET_FROM_DATABASEDOTCOM }" \
    + "}\n\n"                                                                   \
    if !@endpoints.is_a?(Hash) || @endpoints.empty?
      
  fail "\n\ndatabasedotcom-oauth2 initialization error!  :token_encryption_key " \
    + "is invalid.  Do something like this:\n\nuse Databasedotcom::OAuth2::WebS" \
    + "erverFlow, :token_encryption_key => YOUR_VERY_LONG_VERY_RANDOM_SECRET_KE" \
    + "Y_HERE\n\nTo generate a sufficiently long random key, use following comm" \
    + "and:\n\n$ ruby -ropenssl -rbase64 -e \"puts Base64.strict_encode64(OpenS" \
    + "SL::Random.random_bytes(16).to_str)\"\n\n"                                \
    if @token_encryption_key.nil? || @token_encryption_key.size < 16
      
  @path_prefix = "/auth/salesforce" unless @path_prefix.is_a?(String) && !@path_prefix.strip.empty?
  @on_failure = nil unless @on_failure.is_a?(Proc)
end

Class Method Details

._log_exception(exception) ⇒ Object



360
361
362
363
364
# File 'lib/databasedotcom-oauth2.rb', line 360

def _log_exception(exception)
  STDERR.puts "\n\n#{exception.class} (#{exception.message}):\n    " +
    exception.backtrace.join("\n    ") +
    "\n\n"
end

.client_from_oauth_token(token) ⇒ Object



345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/databasedotcom-oauth2.rb', line 345

def client_from_oauth_token(token)
  c = nil
  unless token.nil?
    c = Databasedotcom::Client.new
    m = token["id"].match(/\/id\/([^\/]+)\/([^\/]+)$/)
    c.org_id        = m[1] rescue nil
    c.user_id       = m[2] rescue nil
    c.instance_url   = token.params["instance_url"]
    c.host           = parse_domain(c.instance_url)
    c.oauth_token    = token.token
    c.refresh_token  = token.refresh_token
  end
  c
end

.param_repeated(url = nil, param_name = nil) ⇒ Object



392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/databasedotcom-oauth2.rb', line 392

def param_repeated(url = nil, param_name = nil)
  return_value = nil
  unless url.nil? || url.strip.empty? || param_name.nil?
    url = Addressable::URI.parse(url)
    param_name = param_name.to_s if param_name.is_a?(Symbol)
    query_values = url.query_values(:notation => :flat_array)
    unless query_values.nil? || query_values.empty?
      return_value = query_values.select{|param| param.is_a?(Array) && param.size >= 2 && param[0] == param_name}.collect{|param| param[1]}
    end
  end
  return_value
end

.parse_domain(url = nil) ⇒ Object



329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/databasedotcom-oauth2.rb', line 329

def parse_domain(url = nil)
  url = url.to_s if url.is_a?(Symbol)
  unless url.nil?
    url = "https://" + url if (url =~ /http[s]?:\/\//).nil?
    begin
      url = Addressable::URI.parse(url)
    rescue Addressable::URI::InvalidURIError
      url = nil
    end
    url = url.host unless url.nil?
    url.strip! unless url.nil?
  end
  url = nil if url && url.strip.empty?
  url
end

.sanitize_endpoints(endpoints = nil) ⇒ Object



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
# File 'lib/databasedotcom-oauth2.rb', line 373

def sanitize_endpoints(endpoints = nil)
  endpoints = {} unless endpoints.is_a?(Hash)
  endpoints = endpoints.dup
  endpoints.keep_if do |key,value| 
    value.is_a?(Hash)       &&
    value.has_key?(:key)    && 
    value.has_key?(:secret) &&
    !value[:key].nil?       && 
    !value[:secret].nil?    && 
    !value[:key].empty?     && 
    !value[:secret].empty?
  end
  #set random default if default isn't already populated
  if !endpoints.empty? && endpoints.default.nil?
    endpoints.default = endpoints[endpoints.keys.first]
  end
  endpoints
end

.sanitize_mydomain(mydomain) ⇒ Object



366
367
368
369
370
371
# File 'lib/databasedotcom-oauth2.rb', line 366

def sanitize_mydomain(mydomain)
    mydomain = parse_domain(mydomain)
    mydomain = nil unless mydomain.nil? || !mydomain.strip.empty?
    mydomain = mydomain.split(/\.my\.salesforce\.com/).first + ".my.salesforce.com" unless mydomain.nil?
    mydomain
end

.symbolize_keys!(hash = {}) ⇒ Object



321
322
323
324
325
326
327
# File 'lib/databasedotcom-oauth2.rb', line 321

def symbolize_keys!(hash={})
  hash.keys.each do |key|
    value = hash[(key.to_sym rescue key) || key] = hash.delete(key)
    symbolize_keys!(value) if value.is_a?(Hash)
  end
  hash
end

Instance Method Details

#call(env) ⇒ Object



88
89
90
# File 'lib/databasedotcom-oauth2.rb', line 88

def call(env)
  dup.call!(env)
end

#call!(env) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/databasedotcom-oauth2.rb', line 92

def call!(env)
  @env = env
  begin
    return authorize_call if on_authorize_path?
    return callback_call  if on_callback_path?
  rescue Exception => e
    self.class._log_exception(e)
    if @on_failure.nil?
      new_path = Addressable::URI.parse(@path_prefix + "/failure")
      new_path.query_values={:message => e.message, :state => request.params['state']}
      return [302, {'Location' => new_path.to_s, 'Content-Type'=> 'text/html'}, []]
    else
      return @on_failure.call(env,e)
    end
  end
  @env[CLIENT_KEY] = retrieve_client_from_session
  status, headers, body = @app.call(env)
  save_client_to_session(@env[CLIENT_KEY])
  [status, headers, body]
end