public static async Task <HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req, FunctionContext executionContext) { // Prepare the response object HttpResponseData response = null; // Get the logger var log = executionContext.GetLogger("NotifyFunction"); log.LogInformation("Notify function triggered!"); // Graph Subscription validation logic, if needed var querystring = QueryHelpers.ParseQuery(req.Url.Query); string validationToken = null; if (querystring.ContainsKey("validationToken")) { validationToken = querystring["validationToken"]; } if (!string.IsNullOrEmpty(validationToken)) { response = req.CreateResponse(HttpStatusCode.OK); response.WriteString(validationToken); return(response); } else { // Create a GraphServiceClient instance with the defined TokenCredential var graphClient = GraphUtility.GetGraphClient(); // Load the X509Certificate and add it to the subscription object var certificate = X509CertificateUtility.LoadCertificate(StoreName.My, StoreLocation.CurrentUser, Environment.GetEnvironmentVariable("CertificateThumbprint")); // Get the notification content var collection = graphClient.HttpProvider .Serializer.DeserializeObject <ChangeNotificationCollection>(req.Body); var acceptedTenantIds = new List <Guid>(); acceptedTenantIds.Add(new Guid(Environment.GetEnvironmentVariable("AZURE_TENANT_ID"))); var acceptedClientIds = new List <Guid>(); acceptedClientIds.Add(new Guid(Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"))); // Validate the tokens var areTokensValid = await collection.AreTokensValid(acceptedTenantIds, acceptedClientIds); foreach (var changeNotification in collection.Value) { // And decrypt the encryptedContent var actualNotificationItem = await changeNotification.EncryptedContent.DecryptAsync( (id, thumbprint) => Task.FromResult(certificate)); if (areTokensValid) { // Show the decrypted object content log.LogInformation($"Notification content: {actualNotificationItem}"); } } } response = req.CreateResponse(HttpStatusCode.OK); return(response); }
public static async Task <HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req, FunctionContext executionContext) { // Prepare the response object HttpResponseData response = null; // Get the logger var log = executionContext.GetLogger("SubscribeFunction"); log.LogInformation("Subscribe function triggered!"); // Process the subscription request var request = await JsonSerializer.DeserializeAsync <SubscriptionRequest>(req.Body, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); // Create a GraphServiceClient instance with the defined TokenCredential var graphClient = GraphUtility.GetGraphClient(); // Load the X509Certificate and add it to the subscription object var certificate = X509CertificateUtility.LoadCertificate(StoreName.My, StoreLocation.CurrentUser, Environment.GetEnvironmentVariable("CertificateThumbprint")); if (certificate == null) { var certificateError = "Failed to load certificate!"; log.LogError(certificateError); response = req.CreateResponse(HttpStatusCode.InternalServerError); response.WriteString(certificateError); return(response); } // Create a subscription var subscription = new Subscription { ChangeType = request.ChangeType, IncludeResourceData = true, NotificationUrl = $"https://{Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME")}/api/notify?code={Environment.GetEnvironmentVariable("NotifyFunctionKey")}", Resource = request.Resource, ExpirationDateTime = DateTime.UtcNow.AddMinutes(15), ClientState = request.ClientState, EncryptionCertificateId = !string.IsNullOrEmpty(certificate?.FriendlyName) ? certificate.FriendlyName : certificate?.Subject, }; // Associate the X509Certificate to the subscription object subscription.AddPublicEncryptionCertificate(certificate); try { Subscription subscriptionResult = await graphClient.Subscriptions.Request().AddAsync(subscription); string responseMessage = $"Subscription successfully registered with ID: {subscriptionResult.Id}"; log.LogInformation(responseMessage); response = req.CreateResponse(HttpStatusCode.OK); response.WriteString(responseMessage); return(response); } catch (Exception ex) { log.LogError(ex.Message); response = req.CreateResponse(HttpStatusCode.InternalServerError); response.WriteString(ex.Message); return(response); } }