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
# File 'lib/databasedotcom-oauth2.rb', line 49

def initialize(app, options = nil)
  @app = app       
  unless options.nil?
    @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



348
349
350
351
352
# File 'lib/databasedotcom-oauth2.rb', line 348

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



333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/databasedotcom-oauth2.rb', line 333

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



380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/databasedotcom-oauth2.rb', line 380

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



318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/databasedotcom-oauth2.rb', line 318

def parse_domain(url = nil)
  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



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/databasedotcom-oauth2.rb', line 361

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



354
355
356
357
358
359
# File 'lib/databasedotcom-oauth2.rb', line 354

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

Instance Method Details

#call(env) ⇒ Object



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

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

#call!(env) ⇒ Object



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

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