diff --git a/proxmox-api-macro/src/api/method.rs b/proxmox-api-macro/src/api/method.rs index 33477b10..47268fe5 100644 --- a/proxmox-api-macro/src/api/method.rs +++ b/proxmox-api-macro/src/api/method.rs @@ -17,7 +17,7 @@ use syn::Ident; use syn::visit_mut::{self, VisitMut}; use super::{Schema, SchemaItem}; -use crate::util::{self, FieldName, JSONObject}; +use crate::util::{self, FieldName, JSONObject, JSONValue}; /// Parse `input`, `returns` and `protected` attributes out of an function annotated /// with an `#[api]` attribute and produce a `const ApiMethod` named after the function. @@ -39,6 +39,18 @@ pub fn handle_method(mut attribs: JSONObject, mut func: syn::ItemFn) -> Result { + let access = Access::try_from(access.into_object("access rules")?)?; + let description: syn::LitStr = access.description.try_into()?; + let permission: syn::Expr = access.permission.try_into()?; + quote_spanned! { access.span => + .permissions(#description, #permission) + } + } + None => TokenStream::new(), + }; + let protected: bool = attribs .remove("protected") .map(TryFrom::try_from) @@ -129,6 +141,7 @@ pub fn handle_method(mut attribs: JSONObject, mut func: syn::ItemFn) -> Result DefaultParameters<'a> { } } } + +struct Access { + span: Span, + description: syn::LitStr, + permission: syn::Expr, +} + +impl TryFrom for Access { + type Error = syn::Error; + + fn try_from(value: JSONValue) -> Result { + Self::try_from(value.into_object("an access definition")?) + } +} + +impl TryFrom for Access { + type Error = syn::Error; + + fn try_from(mut obj: JSONObject) -> Result { + let description = obj + .remove("description") + .ok_or_else(|| format_err!(obj.span(), "missing description"))? + .try_into()?; + + let permission = obj + .remove("permission") + .ok_or_else(|| format_err!(obj.span(), "missing `permissions` field"))? + .try_into()?; + + if !obj.is_empty() { + bail!( + obj.span(), + "unexpected elements: {}", + util::join_debug(", ", obj.elements.keys()), + ); + } + + Ok(Self { + span: obj.span(), + description, + permission, + }) + } +} diff --git a/proxmox-api-macro/tests/api1.rs b/proxmox-api-macro/tests/api1.rs index e3e7e822..48d0c409 100644 --- a/proxmox-api-macro/tests/api1.rs +++ b/proxmox-api-macro/tests/api1.rs @@ -3,6 +3,8 @@ use proxmox_api_macro::api; use failure::Error; use serde_json::{json, Value}; +use proxmox::api::Permission; + #[api( input: { properties: { @@ -33,6 +35,10 @@ use serde_json::{json, Value}; }, }, }, + access: { + description: "Only root can access this.", + permission: &Permission::Superuser, + }, protected: true, )] /// Create or verify authentication ticket. @@ -102,6 +108,7 @@ fn create_ticket_schema_check() { ) .schema(), ) + .permissions("Only root can access this.", &Permission::Superuser) .protected(true); assert_eq!(TEST_METHOD, API_METHOD_CREATE_TICKET); }