Class: SiriusApi::Strategies::RemoteOAuthServer

Inherits:
Warden::Strategies::Base
  • Object
show all
Defined in:
lib/sirius_api/strategies/remote_oauth_server.rb

Overview

Simple Warden strategy that authorizes requests with a Bearer access token using a remote OAuth 2.0 authorization server.

TODO: Implement caching!

Constant Summary collapse

AUTHORIZATION_HEADERS =
Rack::Auth::AbstractRequest::AUTHORIZATION_KEYS
CHECK_TOKEN_URI =
Config.oauth_check_token_uri

Instance Method Summary collapse

Instance Method Details

#access_tokenObject


40
41
42
43
44
45
46
47
# File 'lib/sirius_api/strategies/remote_oauth_server.rb', line 40

def access_token
  authz_header = env.select { |key| AUTHORIZATION_HEADERS.include? key }
     .values.select { |v| v.start_with? 'Bearer ' }
     .map { |v| v.split(' ', 2).last }
     .first

  authz_header || params['access_token']
end

#authenticate!Object


26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/sirius_api/strategies/remote_oauth_server.rb', line 26

def authenticate!
  if access_token.blank?
    errors.add(:general, 'Missing OAuth access token.')
    return
  end

  token = request_token_info(access_token)
  if error_msg = validate_token(token)
    errors.add(:general, "[OAuth] #{error_msg}")
  else
    success! User.new(token.user_name, token.scope)
  end
end

#http_clientObject


82
83
84
85
86
87
88
# File 'lib/sirius_api/strategies/remote_oauth_server.rb', line 82

def http_client
  Faraday.new do |c|
    c.request :url_encoded
    c.response :json, content_type: /\bjson$/
    c.adapter Faraday.default_adapter
  end
end

#request_token_info(token_value) ⇒ Object


49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/sirius_api/strategies/remote_oauth_server.rb', line 49

def request_token_info(token_value)
  resp = http_client.post(CHECK_TOKEN_URI, token: token_value)
  if resp.body.is_a?(Hash)
    body = resp.body
  else
    error_body = resp.body
  end
  OpenStruct.new(body || {}).tap do |s|
    s.status = resp.status
    s.error_body = error_body
  end
end

#store?Boolean

Returns:

  • (Boolean)

22
23
24
# File 'lib/sirius_api/strategies/remote_oauth_server.rb', line 22

def store?
  false
end

#validate_token(token) ⇒ Object


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/sirius_api/strategies/remote_oauth_server.rb', line 62

def validate_token(token)
  if token.status == 400
    "Invalid access token."
  elsif token.status != 200
    "Unable to verify access token (status: #{token.status}).".tap do |msg|
      Raven.capture_message(msg, token: token)
    end
  elsif token.client_id.blank? || token.exp.blank?
    "Invalid response from the authorization server.".tap do |msg|
      Raven.capture_message(msg, token: token)
    end
  elsif Time.at(token.exp) < Time.now
    "Access token has expired."
  elsif token.scope.empty?
    "Access token has no scopes granted."
  else
    nil
  end
end