openidauthzen 0.1.0-alpha.1

OpenID AuthZEN Authorization API 1.0 — Policy Decision and Enforcement Points for Rust
Documentation
//! Access evaluation request and response types ([AuthZEN §6]–[§7]).
//!
//! This module covers single and batch access evaluations:
//!
//! | Endpoint | Request | Response |
//! |----------|---------|----------|
//! | `POST /access/v1/evaluation` | [`EvaluationRequest`] | [`EvaluationResponse`] |
//! | `POST /access/v1/evaluations` | [`EvaluationsRequest`] | [`EvaluationsResponse`] |
//!
//! Batch evaluations support three execution semantics via
//! [`EvaluationSemantic`].
//!
//! [AuthZEN §6]: https://openid.net/specs/authorization-api-1_0.html#section-6
//! [AuthZEN §7]: https://openid.net/specs/authorization-api-1_0.html#section-7

use serde::{Deserialize, Serialize};

use crate::model::{Action, Context, Resource, Subject};

/// A single access evaluation request (`POST /access/v1/evaluation`,
/// [AuthZEN §6]).
///
/// [AuthZEN §6]: https://openid.net/specs/authorization-api-1_0.html#section-6
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EvaluationRequest {
    /// The entity requesting access. Required.
    pub subject: Subject,
    /// The operation being requested. Required.
    pub action: Action,
    /// The target being accessed. Required.
    pub resource: Resource,
    /// Environmental context for the evaluation.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub context: Option<Context>,
}

/// Response to a single access evaluation request ([AuthZEN §6]).
///
/// [AuthZEN §6]: https://openid.net/specs/authorization-api-1_0.html#section-6
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EvaluationResponse {
    /// `true` for permit, `false` for deny. Required.
    pub decision: bool,
    /// Additional decision context (reasons, obligations, etc.).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub context: Option<serde_json::Value>,
}

/// A batch access evaluation request (`POST /access/v1/evaluations`,
/// [AuthZEN §7]).
///
/// Top-level `subject`, `action`, `resource`, and `context` fields serve
/// as defaults that individual [`EvaluationItem`] entries can override.
///
/// [AuthZEN §7]: https://openid.net/specs/authorization-api-1_0.html#section-7
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EvaluationsRequest {
    /// Default subject for all evaluations in the batch.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subject: Option<Subject>,
    /// Default action for all evaluations in the batch.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub action: Option<Action>,
    /// Default resource for all evaluations in the batch.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub resource: Option<Resource>,
    /// Default context for all evaluations in the batch.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub context: Option<Context>,
    /// The individual evaluations to perform. Required.
    pub evaluations: Vec<EvaluationItem>,
    /// Execution options for the batch.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub options: Option<EvaluationsOptions>,
}

/// A single evaluation within a batch request ([AuthZEN §7]).
///
/// Each field overrides the corresponding top-level default from the
/// enclosing [`EvaluationsRequest`].
///
/// [AuthZEN §7]: https://openid.net/specs/authorization-api-1_0.html#section-7
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EvaluationItem {
    /// Subject override for this evaluation.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subject: Option<Subject>,
    /// Action override for this evaluation.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub action: Option<Action>,
    /// Resource override for this evaluation.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub resource: Option<Resource>,
    /// Context override for this evaluation.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub context: Option<Context>,
}

/// Execution options for a batch evaluation request ([AuthZEN §7]).
///
/// [AuthZEN §7]: https://openid.net/specs/authorization-api-1_0.html#section-7
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EvaluationsOptions {
    /// The execution semantic for the batch. Defaults to
    /// [`EvaluationSemantic::ExecuteAll`] if not specified.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub evaluations_semantic: Option<EvaluationSemantic>,
    /// Additional implementation-specific options ([AuthZEN §7]).
    ///
    /// [AuthZEN §7]: https://openid.net/specs/authorization-api-1_0.html#section-7
    #[serde(flatten)]
    pub extra: Option<serde_json::Map<String, serde_json::Value>>,
}

/// Execution semantic for batch evaluations ([AuthZEN §7]).
///
/// Controls how the PDP processes evaluations within a batch request
/// and when it may short-circuit.
///
/// [AuthZEN §7]: https://openid.net/specs/authorization-api-1_0.html#section-7
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum EvaluationSemantic {
    /// Evaluate all items and return all results. This is the default.
    #[serde(rename = "execute_all")]
    ExecuteAll,
    /// Stop on the first deny and return immediately.
    #[serde(rename = "deny_on_first_deny")]
    DenyOnFirstDeny,
    /// Stop on the first permit and return immediately.
    #[serde(rename = "permit_on_first_permit")]
    PermitOnFirstPermit,
}

/// Response to a batch access evaluation request ([AuthZEN §7]).
///
/// [AuthZEN §7]: https://openid.net/specs/authorization-api-1_0.html#section-7
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EvaluationsResponse {
    /// An overall decision for the batch. The spec recommends omitting
    /// this field; when present it summarizes the batch outcome.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub decision: Option<bool>,
    /// Per-evaluation results, in the same order as the request.
    pub evaluations: Vec<EvaluationResponse>,
}