rocketmq_auth/authorization/chain/handler.rs
1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Authorization handler trait for Chain of Responsibility pattern.
16//!
17//! This module provides async authorization handlers optimized for:
18//! - Async operations (metadata lookup, policy evaluation)
19//! - Error propagation with fail-fast semantics
20//! - Sequential chain execution
21//! - Type safety with DefaultAuthorizationContext
22
23use std::future::Future;
24use std::pin::Pin;
25
26use rocketmq_security_api::AuthorizationDecision;
27
28use crate::authorization::context::default_authorization_context::DefaultAuthorizationContext;
29use crate::AuthServiceResult;
30
31/// Authorization handler trait.
32///
33/// This trait defines the interface for handlers in the authorization chain.
34/// Each handler returns a final allow/deny decision. Operational failures remain
35/// errors and stop the chain immediately.
36///
37/// # Design Pattern
38///
39/// Implements Chain of Responsibility, allowing multiple authorization
40/// strategies (ACL, RBAC, ABAC) to be chained together.
41///
42/// # Thread Safety
43///
44/// Implementations must be Send + Sync for concurrent access.
45pub trait AuthorizationHandler: Send + Sync {
46 /// Handle the authorization request.
47 ///
48 /// # Arguments
49 ///
50 /// * `context` - The authorization context containing subject, resource, actions, etc.
51 ///
52 /// # Returns
53 ///
54 /// * `Ok(AuthorizationDecision)` - A final authorization decision
55 /// * `Err(AuthServiceError)` - The handler could not make a decision
56 ///
57 /// # Example
58 ///
59 /// ```rust,ignore
60 /// use rocketmq_auth::AuthorizationHandler;
61 /// use rocketmq_auth::DefaultAuthorizationContext;
62 ///
63 /// struct MyHandler;
64 ///
65 /// impl AuthorizationHandler for MyHandler {
66 /// fn handle<'a>(
67 /// &'a self,
68 /// context: &'a DefaultAuthorizationContext,
69 /// ) -> Pin<Box<dyn Future<Output = AuthServiceResult<AuthorizationDecision>> + Send + 'a>> {
70 /// Box::pin(async move {
71 /// // Authorization logic here
72 /// Ok(AuthorizationDecision::Allow)
73 /// })
74 /// }
75 /// }
76 /// ```
77 fn handle<'a>(
78 &'a self,
79 context: &'a DefaultAuthorizationContext,
80 ) -> Pin<Box<dyn Future<Output = AuthServiceResult<AuthorizationDecision>> + Send + 'a>>;
81}