Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
// Licensed under the MIT License.

use crate::{
generated::clients::BlobContainerClient as GeneratedBlobContainerClient,
generated::models::{
BlobContainerClientAcquireLeaseResult, BlobContainerClientBreakLeaseResult,
BlobContainerClientChangeLeaseResult, BlobContainerClientGetAccountInfoResult,
BlobContainerClientGetPropertiesResult, BlobContainerClientReleaseLeaseResult,
BlobContainerClientRenewLeaseResult,
generated::{
clients::BlobContainerClient as GeneratedBlobContainerClient,
models::{
BlobContainerClientAcquireLeaseResult, BlobContainerClientBreakLeaseResult,
BlobContainerClientChangeLeaseResult, BlobContainerClientGetAccountInfoResult,
BlobContainerClientGetPropertiesResult, BlobContainerClientReleaseLeaseResult,
BlobContainerClientRenewLeaseResult, SignedIdentifier,
},
},
models::{
BlobContainerClientAcquireLeaseOptions, BlobContainerClientBreakLeaseOptions,
BlobContainerClientChangeLeaseOptions, BlobContainerClientCreateOptions,
BlobContainerClientDeleteOptions, BlobContainerClientGetAccountInfoOptions,
format_signed_identifiers, BlobContainerClientAcquireLeaseOptions,
BlobContainerClientBreakLeaseOptions, BlobContainerClientChangeLeaseOptions,
BlobContainerClientCreateOptions, BlobContainerClientDeleteOptions,
BlobContainerClientGetAccessPolicyOptions, BlobContainerClientGetAccountInfoOptions,
BlobContainerClientGetPropertiesOptions, BlobContainerClientListBlobFlatSegmentOptions,
BlobContainerClientReleaseLeaseOptions, BlobContainerClientRenewLeaseOptions,
BlobContainerClientSetAccessPolicyOptions, BlobContainerClientSetAccessPolicyResult,
BlobContainerClientSetMetadataOptions, ListBlobsFlatSegmentResponse,
},
pipeline::StorageHeadersPolicy,
Expand All @@ -24,7 +28,7 @@ use azure_core::{
credentials::TokenCredential,
http::{
policies::{BearerTokenCredentialPolicy, Policy},
NoFormat, PageIterator, Pager, Response, Url, XmlFormat,
NoFormat, PageIterator, Pager, RequestContent, Response, Url, XmlFormat,
},
Result,
};
Expand Down Expand Up @@ -249,4 +253,34 @@ impl BlobContainerClient {
) -> Result<Response<BlobContainerClientGetAccountInfoResult, NoFormat>> {
self.client.get_account_info(options).await
}

/// Sets the permissions for the specified container. The permissions indicate whether blobs in a
/// container may be accessed publicly.
///
/// # Arguments
///
/// * `container_acl` - The access control list for the container.
/// * `options` - Optional configuration for the request.
pub async fn set_access_policy(
&self,
container_acl: Vec<SignedIdentifier>,
options: Option<BlobContainerClientSetAccessPolicyOptions<'_>>,
) -> Result<Response<BlobContainerClientSetAccessPolicyResult, NoFormat>> {
self.client
.set_access_policy(format_signed_identifiers(container_acl)?, options)
.await
}

/// Gets the permissions for the specified container. The permissions indicate whether container data
/// may be accessed publicly.
///
/// # Arguments
///
/// * `options` - Optional configuration for the request.
pub async fn get_access_policy(
&self,
options: Option<BlobContainerClientGetAccessPolicyOptions<'_>>,
) -> Result<Response<Vec<SignedIdentifier>, XmlFormat>> {
self.client.get_access_policy(options).await
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 22 additions & 1 deletion sdk/storage/azure_storage_blob/src/models/extensions.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

use azure_core::{
http::{RequestContent, XmlFormat},
xml::to_xml_with_root,
};
use serde::Serialize;

use crate::models::{
AppendBlobClientCreateOptions, BlobTag, BlobTags, BlockBlobClientUploadBlobFromUrlOptions,
PageBlobClientCreateOptions,
PageBlobClientCreateOptions, SignedIdentifier,
};
use azure_core::error::ErrorKind;
use std::collections::HashMap;
Expand Down Expand Up @@ -89,3 +95,18 @@ impl From<HashMap<String, String>> for BlobTags {
}
}
}

// SignedIdentifiers wrapper for correct XML serialization.
#[derive(Serialize)]
struct SignedIdentifiersWrapper {
#[serde(rename = "SignedIdentifier")]
items: Vec<SignedIdentifier>,
}

// Converts a `Vec<SignedIdentifier>` into `RequestContent<Vec<SignedIdentifier>, XmlFormat>`.
pub(crate) fn format_signed_identifiers(
value: Vec<SignedIdentifier>,
) -> Result<RequestContent<Vec<SignedIdentifier>, XmlFormat>, azure_core::Error> {
let wrapper = SignedIdentifiersWrapper { items: value };
Ok(to_xml_with_root("SignedIdentifiers", &wrapper)?.into())
}
21 changes: 11 additions & 10 deletions sdk/storage/azure_storage_blob/src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
mod extensions;

pub use crate::generated::models::{
AccessTier, AccountKind, AppendBlobClientAppendBlockFromUrlOptions,
AccessPolicy, AccessTier, AccountKind, AppendBlobClientAppendBlockFromUrlOptions,
AppendBlobClientAppendBlockFromUrlResult, AppendBlobClientAppendBlockFromUrlResultHeaders,
AppendBlobClientAppendBlockOptions, AppendBlobClientAppendBlockResult,
AppendBlobClientAppendBlockResultHeaders, AppendBlobClientCreateOptions,
Expand Down Expand Up @@ -36,15 +36,16 @@ pub use crate::generated::models::{
BlobContainerClientBreakLeaseResultHeaders, BlobContainerClientChangeLeaseOptions,
BlobContainerClientChangeLeaseResult, BlobContainerClientChangeLeaseResultHeaders,
BlobContainerClientCreateOptions, BlobContainerClientDeleteOptions,
BlobContainerClientGetAccountInfoOptions, BlobContainerClientGetAccountInfoResult,
BlobContainerClientGetAccountInfoResultHeaders, BlobContainerClientGetPropertiesOptions,
BlobContainerClientGetPropertiesResult, BlobContainerClientGetPropertiesResultHeaders,
BlobContainerClientListBlobFlatSegmentOptions, BlobContainerClientReleaseLeaseOptions,
BlobContainerClientReleaseLeaseResult, BlobContainerClientReleaseLeaseResultHeaders,
BlobContainerClientRenameResult, BlobContainerClientRenameResultHeaders,
BlobContainerClientRenewLeaseOptions, BlobContainerClientRenewLeaseResult,
BlobContainerClientRenewLeaseResultHeaders, BlobContainerClientRestoreResult,
BlobContainerClientRestoreResultHeaders, BlobContainerClientSetAccessPolicyResult,
BlobContainerClientGetAccessPolicyOptions, BlobContainerClientGetAccountInfoOptions,
BlobContainerClientGetAccountInfoResult, BlobContainerClientGetAccountInfoResultHeaders,
BlobContainerClientGetPropertiesOptions, BlobContainerClientGetPropertiesResult,
BlobContainerClientGetPropertiesResultHeaders, BlobContainerClientListBlobFlatSegmentOptions,
BlobContainerClientReleaseLeaseOptions, BlobContainerClientReleaseLeaseResult,
BlobContainerClientReleaseLeaseResultHeaders, BlobContainerClientRenameResult,
BlobContainerClientRenameResultHeaders, BlobContainerClientRenewLeaseOptions,
BlobContainerClientRenewLeaseResult, BlobContainerClientRenewLeaseResultHeaders,
BlobContainerClientRestoreResult, BlobContainerClientRestoreResultHeaders,
BlobContainerClientSetAccessPolicyOptions, BlobContainerClientSetAccessPolicyResult,
BlobContainerClientSetAccessPolicyResultHeaders, BlobContainerClientSetMetadataOptions,
BlobCopySourceTags, BlobDeleteType, BlobFlatListSegment, BlobImmutabilityPolicyMode,
BlobItemInternal, BlobMetadata, BlobName, BlobPropertiesInternal,
Expand Down
2 changes: 0 additions & 2 deletions sdk/storage/azure_storage_blob/src/parsers.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

use crate::models::{BlobTag, BlobTags};
use std::collections::HashMap;
use std::io::{Error, ErrorKind};

/// Takes in an offset and a length, verifies alignment to a 512-byte boundary, and
Expand Down
51 changes: 46 additions & 5 deletions sdk/storage/azure_storage_blob/tests/blob_container_client.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

use azure_core::http::StatusCode;
use azure_core::{
http::StatusCode,
time::{Duration, OffsetDateTime},
};
use azure_core_test::{recorded, TestContext};
use azure_storage_blob::models::{
AccountKind, BlobContainerClientAcquireLeaseResultHeaders,
AccessPolicy, AccountKind, BlobContainerClientAcquireLeaseResultHeaders,
BlobContainerClientChangeLeaseResultHeaders, BlobContainerClientGetAccountInfoResultHeaders,
BlobContainerClientGetPropertiesResultHeaders, BlobContainerClientListBlobFlatSegmentOptions,
BlobContainerClientSetMetadataOptions, BlobType, LeaseState,
BlobContainerClientSetMetadataOptions, BlobType, LeaseState, SignedIdentifier,
};
use azure_storage_blob_test::{
create_test_blob, get_blob_service_client, get_container_client, get_container_name,
};
use futures::{StreamExt, TryStreamExt};
use std::{collections::HashMap, error::Error, time::Duration};
use std::{collections::HashMap, error::Error};
use tokio::time;

#[recorded::test]
Expand Down Expand Up @@ -243,7 +246,7 @@ async fn test_container_lease_operations(ctx: TestContext) -> Result<(), Box<dyn
assert_eq!(proposed_lease_id.clone().to_string(), lease_id);

// Sleep until lease expires
time::sleep(Duration::from_secs(15)).await;
time::sleep(std::time::Duration::from_secs(15)).await;

// Renew Lease
container_client
Expand Down Expand Up @@ -293,3 +296,41 @@ async fn test_get_account_info(ctx: TestContext) -> Result<(), Box<dyn Error>> {

Ok(())
}

#[recorded::test]
async fn test_container_access_policy(ctx: TestContext) -> Result<(), Box<dyn Error>> {
// Recording Setup
let recording = ctx.recording();
let container_client = get_container_client(recording, false).await?;
container_client.create_container(None).await?;

// Set Access Policy w/ Policy Defined
let access_policy = AccessPolicy {
expiry: Some(OffsetDateTime::now_utc() + Duration::seconds(10)),
permission: Some("rw".to_string()),
start: Some(OffsetDateTime::now_utc()),
};
let signed_identifier = SignedIdentifier {
access_policy: Some(access_policy),
id: Some("testid".into()),
};

container_client
.set_access_policy(vec![signed_identifier], None)
.await?;

// Assert
let access_policy_response = container_client.get_access_policy(None).await?;
let signed_identifiers = access_policy_response.into_body().await?;
for signed_identifier in &signed_identifiers {
if let Some(access_policy) = &signed_identifier.access_policy {
assert!(signed_identifier.id.is_some());
assert!(access_policy.start.is_some());
assert!(access_policy.expiry.is_some());
assert_eq!("rw", access_policy.permission.as_ref().unwrap());
}
}

container_client.delete_container(None).await?;
Ok(())
}
Loading