bucketwarden-server 0.1.0

BucketWarden storage server runtime.
Documentation
use super::*;

impl BucketWarden {
    pub(crate) fn dispatch_bucket_put_s3_http(
        &mut self,
        request: S3HttpRequest,
        bucket: &str,
    ) -> Result<S3HttpResponse, RuntimeError> {
        let key: Option<&str> = None;
        match ("PUT", Some(bucket), key) {
            ("PUT", Some(bucket), None) if request.query.contains_key("cors") => {
                let rules = parse_bucket_cors_rules(&request.body)?;
                let result = self.put_bucket_cors(&request.principal, bucket, rules)?;
                Ok(xml_response(200, bucket_cors_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("logging") => {
                let result = self.put_bucket_logging(&request.principal, bucket, request.body)?;
                Ok(xml_response(200, bucket_logging_status_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("website") => {
                let config = parse_bucket_website_configuration(bucket, &request.body)?;
                let result = self.put_bucket_website(&request.principal, bucket, config)?;
                Ok(xml_response(200, bucket_website_configuration_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("policy") => {
                let policy_json = String::from_utf8(request.body)
                    .map_err(|error| RuntimeError::InvalidBucketPolicy(error.to_string()))?;
                self.put_bucket_policy(
                    &request.principal,
                    BucketPolicyRequest {
                        bucket: bucket.to_string(),
                        policy_json,
                    },
                )?;
                Ok(S3HttpResponse::new(204))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("tagging") => {
                let tags = parse_object_tags(&request.body)?;
                let result = self.put_bucket_tagging(
                    &request.principal,
                    BucketTaggingRequest {
                        bucket: bucket.to_string(),
                        tags,
                    },
                )?;
                Ok(xml_response(200, bucket_tagging_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("object-lock") => {
                let config = parse_bucket_object_lock_configuration(bucket, &request.body)?;
                let result = self.put_bucket_object_lock_configuration(
                    &request.principal,
                    bucket,
                    config.default_retention,
                )?;
                Ok(xml_response(
                    200,
                    bucket_object_lock_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("encryption") => {
                let encryption = parse_bucket_encryption_configuration(&request.body)?;
                let result = self.put_bucket_encryption(&request.principal, bucket, encryption)?;
                Ok(xml_response(
                    200,
                    bucket_encryption_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("lifecycle") => {
                let rules = parse_bucket_lifecycle_configuration(bucket, &request.body)?.rules;
                let result = self.put_bucket_lifecycle(&request.principal, bucket, rules)?;
                Ok(xml_response(
                    200,
                    bucket_lifecycle_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("notification") => {
                let rules = parse_bucket_notification_configuration(bucket, &request.body)?.rules;
                let result = self.put_bucket_notification(&request.principal, bucket, rules)?;
                Ok(xml_response(
                    200,
                    bucket_notification_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("replication") => {
                let config = parse_bucket_replication_configuration(bucket, &request.body)?;
                let result = self.put_bucket_replication(
                    &request.principal,
                    bucket,
                    config.role,
                    config.rules,
                )?;
                Ok(xml_response(
                    200,
                    bucket_replication_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("versioning") => {
                let status = parse_bucket_versioning_status(&request.body)?;
                let result = self.set_bucket_versioning(&request.principal, bucket, status)?;
                Ok(xml_response(200, bucket_versioning_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("acl") => {
                validate_acl_write(&request.headers, &request.body)?;
                let result = self.put_bucket_acl(&request.principal, bucket)?;
                Ok(xml_response(200, acl_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("ownershipControls") => {
                let object_ownership = parse_bucket_ownership_controls(&request.body)?;
                let result = self.put_bucket_ownership_controls(
                    &request.principal,
                    bucket,
                    object_ownership,
                )?;
                Ok(xml_response(200, bucket_ownership_controls_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("requestPayment") => {
                let payer = parse_bucket_request_payment_payer(&request.body)?;
                let result = self.put_bucket_request_payment(&request.principal, bucket, payer)?;
                Ok(xml_response(200, bucket_request_payment_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("abac") => {
                let status = parse_bucket_abac_status(&request.body)?;
                self.put_bucket_abac(&request.principal, bucket, status)?;
                Ok(S3HttpResponse::new(200))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("accelerate") => {
                let status = parse_bucket_accelerate_status(&request.body)?;
                let result =
                    self.put_bucket_accelerate_configuration(&request.principal, bucket, status)?;
                Ok(xml_response(
                    200,
                    bucket_accelerate_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("publicAccessBlock") => {
                let result = self.put_public_access_block(
                    &request.principal,
                    parse_public_access_block_configuration(bucket, &request.body)?,
                )?;
                Ok(xml_response(
                    200,
                    public_access_block_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("metrics") => {
                let id = request.query.get("id").ok_or_else(|| {
                    RuntimeError::InvalidMetricsConfiguration(
                        "metrics configuration requests require query parameter id".to_string(),
                    )
                })?;
                let configuration = parse_metrics_configuration(bucket, id, &request.body)?;
                let result = self.put_bucket_metrics_configuration(
                    &request.principal,
                    bucket,
                    configuration,
                )?;
                Ok(xml_response(200, bucket_metrics_configuration_xml(&result)))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("analytics") => {
                let id = request.query.get("id").ok_or_else(|| {
                    RuntimeError::InvalidAnalyticsConfiguration(
                        "analytics configuration requests require query parameter id".to_string(),
                    )
                })?;
                let configuration = parse_analytics_configuration(bucket, id, &request.body)?;
                let result = self.put_bucket_analytics_configuration(
                    &request.principal,
                    bucket,
                    configuration,
                )?;
                Ok(xml_response(
                    200,
                    bucket_analytics_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("inventory") => {
                let id = request.query.get("id").ok_or_else(|| {
                    RuntimeError::InvalidInventoryConfiguration(
                        "inventory configuration requests require query parameter id".to_string(),
                    )
                })?;
                let configuration = parse_inventory_configuration(bucket, id, &request.body)?;
                let result = self.put_bucket_inventory_configuration(
                    &request.principal,
                    bucket,
                    configuration,
                )?;
                Ok(xml_response(
                    200,
                    bucket_inventory_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) if request.query.contains_key("intelligent-tiering") => {
                let id = request.query.get("id").ok_or_else(|| {
                    RuntimeError::InvalidIntelligentTieringConfiguration(
                        "intelligent-tiering configuration requests require query parameter id"
                            .to_string(),
                    )
                })?;
                let configuration =
                    parse_intelligent_tiering_configuration(bucket, id, &request.body)?;
                let result = self.put_bucket_intelligent_tiering_configuration(
                    &request.principal,
                    bucket,
                    configuration,
                )?;
                Ok(xml_response(
                    200,
                    bucket_intelligent_tiering_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None)
                if request.query.contains_key("metadataConfiguration")
                    && request.query.contains_key("journalTableConfiguration") =>
            {
                let journal_table_configuration = parse_journal_table_configuration(&request.body)?;
                let result = self.update_bucket_metadata_journal_table_configuration(
                    &request.principal,
                    bucket,
                    journal_table_configuration,
                )?;
                Ok(xml_response(
                    200,
                    bucket_metadata_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None)
                if request.query.contains_key("metadataConfiguration")
                    && request.query.contains_key("inventoryTableConfiguration") =>
            {
                let inventory_table_configuration =
                    parse_inventory_table_configuration_body(&request.body)?;
                let result = self.update_bucket_metadata_inventory_table_configuration(
                    &request.principal,
                    bucket,
                    inventory_table_configuration,
                )?;
                Ok(xml_response(
                    200,
                    bucket_metadata_configuration_xml(&result),
                ))
            }
            ("PUT", Some(bucket), None) => {
                validate_acl_write(&request.headers, &[])?;
                let region = parse_create_bucket_region(&request.body)?;
                self.create_bucket_in_region(&request.principal, bucket, region)?;
                Ok(S3HttpResponse::new(200))
            }
            _ => Ok(general_error_response(
                "MethodNotAllowed",
                405,
                "The specified method is not allowed for this resource.",
            )),
        }
    }
}