Class: Otto::Security::Authentication::StrategyResult

Inherits:
Data
  • Object
show all
Defined in:
lib/otto/security/authentication/strategy_result.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#auth_methodObject (readonly)

Returns the value of attribute auth_method

Returns:

  • (Object)

    the current value of auth_method



24
25
26
# File 'lib/otto/security/authentication/strategy_result.rb', line 24

def auth_method
  @auth_method
end

#metadataObject (readonly)

Returns the value of attribute metadata

Returns:

  • (Object)

    the current value of metadata



24
25
26
# File 'lib/otto/security/authentication/strategy_result.rb', line 24

def 
  @metadata
end

#sessionObject (readonly)

Returns the value of attribute session

Returns:

  • (Object)

    the current value of session



24
25
26
# File 'lib/otto/security/authentication/strategy_result.rb', line 24

def session
  @session
end

#strategy_nameObject (readonly)

Returns the value of attribute strategy_name

Returns:

  • (Object)

    the current value of strategy_name



24
25
26
# File 'lib/otto/security/authentication/strategy_result.rb', line 24

def strategy_name
  @strategy_name
end

#userObject (readonly)

Returns the value of attribute user

Returns:

  • (Object)

    the current value of user



24
25
26
# File 'lib/otto/security/authentication/strategy_result.rb', line 24

def user
  @user
end

Class Method Details

.anonymous(metadata: {}, strategy_name: 'anonymous') ⇒ StrategyResult

Create an anonymous (unauthenticated) result

Used by middleware for routes without auth requirements and by PublicStrategy for publicly accessible routes.

Parameters:

  • metadata (Hash) (defaults to: {})

    Optional metadata (IP, user agent, etc.)

Returns:



113
114
115
116
117
118
119
120
121
# File 'lib/otto/security/authentication/strategy_result.rb', line 113

def self.anonymous(metadata: {}, strategy_name: 'anonymous')
  new(
    session: {},
    user: nil,
    auth_method: 'anonymous',
    metadata: ,
    strategy_name: strategy_name
  )
end

Instance Method Details

#anonymous?Boolean

Check if the request is anonymous (no user in session)

Returns:

  • (Boolean)

    True if not authenticated



156
157
158
# File 'lib/otto/security/authentication/strategy_result.rb', line 156

def anonymous?
  user.nil?
end

#auth_attempt_succeeded?Boolean

Check if authentication strategy just executed and succeeded

This checks AUTH ATTEMPT OUTCOME, not just session state. Returns true only when:

  1. Route had an auth=... requirement (not anonymous/public)
  2. Auth strategy executed
  3. Authentication succeeded (user authenticated)

Examples:

# Redirect after successful login
redirect_to dashboard if @context.auth_attempt_succeeded?

Returns:

  • (Boolean)

    True if auth strategy just succeeded



149
150
151
# File 'lib/otto/security/authentication/strategy_result.rb', line 149

def auth_attempt_succeeded?
  authenticated? && auth_method.to_s != 'anonymous'
end

#authenticated?Boolean

Check if the request has an authenticated user in session

This checks REQUEST STATE, not auth attempt outcome. Returns true if session contains a user, regardless of whether authentication just occurred or was from a previous request.

Examples:

# Block registration if user already logged in
raise FormError if @context.authenticated?

Returns:

  • (Boolean)

    True if user is present in session



133
134
135
# File 'lib/otto/security/authentication/strategy_result.rb', line 133

def authenticated?
  !user.nil?
end

#has_any_permission?(*permissions) ⇒ Boolean

Check if the user has any of the specified permissions

Parameters:

  • permissions (Array<String, Symbol>)

    Permissions to check

Returns:

  • (Boolean)

    True if user has any of the permissions



204
205
206
# File 'lib/otto/security/authentication/strategy_result.rb', line 204

def has_any_permission?(*permissions)
  permissions.flatten.any? { |permission| has_permission?(permission) }
end

#has_any_role?(*roles) ⇒ Boolean

Check if the user has any of the specified roles

Parameters:

  • roles (Array<String, Symbol>)

    Roles to check

Returns:

  • (Boolean)

    True if user has any of the roles



196
197
198
# File 'lib/otto/security/authentication/strategy_result.rb', line 196

def has_any_role?(*roles)
  roles.flatten.any? { |role| has_role?(role) }
end

#has_permission?(permission) ⇒ Boolean

Check if the user has a specific permission

A user model that defines #has_permission? is asked directly. Otherwise the answer is derived from #permissions, so the predicate and the accessor always agree, including for Set-backed and other non-Array Enumerable collections.

Parameters:

  • permission (String, Symbol)

    Permission to check

Returns:

  • (Boolean)

    True if user has the permission



185
186
187
188
189
190
# File 'lib/otto/security/authentication/strategy_result.rb', line 185

def has_permission?(permission)
  return false unless authenticated?
  return user.has_permission?(permission) if user.respond_to?(:has_permission?)

  permissions.include?(permission.to_s)
end

#has_role?(role) ⇒ Boolean

