Skip to content

Commit 66abb84

Browse files
bmc-msftdemoray
andauthored
revamp SAS builders to model operations (#879)
* revamp SAS builders to model operations Moved to using the same Builder pattern implemented by Operations, such that required params are provided by the creator, with setters for optional fields. * remove additional clippy lints from local dev * address feedback Co-authored-by: Brian Caswell <[email protected]>
1 parent 7058845 commit 66abb84

File tree

7 files changed

+165
-425
lines changed

7 files changed

+165
-425
lines changed

sdk/storage/src/core/clients/storage_client.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::authorization_policy::AuthorizationPolicy;
22
use crate::operations::*;
3-
use crate::shared_access_signature::account_sas::AccountSharedAccessSignatureBuilder;
3+
use crate::shared_access_signature::account_sas::{
4+
AccountSasPermissions, AccountSasResource, AccountSasResourceType, AccountSharedAccessSignature,
5+
};
46
use crate::ConnectionString;
57
use azure_core::Method;
68
use azure_core::{
@@ -10,6 +12,7 @@ use azure_core::{
1012
ClientOptions, Context, Pipeline, Request, Response,
1113
};
1214
use bytes::Bytes;
15+
use chrono::{DateTime, Utc};
1316
use std::sync::Arc;
1417
use url::Url;
1518

@@ -413,10 +416,14 @@ impl StorageClient {
413416

414417
pub fn shared_access_signature(
415418
&self,
416-
) -> azure_core::Result<AccountSharedAccessSignatureBuilder> {
419+
resource: AccountSasResource,
420+
resource_type: AccountSasResourceType,
421+
expiry: DateTime<Utc>,
422+
permissions: AccountSasPermissions,
423+
) -> azure_core::Result<AccountSharedAccessSignature> {
417424
match &self.storage_credentials {
418425
StorageCredentials::Key(account, key) => {
419-
Ok(AccountSharedAccessSignatureBuilder::new(account.clone(), key.clone()))
426+
Ok(AccountSharedAccessSignature::new(account.clone(), key.clone(), resource, resource_type, expiry, permissions))
420427
}
421428
_ => Err(Error::message(ErrorKind::Other, "failed shared access signature generation. SAS can be generated only from key and account clients")),
422429
}

sdk/storage/src/core/shared_access_signature/account_sas.rs

Lines changed: 52 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -131,39 +131,63 @@ impl fmt::Display for AccountSasPermissions {
131131
pub struct AccountSharedAccessSignature {
132132
account: String,
133133
key: String,
134-
signed_version: AccountSasVersion,
135-
signed_resource: AccountSasResource,
136-
signed_resource_type: AccountSasResourceType,
137-
signed_start: Option<DateTime<Utc>>,
138-
signed_expiry: DateTime<Utc>,
139-
signed_permissions: AccountSasPermissions,
140-
signed_ip: Option<String>,
141-
signed_protocol: Option<SasProtocol>,
134+
version: AccountSasVersion,
135+
resource: AccountSasResource,
136+
resource_type: AccountSasResourceType,
137+
expiry: DateTime<Utc>,
138+
permissions: AccountSasPermissions,
139+
start: Option<DateTime<Utc>>,
140+
ip: Option<String>,
141+
protocol: Option<SasProtocol>,
142142
}
143143

144144
impl AccountSharedAccessSignature {
145-
#[allow(clippy::new_ret_no_self)]
146-
pub fn new(account: String, key: String) -> AccountSharedAccessSignatureBuilder {
147-
AccountSharedAccessSignatureBuilder::new(account, key)
145+
pub fn new(
146+
account: String,
147+
key: String,
148+
resource: AccountSasResource,
149+
resource_type: AccountSasResourceType,
150+
expiry: DateTime<Utc>,
151+
permissions: AccountSasPermissions,
152+
) -> Self {
153+
Self {
154+
account,
155+
key,
156+
version: AccountSasVersion::V20181109,
157+
resource,
158+
resource_type,
159+
expiry,
160+
permissions,
161+
start: None,
162+
ip: None,
163+
protocol: None,
164+
}
165+
}
166+
167+
setters! {
168+
version: AccountSasVersion => version,
169+
start: DateTime<Utc> => Some(start),
170+
ip: String => Some(ip),
171+
protocol: SasProtocol => Some(protocol),
148172
}
149173

150174
// Azure documentation: https://docs.microsoft.com/rest/api/storageservices/create-service-sas#constructing-the-signature-string
151175
fn signature(&self) -> String {
152-
match self.signed_version {
176+
match self.version {
153177
AccountSasVersion::V20181109 => {
154178
let string_to_sign = format!(
155179
"{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
156180
self.account,
157-
self.signed_permissions,
158-
self.signed_resource,
159-
self.signed_resource_type,
160-
self.signed_start.map_or("".to_string(), format_date),
161-
format_date(self.signed_expiry),
162-
self.signed_ip.clone().unwrap_or_else(|| "".to_string()),
163-
self.signed_protocol
181+
self.permissions,
182+
self.resource,
183+
self.resource_type,
184+
self.start.map_or("".to_string(), format_date),
185+
format_date(self.expiry),
186+
self.ip.clone().unwrap_or_else(|| "".to_string()),
187+
self.protocol
164188
.as_ref()
165189
.map_or("".to_string(), |v| v.to_string()),
166-
self.signed_version,
190+
self.version,
167191
);
168192

169193
sign(&string_to_sign, &self.key).unwrap()
@@ -180,20 +204,20 @@ impl SasToken for AccountSharedAccessSignature {
180204
/// [Example](https://docs.microsoft.com/rest/api/storageservices/create-service-sas#service-sas-example) from Azure documentation.
181205
fn token(&self) -> String {
182206
let mut elements: Vec<String> = vec![
183-
format!("sv={}", self.signed_version),
184-
format!("ss={}", self.signed_resource),
185-
format!("srt={}", self.signed_resource_type),
186-
format!("se={}", format_form(format_date(self.signed_expiry))),
187-
format!("sp={}", self.signed_permissions),
207+
format!("sv={}", self.version),
208+
format!("ss={}", self.resource),
209+
format!("srt={}", self.resource_type),
210+
format!("se={}", format_form(format_date(self.expiry))),
211+
format!("sp={}", self.permissions),
188212
];
189213

190-
if let Some(start) = &self.signed_start {
214+
if let Some(start) = &self.start {
191215
elements.push(format!("st={}", format_form(format_date(*start))))
192216
}
193-
if let Some(ip) = &self.signed_ip {
217+
if let Some(ip) = &self.ip {
194218
elements.push(format!("sip={}", ip))
195219
}
196-
if let Some(protocol) = &self.signed_protocol {
220+
if let Some(protocol) = &self.protocol {
197221
elements.push(format!("spr={}", protocol))
198222
}
199223
let sig = AccountSharedAccessSignature::signature(self);
@@ -214,136 +238,3 @@ impl std::fmt::Debug for AccountSharedAccessSignature {
214238
write!(f, "SharedAccessSignature {{{}}}", self.signature())
215239
}
216240
}
217-
218-
pub struct AccountSharedAccessSignatureBuilder {
219-
account: String,
220-
key: String,
221-
signed_version: AccountSasVersion,
222-
signed_resource: Option<AccountSasResource>,
223-
signed_resource_type: Option<AccountSasResourceType>,
224-
signed_start: Option<DateTime<Utc>>,
225-
signed_expiry: Option<DateTime<Utc>>,
226-
signed_permissions: Option<AccountSasPermissions>,
227-
signed_ip: Option<String>,
228-
signed_protocol: Option<SasProtocol>,
229-
}
230-
231-
impl AccountSharedAccessSignatureBuilder {
232-
pub fn new(account: String, key: String) -> Self {
233-
Self {
234-
account,
235-
key,
236-
signed_version: AccountSasVersion::V20181109,
237-
signed_resource: None,
238-
signed_resource_type: None,
239-
signed_start: None,
240-
signed_expiry: None,
241-
signed_permissions: None,
242-
signed_ip: None,
243-
signed_protocol: None,
244-
}
245-
}
246-
247-
pub fn finalize(&self) -> AccountSharedAccessSignature {
248-
AccountSharedAccessSignature {
249-
account: self.account.to_owned(),
250-
key: self.key.to_owned(),
251-
signed_version: self.signed_version,
252-
signed_resource: self.signed_resource.unwrap(),
253-
signed_resource_type: self.signed_resource_type.unwrap(),
254-
signed_start: self.signed_start,
255-
signed_expiry: self.signed_expiry.unwrap(),
256-
signed_permissions: self.signed_permissions.unwrap(),
257-
signed_ip: self.signed_ip.clone(),
258-
signed_protocol: self.signed_protocol,
259-
}
260-
}
261-
262-
pub fn version(&self) -> AccountSasVersion {
263-
self.signed_version
264-
}
265-
266-
pub fn with_version(self, version: AccountSasVersion) -> Self {
267-
Self {
268-
signed_version: version,
269-
..self
270-
}
271-
}
272-
273-
pub fn resource(&self) -> AccountSasResource {
274-
self.signed_resource.unwrap()
275-
}
276-
277-
pub fn with_resource(self, resource: AccountSasResource) -> Self {
278-
Self {
279-
signed_resource: Some(resource),
280-
..self
281-
}
282-
}
283-
284-
pub fn resource_type_type(&self) -> AccountSasResourceType {
285-
self.signed_resource_type.unwrap()
286-
}
287-
288-
pub fn with_resource_type(self, resource_type: AccountSasResourceType) -> Self {
289-
Self {
290-
signed_resource_type: Some(resource_type),
291-
..self
292-
}
293-
}
294-
295-
pub fn expiry(&self) -> DateTime<Utc> {
296-
self.signed_expiry.unwrap()
297-
}
298-
299-
pub fn with_expiry(self, expiry: DateTime<Utc>) -> Self {
300-
Self {
301-
signed_expiry: Some(expiry),
302-
..self
303-
}
304-
}
305-
306-
pub fn signed_permissions(&self) -> AccountSasPermissions {
307-
self.signed_permissions.unwrap()
308-
}
309-
310-
pub fn with_permissions(self, permissions: AccountSasPermissions) -> Self {
311-
Self {
312-
signed_permissions: Some(permissions),
313-
..self
314-
}
315-
}
316-
317-
pub fn signed_start(&self) -> DateTime<Utc> {
318-
self.signed_start.unwrap()
319-
}
320-
321-
pub fn with_start(self, start: DateTime<Utc>) -> Self {
322-
Self {
323-
signed_start: Some(start),
324-
..self
325-
}
326-
}
327-
328-
pub fn ip(&self) -> &str {
329-
self.signed_ip.as_deref().unwrap()
330-
}
331-
332-
pub fn with_ip(self, ip: String) -> Self {
333-
Self {
334-
signed_ip: Some(ip),
335-
..self
336-
}
337-
}
338-
339-
pub fn protocol(&self) -> SasProtocol {
340-
self.signed_protocol.unwrap()
341-
}
342-
343-
pub fn with_protocol(self, protocol: SasProtocol) -> Self {
344-
Self {
345-
signed_protocol: Some(protocol),
346-
..self
347-
}
348-
}
349-
}

0 commit comments

Comments
 (0)