Support website publishing #7

Merged
lx merged 61 commits from feature/website into master 2021-01-15 16:49:51 +00:00
3 changed files with 58 additions and 11 deletions
Showing only changes of commit e1ce2b228a - Show all commits

View file

@ -156,7 +156,36 @@ impl AdminRpcHandler {
))) )))
} }
BucketOperation::Website(query) => { BucketOperation::Website(query) => {
Ok(AdminRPC::Ok(format!("test"))) let bucket = self.get_existing_bucket(&query.bucket).await?;
if query.allow && query.deny {
return Err(Error::Message(format!("Website can not be both allowed and denied on a bucket")));
}
if query.allow || query.deny {
let exposed = query.allow;
if let BucketState::Present(ak) = bucket.state.get_mut() {
let old_ak = ak.take_and_clear();
ak.merge(&old_ak.update_mutator(
key_id.to_string(),
PermissionSet {
allow_read,
allow_write,
},
));
} else {
return Err(Error::Message(format!(
"Bucket is deleted in update_bucket_key"
quentin marked this conversation as resolved
Review

Probably put unreachable!() in else branch ? Because get_existing_bucket does not return a bucket that is deleted. (I think so, this should be checked)

Probably put `unreachable!()` in else branch ? Because get_existing_bucket does not return a bucket that is deleted. (I think so, this should be checked)
Review

Checked.
Indeed, it does not return deleted buckets.

        async fn get_existing_bucket(&self, bucket: &String) -> Result<Bucket, Error> {
                self.garage
                        .bucket_table
                        .get(&EmptyKey, bucket)
                        .await?
                        .filter(|b| !b.is_deleted())
                        .map(Ok)
                        .unwrap_or(Err(Error::BadRPC(format!(
                                "Bucket {} does not exist",
                                bucket
                        ))))
        }
Checked. Indeed, it does not return deleted buckets. ```rust async fn get_existing_bucket(&self, bucket: &String) -> Result<Bucket, Error> { self.garage .bucket_table .get(&EmptyKey, bucket) .await? .filter(|b| !b.is_deleted()) .map(Ok) .unwrap_or(Err(Error::BadRPC(format!( "Bucket {} does not exist", bucket )))) } ```
)));
}
quentin marked this conversation as resolved
Review

update_bucket_key ?

`update_bucket_key` ?
}
let msg = if bucket.exposed {
"Bucket is exposed as a website."
} else {
"Bucket is not exposed."
};
Ok(AdminRPC::Ok(msg))
} }
} }
} }
@ -240,6 +269,7 @@ impl AdminRpcHandler {
.unwrap_or(Err(Error::BadRPC(format!("Key {} does not exist", id)))) .unwrap_or(Err(Error::BadRPC(format!("Key {} does not exist", id))))
} }
/// Update **bucket table** to inform of the new linked key
async fn update_bucket_key( async fn update_bucket_key(
&self, &self,
mut bucket: Bucket, mut bucket: Bucket,
@ -265,6 +295,7 @@ impl AdminRpcHandler {
Ok(()) Ok(())
} }
/// Update **key table** to inform of the new linked bucket
async fn update_key_bucket( async fn update_key_bucket(
&self, &self,
mut key: Key, mut key: Key,

View file

@ -150,12 +150,12 @@ pub enum BucketOperation {
#[derive(Serialize, Deserialize, StructOpt, Debug)] #[derive(Serialize, Deserialize, StructOpt, Debug)]
pub struct WebsiteOpt { pub struct WebsiteOpt {
/// Create /// Create
#[structopt(long = "create")] #[structopt(long = "allow")]
pub create: bool, pub allow: bool,
/// Delete /// Delete
#[structopt(long = "delete")] #[structopt(long = "deny")]
pub delete: bool, pub deny: bool,
} }
#[derive(Serialize, Deserialize, StructOpt, Debug)] #[derive(Serialize, Deserialize, StructOpt, Debug)]

View file

@ -21,27 +21,43 @@ pub struct Bucket {
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum BucketState { pub enum BucketState {
Deleted, Deleted,
Present(crdt::LWWMap<String, PermissionSet>), Present(BucketParams),
} }
impl CRDT for BucketState { impl CRDT for BucketState {
fn merge(&mut self, o: &Self) { fn merge(&mut self, o: &Self) {
match o { match o {
BucketState::Deleted => *self = BucketState::Deleted, BucketState::Deleted => *self = BucketState::Deleted,
BucketState::Present(other_ak) => { BucketState::Present(other_params) => {
if let BucketState::Present(ak) = self { if let BucketState::Present(params) = self {
ak.merge(other_ak); params.merge(other_params);
} }
} }
} }
} }
} }
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub struct BucketParams {
pub authorized_keys: crdt::LWWMap<String, PermissionSet>,
pub website: crdt::LWW<bool>
}
impl CRDT for BucketParams {
fn merge(&mut self, o: &Self) {
self.authorized_keys.merge(&o.authorized_keys);
self.website.merge(&o.website);
}
}
impl Bucket { impl Bucket {
pub fn new(name: String) -> Self { pub fn new(name: String) -> Self {
Bucket { Bucket {
name, name,
state: crdt::LWW::new(BucketState::Present(crdt::LWWMap::new())), state: crdt::LWW::new(BucketState::Present(BucketParams {
authorized_keys: crdt::LWWMap::new(),
website: crdt::LWW::new(false)
})),
} }
} }
pub fn is_deleted(&self) -> bool { pub fn is_deleted(&self) -> bool {
@ -50,7 +66,7 @@ impl Bucket {
pub fn authorized_keys(&self) -> &[(String, u64, PermissionSet)] { pub fn authorized_keys(&self) -> &[(String, u64, PermissionSet)] {
match self.state.get() { match self.state.get() {
BucketState::Deleted => &[], BucketState::Deleted => &[],
BucketState::Present(ak) => ak.items(), BucketState::Present(state) => state.authorized_keys.items(),
} }
} }
} }