use crate::error::GoogleResponse;
use crate::resources::common::ListResponse;
pub use crate::resources::common::{Entity, ProjectTeam, Role};
#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BucketAccessControl {
pub kind: String,
pub id: String,
pub self_link: String,
pub bucket: String,
pub entity: Entity,
pub role: Role,
pub email: Option<String>,
pub entity_id: Option<String>,
pub domain: Option<String>,
pub project_team: Option<ProjectTeam>,
pub etag: String,
}
#[derive(Debug, PartialEq, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NewBucketAccessControl {
pub entity: Entity,
pub role: Role,
}
impl BucketAccessControl {
pub fn create(
bucket: &str,
new_bucket_access_control: &NewBucketAccessControl,
) -> Result<Self, crate::Error> {
let url = format!("{}/b/{}/acl", crate::BASE_URL, bucket);
let client = reqwest::blocking::Client::new();
let result: GoogleResponse<Self> = client
.post(&url)
.headers(crate::get_headers()?)
.json(new_bucket_access_control)
.send()?
.json()?;
Ok(result?)
}
pub fn list(bucket: &str) -> Result<Vec<Self>, crate::Error> {
let url = format!("{}/b/{}/acl", crate::BASE_URL, bucket);
let client = reqwest::blocking::Client::new();
let result: GoogleResponse<ListResponse<Self>> = client
.get(&url)
.headers(crate::get_headers()?)
.send()?
.json()?;
Ok(result?.items)
}
pub fn read(bucket: &str, entity: &Entity) -> Result<Self, crate::Error> {
let url = format!("{}/b/{}/acl/{}", crate::BASE_URL, bucket, entity);
let client = reqwest::blocking::Client::new();
let result: GoogleResponse<Self> = client
.get(&url)
.headers(crate::get_headers()?)
.send()?
.json()?;
Ok(result?)
}
pub fn update(&self) -> Result<Self, crate::Error> {
let url = format!("{}/b/{}/acl/{}", crate::BASE_URL, self.bucket, self.entity);
let client = reqwest::blocking::Client::new();
let result: GoogleResponse<Self> = client
.put(&url)
.headers(crate::get_headers()?)
.json(self)
.send()?
.json()?;
Ok(result?)
}
pub fn delete(self) -> Result<(), crate::Error> {
let url = format!("{}/b/{}/acl/{}", crate::BASE_URL, self.bucket, self.entity);
let client = reqwest::blocking::Client::new();
let response = client.delete(&url).headers(crate::get_headers()?).send()?;
if response.status().is_success() {
Ok(())
} else {
Err(crate::Error::Google(response.json()?))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn create() -> Result<(), Box<dyn std::error::Error>> {
let bucket = crate::read_test_bucket();
let new_bucket_access_control = NewBucketAccessControl {
entity: Entity::AllUsers,
role: Role::Reader,
};
BucketAccessControl::create(&bucket.name, &new_bucket_access_control)?;
Ok(())
}
#[test]
fn list() -> Result<(), Box<dyn std::error::Error>> {
let bucket = crate::read_test_bucket();
BucketAccessControl::list(&bucket.name)?;
Ok(())
}
#[test]
fn read() -> Result<(), Box<dyn std::error::Error>> {
let bucket = crate::read_test_bucket();
BucketAccessControl::read(&bucket.name, &Entity::AllUsers)?;
Ok(())
}
#[test]
fn update() -> Result<(), Box<dyn std::error::Error>> {
let bucket = crate::create_test_bucket("test-update-bucket-access-controls");
let new_bucket_access_control = NewBucketAccessControl {
entity: Entity::AllUsers,
role: Role::Reader,
};
BucketAccessControl::create(&bucket.name, &new_bucket_access_control)?;
let mut acl = dbg!(BucketAccessControl::read(&bucket.name, &Entity::AllUsers)?);
acl.entity = Entity::AllAuthenticatedUsers;
acl.update()?;
bucket.delete()?;
Ok(())
}
#[test]
fn delete() -> Result<(), Box<dyn std::error::Error>> {
let bucket = crate::create_test_bucket("test-delete-bucket-access-controls");
let new_bucket_access_control = NewBucketAccessControl {
entity: Entity::AllUsers,
role: Role::Reader,
};
BucketAccessControl::create(&bucket.name, &new_bucket_access_control)?;
let acl = BucketAccessControl::read(&bucket.name, &Entity::AllUsers)?;
acl.delete()?;
bucket.delete()?;
Ok(())
}
}