Class: Capsium::Reactor::Authenticator

Inherits:
Object
  • Object
show all
Defined in:
lib/capsium/reactor/authenticator.rb,
sig/capsium/reactor/authenticator.rbs

Overview

Request authentication and route authorization for the reactor (05x-authentication, ARCHITECTURE.md section 4b).

Constant Summary collapse

LOGIN_PATH =

Returns:

  • (String)
"/auth/login"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(authentication, deploy:, package_path:, base_url: nil, state_file: nil) ⇒ Authenticator

Returns a new instance of Authenticator.



22
23
24
25
26
27
28
29
30
# File 'lib/capsium/reactor/authenticator.rb', line 22

def initialize(authentication, deploy:, package_path:, base_url: nil,
               state_file: nil)
  @authentication = authentication
  @deploy = deploy
  @package_path = package_path
  @base_url = base_url
  @state_file = state_file
  build_oauth2_flow if oauth2_enabled?
end

Instance Attribute Details

#authenticationPackage::Authentication (readonly)

Returns the value of attribute authentication.



20
21
22
# File 'lib/capsium/reactor/authenticator.rb', line 20

def authentication
  @authentication
end

#deployDeploy (readonly)

Returns the value of attribute deploy.

Returns:



20
21
22
# File 'lib/capsium/reactor/authenticator.rb', line 20

def deploy
  @deploy
end

Instance Method Details

#authenticate(request) ⇒ Hash[String, untyped]?

The identity for a request — from the session cookie or Basic credentials — or nil. An identity always carries "roles" (possibly empty).

Parameters:

  • request (Object)

Returns:

  • (Hash[String, untyped], nil)


59
60
61
62
# File 'lib/capsium/reactor/authenticator.rb', line 59

def authenticate(request)
  identity = @session&.identity_from(request)
  identity || authenticate_basic(request)
end

#authorize(identity, access_control) ⇒ Object

:ok, :unauthenticated or :forbidden for a route's accessControl ([...], "authenticationRequired": bool).



74
75
76
77
78
79
80
# File 'lib/capsium/reactor/authenticator.rb', line 74

def authorize(identity, access_control)
  return :ok unless access_control
  return :unauthenticated if unauthenticated?(identity, access_control)
  return :forbidden unless roles_allowed?(identity, access_control["roles"])

  :ok
end

#challenge(response) ⇒ Object

401, with a Basic challenge when basicAuth is enabled.

Parameters:

  • response (Object)

Returns:

  • (Object)


65
66
67
68
69
70
# File 'lib/capsium/reactor/authenticator.rb', line 65

def challenge(response)
  response.status = 401
  response["Content-Type"] = "text/plain"
  response["WWW-Authenticate"] = %(Basic realm="#{realm}") if basic_enabled?
  response.body = "Unauthorized"
end

#enabled?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/capsium/reactor/authenticator.rb', line 32

def enabled?
  @authentication.enabled?
end

#endpoint?(path) ⇒ Boolean

Parameters:

  • path (String)

Returns:

  • (Boolean)


42
43
44
# File 'lib/capsium/reactor/authenticator.rb', line 42

def endpoint?(path)
  endpoints.include?(path)
end

#endpointsArray[String]

The paths this authenticator answers itself (OAuth2 login and callback), mounted by the reactor.

Returns:

  • (Array[String])


38
39
40
# File 'lib/capsium/reactor/authenticator.rb', line 38

def endpoints
  oauth2_enabled? ? [LOGIN_PATH, @authentication.oauth2.redirect_path] : []
end

#serve_endpoint(request, response) ⇒ Object

Parameters:

  • request (Object)
  • response (Object)

Returns:

  • (Object)


46
47
48
49
50
51
52
53
54
# File 'lib/capsium/reactor/authenticator.rb', line 46

def serve_endpoint(request, response)
  if request.path == LOGIN_PATH
    response.status = 302
    response["Location"] = @oauth2_flow.authorization_url(request)
    response.body = "Redirecting to the identity provider"
  else
    handle_callback(request, response)
  end
end