Skip to content

Commit 877ad63

Browse files
committed
Merge pull request #424 from Azure/dev
HPF PR: vmss <- Azure:dev
2 parents 2a33557 + c2b149e commit 877ad63

File tree

35 files changed

+25867
-23052
lines changed

35 files changed

+25867
-23052
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Contribute Code or Provide Feedback
22

3-
If you would like to become an active contributor to this project please follow the instructions provided in [Microsoft Azure Projects Contribution Guidelines](http://windowsazure.github.com/guidelines.html).
3+
If you would like to become an active contributor to this project please follow the instructions provided in [Microsoft Azure Projects Contribution Guidelines](http://azure.github.io/guidelines/).
44

55
If you encounter any bugs with Microsoft Azure PowerShell please file an issue in the [Issues](https://github.com/Azure/azure-powershell/issues) section of the project.

ChangeLog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@
1212
* Set-AzureLogicAppAccessKey
1313
* Set-AzureLogicApp
1414
* Stop-AzureLogicAppRun
15+
* Azure Storage
16+
* Added cmdlet to generate SAS token against storage account
17+
- New-AzureStorageAccountSASToken
18+
* Added IPAddressOrRange/Protocol support in cmdlets to generate SAS token against blob, container, file, share, table, queue
19+
- New-AzureStorageBlobSASToken
20+
- New-AzureStorageContainerSASToken
21+
- New-AzureStorageFileSASToken
22+
- New-AzureStorageShareSASToken
23+
- New-AzureStorageQueueSASToken
24+
- New-AzureStorageTableSASToken
1525

1626
## 2016.02.04 version 1.2.1
1727
* Fix installer issue - remove PSGallery modules on install

src/Common/Commands.Common.Authentication/Commands.Common.Authentication.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<AssemblyName>Commands.Common.Authentication</AssemblyName>
1212
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1313
<FileAlignment>512</FileAlignment>
14-
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
14+
<TargetFrameworkProfile />
1515
<RestorePackages>true</RestorePackages>
1616
<CodeAnalysisAdditionalOptions>/assemblyCompareMode:StrongNameIgnoringVersion</CodeAnalysisAdditionalOptions>
1717
<NuGetPackageImportStamp>06e19c11</NuGetPackageImportStamp>
@@ -51,7 +51,8 @@
5151
</PropertyGroup>
5252
<ItemGroup>
5353
<Reference Include="Hyak.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
54-
<HintPath>..\..\packages\Hyak.Common.1.0.3\lib\net45\Hyak.Common.dll</HintPath>
54+
<SpecificVersion>False</SpecificVersion>
55+
<HintPath>..\..\packages\Hyak.Common.1.0.3\lib\portable-net403+win+wpa81\Hyak.Common.dll</HintPath>
5556
<Private>True</Private>
5657
</Reference>
5758
<Reference Include="Microsoft.Azure.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -178,5 +179,4 @@
178179
<None Include="packages.config" />
179180
</ItemGroup>
180181
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
181-
<Import Project="..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
182182
</Project>

src/Common/Commands.Common.Authentication/Models/XmlProfileSerializer.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ public bool Deserialize(string contents, AzureSMProfile profile)
3838
DeserializeErrors = new List<string>();
3939

4040
DataContractSerializer serializer = new DataContractSerializer(typeof(ProfileData));
41+
42+
// For backward compatibility since namespace of ProfileData has been changed
43+
// we need to replace previous namespace with the current one
44+
if (!string.IsNullOrWhiteSpace(contents))
45+
{
46+
contents = contents.Replace(
47+
"http://schemas.datacontract.org/2004/07/Microsoft.Azure.Common.Authentication",
48+
"http://schemas.datacontract.org/2004/07/Microsoft.Azure.Commands.Common.Authentication");
49+
}
50+
4151
using (MemoryStream s = new MemoryStream(Encoding.UTF8.GetBytes(contents ?? "")))
4252
{
4353
data = (ProfileData)serializer.ReadObject(s);

src/Common/Storage/Commands.Storage.Test/Service/MockStorageBlobManagement.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,16 @@ public Task<string> StartCopyAsync(CloudBlob blob, Uri source, AccessCondition s
685685
throw new NotImplementedException();
686686
}
687687

688+
/// <summary>
689+
/// Get the SAS token for an account.
690+
/// </summary>
691+
/// <param name="sharedAccessAccountPolicy">Shared access policy to generate the SAS token.</param>
692+
/// <returns>Account SAS token.</returns>
693+
public string GetStorageAccountSASToken(SharedAccessAccountPolicy sharedAccessAccountPolicy)
694+
{
695+
throw new NotImplementedException();
696+
}
697+
688698
/// <summary>
689699
/// The storage context
690700
/// </summary>

src/Common/Storage/Commands.Storage/Blob/Cmdlet/NewAzureStorageBlobSasToken.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet
2020
using Microsoft.WindowsAzure.Commands.Storage.Common;
2121
using Microsoft.WindowsAzure.Commands.Storage.Model.Contract;
2222
using Microsoft.WindowsAzure.Storage.Blob;
23+
using Microsoft.WindowsAzure.Storage;
2324

2425
[Cmdlet(VerbsCommon.New, StorageNouns.BlobSas, DefaultParameterSetName = BlobNamePipelineParmeterSetWithPermission), OutputType(typeof(String))]
2526
public class NewAzureStorageBlobSasTokenCommand : StorageCloudBlobCmdletBase
@@ -80,6 +81,12 @@ public string Policy
8081
ParameterSetName = BlobPipelineParameterSetWithPermision)]
8182
public string Permission { get; set; }
8283

84+
[Parameter(Mandatory = false, HelpMessage = "Protocol can be used in the request with this SAS token.")]
85+
public SharedAccessProtocol Protocol { get; set; }
86+
87+
[Parameter(Mandatory = false, HelpMessage = "IP, or IP range ACL (access control list) that the request would be accepted from by Azure Storage.")]
88+
public string IPAddressOrRange { get; set; }
89+
8390
[Parameter(HelpMessage = "Start Time")]
8491
public DateTime? StartTime { get; set; }
8592

@@ -133,7 +140,7 @@ public override void ExecuteCmdlet()
133140
SharedAccessBlobPolicy accessPolicy = new SharedAccessBlobPolicy();
134141
bool shouldSetExpiryTime = SasTokenHelper.ValidateContainerAccessPolicy(Channel, blob.Container.Name, accessPolicy, accessPolicyIdentifier);
135142
SetupAccessPolicy(accessPolicy, shouldSetExpiryTime);
136-
string sasToken = GetBlobSharedAccessSignature(blob, accessPolicy, accessPolicyIdentifier);
143+
string sasToken = GetBlobSharedAccessSignature(blob, accessPolicy, accessPolicyIdentifier, Protocol, Util.SetupIPAddressOrRangeForSAS(IPAddressOrRange));
137144

138145
if (FullUri)
139146
{
@@ -154,10 +161,10 @@ public override void ExecuteCmdlet()
154161
/// <param name="accessPolicy">SharedAccessBlobPolicy object</param>
155162
/// <param name="policyIdentifier">The existing policy identifier.</param>
156163
/// <returns></returns>
157-
private string GetBlobSharedAccessSignature(CloudBlob blob, SharedAccessBlobPolicy accessPolicy, string policyIdentifier)
164+
private string GetBlobSharedAccessSignature(CloudBlob blob, SharedAccessBlobPolicy accessPolicy, string policyIdentifier, SharedAccessProtocol protocol, IPAddressOrRange iPAddressOrRange)
158165
{
159166
CloudBlobContainer container = blob.Container;
160-
return blob.GetSharedAccessSignature(accessPolicy, policyIdentifier);
167+
return blob.GetSharedAccessSignature(accessPolicy, null, policyIdentifier, protocol, iPAddressOrRange);
161168
}
162169

163170
/// <summary>

src/Common/Storage/Commands.Storage/Blob/Cmdlet/NewAzureStorageContainerSasToken.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet
2020
using Microsoft.WindowsAzure.Commands.Storage.Common;
2121
using Microsoft.WindowsAzure.Commands.Storage.Model.Contract;
2222
using Microsoft.WindowsAzure.Storage.Blob;
23+
using Microsoft.WindowsAzure.Storage;
2324

2425
[Cmdlet(VerbsCommon.New, StorageNouns.ContainerSas), OutputType(typeof(String))]
2526
public class NewAzureStorageContainerSasTokenCommand : StorageCloudBlobCmdletBase
@@ -51,9 +52,15 @@ public string Policy
5152
private string accessPolicyIdentifier;
5253

5354
[Parameter(HelpMessage = "Permissions for a container. Permissions can be any not-empty subset of \"rwdl\".",
54-
ParameterSetName = SasPermissionParameterSet)]
55+
ParameterSetName = SasPermissionParameterSet)]
5556
public string Permission { get; set; }
5657

58+
[Parameter(Mandatory = false, HelpMessage = "Protocol can be used in the request with this SAS token.")]
59+
public SharedAccessProtocol Protocol { get; set; }
60+
61+
[Parameter(Mandatory = false, HelpMessage = "IP, or IP range ACL (access control list) that the request would be accepted from by Azure Storage.")]
62+
public string IPAddressOrRange { get; set; }
63+
5764
[Parameter(HelpMessage = "Start Time")]
5865
public DateTime? StartTime { get; set; }
5966

@@ -98,7 +105,7 @@ public override void ExecuteCmdlet()
98105
SharedAccessBlobPolicy accessPolicy = new SharedAccessBlobPolicy();
99106
bool shouldSetExpiryTime = SasTokenHelper.ValidateContainerAccessPolicy(Channel, container.Name, accessPolicy, accessPolicyIdentifier);
100107
SetupAccessPolicy(accessPolicy, shouldSetExpiryTime);
101-
string sasToken = container.GetSharedAccessSignature(accessPolicy, accessPolicyIdentifier);
108+
string sasToken = container.GetSharedAccessSignature(accessPolicy, accessPolicyIdentifier, Protocol, Util.SetupIPAddressOrRangeForSAS(IPAddressOrRange));
102109

103110
if (FullUri)
104111
{

src/Common/Storage/Commands.Storage/Blob/Cmdlet/StartAzureStorageBlobCopy.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,10 @@ private async Task StartCopyFromBlob(long taskId, IStorageBlobManagement destCha
489489
// Opened workitem 1487579 to track this.
490490
throw new InvalidOperationException(Resources.DestinationBlobTypeNotMatch);
491491
}
492+
else
493+
{
494+
throw;
495+
}
492496
}
493497
}
494498

