/WP7.1/BabelCam/C#/BabelCam.Web/Services/SharedAccessSignatureService.cs
C# | 181 lines | 136 code | 25 blank | 20 comment | 10 complexity | 0a11773867fa074d32634960ed64d6ee MD5 | raw file
- // ----------------------------------------------------------------------------------
- // Microsoft Developer & Platform Evangelism
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
- // EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
- // OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
- // ----------------------------------------------------------------------------------
- // The example companies, organizations, products, domain names,
- // e-mail addresses, logos, people, places, and events depicted
- // herein are fictitious. No association with any real company,
- // organization, product, domain name, email address, logo, person,
- // places, or events is intended or should be inferred.
- // ----------------------------------------------------------------------------------
-
- namespace Microsoft.Samples.BabelCam.Web.Services
- {
- using System;
- using System.Globalization;
- using System.Linq;
- using System.Net;
- using System.ServiceModel;
- using System.ServiceModel.Activation;
- using System.ServiceModel.Web;
- using System.Web;
- using System.Web.Security;
- using Microsoft.Samples.BabelCam.Infrastructure.Helpers;
- using Microsoft.Samples.BabelCam.Web.Helpers;
- using Microsoft.Samples.BabelCam.Web.UserAccountWrappers;
- using Microsoft.WindowsAzure;
- using Microsoft.WindowsAzure.StorageClient;
-
- [ServiceBehavior(IncludeExceptionDetailInFaults = false)]
- [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
- public class SharedAccessSignatureService : ISharedAccessSignatureService
- {
- private const SharedAccessPermissions ContainerSharedAccessPermissions = SharedAccessPermissions.Write | SharedAccessPermissions.Delete | SharedAccessPermissions.List;
-
- private readonly CloudBlobClient cloudBlobClient;
- private readonly WebOperationContext webOperationContext;
-
- public SharedAccessSignatureService()
- : this(null, WebOperationContext.Current)
- {
- }
-
- [CLSCompliant(false)]
- public SharedAccessSignatureService(CloudBlobClient cloudBlobClient, WebOperationContext webOperationContext)
- {
- if ((cloudBlobClient == null) && (GetStorageAccountFromConfigurationSetting() == null))
- {
- throw new ArgumentNullException("cloudBlobClient", "The Cloud Blob Client cannot be null if no configuration is loaded.");
- }
-
- this.cloudBlobClient = cloudBlobClient ?? GetStorageAccountFromConfigurationSetting().CreateCloudBlobClient();
- this.webOperationContext = webOperationContext;
- }
-
- private string UserId
- {
- get
- {
- var identity = HttpContext.Current.User.Identity as Microsoft.IdentityModel.Claims.IClaimsIdentity;
- return identity.Claims.Single(c => c.ClaimType == Microsoft.IdentityModel.Claims.ClaimTypes.NameIdentifier).Value;
- }
- }
-
- public Uri GetContainerSharedAccessSignature(string containerName)
- {
- // Authenticate.
- // TODO: Authorize (user and container access).
- var userId = this.UserId;
-
- try
- {
- var container = this.GetCloudBlobContainer(containerName);
- var containerSASExperiationTime = int.Parse(ConfigReader.GetConfigValue("ContainerSASExperiationTime"), NumberStyles.Integer, CultureInfo.InvariantCulture);
- var sas = container.GetSharedAccessSignature(new SharedAccessPolicy()
- {
- Permissions = ContainerSharedAccessPermissions,
- SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(containerSASExperiationTime)
- });
-
- if (this.webOperationContext != null)
- {
- this.webOperationContext.OutgoingResponse.Headers.Add("Cache-Control", "no-cache");
- }
-
- var uriBuilder = new UriBuilder(container.Uri) { Query = sas.TrimStart('?') };
- return uriBuilder.Uri;
- }
- catch (Exception exception)
- {
- throw new WebFaultException<string>(exception.Message, HttpStatusCode.InternalServerError);
- }
- }
-
- public Models.CloudBlobCollection GetBlobsSharedAccessSignatures(string containerName, string blobPrefix, bool useFlatBlobListing)
- {
- // Authenticate.
- // TODO: Authorize (user and container access).
- var userId = this.UserId;
-
- if (!string.IsNullOrEmpty(blobPrefix))
- {
- blobPrefix = blobPrefix.TrimStart('/', '\\').Replace('\\', '/');
- }
-
- try
- {
- SetReadOnlySharedAccessPolicy(this.GetCloudBlobContainer(containerName));
- var prefix = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", containerName, blobPrefix);
-
- var blobs = this.cloudBlobClient.ListBlobsWithPrefix(prefix, new BlobRequestOptions { UseFlatBlobListing = useFlatBlobListing });
- var result = new Models.CloudBlobCollection
- {
- Blobs = blobs.Where(b => b is CloudBlob)
- .Select(b => b.ToModel(containerName, this.cloudBlobClient.Credentials.AccountName))
- .ToArray()
- };
-
- if (this.webOperationContext != null)
- {
- this.webOperationContext.OutgoingResponse.Headers.Add("Cache-Control", "no-cache");
- }
-
- return result;
- }
- catch (Exception exception)
- {
- throw new WebFaultException<string>(exception.Message, HttpStatusCode.InternalServerError);
- }
- }
-
- private static void SetReadOnlySharedAccessPolicy(CloudBlobContainer container)
- {
- var blobSASExperiationTime = int.Parse(ConfigReader.GetConfigValue("BlobSASExperiationTime"), NumberStyles.Integer, CultureInfo.InvariantCulture);
- var permissions = container.GetPermissions();
- var options = new BlobRequestOptions
- {
- // Fail if someone else has already changed the container before we do.
- AccessCondition = AccessCondition.IfMatch(container.Properties.ETag)
- };
- var sharedAccessPolicy = new SharedAccessPolicy
- {
- Permissions = SharedAccessPermissions.Read,
- SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromDays(blobSASExperiationTime)
- };
-
- permissions.SharedAccessPolicies.Remove("readonly");
- permissions.SharedAccessPolicies.Add("readonly", sharedAccessPolicy);
-
- container.SetPermissions(permissions, options);
- }
-
- private static CloudStorageAccount GetStorageAccountFromConfigurationSetting()
- {
- CloudStorageAccount account = null;
-
- try
- {
- account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
- }
- catch (InvalidOperationException)
- {
- account = null;
- }
-
- return account;
- }
-
- private CloudBlobContainer GetCloudBlobContainer(string containerName)
- {
- var container = this.cloudBlobClient.GetContainerReference(containerName);
- container.CreateIfNotExist();
-
- return container;
- }
- }
- }