PhoenixGenApi.Permission (PhoenixGenApi v1.1.2)

View Source

Provides permission checking functionality for API requests.

This module implements a flexible permission system that can verify whether a user has the right to execute a specific request. Permissions can be disabled, or configured to check that certain request arguments match the requesting user's identity.

Permission Modes

Disabled Permissions (false)

When check_permission: false is set in the FunConfig, all permission checks pass. This is useful for public endpoints that don't require authentication or authorization.

Argument-Based Permissions ({:arg, arg_name})

When check_permission: {:arg, arg_name} is configured, the system verifies that the value of the specified argument matches the request's user_id. This ensures users can only access their own data.

For example, with {:arg, "user_id"}, a request from user "123" will only be allowed if request.args["user_id"] == "123".

Examples

# Public endpoint - no permission check
config = %FunConfig{
  request_type: "get_public_data",
  check_permission: false
}

request = %Request{user_id: "any_user"}
Permission.check_permission(request, config)
# => true

# User-specific endpoint - must match user_id
config = %FunConfig{
  request_type: "get_user_profile",
  check_permission: {:arg, "user_id"}
}

# This passes - user accessing their own data
request = %Request{
  user_id: "user_123",
  args: %{"user_id" => "user_123"}
}
Permission.check_permission(request, config)
# => true

# This fails - user trying to access another user's data
request = %Request{
  user_id: "user_123",
  args: %{"user_id" => "user_999"}
}
Permission.check_permission(request, config)
# => false

Security Considerations

  • Always use check_permission!/2 in the execution path to raise on failures
  • The check_permission/2 function is non-raising and returns a boolean
  • Missing arguments result in permission denial (returns false)
  • Permission checks happen before argument validation and function execution

Summary

Functions

Checks if a request has permission to be executed based on the configuration.

Checks permission and raises an exception if the check fails.

Functions

check_permission(request, fun_config)

Checks if a request has permission to be executed based on the configuration.

This is a non-raising version that returns a boolean result. Use this when you need to check permissions without raising an exception.

Parameters

  • request - The Request struct containing user information and arguments
  • fun_config - The FunConfig struct with permission settings

Returns

  • true - Permission check passed
  • false - Permission check failed

Examples

request = %Request{
  user_id: "user_123",
  args: %{"user_id" => "user_123"}
}

config = %FunConfig{check_permission: {:arg, "user_id"}}

if Permission.check_permission(request, config) do
  # Execute the request
else
  # Deny access
end

check_permission!(request, fun_config)

Checks permission and raises an exception if the check fails.

This is the raising version of check_permission/2. It should be used in the request execution pipeline where permission failures should halt processing.

Parameters

  • request - The Request struct containing user information and arguments
  • fun_config - The FunConfig struct with permission settings

Returns

  • nil - Permission check passed (function returns nothing on success)

Raises

Examples

request = %Request{
  user_id: "user_123",
  args: %{"user_id" => "user_999"}
}

config = %FunConfig{check_permission: {:arg, "user_id"}}

# This will raise because user_ids don't match
Permission.check_permission!(request, config)
# ** (RuntimeError) Permission denied for request from user: "user_123"

Notes

  • Logs a warning with request details when permission is denied
  • Always called before request execution in the Executor module
  • Returns nothing on success (only side effect is potential exception)