Check if the user has a specific role

A user model that defines #has_role? is asked directly. Otherwise the answer is derived from #roles, so the predicate and the accessor always agree: has_role?(r) is roles.include?(r.to_s) for Hash, PORO, ORM, Set-backed, and single-#role users alike.

Parameters:

  • role (String, Symbol)

    Role to check

Returns:

  • (Boolean)

    True if user has the role



169
170
171
172
173
174
# File 'lib/otto/security/authentication/strategy_result.rb', line 169

def has_role?(role)
  return false unless authenticated?
  return user.has_role?(role) if user.respond_to?(:has_role?)

  roles.include?(role.to_s)
end

#inspectString

Create a string representation for debugging

Returns:

  • (String)

    Debug representation



307
308
309
310
311
312
313
# File 'lib/otto/security/authentication/strategy_result.rb', line 307

def inspect
  if authenticated?
    "#<StrategyResult authenticated user=#{user_name || user_id} roles=#{roles} method=#{auth_method}>"
  else
    "#<StrategyResult anonymous method=#{auth_method}>"
  end
end

#permissionsArray<String>

Get all user permissions as an array

Supports object-backed users via #permissions and Hash users via :permissions/'permissions'. Never calls #[] on a non-Hash user.

Returns:

  • (Array<String>)

    Array of permissions (empty if none)



291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/otto/security/authentication/strategy_result.rb', line 291

def permissions
  return [] unless authenticated?

  # Try user model methods first, fall back to hash access for backward compatibility
  if user.respond_to?(:permissions)
    normalize_list(user.permissions)
  elsif user.is_a?(Hash)
    normalize_list(user[:permissions] || user['permissions'])
  else
    []
  end
end

#rolesArray<String>

Get all user roles as an array

Supports object-backed users (ORM models, POROs, Data/Struct) via #roles / #role, and Hash users via :roles/'roles' then :role/'role'. Never calls #[] on a non-Hash user, so a model without role support yields [] instead of raising. #roles on an object must return role names (Strings or Symbols, in any Enumerable); an association of role records is stringified as-is and matches nothing, which denies rather than grants.

Returns:

  • (Array<String>)

    Array of roles (empty if none)



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/otto/security/authentication/strategy_result.rb', line 258

def roles
  return [] unless authenticated?

  # Try user model methods first, fall back to hash access for backward compatibility
  if user.respond_to?(:roles)
    normalized = normalize_list(user.roles)
    return normalized unless normalized.empty?
  end

  if user.respond_to?(:role)
    role = user.role
    return [role.to_s] if role
  end

  return [] unless user.is_a?(Hash)

  roles_data = user[:roles] || user['roles']
  if roles_data.is_a?(Array)
    roles_data.map(&:to_s)
  elsif roles_data
    [roles_data.to_s]
  else
    role = user[:role] || user['role']
    role ? [role.to_s] : []
  end
end

#session_idString?

Get session ID from various possible locations

Returns:

  • (String, nil)

    Session ID or nil



243
244
245
# File 'lib/otto/security/authentication/strategy_result.rb', line 243

def session_id
  session[:id] || session['id'] || session[:session_id] || session['session_id']
end

#to_hHash

Create a hash representation

Returns:

  • (Hash)

    Hash representation of the context



339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/otto/security/authentication/strategy_result.rb', line 339

def to_h
  {
                   session: session,
                      user: user,
               auth_method: auth_method,
                  metadata: ,
             authenticated: authenticated?,
    auth_attempt_succeeded: auth_attempt_succeeded?,
                   user_id: user_id,
                 user_name: user_name,
                     roles: roles,
               permissions: permissions,
  }
end

#user_contextHash

Get user context - a hash containing user-specific information and metadata

Returns:

  • (Hash)

    User context hash



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/otto/security/authentication/strategy_result.rb', line 318

def user_context
  if authenticated?
    case auth_method
    when 'session'
      { user_id: user_id, session: session }
    else
      
    end
  else
    case auth_method
    when 'anonymous'
      {}
    else
      
    end
  end
end

#user_idString, ...

Get user ID from various possible locations

Returns:

  • (String, Integer, nil)

    User ID or nil



211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/otto/security/authentication/strategy_result.rb', line 211

def user_id
  return nil unless authenticated?

  # Try user model methods first, fall back to hash access and session
  if user.respond_to?(:id)
    user.id
  elsif user.respond_to?(:user_id)
    user.user_id
  elsif user.is_a?(Hash)
    user[:id] || user['id'] || user[:user_id] || user['user_id']
  end || session[:user_id] || session['user_id']
end

#user_nameString?

Get user name from various possible locations

Returns:

  • (String, nil)

    User name or nil



227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/otto/security/authentication/strategy_result.rb', line 227

def user_name
  return nil unless authenticated?

  # Try user model methods first, fall back to hash access
  if user.respond_to?(:name)
    user.name
  elsif user.respond_to?(:username)
    user.username
  elsif user.is_a?(Hash)
    user[:name] || user['name'] || user[:username] || user['username']
  end
end