Class: Steppe::Auth::Basic

Inherits:
Object
  • Object
show all
Includes:
Responses
Defined in:
lib/steppe/auth/basic.rb

Overview

HTTP Basic authentication security scheme. Validates username and password credentials from the Authorization header against a credentials store.

Examples:

Using a simple hash store

store = {
  'joe' => 'secret123',
  'anna' => 'password456'
}
basic_auth = Steppe::Auth::Basic.new('my_auth', store: store)

# In a service definition:
api.security_scheme basic_auth

# Or use the shortcut
api.basic_auth 'my_auth', store: { 'joe' => 'secret123' }

# Then in an endpoint in the service:
e.security 'my_auth'

Using a custom credentials store

class DatabaseCredentialsStore
  def lookup(username)
    user = User.find_by(username: username)
    user&.password_digest
  end
end

store = DatabaseCredentialsStore.new
api.basic_auth 'my_auth', store: store

Defined Under Namespace

Classes: SimpleUserPasswordStore

Constant Summary collapse

SCHEME =
'basic'
EXP =
/^Basic\s+([A-Za-z0-9+\/=]+)\s*$/
CredentialsStoreInterface =

Interface for custom credentials store implementations. Required methods:

  • lookup(username): Returns the password for the given username, or nil if not found

Types::Interface[:lookup]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, store:) ⇒ Basic

Returns a new instance of Basic.

Parameters:

  • name (String)

    The security scheme name (used in OpenAPI)

  • store (CredentialsStoreInterface)

    Credentials store for validating username/password pairs



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/steppe/auth/basic.rb', line 75

def initialize(name, store:)
  @name = name
  @scheme = SCHEME
  @store = case store
  when SimpleUserPasswordStore::HashInterface
    SimpleUserPasswordStore.new(store)
  when CredentialsStoreInterface
    store
  else
    raise ArgumentError, "expected a CredentialsStoreInterface interface #{CredentialsStoreInterface}, but got #{store.inspect}"
  end
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



71
72
73
# File 'lib/steppe/auth/basic.rb', line 71

def name
  @name
end

Instance Method Details

#handle(conn, _required_scopes = nil) ⇒ Steppe::Result::Continue, Steppe::Result::Halt

Handle authentication for a connection. Validates the Basic credentials from the Authorization header and checks username/password match.

Parameters:

  • conn (Steppe::Result)

    The connection/result object

  • _required_scopes (nil) (defaults to: nil)

    Unused parameter (Basic auth does not support scopes)

Returns:



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/steppe/auth/basic.rb', line 94

def handle(conn, _required_scopes = nil)
  auth_str = conn.request.env[HTTP_AUTHORIZATION]
  return unauthorized(conn) if auth_str.nil?

  match = auth_str.match(EXP)
  return unauthorized(conn) if match.nil?

  username, password = decode(match[1])
  return forbidden(conn) if @store.lookup(username) != password

  conn
end

#to_openapiHash

Convert this security scheme to OpenAPI 3.0 format.

Returns:

  • (Hash)

    OpenAPI security scheme object



110
111
112
113
114
115
# File 'lib/steppe/auth/basic.rb', line 110

def to_openapi
  {
    'type' => 'http',
    'scheme' => scheme
  }
end