PageRenderTime 55ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/WP7.1/Templates/VB/WPCloud.SQL.Mem/WindowsPhoneCloud.Web/Services/SamplePushUserRegistrationService.vb

#
Visual Basic | 205 lines | 143 code | 38 blank | 24 comment | 2 complexity | b9ba201641905f853d045787b588950c 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. Imports WindowsPhone.Recipes.Push.Messages
  17. Imports Microsoft.Samples.WindowsPhoneCloud.Web.UserAccountWrappers
  18. Imports Microsoft.Samples.WindowsPhoneCloud.Web.Models
  19. Imports Microsoft.Samples.WindowsPhoneCloud.Web.Infrastructure
  20. Imports System.ServiceModel.Web
  21. Imports System.ServiceModel.Activation
  22. Imports System.ServiceModel
  23. Imports System.Net
  24. Imports System.Globalization
  25. Namespace Services
  26. <ServiceBehavior(IncludeExceptionDetailInFaults:=False), AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Required)> _
  27. Public Class SamplePushUserRegistrationService
  28. Implements ISamplePushUserRegistrationService
  29. Private ReadOnly context As HttpContextBase
  30. Private ReadOnly pushUserEndpointsRepository As IPushUserEndpointsRepository
  31. Private ReadOnly webOperationContext As WebOperationContext
  32. #If ACS Then
  33. Public Sub New()
  34. Me.New(New HttpContextWrapper(HttpContext.Current), WebOperationContext.Current, New SqlDataContext())
  35. End Sub
  36. <CLSCompliant(False)> _
  37. Public Sub New(ByVal context As HttpContextBase, ByVal webOperationContext As WebOperationContext, ByVal pushUserEndpointsRepository As IPushUserEndpointsRepository)
  38. If (context Is Nothing) AndAlso (HttpContext.Current Is Nothing) Then
  39. Throw New ArgumentNullException("context", "Context cannot be null if not running on a Web context.")
  40. End If
  41. If pushUserEndpointsRepository Is Nothing Then
  42. Throw New ArgumentNullException("pushUserEndpointsRepository", "PushUserEndpoints repository cannot be null.")
  43. End If
  44. Me.webOperationContext = webOperationContext
  45. Me.context = context
  46. Me.pushUserEndpointsRepository = pushUserEndpointsRepository
  47. End Sub
  48. Private ReadOnly Property UserId() As String
  49. Get
  50. Dim identity = TryCast(HttpContext.Current.User.Identity, Microsoft.IdentityModel.Claims.IClaimsIdentity)
  51. Return identity.Claims.Single(Function(c) c.ClaimType = Microsoft.IdentityModel.Claims.ClaimTypes.NameIdentifier).Value
  52. End Get
  53. End Property
  54. #Else
  55. Private ReadOnly formsAuth As IFormsAuthentication
  56. Private ReadOnly membershipService As IMembershipService
  57. Public Sub New()
  58. Me.New(New HttpContextWrapper(HttpContext.Current), webOperationContext.Current, New FormsAuthenticationService(), New AccountMembershipService(), New SqlDataContext())
  59. End Sub
  60. <CLSCompliant(False)> _
  61. Public Sub New(ByVal context As HttpContextBase, ByVal webOperationContext As WebOperationContext, ByVal formsAuth As IFormsAuthentication, ByVal membershipService As IMembershipService, ByVal pushUserEndpointsRepository As IPushUserEndpointsRepository)
  62. If (context Is Nothing) AndAlso (HttpContext.Current Is Nothing) Then
  63. Throw New ArgumentNullException("context", "Context cannot be null if not running on a Web context.")
  64. End If
  65. If pushUserEndpointsRepository Is Nothing Then
  66. Throw New ArgumentNullException("pushUserEndpointsRepository", "PushUserEndpoints repository cannot be null.")
  67. End If
  68. If formsAuth Is Nothing Then
  69. Throw New ArgumentNullException("formsAuth", "Forms Authentication service cannot be null.")
  70. End If
  71. If membershipService Is Nothing Then
  72. Throw New ArgumentNullException("membershipService", "Membership service cannot be null.")
  73. End If
  74. Me.webOperationContext = webOperationContext
  75. Me.context = context
  76. Me.pushUserEndpointsRepository = pushUserEndpointsRepository
  77. Me.formsAuth = formsAuth
  78. Me.membershipService = membershipService
  79. End Sub
  80. Private ReadOnly Property UserId() As String
  81. Get
  82. Dim ticketValue As String = Nothing
  83. Dim cookie = Me.context.Request.Cookies(Me.formsAuth.FormsCookieName)
  84. If cookie IsNot Nothing Then
  85. ' From cookie.
  86. ticketValue = cookie.Value
  87. ElseIf Me.context.Request.Headers("AuthToken") IsNot Nothing Then
  88. ' From HTTP header.
  89. ticketValue = Me.context.Request.Headers("AuthToken")
  90. End If
  91. If Not String.IsNullOrEmpty(ticketValue) Then
  92. Dim ticket As FormsAuthenticationTicket
  93. Try
  94. ticket = Me.formsAuth.Decrypt(ticketValue)
  95. Catch
  96. Throw New WebFaultException(Of String)("The authorization ticket cannot be decrypted.", HttpStatusCode.Unauthorized)
  97. End Try
  98. If ticket IsNot Nothing Then
  99. Return Me.membershipService.GetUser(New FormsIdentity(ticket).Name).ProviderUserKey.ToString()
  100. Else
  101. Throw New WebFaultException(Of String)("The authorization token is no longer valid.", HttpStatusCode.Unauthorized)
  102. End If
  103. Else
  104. Throw New WebFaultException(Of String)("Resource not found.", HttpStatusCode.NotFound)
  105. End If
  106. End Get
  107. End Property
  108. #End If
  109. Public Function Register(ByVal pushUserRegister As PushUserServiceRequest) As String Implements ISamplePushUserRegistrationService.Register
  110. ' Authenticate.
  111. Dim userId = Me.UserId
  112. Try
  113. Dim pushUserEndpoint = Me.pushUserEndpointsRepository.GetPushUserByApplicationAndDevice(pushUserRegister.ApplicationId, pushUserRegister.DeviceId)
  114. If pushUserEndpoint Is Nothing Then
  115. Dim newPushUserEndPoint = New PushUserEndpoint() With {.ApplicationId = pushUserRegister.ApplicationId, .DeviceId = pushUserRegister.DeviceId, .ChannelUri = pushUserRegister.ChannelUri.ToString(), .UserId = userId}
  116. Me.pushUserEndpointsRepository.AddPushUserEndpoint(newPushUserEndPoint)
  117. Else
  118. ' If the user did not change the channel URI, then, there is nothing to update, otherwise, set the new connection status
  119. If (Not pushUserEndpoint.ChannelUri.Equals(pushUserRegister.ChannelUri.ToString())) OrElse (Not pushUserEndpoint.UserId.Equals(userId)) Then
  120. ' Update che channelUri for the UserEndpoint and reset status fields.
  121. pushUserEndpoint.ChannelUri = pushUserRegister.ChannelUri.ToString()
  122. pushUserEndpoint.UserId = userId
  123. End If
  124. Me.pushUserEndpointsRepository.UpdatePushUserEndpoint(pushUserEndpoint)
  125. End If
  126. Catch exception As Exception
  127. Throw New WebFaultException(Of String)(String.Format(CultureInfo.InvariantCulture, "There was an error registering the Push Notification Endpoint: {0}", exception.Message), HttpStatusCode.InternalServerError)
  128. End Try
  129. Return "Success"
  130. End Function
  131. Public Function Unregister(ByVal pushUserUnregister As PushUserServiceRequest) As String Implements ISamplePushUserRegistrationService.Unregister
  132. ' Authenticate.
  133. Dim userId = Me.UserId
  134. Try
  135. Me.pushUserEndpointsRepository.RemovePushUserEndpoint(New PushUserEndpoint() With {.ApplicationId = pushUserUnregister.ApplicationId, .DeviceId = pushUserUnregister.DeviceId, .UserId = userId})
  136. Catch exception As Exception
  137. Throw New WebFaultException(Of String)(String.Format(CultureInfo.InvariantCulture, "There was an error unregistering the Push Notification Endpoint: {0}", exception.Message), HttpStatusCode.InternalServerError)
  138. End Try
  139. Return "Success"
  140. End Function
  141. Public Function GetUpdates(ByVal applicationId As String, ByVal deviceId As String) As String() Implements ISamplePushUserRegistrationService.GetUpdates
  142. ' Authenticate.
  143. Dim userId = Me.UserId
  144. Me.webOperationContext.OutgoingResponse.Headers.Add("Cache-Control", "no-cache")
  145. Try
  146. Dim pushUserEndpoint = Me.pushUserEndpointsRepository.GetPushUserByApplicationAndDevice(applicationId, deviceId)
  147. Dim messages = Me.pushUserEndpointsRepository.GetQueuedPushNotificationsByChannel(New Uri(pushUserEndpoint.ChannelUri)).ToArray()
  148. For Each message In messages
  149. Me.pushUserEndpointsRepository.DeleteQueuedMessage(message)
  150. Next message
  151. Me.ResetTileNotificationCount(applicationId, deviceId)
  152. Return messages.Select(Function(m) m.Message).ToArray()
  153. Catch exception As Exception
  154. Throw New WebFaultException(Of String)(String.Format(CultureInfo.InvariantCulture, "There was an error getting the push notification updates: {0}", exception.Message), HttpStatusCode.InternalServerError)
  155. End Try
  156. End Function
  157. Private Sub ResetTileNotificationCount(ByVal applicationId As String, ByVal deviceId As String)
  158. Dim pushUserEndpoint = Me.pushUserEndpointsRepository.GetPushUserByApplicationAndDevice(applicationId, deviceId)
  159. pushUserEndpoint.TileCount = 0
  160. Dim tile = New TilePushNotificationMessage With {.SendPriority = MessageSendPriority.High, .Count = pushUserEndpoint.TileCount}
  161. ' Send a new tile notification message to reset the count in the phone application.
  162. tile.SendAndHandleErrors(New Uri(pushUserEndpoint.ChannelUri))
  163. ' Save the updated count.
  164. Me.pushUserEndpointsRepository.UpdatePushUserEndpoint(pushUserEndpoint)
  165. End Sub
  166. End Class
  167. End Namespace