use super::{Object, Privilege, Subject};
use crate::Result;
use serde::{Deserialize, Serialize};
#[derive(Clone, Default, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ListAccessControlEntriesRequest {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub object: Option<Object>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subject: Option<Subject>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub continuation_token: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_results: Option<u32>,
}
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct AccessControlEntry {
#[serde(deserialize_with = "Subject::deserialize_canonical")]
pub subject_id: Subject,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subject_name: Option<String>,
pub object: Object,
pub privilege: Privilege,
}
#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct ListAccessControlEntriesResponse {
pub entries: Vec<AccessControlEntry>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub continuation_token: Option<String>,
}
#[derive(Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct AccessControlEntryRequest {
pub subject: Subject,
pub object: Object,
pub privilege: Privilege,
}
#[derive(Clone, Default, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ListRoleBindingsRequest {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subject: Option<Subject>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub continuation_token: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_results: Option<u32>,
}
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct RoleBinding {
#[serde(deserialize_with = "Subject::deserialize_canonical")]
pub subject_id: Subject,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subject_name: Option<String>,
pub role: String,
}
#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct ListRoleBindingsResponse {
pub bindings: Vec<RoleBinding>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub continuation_token: Option<String>,
}
#[derive(Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct RoleBindingRequest {
pub subject: Subject,
pub role: String,
}
#[derive(Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct GetPrincipalRequest {
pub principal: Subject,
}
#[derive(Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct GetGroupRequest {
pub group: Subject,
}
#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct IdentityInfo {
pub id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
}
#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct PrincipalInfo {
pub principal_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub principal_name: Option<String>,
pub groups: Vec<IdentityInfo>,
pub roles: Vec<String>,
}
#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct GroupInfo {
pub group_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub group_name: Option<String>,
pub principals: Vec<IdentityInfo>,
pub roles: Vec<String>,
}
#[async_trait::async_trait]
pub trait Authorization: Send + Sync + std::fmt::Debug + 'static {
async fn list_acls(
&self,
request: ListAccessControlEntriesRequest,
) -> Result<ListAccessControlEntriesResponse>;
async fn add_acl(&self, request: AccessControlEntryRequest) -> Result<()>;
async fn delete_acl(&self, request: AccessControlEntryRequest) -> Result<()>;
async fn list_role_bindings(
&self,
request: ListRoleBindingsRequest,
) -> Result<ListRoleBindingsResponse>;
async fn add_role_binding(&self, request: RoleBindingRequest) -> Result<()>;
async fn delete_role_binding(&self, request: RoleBindingRequest) -> Result<()>;
async fn get_principal(&self, request: GetPrincipalRequest) -> Result<PrincipalInfo>;
async fn get_group(&self, request: GetGroupRequest) -> Result<GroupInfo>;
}
impl AccessControlEntryRequest {
pub fn new(object: Object, subject: Subject, privilege: Privilege) -> Self {
Self {
object,
subject,
privilege,
}
}
}
impl ListRoleBindingsRequest {
pub fn validate(&self) -> Result<()> {
if let Some(subject) = &self.subject {
subject.validate_role_member()?;
}
Ok(())
}
}
impl RoleBindingRequest {
pub fn new(subject: Subject, role: impl Into<String>) -> Result<Self> {
subject.validate_role_member()?;
Ok(Self {
subject,
role: role.into(),
})
}
pub fn validate(&self) -> Result<()> {
self.subject.validate_role_member()
}
}
impl GetPrincipalRequest {
pub fn new(principal: Subject) -> Result<Self> {
principal.validate_principal()?;
Ok(Self { principal })
}
pub fn validate(&self) -> Result<()> {
self.principal.validate_principal()
}
}
impl GetGroupRequest {
pub fn new(group: Subject) -> Result<Self> {
group.validate_group()?;
Ok(Self { group })
}
pub fn validate(&self) -> Result<()> {
self.group.validate_group()
}
}