Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,24 @@
// 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,
BlobContainerClientGetPropertiesOptions, BlobContainerClientListBlobFlatSegmentOptions,
BlobContainerClientReleaseLeaseOptions, BlobContainerClientRenewLeaseOptions,
BlobContainerClientSetMetadataOptions, ListBlobsFlatSegmentResponse,
BlobContainerClientDeleteOptions, BlobContainerClientGetAccessPolicyOptions,
BlobContainerClientGetAccountInfoOptions, BlobContainerClientGetPropertiesOptions,
BlobContainerClientListBlobFlatSegmentOptions, BlobContainerClientReleaseLeaseOptions,
BlobContainerClientRenewLeaseOptions, BlobContainerClientSetAccessPolicyOptions,
BlobContainerClientSetAccessPolicyResult, BlobContainerClientSetMetadataOptions,
ListBlobsFlatSegmentResponse,
},
pipeline::StorageHeadersPolicy,
BlobClient, BlobContainerClientOptions,
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,32 @@ 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: RequestContent<Vec<SignedIdentifier>, XmlFormat>,
options: Option<BlobContainerClientSetAccessPolicyOptions<'_>>,
) -> Result<Response<BlobContainerClientSetAccessPolicyResult, NoFormat>> {
self.client.set_access_policy(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
}
}
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
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: None,
};

container_client
.set_access_policy(signed_identifier.into()?, 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