src/Common/Storage/Commands.Storage/Commands.Storage.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@
173173
<Compile Include="Common\BlobToFileSystemNameResolver.cs" />
174174
<Compile Include="Blob\Cmdlet\StartAzureStorageBlobCopy.cs" />
175175
<Compile Include="Blob\Cmdlet\StopAzureStorageBlobCopy.cs" />
176+
<Compile Include="Common\Cmdlet\NewAzureStorageAccountSasToken.cs" />
176177
<Compile Include="Common\Cmdlet\SetAzureStorageCORSRule.cs" />
177178
<Compile Include="Common\Cmdlet\GetAzureStorageCORSRule.cs" />
178179
<Compile Include="Common\Cmdlet\GetAzureStorageServiceLogging.cs" />
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.WindowsAzure.Commands.Storage.Common.Cmdlet
16+
{
17+
using System;
18+
using System.Management.Automation;
19+
using System.Security.Permissions;
20+
using Microsoft.WindowsAzure.Commands.Storage.Model.Contract;
21+
using Microsoft.WindowsAzure.Storage;
22+
23+
[Cmdlet(VerbsCommon.New, StorageNouns.AccountSas), OutputType(typeof(String))]
24+
public class NewAzureStorageAccountSasTokenCommand : StorageCloudBlobCmdletBase
25+
{
26+
[Parameter(Mandatory = true, HelpMessage = "Service type that this SAS token applies to.")]
27+
public SharedAccessAccountServices Service { get; set; }
28+
29+
[Parameter(Mandatory = true, HelpMessage = "Resource type that this SAS token applies to.")]
30+
public SharedAccessAccountResourceTypes ResourceType { get; set; }
31+
32+
[Parameter(Mandatory = true, HelpMessage = "Permissions.")]
33+
public string Permission { get; set; }
34+
35+
[Parameter(Mandatory = false, HelpMessage = "Protocol can be used in the request with this SAS token.")]
36+
public SharedAccessProtocol Protocol { get; set; }
37+
38+
[Parameter(Mandatory = false, HelpMessage = "IP, or IP range ACL (access control list) that the request would be accepted from by Azure Storage.")]
39+
public string IPAddressOrRange { get; set; }
40+
41+
[Parameter(Mandatory = false, HelpMessage = "Start Time")]
42+
public DateTime? StartTime { get; set; }
43+
44+
[Parameter(Mandatory = false, HelpMessage = "Expiry Time")]
45+
public DateTime? ExpiryTime { get; set; }
46+
47+
// Overwrite the useless parameter
48+
public override int? ServerTimeoutPerRequest { get; set; }
49+
public override int? ClientTimeoutPerRequest { get; set; }
50+
public override int? ConcurrentTaskCount { get; set; }
51+
52+
/// <summary>
53+
/// Initializes a new instance of the NewAzureStorageAccountSasTokenCommand class.
54+
/// </summary>
55+
public NewAzureStorageAccountSasTokenCommand()
56+
: this(null)
57+
{
58+
}
59+
60+
/// <summary>
61+
/// Initializes a new instance of the NewAzureStorageAccountSasTokenCommand class.
62+
/// </summary>
63+
/// <param name="channel">IStorageBlobManagement channel</param>
64+
public NewAzureStorageAccountSasTokenCommand(IStorageBlobManagement channel)
65+
{
66+
Channel = channel;
67+
EnableMultiThread = false;
68+
}
69+
70+
/// <summary>
71+
/// Execute command
72+
/// </summary>
73+
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
74+
public override void ExecuteCmdlet()
75+
{
76+
var sharedAccessPolicy = new SharedAccessAccountPolicy()
77+
{
78+
Permissions = SetupAccessPolicyPermission(this.Permission),
79+
Services = Service,
80+
ResourceTypes = ResourceType,
81+
Protocols = Protocol,
82+
IPAddressOrRange = Util.SetupIPAddressOrRangeForSAS(this.IPAddressOrRange)
83+
};
84+
85+
DateTimeOffset? accessStartTime;
86+
DateTimeOffset? accessEndTime;
87+
SasTokenHelper.SetupAccessPolicyLifeTime(StartTime, ExpiryTime,
88+
out accessStartTime, out accessEndTime, true);
89+
sharedAccessPolicy.SharedAccessStartTime = accessStartTime;
90+
sharedAccessPolicy.SharedAccessExpiryTime = accessEndTime;
91+
92+
this.WriteObject(Channel.GetStorageAccountSASToken(sharedAccessPolicy));
93+
}
94+
95+
/// <summary>
96+
/// Set up access policy permission
97+
/// </summary>
98+
/// <param name="policy">SharedAccessBlobPolicy object</param>
99+
/// <param name="permission">Permisson</param>
100+
internal SharedAccessAccountPermissions SetupAccessPolicyPermission(string permission)
101+
{
102+
if (string.IsNullOrEmpty(permission)) return SharedAccessAccountPermissions.None;
103+
104+
SharedAccessAccountPermissions accountPermission = SharedAccessAccountPermissions.None;
105+
permission = permission.ToLower();
106+
foreach (char op in permission)
107+
{
108+
switch (op)
109+
{
110+
case StorageNouns.Permission.Read:
111+
case StorageNouns.Permission.Query:
112+
accountPermission |= SharedAccessAccountPermissions.Read;
113+
break;
114+
case StorageNouns.Permission.Process:
115+
accountPermission |= SharedAccessAccountPermissions.ProcessMessages;
116+
break;
117+
case StorageNouns.Permission.Write:
118+
accountPermission |= SharedAccessAccountPermissions.Write;
119+
break;
120+
case StorageNouns.Permission.Add:
121+
accountPermission |= SharedAccessAccountPermissions.Add;
122+
break;
123+
case StorageNouns.Permission.Create:
124+
accountPermission |= SharedAccessAccountPermissions.Create;
125+
break;
126+
case StorageNouns.Permission.Update:
127+
accountPermission |= SharedAccessAccountPermissions.Update;
128+
break;
129+
case StorageNouns.Permission.Delete:
130+
accountPermission |= SharedAccessAccountPermissions.Delete;
131+
break;
132+
case StorageNouns.Permission.List:
133+
accountPermission |= SharedAccessAccountPermissions.List;
134+
break;
135+
default:
136+
throw new ArgumentException(string.Format(Resources.InvalidAccessPermission, op));
137+
}
138+
}
139+
140+
return accountPermission;
141+
}
142+
}
143+
}

