PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/WP7.1/Templates/C#/WPCloud.ACS/WindowsPhoneCloud.Web/Global.asax.cs

#
C# | 295 lines | 231 code | 43 blank | 21 comment | 26 complexity | 8f7e21ea64dbd88bd0c385db5c8a4f45 MD5 | raw file
  1. // ----------------------------------------------------------------------------------
  2. // Microsoft Developer & Platform Evangelism
  3. //
  4. // Copyright (c) Microsoft Corporation. All rights reserved.
  5. //
  6. // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  7. // EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
  8. // OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
  9. // ----------------------------------------------------------------------------------
  10. // The example companies, organizations, products, domain names,
  11. // e-mail addresses, logos, people, places, and events depicted
  12. // herein are fictitious. No association with any real company,
  13. // organization, product, domain name, email address, logo, person,
  14. // places, or events is intended or should be inferred.
  15. // ----------------------------------------------------------------------------------
  16. namespace Microsoft.Samples.WindowsPhoneCloud.Web
  17. {
  18. using System;
  19. using System.Data.Entity;
  20. using System.Globalization;
  21. using System.Linq;
  22. using System.Web;
  23. using System.Web.Mvc;
  24. using System.Web.Routing;
  25. using System.Web.Security;
  26. using Microsoft.Samples.WindowsPhoneCloud.Web.Controllers;
  27. using Microsoft.Samples.WindowsPhoneCloud.Web.Infrastructure;
  28. using Microsoft.Samples.WindowsPhoneCloud.Web.Models;
  29. using Microsoft.Samples.WindowsPhoneCloud.Web.Services;
  30. using Microsoft.WindowsAzure;
  31. using Microsoft.WindowsAzure.ServiceRuntime;
  32. using Microsoft.WindowsAzure.StorageClient;
  33. public class MvcApplication : System.Web.HttpApplication
  34. {
  35. private const int DefaultHttpsPort = 443;
  36. private const int DefaultHttpPort = 10080;
  37. private const string PortErrorMessage = @"The Web role was started in a wrong port.
  38. For this sample application to work correctly, please make sure that it is running in port {0}.
  39. Please review the Troubleshooting section of the sample documentation for instructions on how to do this.";
  40. private static bool securityInitialized = false;
  41. public static void RegisterGlobalFilters(GlobalFilterCollection filters)
  42. {
  43. filters.Add(new HandleErrorAttribute());
  44. }
  45. public static void RegisterRoutes(RouteCollection routes)
  46. {
  47. routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  48. routes.MapRoute(
  49. "Default",
  50. "{controller}/{action}/{id}",
  51. new { controller = "Home", action = "Index", id = (string)null },
  52. new { controller = new ListConstraint(ListConstraintType.Exclude, "RegistrationService", "SharedAccessSignatureService", "PushNotificationService", "SqlAzureSampleODataService") });
  53. }
  54. protected void Application_Start()
  55. {
  56. // This code sets up a handler to update CloudStorageAccount instances when their corresponding
  57. // configuration settings change in the service configuration file.
  58. CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
  59. {
  60. // Provide the configSetter with the initial value.
  61. configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
  62. });
  63. AreaRegistration.RegisterAllAreas();
  64. RegisterGlobalFilters(GlobalFilters.Filters);
  65. RegisterRoutes(RouteTable.Routes);
  66. RouteTable.Routes.AddWcfServiceRoute<RegistrationService>("RegistrationService");
  67. RouteTable.Routes.AddWcfServiceRoute<SharedAccessSignatureService>("SharedAccessSignatureService");
  68. RouteTable.Routes.AddWcfServiceRoute<SamplePushUserRegistrationService>("PushNotificationService");
  69. RouteTable.Routes.AddWcfServiceRoute<SqlAzureSampleODataService>("SqlAzureSampleODataService");
  70. var account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
  71. CreateSilverlightClientAccessPolicy(account.CreateCloudBlobClient());
  72. CreateCloudTables(account.CreateCloudTableClient());
  73. Database.SetInitializer<SqlSampleDataContext>(new SqlSampleDataInitializer());
  74. }
  75. protected void Session_Start(object sender, EventArgs e)
  76. {
  77. if (!securityInitialized)
  78. {
  79. InitializeSecurity();
  80. securityInitialized = true;
  81. }
  82. }
  83. protected void Application_BeginRequest(object sender, EventArgs e)
  84. {
  85. if (this.ShouldRedirectToHttps())
  86. {
  87. this.RedirectScheme(this.Context.Request.Url, "https");
  88. }
  89. else if (this.ShouldRedirectToHttp())
  90. {
  91. this.RedirectScheme(this.Context.Request.Url, "http");
  92. }
  93. if (!this.IsPortNumberOK() && !IsAllowedContent(this.Context.Request.Path))
  94. {
  95. this.CreateWrongPortException();
  96. }
  97. }
  98. private static void InitializeSecurity()
  99. {
  100. var adminUser = Membership.FindUsersByName("admin").Cast<MembershipUser>().FirstOrDefault();
  101. if (adminUser == null)
  102. {
  103. adminUser = Membership.CreateUser("admin", "Passw0rd!", "admin@wp7cloudapp.com");
  104. }
  105. var adminUserId = adminUser.ProviderUserKey.ToString();
  106. IUserPrivilegesRepository userPrivilegesRepository = new UserTablesServiceContext();
  107. userPrivilegesRepository.AddPrivilegeToUser(adminUserId, PrivilegeConstants.AdminPrivilege);
  108. }
  109. private static bool IsAllowedContent(string path)
  110. {
  111. return path.EndsWith("/Error", StringComparison.OrdinalIgnoreCase)
  112. || path.StartsWith("/Content", StringComparison.OrdinalIgnoreCase)
  113. || path.StartsWith("/Scripts", StringComparison.OrdinalIgnoreCase);
  114. }
  115. private static void CreateSilverlightClientAccessPolicy(CloudBlobClient cloudBlobClient)
  116. {
  117. var container = cloudBlobClient.GetContainerReference("$root");
  118. container.CreateIfNotExist();
  119. container.SetPermissions(
  120. new BlobContainerPermissions
  121. {
  122. PublicAccess = BlobContainerPublicAccessType.Blob
  123. });
  124. var blob = cloudBlobClient.GetBlobReference("clientaccesspolicy.xml");
  125. blob.Properties.ContentType = "text/xml";
  126. blob.UploadText(
  127. @"<?xml version=""1.0"" encoding=""utf-8""?>
  128. <access-policy>
  129. <cross-domain-access>
  130. <policy>
  131. <allow-from http-methods=""*"" http-request-headers=""*"">
  132. <domain uri=""*"" />
  133. <domain uri=""http://*"" />
  134. </allow-from>
  135. <grant-to>
  136. <resource path=""/"" include-subpaths=""true"" />
  137. </grant-to>
  138. </policy>
  139. </cross-domain-access>
  140. </access-policy>");
  141. }
  142. private static void CreateCloudTables(CloudTableClient cloudTableClient)
  143. {
  144. CreatePushNotificationTable(cloudTableClient);
  145. CreateUserTable(cloudTableClient);
  146. CreateUserPrivilegeTable(cloudTableClient);
  147. }
  148. private static void CreatePushNotificationTable(CloudTableClient cloudTableClient)
  149. {
  150. cloudTableClient.CreateTableIfNotExist(UserTablesServiceContext.PushUserTableName);
  151. // Execute conditionally for development storage only.
  152. if (cloudTableClient.BaseUri.IsLoopback)
  153. {
  154. var context = cloudTableClient.GetDataServiceContext();
  155. var entity = new PushUserEndpoint("applicationID", "deviceId") { UserId = "UserName", ChannelUri = "http://tempuri", TileCount = 0 };
  156. context.AddObject(UserTablesServiceContext.PushUserTableName, entity);
  157. context.SaveChangesWithRetries();
  158. context.DeleteObject(entity);
  159. context.SaveChangesWithRetries();
  160. }
  161. }
  162. private static void CreateUserTable(CloudTableClient cloudTableClient)
  163. {
  164. cloudTableClient.CreateTableIfNotExist(UserTablesServiceContext.UserTableName);
  165. // Execute conditionally for development storage only.
  166. if (cloudTableClient.BaseUri.IsLoopback)
  167. {
  168. var context = cloudTableClient.GetDataServiceContext();
  169. var entity = new User { Name = "UserName", Email = "user@email.com" };
  170. context.AddObject(UserTablesServiceContext.UserTableName, entity);
  171. context.SaveChangesWithRetries();
  172. context.DeleteObject(entity);
  173. context.SaveChangesWithRetries();
  174. }
  175. }
  176. private static void CreateUserPrivilegeTable(CloudTableClient cloudTableClient)
  177. {
  178. cloudTableClient.CreateTableIfNotExist(UserTablesServiceContext.UserPrivilegeTableName);
  179. // Execute conditionally for development storage only.
  180. if (cloudTableClient.BaseUri.IsLoopback)
  181. {
  182. var context = cloudTableClient.GetDataServiceContext();
  183. var entity = new UserPrivilege { UserId = "UserId", Privilege = "Privilege" };
  184. context.AddObject(UserTablesServiceContext.UserPrivilegeTableName, entity);
  185. context.SaveChangesWithRetries();
  186. context.DeleteObject(entity);
  187. context.SaveChangesWithRetries();
  188. }
  189. }
  190. private void RedirectScheme(Uri originalUri, string intendedScheme)
  191. {
  192. int portNumber = 0;
  193. if (intendedScheme.Equals("https", StringComparison.OrdinalIgnoreCase))
  194. {
  195. portNumber = DefaultHttpsPort;
  196. }
  197. else if (intendedScheme.Equals("http", StringComparison.OrdinalIgnoreCase))
  198. {
  199. portNumber = DefaultHttpPort;
  200. }
  201. var redirectUrl = string.Format(
  202. CultureInfo.InvariantCulture,
  203. "{0}://{1}:{2}{3}",
  204. intendedScheme,
  205. originalUri.Host,
  206. portNumber,
  207. originalUri.PathAndQuery);
  208. this.Response.Redirect(redirectUrl, true);
  209. }
  210. private bool ShouldRedirectToHttp()
  211. {
  212. return this.Request.IsSecureConnection && this.Context.Request.Url.ToString().EndsWith(".cer", StringComparison.OrdinalIgnoreCase);
  213. }
  214. private bool ShouldRedirectToHttps()
  215. {
  216. return !this.Request.IsSecureConnection && !this.Context.Request.Url.ToString().EndsWith(".cer", StringComparison.OrdinalIgnoreCase);
  217. }
  218. private void CreateWrongPortException()
  219. {
  220. var exception = new RoleInWrongPortException(string.Format(CultureInfo.InvariantCulture, PortErrorMessage, DefaultHttpsPort));
  221. var routeData = new RouteData();
  222. routeData.Values.Add("Controller", "Error");
  223. routeData.Values.Add("Action", "Index");
  224. routeData.Values.Add("Error", exception);
  225. using (var errorController = new ErrorController())
  226. {
  227. ((IController)errorController).Execute(new RequestContext(new HttpContextWrapper(this.Context), routeData));
  228. }
  229. this.Context.Response.End();
  230. }
  231. private bool IsPortNumberOK()
  232. {
  233. var scheme = this.Context.Request.Url.Scheme;
  234. var portNumber = 0;
  235. if (scheme.Equals("https"))
  236. {
  237. portNumber = DefaultHttpsPort;
  238. }
  239. else if (scheme.Equals("http"))
  240. {
  241. portNumber = DefaultHttpPort;
  242. }
  243. var hostAddress = this.Context.Request.Headers["Host"] ?? string.Empty;
  244. var portPosition = hostAddress.IndexOf(":", StringComparison.OrdinalIgnoreCase);
  245. if (portPosition > 0)
  246. {
  247. int.TryParse(hostAddress.Substring(portPosition + 1), out portNumber);
  248. }
  249. return (portNumber == DefaultHttpsPort) || ((portNumber == DefaultHttpPort) && Context.Request.Url.ToString().EndsWith(".cer", StringComparison.OrdinalIgnoreCase));
  250. }
  251. }
  252. }