mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-14 11:08:14 +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 syn::visit_mut::{self, VisitMut};
|
||||||
|
|
||||||
use super::{Schema, SchemaItem};
|
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
|
/// Parse `input`, `returns` and `protected` attributes out of an function annotated
|
||||||
/// with an `#[api]` attribute and produce a `const ApiMethod` named after the function.
|
/// 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())
|
.map(|ret| ret.into_object("return schema definition")?.try_into())
|
||||||
.transpose()?;
|
.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
|
let protected: bool = attribs
|
||||||
.remove("protected")
|
.remove("protected")
|
||||||
.map(TryFrom::try_from)
|
.map(TryFrom::try_from)
|
||||||
@ -129,6 +141,7 @@ pub fn handle_method(mut attribs: JSONObject, mut func: syn::ItemFn) -> Result<T
|
|||||||
#input_schema_name,
|
#input_schema_name,
|
||||||
)
|
)
|
||||||
#returns_schema_setter
|
#returns_schema_setter
|
||||||
|
#access_setter
|
||||||
.protected(#protected);
|
.protected(#protected);
|
||||||
|
|
||||||
#default_consts
|
#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 failure::Error;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
use proxmox::api::Permission;
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
input: {
|
input: {
|
||||||
properties: {
|
properties: {
|
||||||
@ -33,6 +35,10 @@ use serde_json::{json, Value};
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
access: {
|
||||||
|
description: "Only root can access this.",
|
||||||
|
permission: &Permission::Superuser,
|
||||||
|
},
|
||||||
protected: true,
|
protected: true,
|
||||||
)]
|
)]
|
||||||
/// Create or verify authentication ticket.
|
/// Create or verify authentication ticket.
|
||||||
@ -102,6 +108,7 @@ fn create_ticket_schema_check() {
|
|||||||
)
|
)
|
||||||
.schema(),
|
.schema(),
|
||||||
)
|
)
|
||||||
|
.permissions("Only root can access this.", &Permission::Superuser)
|
||||||
.protected(true);
|
.protected(true);
|
||||||
assert_eq!(TEST_METHOD, API_METHOD_CREATE_TICKET);
|
assert_eq!(TEST_METHOD, API_METHOD_CREATE_TICKET);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user