src/Common/Storage/Commands.Storage/Common/StorageNouns.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ public static class StorageNouns
104104
/// </summary>
105105
public const string StorageCORSRule = "AzureStorageCORSRule";
106106

107+
/// <summary>
108+
/// Azure storage account sas
109+
/// </summary>
110+
public const string AccountSas = "AzureStorageAccountSASToken";
111+
107112
/// <summary>
108113
/// Azure storage container sas
109114
/// </summary>
@@ -214,6 +219,11 @@ public static class Permission
214219
/// Query permission
215220
/// </summary>
216221
public const char Query = 'q';
222+
223+
/// <summary>
224+
/// Create permission.
225+
/// </summary>
226+
public const char Create = 'c';
217227
}
218228
}
219229
}

src/Common/Storage/Commands.Storage/Common/Util.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,21 @@ public static CloudBlob GetBlobReference(Uri blobUri, StorageCredentials storage
161161
blobUri));
162162
}
163163
}
164+
165+
public static IPAddressOrRange SetupIPAddressOrRangeForSAS(string inputIPACL)
166+
{
167+
if (string.IsNullOrEmpty(inputIPACL)) return null;
168+
169+
int separator = inputIPACL.IndexOf('-');
170+
171+
if (-1 == separator)
172+
{
173+
return new IPAddressOrRange(inputIPACL);
174+
}
175+
else
176+
{
177+
return new IPAddressOrRange(inputIPACL.Substring(0, separator), inputIPACL.Substring(separator + 1));
178+
}
179+
}
164180
}
165181
}

0 commit comments

Comments
 (0)