Example #1
0
        public async Task <IActionResult> Subscribe(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("Subscribe function triggered!");

            // Process the subscription request
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            var    request     = JsonConvert.DeserializeObject <SubscriptionRequest>(requestBody);

            // 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)
            {
                log.LogError("Failed to load certificate!");
                return(new StatusCodeResult(500));
            }

            // Create a subscription
            var subscription = new Subscription
            {
                ChangeType              = request.ChangeType,
                IncludeResourceData     = true,
                NotificationUrl         = $"{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}";
                return(new OkObjectResult(responseMessage));
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);
                return(new StatusCodeResult(500));
            }
        }
Example #2
0
        public async Task <IActionResult> Notify(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("Notify function triggered!");

            // Graph Subscription validation logic, if needed
            string validationToken = req.Query["validationToken"];

            if (!string.IsNullOrEmpty(validationToken))
            {
                return(new OkObjectResult(validationToken));
            }

            // 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
            string notificationContent = await new StreamReader(req.Body).ReadToEndAsync();
            var    collection          = graphClient.HttpProvider.Serializer.DeserializeObject <ChangeNotificationCollection>(notificationContent);

            var acceptedTenantIds = new List <Guid>();

            acceptedTenantIds.Add(new Guid(Environment.GetEnvironmentVariable("AZURE_TENANT_ID")));

            var acceptedClientIds = new List <Guid>();

            acceptedTenantIds.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}");
                }
            }

            return(new OkResult());
        }