Module: RazorRisk::Sinatra::Helpers::CheckAuthHelper

Includes:
Cassini::Authorisation::HeaderHelpers, Cassini::HeaderFunctions, Core::Diagnostics::Logger, Xqsr3::Quality::ParameterChecking
Defined in:
lib/razor_risk/sinatra/helpers/check_auth_helper.rb

Overview

########################################################################## CheckAuthHelper

Constant Summary collapse

RECOGNISED_AUTHENTICATION_SCHEMES =
%w{ none basic authorisation_only jwt }.map { |v| v.to_sym }
RECOGNISED_ALGORITHMS =
%w{ HS256 SHA256 AES-256-CBC }

Instance Method Summary collapse

Methods included from Cassini::HeaderFunctions

#make_WWW_auth_header

Methods included from Cassini::Authorisation::HeaderHelpers

#AuthorisationOnly_from_credentials, #Basic_from_credentials, #JWT_from_credentials, #credentials_from_AuthorisationOnly, #credentials_from_Basic, #credentials_from_JWT

Instance Method Details

#check_auth(env, auth_scheme, **options) ⇒ Array<::String>, ...

Checks the authentication information for one of the four accepted schemes - None, Basic, Authorisation-only (Razor Risk-specific),and JWT.

Parameters:

  • env (::Hash) —

    The request's env hash.

  • auth_scheme (::Symbol) —

    The authorisation scheme.

  • options (::Hash) —

    The options hash.

Options Hash (**options):

  • :credentials (Boolean) — default: false —

    When true the function will return the credentials, if they can be obtained.

  • :halt_unless_auth (Boolean) — default: true —

    If true the function will invoke Sinatra's halt with 401 when the authorisation field HTTP_AUTHORIZATION is not present.

  • :auth_sentinel (Object) —

    The value returned if :halt_unless_auth is false.

  • :auth_param_name (::String, Array<::String>) — default: 'HTTP_AUTHORIZATION' —

    The authorisation parameter name(s).

  • :jwt_secret (::String, ::Proc) —

    The JWT secret, or a lambda from which to obtain one, when auth_scheme is :jwt.

  • :halt_unless_cred (Boolean) — default: true —

    If true the function will invoke Sinatra's halt with 401 when the authorisation information does not contain valid credentials.

  • :cred_sentinel (Object) —

    The value returned if :halt_unless_cred is true.

Returns:

  • (Array<::String>) —

    If option :credentials and credentials can be obtained, returns an array containing the credentials appropriate for the specified auth_sheme.

  • (true) —

    If not option :credentials and credentials can be obtained.

  • (Object) —

    Returns the value of the :auth_sentinel if :halt_unless_auth is false and the auth header is not present.

  • (Object) —

    Returns the value of the :cred_sentinel if :halt_unless_cred is false and no credentials could be obtained.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/razor_risk/sinatra/helpers/check_auth_helper.rb', line 96

def check_auth env, auth_scheme, **options

    trace ParamNames[ :env, :auth_scheme, :options ], env, auth_scheme, options

    check_param env, 'env', type: ::Hash
    check_param auth_scheme, 'auth_scheme', type: ::Symbol, values: RECOGNISED_AUTHENTICATION_SCHEMES
    check_param options, 'options', type: ::Hash

    check_param options[:credentials], 'credentials', treat_as_option: true, types: [ ::FalseClass, ::TrueClass ], allow_nil: true
    check_param options[:halt_unless_auth], 'halt_unless_auth', treat_as_option: true, types: [ ::FalseClass, ::TrueClass ], allow_nil: true
    check_param options[:auth_sentinel], 'auth_sentinel', treat_as_option: true, allow_nil: true
    check_param options[:auth_param_name], 'auth_param_name', treat_as_option: true, types: [ ::String, [ ::String] ], allow_nil: true
    check_param options[:jwt_secret], 'jwt_secret', treat_as_option: true, types: [ ::String, ::Proc ], allow_nil: :jwt != auth_scheme
    check_param options[:halt_unless_cred], 'halt_unless_auth', treat_as_option: true, types: [ ::FalseClass, ::TrueClass ], allow_nil: true


    options = {

        auth_param_name: HTTP_AUTHORIZATION,
        credentials: false,
        halt_unless_auth: true,
        halt_unless_cred: true,
    }.merge options


    auth = nil

    auth_param_name =   options[:auth_param_name] || HTTP_AUTHORIZATION
    case auth_param_name
    when ::Array

        auth_param_name.each do |name|

            break if auth = env[name]
        end
    else

        # will be a ::String
        auth = env[auth_param_name]
    end


    log :debug4, "auth(#{auth.class})='#{auth}'"


    unless auth || :none == auth_scheme

        return options[:auth_sentinel] unless options[:halt_unless_auth]
        halt 401, make_WWW_auth_header(auth_scheme), 'Missing or invalid authenticate header'
    end


    return true unless options[:credentials]


    credentials = nil

    case auth_scheme
    when :none

        credentials = []
    when :basic

        credentials = credentials_from_Basic auth, nil: true
    when :authorisation_only, :authorization_only

        credentials = credentials_from_AuthorisationOnly(auth)
    when :jwt

        jwt_secret = options[:jwt_secret]
        jwt_secret = jwt_secret.call() if ::Proc == jwt_secret

        begin

            credentials = credentials_from_JWT auth, jwt_secret, nil: true
        rescue JWT::ValidationError => x

            log "exception (#{x.class}): #{x.message}"
            halt 401, make_WWW_auth_header(auth_scheme), 'Invalid credentials'
        rescue JWT::DecodeError => x

            log "exception (#{x.class}): #{x.message}"
            halt 401, make_WWW_auth_header(auth_scheme), 'Missing or invalid authenticate header'
        end
    end

    return credentials if credentials

    return options[:cred_sentinel] unless options[:halt_unless_cred]

    halt 401, make_WWW_auth_header(auth_scheme), 'Missing or invalid authenticate header'
end