Class: HaveAPI::Authentication::OAuth2::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/haveapi/authentication/oauth2/config.rb

Overview

Config passed to the OAuth2 provider

Create your own subclass and pass it to with_config. The created provider can then be added to authentication chain.

In general, it is up to the implementation to provide the authentication flow -- render HTML page in #handle_get_authorize and then process it in #handle_post_authorize. The implementation must also handle generation of all needed tokens, their persistence and validity checking.

Instance Method Summary collapse

Constructor Details

#initialize(provider, server, v) ⇒ Config

Returns a new instance of Config.



13
14
15
16
17
# File 'lib/haveapi/authentication/oauth2/config.rb', line 13

def initialize(provider, server, v)
  @provider = provider
  @server = server
  @version = v
end

Instance Method Details

#authorize_pathString

Path to the authorization endpoint on this API

Returns:

  • (String)


150
151
152
# File 'lib/haveapi/authentication/oauth2/config.rb', line 150

def authorize_path
  @provider.authorize_path
end

#base_urlString

Base URL of the authorization server, including protocol

This should in general be the same URL at which your API is located. It can be useful if you wish to have a separate domain for authentication.

Example: https://api.domain.tld

Returns:

  • (String)

Raises:

  • (NotImplementedError)


144
145
146
# File 'lib/haveapi/authentication/oauth2/config.rb', line 144

def base_url
  raise NotImplementedError
end

#find_authorization_by_code(client, code) ⇒ Authorization?

Find authorization by code

Parameters:

  • client (Client)
  • code (String)

Returns:



116
117
118
# File 'lib/haveapi/authentication/oauth2/config.rb', line 116

def find_authorization_by_code(client, code)

end

#find_authorization_by_refresh_token(client, refresh_token) ⇒ Authorization?

Find authorization by refresh token

Parameters:

  • client (Client)
  • refresh_token (String)

Returns:



124
125
126
# File 'lib/haveapi/authentication/oauth2/config.rb', line 124

def find_authorization_by_refresh_token(client, refresh_token)

end

#find_client_by_id(client_id) ⇒ Client?

Find client by ID

Parameters:

  • client_id (String)

Returns:



108
109
110
# File 'lib/haveapi/authentication/oauth2/config.rb', line 108

def find_client_by_id(client_id)

end

#find_user_by_access_token(request, access_token) ⇒ Object?

Find user by the bearer token sent in HTTP header or as a query parameter

Parameters:

  • sinatra_request (Sinatra::Request)
  • access_token (String)

Returns:

  • (Object, nil)

    user



132
133
134
# File 'lib/haveapi/authentication/oauth2/config.rb', line 132

def find_user_by_access_token(request, access_token)

end

#get_authorization_code(auth_res) ⇒ String

Get oauth2 authorization code

Called when the authentication is successful and complete. This method must generate and return authorization_code which is then sent to the client. It is up to the API implementation to persist the code.

Parameters:

Returns:

  • (String)


63
64
65
# File 'lib/haveapi/authentication/oauth2/config.rb', line 63

def get_authorization_code(auth_res)

end

#get_tokens(authorization, sinatra_request) ⇒ Array

Get access token, its expiration date and optionally a refresh token

The client has used the authorization_code returned by #get_authorization_code and now requests its access token. It is up to the implementation to create and persist the tokens. The authorization code should be invalidated.

Parameters:

  • authorization (Authorization)
  • sinatra_request (Sinatra::Request)

Returns:

  • (Array)

    access token, expiration date and optional refresh token



76
77
78
# File 'lib/haveapi/authentication/oauth2/config.rb', line 76

def get_tokens(authorization, sinatra_request)

end

#handle_get_authorize(sinatra_handler:, sinatra_request:, sinatra_params:, oauth2_request:, oauth2_response:, client:) ⇒ AuthResult?

Handle GET authorize requests

This method usually writes HTML to oauth2_response, you must also set content type.

Parameters:

  • sinatra_handler (Object)
  • sinatra_request (Sinatra::Request)
  • sinatra_params (Hash)

    request params

  • oauth2_request (Rack::OAuth2::Server::Authorize::Request)
  • oauth2_response (Rack::OAuth2::Server::Authorize::Response)
  • client (Client)

Returns:



31
32
33
# File 'lib/haveapi/authentication/oauth2/config.rb', line 31

def handle_get_authorize(sinatra_handler:, sinatra_request:, sinatra_params:, oauth2_request:, oauth2_response:, client:)

end

#handle_post_authorize(sinatra_handler:, sinatra_request:, sinatra_params:, oauth2_request:, oauth2_response:, client:) ⇒ AuthResult?

Handle POST authorize requests

Process form data and return AuthResult or nil. When nil is returned the authorization process is aborted and the user is redirected back to the client.

If the authentication is incomplete, this method must also write output to oauth2_response, usually HTML. Content type must be set.

Parameters:

  • sinatra_handler (Object)
  • sinatra_request (Sinatra::Request)
  • sinatra_params (Hash)

    request params

  • oauth2_request (Rack::OAuth2::Server::Authorize::Request)
  • oauth2_response (Rack::OAuth2::Server::Authorize::Response)
  • client (Client)

Returns:



51
52
53
# File 'lib/haveapi/authentication/oauth2/config.rb', line 51

def (sinatra_handler:, sinatra_request:, sinatra_params:, oauth2_request:, oauth2_response:, client:)

end

#handle_post_revoke(sinatra_request, token, token_type_hint: nil) ⇒ :revoked, :unsupported

Revoke access or refresh token

Note that even if the token is not found, this method should return :revoked.

Parameters:

  • sinatra_request (Sinatra::Request)
  • token (String)
  • token_type_hint (nil, 'access_token', 'refresh_token') (defaults to: nil)

Returns:

  • (:revoked, :unsupported)


101
102
103
# File 'lib/haveapi/authentication/oauth2/config.rb', line 101

def handle_post_revoke(sinatra_request, token, token_type_hint: nil)

end

#http_headerString

Custom HTTP header that is searched for the access token

The authorization header is not feasible from web browsers, so we optionally use our own header for the purpose.

Returns:

  • (String)


160
161
162
# File 'lib/haveapi/authentication/oauth2/config.rb', line 160

def http_header
  'X-HaveAPI-OAuth2-Token'
end

#oauth2_params(req) ⇒ Hash<String, String>

Parameters needed for the authorization process

Use these in #render_authorization_page, put them e.g. in hidden form fields.

Returns:

  • (Hash<String, String>)


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/haveapi/authentication/oauth2/config.rb', line 170

def oauth2_params(req)
  ret = {
    client_id: req.client_id,
    response_type: req.response_type,
    redirect_uri: req.redirect_uri,
    scope: req.scope.join(' '),
    state: req.state,
  }

  if req.code_challenge.present? && req.code_challenge_method.present?
    ret.update(
      code_challenge: req.code_challenge,
      code_challenge_method: req.code_challenge_method,
    )
  end

  ret
end

#refresh_tokens(authorization, sinatra_request) ⇒ Array

Refresh access token and optionally generate new refresh token

The implementation should invalidate the current tokens and generate and persist new ones.

Parameters:

  • authorization (Authorization)
  • sinatra_request (Sinatra::Request)

Returns:

  • (Array)

    access token, expiration date and optional refresh token



88
89
90
# File 'lib/haveapi/authentication/oauth2/config.rb', line 88

def refresh_tokens(authorization, sinatra_request)

end