mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-12 13:44:32 +00:00
api-macro: support 'access' specification for methods
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
19ad65ac84
commit
510d410b7a
@ -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<T
|
||||
.map(|ret| ret.into_object("return schema definition")?.try_into())
|
||||
.transpose()?;
|
||||
|
||||
let access_setter = match attribs.remove("access") {
|
||||
Some(access) => {
|
||||
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<T
|
||||
#input_schema_name,
|
||||
)
|
||||
#returns_schema_setter
|
||||
#access_setter
|
||||
.protected(#protected);
|
||||
|
||||
#default_consts
|
||||
@ -510,3 +523,47 @@ impl<'a> DefaultParameters<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Access {
|
||||
span: Span,
|
||||
description: syn::LitStr,
|
||||
permission: syn::Expr,
|
||||
}
|
||||
|
||||
impl TryFrom<JSONValue> for Access {
|
||||
type Error = syn::Error;
|
||||
|
||||
fn try_from(value: JSONValue) -> Result<Self, syn::Error> {
|
||||
Self::try_from(value.into_object("an access definition")?)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<JSONObject> for Access {
|
||||
type Error = syn::Error;
|
||||
|
||||
fn try_from(mut obj: JSONObject) -> Result<Self, syn::Error> {
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user