openzeppelin_relayer/api/routes/
api_keys.rs

1//! This module defines the HTTP routes for api keys operations.
2//! The routes are integrated with the Actix-web framework and interact with the api key controller.
3use crate::{
4    api::controllers::api_key,
5    models::{ApiKeyRequest, DefaultAppState, PaginationQuery},
6};
7use actix_web::{delete, get, post, web, Responder};
8
9/// List API keys
10#[get("/api-keys")]
11async fn list_api_keys(
12    query: web::Query<PaginationQuery>,
13    data: web::ThinData<DefaultAppState>,
14) -> impl Responder {
15    api_key::list_api_keys(query.into_inner(), data).await
16}
17
18#[get("/api-keys/{api_key_id}/permissions")]
19async fn get_api_key_permissions(
20    api_key_id: web::Path<String>,
21    data: web::ThinData<DefaultAppState>,
22) -> impl Responder {
23    api_key::get_api_key_permissions(api_key_id.into_inner(), data).await
24}
25
26/// Create a new API key
27#[post("/api-keys")]
28async fn create_api_key(
29    req: web::Json<ApiKeyRequest>,
30    data: web::ThinData<DefaultAppState>,
31) -> impl Responder {
32    api_key::create_api_key(req.into_inner(), data).await
33}
34
35#[delete("/api-keys/{api_key_id}")]
36async fn delete_api_key(
37    api_key_id: web::Path<String>,
38    data: web::ThinData<DefaultAppState>,
39) -> impl Responder {
40    api_key::delete_api_key(api_key_id.into_inner(), data).await
41}
42
43/// Initializes the routes for api keys.
44pub fn init(cfg: &mut web::ServiceConfig) {
45    // Register routes with literal segments before routes with path parameters
46    cfg.service(create_api_key); // /api-keys
47    cfg.service(list_api_keys); // /api-keys
48    cfg.service(get_api_key_permissions); // /api-keys/{api_key_id}/permissions
49    cfg.service(delete_api_key); // /api-keys/{api_key_id}
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use crate::utils::mocks::mockutils::create_mock_app_state;
56    use actix_web::{http::StatusCode, test, web, App};
57
58    #[actix_web::test]
59    async fn test_api_key_routes_are_registered() {
60        // Arrange - Create app with API key routes
61        let app_state = create_mock_app_state(None, None, None, None, None, None).await;
62        let app = test::init_service(
63            App::new()
64                .app_data(web::Data::new(app_state))
65                .configure(init),
66        )
67        .await;
68
69        // Test GET /api-keys - should not return 404 (route exists)
70        let req = test::TestRequest::get().uri("/api-keys").to_request();
71        let resp = test::call_service(&app, req).await;
72        assert_ne!(
73            resp.status(),
74            StatusCode::NOT_FOUND,
75            "GET /api-keys route not registered"
76        );
77
78        // Test POST /api-keys - should not return 404
79        let req = test::TestRequest::post()
80            .uri("/api-keys")
81            .set_json(serde_json::json!({
82                "name": "Test API Key",
83                "permissions": ["relayer:all:execute"],
84                "allowed_origins": ["*"]
85            }))
86            .to_request();
87        let resp = test::call_service(&app, req).await;
88        assert_ne!(
89            resp.status(),
90            StatusCode::NOT_FOUND,
91            "POST /api-keys route not registered"
92        );
93
94        // Test GET /api-keys/{api_key_id}/permissions - should not return 404
95        let req = test::TestRequest::get()
96            .uri("/api-keys/test-id/permissions")
97            .to_request();
98        let resp = test::call_service(&app, req).await;
99        assert_ne!(
100            resp.status(),
101            StatusCode::NOT_FOUND,
102            "GET /api-keys/{{api_key_id}}/permissions route not registered"
103        );
104
105        // Test DELETE /api-keys/{api_key_id} - should not return 404
106        let req = test::TestRequest::delete()
107            .uri("/api-keys/test-id")
108            .to_request();
109        let resp = test::call_service(&app, req).await;
110        assert_ne!(
111            resp.status(),
112            StatusCode::NOT_FOUND,
113            "DELETE /api-keys/{{api_key_id}} route not registered"
114        );
115    }
116
117    #[actix_web::test]
118    async fn test_api_key_routes_with_query_params() {
119        // Arrange - Create app with API key routes
120        let app_state = create_mock_app_state(None, None, None, None, None, None).await;
121        let app = test::init_service(
122            App::new()
123                .app_data(web::Data::new(app_state))
124                .configure(init),
125        )
126        .await;
127
128        // Test GET /api-keys with pagination parameters
129        let req = test::TestRequest::get()
130            .uri("/api-keys?page=1&per_page=10")
131            .to_request();
132        let resp = test::call_service(&app, req).await;
133        assert_ne!(
134            resp.status(),
135            StatusCode::NOT_FOUND,
136            "GET /api-keys with query params route not registered"
137        );
138    }
139}