├── .editorconfig ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── IntegrationBuild.yml │ └── TriggerAzurePipeline.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── NotificationService-CI.yml ├── NotificationService ├── .dockerignore ├── CodeCoverage.runsettings ├── Local.testsettings ├── NotificationHandler │ ├── Controllers │ │ └── v1 │ │ │ ├── BaseController.cs │ │ │ ├── EmailController.cs │ │ │ ├── MeetingInviteController.cs │ │ │ └── NotificationReportController.cs │ ├── Dockerfile │ ├── NotificationHandler.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.json │ └── web.config ├── NotificationProviders │ ├── DirectSend.Core │ │ └── DirectSend.NetCore.csproj │ ├── DirectSend.NetFramework │ │ ├── DirectSend.NetFramework.csproj │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── app.config │ │ ├── nuget.config │ │ └── packages.config │ ├── DirectSend.Shared │ │ ├── DSSmtpClient.cs │ │ ├── DSSmtpClientFactory.cs │ │ ├── DirectSend.Shared.projitems │ │ ├── DirectSend.Shared.shproj │ │ ├── DirectSendMailService.cs │ │ ├── IDSSmtpClient.cs │ │ ├── IEmailService.cs │ │ ├── ISmtpClientFactory.cs │ │ ├── ISmtpClientPool.cs │ │ ├── Logger │ │ │ ├── AILogger.cs │ │ │ ├── EnvironmentInitializer.cs │ │ │ ├── ILogger.cs │ │ │ └── LoggingConfiguration.cs │ │ ├── Models │ │ │ ├── Configurations │ │ │ │ ├── ISmtpConfiguration.cs │ │ │ │ ├── SendAccountConfiguration.cs │ │ │ │ └── SmtpConfiguration.cs │ │ │ ├── DTO │ │ │ │ └── MailData.cs │ │ │ ├── LogEvent.cs │ │ │ └── Mail │ │ │ │ ├── EmailAddress.cs │ │ │ │ ├── EmailMessage.cs │ │ │ │ ├── RecipientType.cs │ │ │ │ └── Recipients.cs │ │ ├── SmptInitializationException.cs │ │ └── SmtpClientPool.cs │ └── DirectSend.Tests │ │ ├── DirectSend.UnitTests.csproj │ │ ├── DirectSendMailServiceTests.cs │ │ ├── SmtpClientPoolTests.cs │ │ └── TestDocument.docx ├── NotificationService.BusinessLibrary │ ├── Business │ │ └── v1 │ │ │ ├── EmailAccountManager.cs │ │ │ ├── EmailHandlerManager.cs │ │ │ ├── EmailManager.cs │ │ │ ├── EmailServiceManager.cs │ │ │ ├── Enums.cs │ │ │ ├── MailTemplateManager.cs │ │ │ └── NotificationReportManager.cs │ ├── Interfaces │ │ ├── IEmailAccountManager.cs │ │ ├── IEmailHandlerManager.cs │ │ ├── IEmailManager.cs │ │ ├── IEmailServiceManager.cs │ │ ├── IMailTemplateManager.cs │ │ ├── INotificationProvider.cs │ │ ├── INotificationProviderFactory.cs │ │ ├── INotificationReportManager.cs │ │ ├── ITemplateMerge.cs │ │ ├── ITokenHelper.cs │ │ └── NotificationProviderType.cs │ ├── Models │ │ └── ResponseData.cs │ ├── NotificationService.BusinessLibrary.csproj │ ├── Providers │ │ ├── DirectSendNotificationProvider.cs │ │ ├── IMSGraphProvider.cs │ │ ├── MSGraphNotificationProvider.cs │ │ ├── MSGraphProvider.cs │ │ ├── NotificationProviderFactory.cs │ │ └── SMTPNotificationProvider.cs │ └── Utilities │ │ ├── BusinessConstants.cs │ │ ├── BusinessUtilities.cs │ │ ├── MeetingInviteUtilities.cs │ │ ├── TemplateMerge.cs │ │ └── TokenHelper.cs ├── NotificationService.Common │ ├── ApplicationConstants.cs │ ├── Configurations │ │ ├── ConfigConstants.cs │ │ ├── CosmosDBSetting.cs │ │ ├── DirectSendSetting.cs │ │ ├── MSGraphSetting.cs │ │ ├── MailSettings.cs │ │ ├── RetrySetting.cs │ │ ├── SMTPSetting.cs │ │ ├── StorageAccountSetting.cs │ │ └── UserTokenSetting.cs │ ├── Encryption │ │ ├── EncryptionService.cs │ │ ├── IEncryptionService.cs │ │ └── KeyInfo.cs │ ├── Exceptions │ │ ├── ErrorDetails.cs │ │ ├── ExceptionMiddleware.cs │ │ └── NotificationServiceException.cs │ ├── Logger │ │ ├── AIConstants.cs │ │ ├── AILogger.cs │ │ ├── EnvironmentInitializer.cs │ │ ├── ILogger.cs │ │ └── LoggingConfiguration.cs │ ├── NotificationService.Common.csproj │ └── Utility │ │ ├── ExpressionExtensions.cs │ │ ├── ExpressionReplaceVisitor.cs │ │ └── Extensions.cs ├── NotificationService.Contracts │ ├── CustomValidations │ │ └── EmailIdListValidationAttribute.cs │ ├── Entities │ │ ├── BlobEmailData.cs │ │ ├── CosmosDBEntity.cs │ │ ├── EmailNotificationItemCosmosDbEntity.cs │ │ ├── EmailNotificationItemEntity.cs │ │ ├── EmailNotificationItemTableEntity.cs │ │ ├── EntityCollection.cs │ │ ├── MailTemplateEntity.cs │ │ ├── MeetingNotificationItemCosmosDbEntity.cs │ │ ├── MeetingNotificationItemEntity.cs │ │ ├── MeetingNotificationItemTableEntity.cs │ │ ├── NotificationAttachmentEntity.cs │ │ ├── NotificationAttachmentReference.cs │ │ ├── NotificationItemBaseEntity.cs │ │ ├── NotificationItemStatus.cs │ │ └── NotificationReportRequest.cs │ ├── Extensions │ │ ├── EmailNotificationItemCosmosDbEntityExtension.cs │ │ ├── EmailNotificationItemEntityExtensions.cs │ │ ├── EmailNotificationItemExtensions.cs │ │ ├── EmailNotificationItemTableEntityExtension.cs │ │ ├── GraphResponseExtensions.cs │ │ ├── MailTemplateExtensions.cs │ │ ├── MeetingNotificationItemCosmosDbEntityExtension.cs │ │ ├── MeetingNotificationItemEntityExtensions.cs │ │ ├── MeetingNotificationItemExtensions.cs │ │ └── MeetingNotificationItemTableEntityExtension.cs │ ├── GlobalSuppressions.cs │ ├── Models │ │ ├── AccountCredential.cs │ │ ├── ApplicationAccounts.cs │ │ ├── EmailNotificationItem.cs │ │ ├── Graph │ │ │ ├── EmailAddress.cs │ │ │ ├── EmailMessage.cs │ │ │ ├── EmailMessagePayload.cs │ │ │ ├── FileAttachment.cs │ │ │ ├── GraphBatchRequest.cs │ │ │ ├── GraphBatchResponse.cs │ │ │ ├── GraphRequest.cs │ │ │ ├── GraphRequestHeaders.cs │ │ │ ├── GraphResponse.cs │ │ │ ├── GraphResponseBody.cs │ │ │ ├── GraphResponseError.cs │ │ │ ├── ImportanceType.cs │ │ │ ├── Invite │ │ │ │ ├── Address.cs │ │ │ │ ├── Attendee.cs │ │ │ │ ├── AttendeeType.cs │ │ │ │ ├── DayOfTheWeek.cs │ │ │ │ ├── InviteDateTime.cs │ │ │ │ ├── InvitePayload.cs │ │ │ │ ├── InviteResponse.cs │ │ │ │ ├── InviteTimeZone.cs │ │ │ │ ├── Location.cs │ │ │ │ ├── LocationType.cs │ │ │ │ ├── OnlineMeetingInfo.cs │ │ │ │ ├── OnlineMeetingProviderType.cs │ │ │ │ ├── Organizer.cs │ │ │ │ ├── Phone.cs │ │ │ │ ├── PhoneType.cs │ │ │ │ ├── Recurrence.cs │ │ │ │ ├── RecurrencePattern.cs │ │ │ │ ├── RecurrencePatternType.cs │ │ │ │ ├── RecurrenceRange.cs │ │ │ │ └── RecurrenceRangeType.cs │ │ │ ├── MessageBody.cs │ │ │ ├── Person.cs │ │ │ ├── Recipient.cs │ │ │ └── SingleValueExtendedProperty.cs │ │ ├── MailTemplate.cs │ │ ├── MailTemplateInfo.cs │ │ ├── MeetingInviteReportResponse.cs │ │ ├── MeetingNotificationItem.cs │ │ ├── NotificationAttachment.cs │ │ ├── NotificationBatchItemResponse.cs │ │ ├── NotificationEnumerations.cs │ │ ├── NotificationItemBase.cs │ │ ├── NotificationReportResponse.cs │ │ ├── NotificationResponse.cs │ │ ├── QueueNotificationItem.cs │ │ ├── Reports │ │ │ └── MeetingInviteMessage.cs │ │ ├── Request │ │ │ └── DateTimeRange.cs │ │ ├── TableEntityBase.cs │ │ └── ValidationResult.cs │ └── NotificationService.Contracts.csproj ├── NotificationService.Data │ ├── CloudStorage │ │ ├── CloudStorageClient.cs │ │ └── ICloudStorageClient.cs │ ├── CosmosDB │ │ ├── CosmosDBQueryClient.cs │ │ └── ICosmosDBQueryClient.cs │ ├── Helper │ │ └── AzureCredentialHelper.cs │ ├── Interfaces │ │ ├── IEmailNotificationRepository.cs │ │ ├── IMailAttachmentRepository.cs │ │ ├── IMailTemplateRepository.cs │ │ ├── IRepository.cs │ │ ├── IRepositoryFactory.cs │ │ └── StorageType.cs │ ├── NotificationService.Data.csproj │ ├── Repositories │ │ ├── CustomCosmosLinqQuery.cs │ │ ├── EmailNotificationRepository.cs │ │ ├── ICosmosLinqQuery.cs │ │ ├── MailAttachmentRepository.cs │ │ ├── MailTemplateRepository.cs │ │ ├── RepositoryFactory.cs │ │ └── TableStorageEmailRepository.cs │ └── TableStorage │ │ ├── ITableStorageClient.cs │ │ └── TableStorageClient.cs ├── NotificationService.FunctionalTests │ ├── BaseTests.cs │ ├── EmailNotificationQueueTest.cs │ ├── EmailNotificationSendTest.cs │ ├── FunctionalConstants.cs │ ├── MeetingInviteTest.cs │ ├── NotificationService.FunctionalTests.csproj │ ├── NotificationTemplateTest.cs │ ├── TokenUtility.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── NotificationService.IaaC │ ├── Deploy-AzTemplate.ps1 │ ├── Deployment.targets │ ├── NotificationService.IaaC.deployproj │ ├── cspnotification.json │ └── cspnotification.parameters.json ├── NotificationService.LoadTests │ ├── NotificationService.LoadTests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── QueueEmailNotificationTest.webtest │ ├── QueueEmailNotifications.loadtest │ ├── SendEmailNotificationTest.webtest │ ├── SendEmailNotifications.loadtest │ └── packages.config ├── NotificationService.SvCommon │ ├── APIConstants │ │ └── ClaimTypeConstants.cs │ ├── Attributes │ │ └── ValidateModelAttribute.cs │ ├── Common │ │ └── StartupCommon.cs │ ├── NotificationService.SvCommon.csproj │ ├── PolicyHandlers │ │ ├── AppIdAuthorizePolicyHandler.cs │ │ └── AppNameAuthorizePolicyHandler.cs │ └── PolicyRequirements │ │ ├── AppIdAuthorizeRequirement.cs │ │ └── AppNameAuthorizeRequirement.cs ├── NotificationService.UnitTests │ ├── BusinessLibrary │ │ ├── Providers │ │ │ ├── DirectSendNotificationProviderTests.cs │ │ │ ├── MSGraphNotificationProviderTests.cs │ │ │ ├── MSGraphProviderTestBase.cs │ │ │ └── MSGraphProviderTests.cs │ │ └── V1 │ │ │ ├── EmailHandlerManager │ │ │ └── EmailHandlerManagerTests.cs │ │ │ ├── EmailManager │ │ │ ├── EmailManagerTests.cs │ │ │ ├── EmailManagerTestsBase.cs │ │ │ ├── GetNotificationMessageBodyAsyncTests.cs │ │ │ ├── MailAttachmentRepositoryTests.cs │ │ │ ├── ProcessEmailNotificationsTests.cs │ │ │ ├── ProcessMeetingInvitesTests.cs │ │ │ ├── QueueEmailNotificationsTests.cs │ │ │ ├── ResendEmailNotificationsTests.cs │ │ │ └── SendEmailNotificationsTests.cs │ │ │ ├── NotifiationReportManager │ │ │ ├── GetMeetingInviteMessage.cs │ │ │ └── NotificationReportManagerTestBase.cs │ │ │ └── NotificationReportManager │ │ │ └── NotificationReportManagerTests.cs │ ├── Common │ │ ├── Encryption │ │ │ └── EncryptionServiceTests.cs │ │ └── Exceptions │ │ │ └── NotificationServiceException_Tests │ │ │ └── NotificationServiceException_Ctor_Tests.cs │ ├── Controllers │ │ └── V1 │ │ │ ├── EmailController │ │ │ ├── ProcessQueuedEmailNotificationsTests.cs │ │ │ ├── QueueEmailNotificationsRequestHandlerTests.cs │ │ │ ├── QueueEmailNotificationsTests.cs │ │ │ ├── ResendEmailNotificationsRequestHandlerTests.cs │ │ │ ├── ResendEmailNotificationsTests.cs │ │ │ ├── SendEmailNotificationsTests.cs │ │ │ └── TemplateAPITests.cs │ │ │ ├── MeetingInviteController │ │ │ ├── ProcessQueueMeetingNotificationsTests.cs │ │ │ ├── ResendMeetingInvitesByNotificationIds.cs │ │ │ └── SendMeetingNotificationsTest.cs │ │ │ └── NotificationReportController │ │ │ └── NotificationReportControllerTests.cs │ ├── Data │ │ ├── CloudStorage │ │ │ ├── CloudStorageClientSetup.cs │ │ │ └── CloudStorageClientTest.cs │ │ ├── Repositories │ │ │ ├── EmailNotificationRepository │ │ │ │ ├── CreateEmailNotificationItemEntitiesTests.cs │ │ │ │ ├── EmailNotificationRepositoryMeetingInviteTests.cs │ │ │ │ ├── EmailNotificationRepositoryTestsBase.cs │ │ │ │ ├── GetEmailNotificationItemEntitiesTests.cs │ │ │ │ └── UpdateEmailNotificationItemEntitiesTests.cs │ │ │ └── TableStorageRepositoryTests.cs │ │ └── TableStorage │ │ │ └── TableStorageClientTests.cs │ ├── GlobalSuppressions.cs │ ├── Mocks │ │ ├── MockNotificationProvider.cs │ │ └── MockedCryptoGraphyClient.cs │ ├── NotificationService.UnitTests.csproj │ └── ServiceCommon │ │ ├── Attributes │ │ └── ValidateModelAttributeTests.cs │ │ └── PolicyHandlers │ │ └── PolicyHandlerTests.cs ├── NotificationService.sln ├── NotificationService │ ├── Controllers │ │ └── v1 │ │ │ ├── EmailController.cs │ │ │ ├── MeetingInviteController.cs │ │ │ └── RootPingController.cs │ ├── Dockerfile │ ├── GlobalSuppressions.cs │ ├── NotificationService.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ └── web.config ├── NotificationsQueueProcessor │ ├── .dockerignore │ ├── .gitignore │ ├── Constants.cs │ ├── Dockerfile │ ├── HttpClientHelper.cs │ ├── IHttpClientHelper.cs │ ├── NotificationsQueueProcessor.csproj │ ├── ProcessNotificationQueueItem.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── functionSettings.json │ └── host.json ├── WebNotifications │ ├── BackgroundServices │ │ └── NotificationsCarrierService.cs │ ├── Carriers │ │ ├── Interfaces │ │ │ └── IWebNotificationsCarrier.cs │ │ └── WebNotificationsCarrier.cs │ ├── Channels │ │ ├── INotificationsChannel.cs │ │ ├── Internals │ │ │ ├── ChannelProvider.cs │ │ │ └── IChannelProvider.cs │ │ └── NotificationsChannel.cs │ ├── Controllers │ │ └── v1 │ │ │ ├── NotificationsController.cs │ │ │ └── RootPingController.cs │ ├── GlobalSuppressions.cs │ ├── Hubs │ │ ├── Interfaces │ │ │ └── INotificationsClient.cs │ │ └── NotificationsHub.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Providers │ │ └── UserObjectIdentifierProvider.cs │ ├── Startup.cs │ ├── WebNotifications.csproj │ ├── appsettings.Development.json │ └── appsettings.json └── stylecop.json ├── README.md ├── SECURITY.md ├── SUPPORT.md └── nuget.config /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @microsoft/notification-service 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/IntegrationBuild.yml: -------------------------------------------------------------------------------- 1 | name: Integration Build 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | IntegrationBuild: 11 | runs-on: windows-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Setup .NET Core 15 | uses: actions/setup-dotnet@v1 16 | with: 17 | dotnet-version: 3.1.301 18 | - name: Restore Packages 19 | run: dotnet restore NotificationService/NotificationService.sln --configfile nuget.config 20 | - name: Build Solution 21 | run: dotnet build NotificationService/NotificationService.sln --configuration Release --no-restore 22 | - name: Execute Unit Tests 23 | run: dotnet test NotificationService/NotificationService.UnitTests/NotificationService.UnitTests.csproj --no-build --configuration Release 24 | -------------------------------------------------------------------------------- /.github/workflows/TriggerAzurePipeline.yml: -------------------------------------------------------------------------------- 1 | name: Call Azure Pipeline 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | 10 | jobs: 11 | build: 12 | name: Call Azure Pipeline 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Azure Pipelines Action 16 | uses: Azure/pipelines@v1 17 | with: 18 | azure-devops-project-url: https://dev.azure.com/microsoftit/OneITVSO 19 | azure-pipeline-name: 'NotificationService-Github-CI' 20 | azure-devops-token: ${{ secrets.AZURE_DEVOPS_TOKEN }} 21 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /NotificationService/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /NotificationService/Local.testsettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | These are default test settings for a local test run. 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /NotificationService/NotificationHandler/Controllers/v1/BaseController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationHandler.Controllers.V1 5 | { 6 | using System.Collections.Generic; 7 | using Microsoft.AspNetCore.Mvc; 8 | using NotificationService.Common.Logger; 9 | 10 | /// 11 | /// Base Controller for Notification Handler service. 12 | /// 13 | public class BaseController : Controller 14 | { 15 | /// 16 | /// Instance of . 17 | /// 18 | #pragma warning disable SA1401 // Fields should be private 19 | #pragma warning disable CA1051 // Do not declare visible instance fields 20 | protected readonly ILogger logger; 21 | #pragma warning restore CA1051 // Do not declare visible instance fields 22 | #pragma warning restore SA1401 // Fields should be private 23 | 24 | /// 25 | /// Initializes a new instance of the class. 26 | /// 27 | /// An instance of . 28 | public BaseController(ILogger logger) 29 | { 30 | this.logger = logger ?? throw new System.ArgumentNullException(nameof(logger)); 31 | } 32 | 33 | /// 34 | /// Logs and rethrow the exception. 35 | /// 36 | /// Error message. 37 | /// Name of input type. 38 | /// custom properties, add more dimensions to this, so it will be easy to trace and query. 39 | protected void LogAndThrowArgumentNullException(string message, string inputName, Dictionary traceProps) 40 | { 41 | var argumentException = new System.ArgumentNullException(inputName, message); 42 | this.logger.TraceInformation(argumentException.Message, traceProps); 43 | throw argumentException; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /NotificationService/NotificationHandler/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base 4 | WORKDIR /app 5 | EXPOSE 80 6 | EXPOSE 443 7 | 8 | FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build 9 | WORKDIR /src 10 | COPY ["NotificationHandler/NotificationHandler.csproj", "NotificationHandler/"] 11 | COPY ["NotificationService.Contracts/NotificationService.Contracts.csproj", "NotificationService.Contracts/"] 12 | COPY ["NotificationService.Common/NotificationService.Common.csproj", "NotificationService.Common/"] 13 | COPY ["NotificationService.BusinessLibrary/NotificationService.BusinessLibrary.csproj", "NotificationService.BusinessLibrary/"] 14 | COPY ["NotificationService.Data/NotificationService.Data.csproj", "NotificationService.Data/"] 15 | COPY ["NotificationService.SvCommon/NotificationService.SvCommon.csproj", "NotificationService.SvCommon/"] 16 | COPY ["NotificationProviders/DirectSend.Core/DirectSend.NetCore.csproj", "NotificationProviders/DirectSend.Core/"] 17 | COPY ["NotificationProviders/DirectSend.Shared/DirectSend.Shared.shproj", "NotificationProviders/DirectSend.Core/"] 18 | RUN dotnet restore "NotificationHandler/NotificationHandler.csproj" 19 | COPY . . 20 | WORKDIR "/src/NotificationHandler" 21 | RUN dotnet build "NotificationHandler.csproj" -c Release -o /app/build 22 | 23 | FROM build AS publish 24 | RUN dotnet publish "NotificationHandler.csproj" -c Release -o /app/publish 25 | 26 | FROM base AS final 27 | WORKDIR /app 28 | COPY --from=publish /app/publish . 29 | ENTRYPOINT ["dotnet", "NotificationHandler.dll"] -------------------------------------------------------------------------------- /NotificationService/NotificationHandler/NotificationHandler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | Linux 6 | False 7 | False 8 | False 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | all 23 | runtime; build; native; contentfiles; analyzers; buildtransitive 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /NotificationService/NotificationHandler/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationHandler 5 | { 6 | using System.Diagnostics.CodeAnalysis; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Hosting; 9 | 10 | /// 11 | /// Starting point of the service. 12 | /// 13 | [ExcludeFromCodeCoverage] 14 | public static class Program 15 | { 16 | /// 17 | /// Main entry point for the application start. 18 | /// 19 | /// Arguments. 20 | public static void Main(string[] args) 21 | { 22 | CreateHostBuilder(args).Build().Run(); 23 | } 24 | 25 | /// 26 | /// Creates a web host builder. 27 | /// 28 | /// Arguments. 29 | /// An instance of . 30 | public static IHostBuilder CreateHostBuilder(string[] args) => 31 | Host.CreateDefaultBuilder(args) 32 | .ConfigureWebHostDefaults(webBuilder => 33 | { 34 | _ = webBuilder.UseStartup(); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /NotificationService/NotificationHandler/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:13198", 7 | "sslPort": 44372 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "swagger", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "NotificationHandler": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "swagger", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 33 | "publishAllPorts": true, 34 | "useSSL": true 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /NotificationService/NotificationHandler/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "KeyVaultConfigRefreshDurationSeconds": "120", 3 | "KeyVaultUrl": "__KeyVaultUrl__" 4 | } -------------------------------------------------------------------------------- /NotificationService/NotificationHandler/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Core/DirectSend.NetCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | False 6 | False 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.NetFramework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MS.GTA.DirectSend.NetFramework")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MS.GTA.DirectSend.NetFramework")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("45a97c4f-6ebd-4cda-972a-3d3bad098c8d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.NetFramework/nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.NetFramework/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/DSSmtpClientFactory.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace DirectSend 6 | { 7 | using DirectSend.Models.Configurations; 8 | using NotificationProviders.Common.Logger; 9 | 10 | /// 11 | /// DSSmtpClientFactory. 12 | /// 13 | /// 14 | public class DSSmtpClientFactory : ISmtpClientFactory 15 | { 16 | /// 17 | /// Creates the client. 18 | /// 19 | /// The configuration. 20 | /// The logger. 21 | /// A . 22 | public IDSSmtpClient CreateClient(ISmtpConfiguration config, ILogger logger) 23 | { 24 | return new DSSmtpClient(config, logger); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/DirectSend.Shared.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 63dd255d-4c9f-4ea7-9f3b-5f7b32657058 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/IDSSmtpClient.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace DirectSend 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | using MailKit; 12 | using MimeKit; 13 | 14 | /// 15 | /// IDSSmtpClient. 16 | /// 17 | /// 18 | public interface IDSSmtpClient : IDisposable 19 | { 20 | /// 21 | /// Refreshes the specified log event. 22 | /// 23 | /// traceProps. 24 | void Refresh(Dictionary traceProps); 25 | 26 | /// 27 | /// Sends the asynchronous. 28 | /// 29 | /// The message. 30 | /// The traceProperties. 31 | /// The progress. 32 | /// The cancellation token. 33 | /// A . 34 | Task SendAsync(MimeMessage message, Dictionary traceProperties, ITransferProgress progress = null, CancellationToken cancellationToken = default); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/IEmailService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace DirectSend 6 | { 7 | using System.Threading.Tasks; 8 | using DirectSend.Models.Mail; 9 | 10 | /// 11 | /// IEmailService. 12 | /// 13 | public interface IEmailService 14 | { 15 | /// 16 | /// Sends the asynchronous. 17 | /// 18 | /// The EmailMessage. 19 | /// A . 20 | Task SendEmailAsync(EmailMessage email); 21 | 22 | /// 23 | /// Sends the asynchronous. 24 | /// 25 | /// The EmailMessage. 26 | /// A . 27 | Task SendMeetingInviteAsync(EmailMessage email); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/ISmtpClientFactory.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace DirectSend 6 | { 7 | using DirectSend.Models.Configurations; 8 | using NotificationProviders.Common.Logger; 9 | 10 | /// 11 | /// ISmtpClientFactory. 12 | /// 13 | public interface ISmtpClientFactory 14 | { 15 | /// 16 | /// Creates the client. 17 | /// 18 | /// The configuration. 19 | /// The logger. 20 | /// A . 21 | IDSSmtpClient CreateClient(ISmtpConfiguration config, ILogger logger); 22 | } 23 | } -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/ISmtpClientPool.cs: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DirectSend 5 | { 6 | using System.Collections.Generic; 7 | using System.Threading.Tasks; 8 | 9 | /// 10 | /// ISmtpClientPool. 11 | /// 12 | public interface ISmtpClientPool 13 | { 14 | /// 15 | /// Gets the end point. 16 | /// 17 | /// 18 | /// The end point. 19 | /// 20 | string EndPoint { get; } 21 | 22 | /// 23 | /// Gets the client. 24 | /// 25 | /// The trace properties. 26 | /// A . 27 | Task GetClient(Dictionary traceProperties); 28 | 29 | /// 30 | /// Returns the client. 31 | /// 32 | /// The client. 33 | /// The trace properties. 34 | /// A . 35 | Task ReturnClient(IDSSmtpClient client, Dictionary traceProperties); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/Logger/LoggingConfiguration.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace NotificationProviders.Common.Logger 6 | { 7 | using Microsoft.ApplicationInsights.DataContracts; 8 | 9 | /// 10 | /// Entity for maintaining the logging configuration. 11 | /// 12 | public class LoggingConfiguration 13 | { 14 | /// 15 | /// Gets or sets a value indicating whether the IsTraceEnabled property is true or false. 16 | /// 17 | public bool IsTraceEnabled { get; set; } 18 | 19 | /// 20 | /// Gets or sets the TraceLevel property. 21 | /// 22 | public SeverityLevel TraceLevel { get; set; } 23 | 24 | /// 25 | /// Gets or sets the EnvironmentName property. 26 | /// 27 | public string EnvironmentName { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/Models/Configurations/ISmtpConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DirectSend.Models.Configurations 5 | { 6 | /// 7 | /// ISmtpConfiguration. 8 | /// 9 | public interface ISmtpConfiguration 10 | { 11 | /// 12 | /// Gets the SMTP server. 13 | /// 14 | /// 15 | /// The SMTP server. 16 | /// 17 | string SmtpServer { get; } 18 | 19 | /// 20 | /// Gets the SMTP port. 21 | /// 22 | /// 23 | /// The SMTP port. 24 | /// 25 | int SmtpPort { get; } 26 | 27 | /// 28 | /// Gets or sets the SMTP username. 29 | /// 30 | /// 31 | /// The SMTP username. 32 | /// 33 | string SmtpUsername { get; set; } 34 | 35 | /// 36 | /// Gets or sets the SMTP password. 37 | /// 38 | /// 39 | /// The SMTP password. 40 | /// 41 | string SmtpPassword { get; set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/Models/Configurations/SendAccountConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DirectSend.Models.Configurations 5 | { 6 | /// 7 | /// SendAccountConfiguration. 8 | /// 9 | public class SendAccountConfiguration 10 | { 11 | /// 12 | /// Gets or sets the address. 13 | /// 14 | /// 15 | /// The address. 16 | /// 17 | public string Address { get; set; } 18 | 19 | /// 20 | /// Gets or sets the display name. 21 | /// 22 | /// 23 | /// The display name. 24 | /// 25 | public string FromAddressDisplayName { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/Models/Configurations/SmtpConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DirectSend.Models.Configurations 5 | { 6 | /// 7 | /// SmtpConfiguration. 8 | /// 9 | public class SmtpConfiguration : ISmtpConfiguration 10 | { 11 | /// 12 | /// Gets or sets the SMTP server. 13 | /// 14 | /// 15 | /// The SMTP server. 16 | /// 17 | public string SmtpServer { get; set; } 18 | 19 | /// 20 | /// Gets or sets the SMTP port. 21 | /// 22 | /// 23 | /// The SMTP port. 24 | /// 25 | public int SmtpPort { get; set; } 26 | 27 | /// 28 | /// Gets or sets the SMTP username. 29 | /// 30 | /// 31 | /// The SMTP username. 32 | /// 33 | public string SmtpUsername { get; set; } 34 | 35 | /// 36 | /// Gets or sets the SMTP password. 37 | /// 38 | /// 39 | /// The SMTP password. 40 | /// 41 | public string SmtpPassword { get; set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/Models/DTO/MailData.cs: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DirectSend.Models.DTO 5 | { 6 | using DirectSend.Models.Mail; 7 | 8 | /// 9 | /// MailData. 10 | /// 11 | public class MailData 12 | { 13 | /// 14 | /// Gets or sets the message. 15 | /// 16 | /// 17 | /// The message. 18 | /// 19 | public EmailMessage Message { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/Models/Mail/EmailAddress.cs: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DirectSend.Models.Mail 5 | { 6 | /// 7 | /// EmailAddress Model. 8 | /// 9 | public class EmailAddress 10 | { 11 | /// 12 | /// Gets or sets Name. 13 | /// 14 | public string Name { get; set; } 15 | 16 | /// 17 | /// Gets or sets Address. 18 | /// 19 | public string Address { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/Models/Mail/RecipientType.cs: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DirectSend.Models.Mail 5 | { 6 | /// 7 | /// RecipientsType Enum. 8 | /// 9 | public enum RecipientsType 10 | { 11 | /// 12 | /// Owner 13 | /// 14 | Owner, 15 | 16 | /// 17 | /// Member 18 | /// 19 | Member, 20 | 21 | /// 22 | /// GroupMailBox 23 | /// 24 | GroupMailBox, 25 | 26 | /// 27 | /// ServiceOrAlt 28 | /// 29 | ServiceOrAlt, 30 | 31 | /// 32 | /// Default 33 | /// 34 | Default, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Shared/Models/Mail/Recipients.cs: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DirectSend.Models.Mail 5 | { 6 | using System.Collections.Generic; 7 | 8 | /// 9 | /// Recipients Model. 10 | /// 11 | public class Recipients 12 | { 13 | /// 14 | /// Gets or sets EmailAddresses. 15 | /// 16 | public IEnumerable EmailAddresses { get; set; } 17 | 18 | /// 19 | /// Gets or sets RecipientsType. 20 | /// 21 | public RecipientsType RecipientsType { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Tests/DirectSend.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | 6 | false 7 | 8 | False 9 | 10 | False 11 | 12 | False 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Always 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /NotificationService/NotificationProviders/DirectSend.Tests/TestDocument.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/notification-provider/b8523a343a17cab1a08112ac773f7e5e67763994/NotificationService/NotificationProviders/DirectSend.Tests/TestDocument.docx -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Business/v1/EmailAccountManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary 5 | { 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using NotificationService.BusinessLibrary.Interfaces; 9 | using NotificationService.Contracts; 10 | 11 | /// 12 | /// EmailAccountManager. 13 | /// 14 | public class EmailAccountManager : IEmailAccountManager 15 | { 16 | /// 17 | /// selectedIndex. 18 | /// 19 | private int selectedIndex = 0; 20 | 21 | /// 22 | /// increments the selectedindex. 23 | /// 24 | public void IncrementIndex() 25 | { 26 | this.selectedIndex = this.selectedIndex + 1; 27 | } 28 | 29 | /// 30 | /// FetchAccountToBeUsedForApplication. 31 | /// 32 | /// applicationName. 33 | /// applicationAccounts. 34 | /// Tuple(AuthenticationHeaderValue, AccountCredential). 35 | public AccountCredential FetchAccountToBeUsedForApplication(string applicationName, List applicationAccounts) 36 | { 37 | AccountCredential selectedAccountCredential = null; 38 | var accountsOfApplication = applicationAccounts?.Find(a => a.ApplicationName == applicationName)?.Accounts?.FindAll(acc => acc.IsEnabled); 39 | 40 | if (accountsOfApplication != null && accountsOfApplication.Count > 0) 41 | { 42 | this.selectedIndex = this.selectedIndex > accountsOfApplication.Count - 1 ? 0 : this.selectedIndex; 43 | int indexOfAccountToBeUsedRR = this.selectedIndex; 44 | selectedAccountCredential = accountsOfApplication[indexOfAccountToBeUsedRR]; 45 | } 46 | 47 | return selectedAccountCredential; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Business/v1/Enums.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | namespace NotificationService.BusinessLibrary.Business 4 | { 5 | /// 6 | /// Speciefis Day of the week. 7 | /// 8 | /// 9 | /// Remarks: 10 | /// For the standard days of the week (Sunday, Monday...) the DayOfTheWeek enum value 11 | /// is the same as the System.DayOfWeek enum type. These values can be safely cast 12 | /// between the two enum types. The special days of the week (Day, Weekday and WeekendDay) 13 | /// are used for monthly and yearly recurrences and cannot be cast to System.DayOfWeek 14 | /// values. 15 | /// 16 | public enum DayOfTheWeek 17 | { 18 | /// 19 | /// The sunday 20 | /// 21 | Sunday = 0, 22 | 23 | /// 24 | /// The monday 25 | /// 26 | Monday = 1, 27 | 28 | /// 29 | /// The tuesday 30 | /// 31 | Tuesday = 2, 32 | 33 | /// 34 | /// The wednesday 35 | /// 36 | Wednesday = 3, 37 | 38 | /// 39 | /// The thursday 40 | /// 41 | Thursday = 4, 42 | 43 | /// 44 | /// The friday 45 | /// 46 | Friday = 5, 47 | 48 | /// 49 | /// The saturday 50 | /// 51 | Saturday = 6, 52 | 53 | /// 54 | /// The day 55 | /// 56 | Day = 7, 57 | 58 | /// 59 | /// The weekday 60 | /// 61 | Weekday = 8, 62 | 63 | /// 64 | /// The weekend day 65 | /// 66 | WeekendDay = 9, 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Interfaces/IEmailAccountManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary.Interfaces 5 | { 6 | using System.Collections.Generic; 7 | using NotificationService.Contracts; 8 | 9 | /// 10 | /// IEmailAccountManager interface. 11 | /// 12 | public interface IEmailAccountManager 13 | { 14 | /// 15 | /// Method to fetch account from the acccounts provided. 16 | /// 17 | /// Application Name to be used as filter. 18 | /// List of applicationAccounts. 19 | /// . 20 | public AccountCredential FetchAccountToBeUsedForApplication( 21 | string applicationName, List applicationAccounts); 22 | 23 | /// 24 | /// Increments index. 25 | /// 26 | public void IncrementIndex(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Interfaces/IMailTemplateManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary 5 | { 6 | using System.Threading.Tasks; 7 | using NotificationService.Contracts; 8 | 9 | /// 10 | /// Interface for mail template manager. 11 | /// 12 | public interface IMailTemplateManager 13 | { 14 | /// 15 | /// Saves email template. 16 | /// 17 | /// Application sourcing the email template. 18 | /// Mail template item. 19 | /// Success or Failure. 20 | Task SaveEmailTemplate(string applicationName, MailTemplate mailTempalte); 21 | 22 | /// 23 | /// Gets the email template entities from database. 24 | /// 25 | /// Application sourcing the email template. 26 | /// Mail template name. 27 | /// . 28 | Task GetMailTemplate(string applicationName, string templateName); 29 | 30 | /// 31 | /// Deletes email template. 32 | /// 33 | /// Application sourcing the email template. 34 | /// Mail template name. 35 | /// Success or Failure. 36 | Task DeleteMailTemplate(string applicationName, string templateName); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Interfaces/INotificationProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary.Interfaces 5 | { 6 | using System.Collections.Generic; 7 | using System.Threading.Tasks; 8 | using NotificationService.Contracts; 9 | using NotificationService.Contracts.Entities; 10 | 11 | /// 12 | /// The Notification provider Interface. 13 | /// 14 | public interface INotificationProvider 15 | { 16 | /// 17 | /// Process notifiication entities using corresponding provider. 18 | /// 19 | /// applicationName sourcing the notifications. 20 | /// List of notification entities that are to be processed. 21 | /// A representing the result of the asynchronous operation. 22 | Task ProcessNotificationEntities(string applicationName, IList notificationEntities); 23 | 24 | /// 25 | /// Processes the meeting notification entities. 26 | /// 27 | /// Name of the application. 28 | /// The notification entities. 29 | /// Task. 30 | Task ProcessMeetingNotificationEntities(string applicationName, IList notificationEntities); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Interfaces/INotificationProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary.Interfaces 5 | { 6 | /// 7 | /// The Notification provider factory Interface. 8 | /// 9 | public interface INotificationProviderFactory 10 | { 11 | /// 12 | /// provides the notification provider basing on type. 13 | /// 14 | /// NotificationProviderType. 15 | /// return NotificationProvider . 16 | public INotificationProvider GetNotificationProvider(NotificationProviderType type); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Interfaces/ITemplateMerge.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary.Interfaces 5 | { 6 | /// 7 | /// Merge templates with template input tokens. 8 | /// 9 | public interface ITemplateMerge 10 | { 11 | /// 12 | /// Creates mailbody using template and templateData provided in notification input. 13 | /// 14 | /// template type. 15 | /// notification template . 16 | /// notification Input . 17 | /// Email Body created using templates. 18 | string CreateMailBodyUsingTemplate(string templateType, string notificationTemplate, string notificationInput); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Interfaces/ITokenHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary 5 | { 6 | using System.Net.Http.Headers; 7 | using System.Threading.Tasks; 8 | using NotificationService.Contracts; 9 | 10 | /// 11 | /// Helper class to handle token related activities. 12 | /// 13 | public interface ITokenHelper 14 | { 15 | /// 16 | /// Fetches the token for the selected account credential. 17 | /// 18 | /// Account credential. 19 | /// Token value. 20 | Task GetAccessTokenForSelectedAccount(AccountCredential selectedAccountCredential); 21 | 22 | /// 23 | /// Creates an authentication token for the graph resource from the user access token. 24 | /// 25 | /// User access token. 26 | /// Authentication token for the graph resource defined in the graph provider. 27 | Task GetAuthenticationHeaderFromToken(string userAccessToken); 28 | 29 | /// 30 | /// return the authentication header for selected account. 31 | /// 32 | /// selectedAccountCredential. 33 | /// AuthenticationHeaderValue. 34 | Task GetAuthenticationHeaderValueForSelectedAccount(AccountCredential selectedAccountCredential); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Interfaces/NotificationProviderType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary.Interfaces 5 | { 6 | /// 7 | /// NotificationProviderType. 8 | /// 9 | public enum NotificationProviderType 10 | { 11 | /// 12 | /// Graph API 13 | /// 14 | Graph, 15 | 16 | /// 17 | /// Direct Send API 18 | /// 19 | DirectSend, 20 | 21 | /// 22 | /// SMTP API 23 | /// 24 | SMTP, 25 | } 26 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Models/ResponseData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary.Models 5 | { 6 | using System.Net; 7 | 8 | /// 9 | /// Capture Response from API calls. 10 | /// 11 | /// Type parameter for Result. 12 | public class ResponseData 13 | { 14 | /// 15 | /// Gets or sets a value indicating whether gets or Sets value for success/failed. 16 | /// 17 | public bool Status { get; set; } 18 | 19 | /// 20 | /// Gets or Sets Result. 21 | /// 22 | public T Result { get; set; } 23 | 24 | /// 25 | /// Gets or Sets ErrorMessage. 26 | /// 27 | public string ErrorMessage { get; set; } 28 | 29 | /// 30 | /// Gets or Sets StatusCode. 31 | /// 32 | public HttpStatusCode StatusCode { get; set; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Providers/NotificationProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary.Providers 5 | { 6 | using System; 7 | using NotificationService.BusinessLibrary.Interfaces; 8 | 9 | /// 10 | /// Notification Provider Factory. 11 | /// 12 | public class NotificationProviderFactory : INotificationProviderFactory 13 | { 14 | private readonly IServiceProvider serviceProvider; 15 | 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// Instance of . 20 | public NotificationProviderFactory(IServiceProvider serviceProvider) 21 | { 22 | this.serviceProvider = serviceProvider; 23 | } 24 | 25 | /// 26 | public INotificationProvider GetNotificationProvider(NotificationProviderType type) 27 | { 28 | switch (type) 29 | { 30 | case NotificationProviderType.Graph: 31 | return (INotificationProvider)this.serviceProvider.GetService(typeof(MSGraphNotificationProvider)); 32 | case NotificationProviderType.DirectSend: 33 | return (INotificationProvider)this.serviceProvider.GetService(typeof(DirectSendNotificationProvider)); 34 | case NotificationProviderType.SMTP: 35 | return (INotificationProvider)this.serviceProvider.GetService(typeof(SMTPNotificationProvider)); 36 | default: 37 | return null; 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.BusinessLibrary/Utilities/BusinessConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.BusinessLibrary 5 | { 6 | /// 7 | /// Constants for the business layer. 8 | /// 9 | public static class BusinessConstants 10 | { 11 | /// 12 | /// The page size. 13 | /// 14 | public const int PageSize = 50; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Configurations/CosmosDBSetting.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common 5 | { 6 | /// 7 | /// Cosmos DB Configuration Settings. 8 | /// 9 | public class CosmosDBSetting 10 | { 11 | /// 12 | /// Gets or sets Uri. 13 | /// 14 | public string Uri { get; set; } 15 | 16 | /// 17 | /// Gets or sets Key. 18 | /// 19 | public string Key { get; set; } 20 | 21 | /// 22 | /// Gets or sets Database name. 23 | /// 24 | public string Database { get; set; } 25 | 26 | /// 27 | /// Gets or sets EmailHistoryContainer name. 28 | /// 29 | public string EmailHistoryContainer { get; set; } 30 | 31 | /// 32 | /// Gets or sets MeetingHistoryContainer name. 33 | /// 34 | public string MeetingHistoryContainer { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Configurations/DirectSendSetting.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Configurations 5 | { 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | /// 9 | /// Direct Send Configuration Settings. 10 | /// 11 | [ExcludeFromCodeCoverage] 12 | public class DirectSendSetting 13 | { 14 | /// 15 | /// Gets or sets FromAddressDisplayName. 16 | /// 17 | public string FromAddressDisplayName { get; set; } 18 | 19 | /// 20 | /// Gets or sets FromAddress. 21 | /// 22 | public string FromAddress { get; set; } 23 | 24 | /// 25 | /// Gets or sets SmtpPort. 26 | /// 27 | public string SmtpPort { get; set; } 28 | 29 | /// 30 | /// Gets or sets SmtpServer. 31 | /// 32 | public string SmtpServer { get; set; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Configurations/MailSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Configurations 5 | { 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | /// 9 | /// MailSettings Configuration Settings. 10 | /// 11 | [ExcludeFromCodeCoverage] 12 | public class MailSettings 13 | { 14 | /// 15 | /// Gets or sets Application Name. 16 | /// 17 | public string ApplicationName { get; set; } 18 | 19 | /// 20 | /// Gets or sets a value indicating whether Mails should be actually sent or not. 21 | /// 22 | public bool MailOn { get; set; } = true; 23 | 24 | /// 25 | /// Gets or sets Email address which shall override the to address of recipients. 26 | /// 27 | public string ToOverride { get; set; } 28 | 29 | /// 30 | /// Gets or sets a value indicating whether SendForReal is true or false, If false ToOverride would be used to override the recipient address. 31 | /// 32 | public bool SendForReal { get; set; } = false; 33 | 34 | /// 35 | /// Gets or sets a value indicating whether gets or sets SaveToSent. 36 | /// 37 | public bool SaveToSent { get; set; } = true; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Configurations/RetrySetting.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common 5 | { 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | /// 9 | /// Retry Configuration Settings. 10 | /// 11 | [ExcludeFromCodeCoverage] 12 | public class RetrySetting 13 | { 14 | /// 15 | /// Gets or sets Max Retries. 16 | /// 17 | public int MaxRetries { get; set; } 18 | 19 | /// 20 | /// Gets or sets TransientRetryCount. 21 | /// 22 | public int TransientRetryCount { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Configurations/SMTPSetting.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Configurations 5 | { 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | /// 9 | /// SMTP Configuration Settings. 10 | /// 11 | [ExcludeFromCodeCoverage] 12 | public class SMTPSetting 13 | { 14 | /// 15 | /// Gets or sets SmtpUrl. 16 | /// 17 | public string SmtpUrl { get; set; } 18 | 19 | /// 20 | /// Gets or sets SmtpPort. 21 | /// 22 | public int SmtpPort { get; set; } 23 | 24 | /// 25 | /// Gets or sets SmtpDomain. 26 | /// 27 | public string SmtpDomain { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Configurations/StorageAccountSetting.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common 5 | { 6 | /// 7 | /// Storage Account Configuration Settings. 8 | /// 9 | public class StorageAccountSetting 10 | { 11 | /// 12 | /// Gets or sets the Blob Container Name. 13 | /// 14 | public string BlobContainerName { get; set; } 15 | 16 | /// 17 | /// Gets or sets the Mail template table name. 18 | /// 19 | public string MailTemplateTableName { get; set; } 20 | 21 | /// 22 | /// Gets or sets the Email History table name. 23 | /// 24 | public string EmailHistoryTableName { get; set; } 25 | 26 | /// 27 | /// Gets or sets the Meeting History table name. 28 | /// 29 | public string MeetingHistoryTableName { get; set; } 30 | 31 | /// 32 | /// Gets or sets the Notification queue name. 33 | /// 34 | public string NotificationQueueName { get; set; } 35 | public string StorageAccountName { get; set; } 36 | public string StorageTableAccountURI { get; set; } 37 | public string StorageBlobAccountURI { get; set; } 38 | public string StorageQueueAccountURI { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Configurations/UserTokenSetting.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common 5 | { 6 | /// 7 | /// User Token Configuration Settings. 8 | /// 9 | public class UserTokenSetting 10 | { 11 | /// 12 | /// Gets or sets Authority. 13 | /// 14 | public string Authority { get; set; } 15 | 16 | /// 17 | /// Gets or sets Client Id. 18 | /// 19 | public string ClientId { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Encryption/IEncryptionService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Encryption 5 | { 6 | /// 7 | /// Common service to encrypt/decrypt sensitive data. 8 | /// 9 | public interface IEncryptionService 10 | { 11 | /// 12 | /// Encrypts the input text. 13 | /// 14 | /// string to be encrypted. 15 | /// Cipher text. 16 | string Encrypt(string input); 17 | 18 | /// 19 | /// Decrypts the cipher text. 20 | /// 21 | /// Cipher text to be decrypted. 22 | /// Plain text. 23 | string Decrypt(string cipherText); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Exceptions/ErrorDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Exceptions 5 | { 6 | using Newtonsoft.Json; 7 | 8 | /// 9 | /// Model for Error Info in response in case of exception. 10 | /// 11 | public class ErrorDetails 12 | { 13 | /// 14 | /// Gets or Sets StatusCode. 15 | /// 16 | public int StatusCode { get; set; } 17 | 18 | /// 19 | /// Gets or Sets Message. 20 | /// 21 | public string Message { get; set; } 22 | 23 | /// 24 | /// Overriden method ToString. 25 | /// 26 | /// serialized ErrordDetails object. 27 | public override string ToString() 28 | { 29 | return JsonConvert.SerializeObject(this); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Exceptions/NotificationServiceException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Exceptions 5 | { 6 | using System; 7 | 8 | /// 9 | /// The class represents exceptional behavior of notification service. 10 | /// 11 | /// 12 | public class NotificationServiceException : Exception 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | public NotificationServiceException() 18 | : this("Something went wrong!") 19 | { 20 | } 21 | 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// The message that describes the error. 26 | public NotificationServiceException(string message) 27 | : base(message) 28 | { 29 | } 30 | 31 | /// 32 | /// Initializes a new instance of the class. 33 | /// 34 | /// The message that describes the error. 35 | /// The instance of . 36 | public NotificationServiceException(string message, Exception innerException) 37 | : base(message, innerException) 38 | { 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Logger/LoggingConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Logger 5 | { 6 | using Microsoft.ApplicationInsights.DataContracts; 7 | 8 | /// 9 | /// Entity for maintaining the logging configuration. 10 | /// 11 | public class LoggingConfiguration 12 | { 13 | /// 14 | /// Gets or sets a value indicating whether the IsTraceEnabled property is true or false. 15 | /// 16 | public bool IsTraceEnabled { get; set; } 17 | 18 | /// 19 | /// Gets or sets the TraceLevel property. 20 | /// 21 | public SeverityLevel TraceLevel { get; set; } 22 | 23 | /// 24 | /// Gets or sets the EnvironmentName property. 25 | /// 26 | public string EnvironmentName { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Utility/ExpressionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Utility 5 | { 6 | using System; 7 | using System.Linq.Expressions; 8 | 9 | /// 10 | /// ExpressionExtensions. 11 | /// 12 | public static class ExpressionExtensions 13 | { 14 | /// 15 | /// And Operation. 16 | /// 17 | /// Type. 18 | /// First Expression. 19 | /// Second Expression. 20 | /// Combined Expression. 21 | public static Expression> And( 22 | this Expression> expr1, 23 | Expression> expr2) 24 | { 25 | if (expr1 == null || expr2 == null) 26 | { 27 | #pragma warning disable CA2208 // Instantiate argument exceptions correctly 28 | throw new ArgumentNullException($"Expression cannot be null"); 29 | #pragma warning restore CA2208 // Instantiate argument exceptions correctly 30 | } 31 | 32 | var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]); 33 | return Expression.Lambda>(Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters); 34 | } 35 | 36 | private static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx) 37 | { 38 | return new ExpressionReplaceVisitor(searchEx, replaceEx).Visit(expression); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService.Common/Utility/ExpressionReplaceVisitor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.Utility 5 | { 6 | using System.Linq.Expressions; 7 | 8 | /// 9 | /// ReplaceVisitor. 10 | /// 11 | internal class ExpressionReplaceVisitor : ExpressionVisitor 12 | { 13 | private readonly Expression fromExpression; 14 | private readonly Expression toExpression; 15 | 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// From Expression. 20 | /// To Expression. 21 | public ExpressionReplaceVisitor(Expression fromExpression, Expression toExpression) 22 | { 23 | this.fromExpression = fromExpression; 24 | this.toExpression = toExpression; 25 | } 26 | 27 | /// 28 | /// Visit. 29 | /// 30 | /// Node. 31 | /// Expression. 32 | public override Expression Visit(Expression node) 33 | { 34 | return node == this.fromExpression ? this.toExpression : base.Visit(node); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/CustomValidations/EmailIdListValidationAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Common.CustomValidations 5 | { 6 | using System.ComponentModel.DataAnnotations; 7 | using NotificationService.Common; 8 | using NotificationService.Common.Utility; 9 | 10 | /// 11 | /// Class to validate emails. 12 | /// 13 | public sealed class EmailIdListValidationAttribute : ValidationAttribute 14 | { 15 | public string PropertyName { get; set; } 16 | 17 | public bool Nullable { get; set; } = true; 18 | 19 | /// 20 | protected override ValidationResult IsValid(object emailIdsString, ValidationContext validationContext) 21 | { 22 | if (emailIdsString == null ) 23 | { 24 | return this.Nullable ? ValidationResult.Success : new ValidationResult($"{this.PropertyName} can't be null/empty "); 25 | } 26 | 27 | if (emailIdsString.ToString().HasWhitespaces()) 28 | { 29 | return new ValidationResult($"Whitespaces are not allowed in property ['{this.PropertyName}']."); 30 | } 31 | 32 | string[] emailIds = emailIdsString.ToString().Split(ApplicationConstants.SplitCharacter, System.StringSplitOptions.RemoveEmptyEntries); 33 | 34 | bool isValid = true; 35 | string invalidEmailAddresses = null; 36 | foreach (var emailId in emailIds) 37 | { 38 | if (!emailId.IsValidEmail()) 39 | { 40 | isValid = false; 41 | invalidEmailAddresses = invalidEmailAddresses == null ? emailId : string.Concat(invalidEmailAddresses, ",", emailId); 42 | } 43 | } 44 | 45 | return isValid ? ValidationResult.Success : new ValidationResult($"EmailIds [{invalidEmailAddresses}] are invalid for property ['{this.PropertyName}']."); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Entities/BlobEmailData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Entities 5 | { 6 | using System.Collections.Generic; 7 | 8 | /// 9 | /// BlobEmailData. 10 | /// 11 | public class BlobEmailData 12 | { 13 | /// 14 | /// Gets or sets notificationId. 15 | /// 16 | public string NotificationId { get; set; } 17 | 18 | /// 19 | /// Gets or Sets Email Body. 20 | /// 21 | public string Body { get; set; } 22 | 23 | /// 24 | /// Gets or Sets Attachments. 25 | /// 26 | public IEnumerable Attachments { get; set; } 27 | 28 | /// 29 | /// Gets or sets templateData. 30 | /// 31 | public string TemplateData { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Entities/CosmosDBEntity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System; 7 | using System.Runtime.Serialization; 8 | using NotificationService.Contracts.Models; 9 | using Azure.Data.Tables; 10 | 11 | /// 12 | /// Cosmos DB Base entity. 13 | /// 14 | [DataContract] 15 | public abstract class CosmosDBEntity: TableEntityBase 16 | { 17 | /// Gets or sets the id. 18 | [DataMember(Name = "id")] 19 | public string Id { get; set; } 20 | 21 | /// Gets or sets the OID that the document was created by. 22 | [DataMember(Name = "CreatedBy")] 23 | public string CreatedBy { get; set; } 24 | 25 | /// Gets or sets the OID that the document was updated by. 26 | [DataMember(Name = "UpdatedBy")] 27 | public string UpdatedBy { get; set; } 28 | 29 | /// Gets or sets the created at. 30 | [DataMember(Name = "CreatedAt")] 31 | public long CreatedAt { get; set; } 32 | 33 | /// Gets or sets the updated at. 34 | [DataMember(Name = "UpdatedAt")] 35 | public long UpdatedAt { get; set; } 36 | 37 | /// Gets or sets the created at. 38 | [DataMember(Name = "CreatedDateTime")] 39 | public DateTime CreatedDateTime { get; set; } 40 | 41 | /// Gets or sets the updated at. 42 | [DataMember(Name = "UpdatedDateTime")] 43 | public DateTime UpdatedDateTime { get; set; } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Entities/EntityCollection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Entities 5 | { 6 | using System.Collections.Generic; 7 | 8 | /// 9 | /// The class stores the items and the continuation page token. 10 | /// 11 | /// The instance for . 12 | public class EntityCollection 13 | where T : CosmosDBEntity 14 | { 15 | /// 16 | /// Gets or sets the entity items. 17 | /// 18 | /// 19 | /// The entitiy items. 20 | /// 21 | public IEnumerable Items { get; set; } 22 | 23 | /// 24 | /// Gets or sets the next page identifier. 25 | /// 26 | /// 27 | /// The next page identifier. 28 | /// 29 | public string NextPageId { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Entities/MailTemplateEntity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Entities 5 | { 6 | using System.Runtime.Serialization; 7 | using NotificationService.Contracts.Models; 8 | using Azure.Data.Tables; 9 | 10 | /// 11 | /// Mail template entity. 12 | /// 13 | [DataContract] 14 | public class MailTemplateEntity : TableEntityBase 15 | { 16 | /// 17 | /// Gets or sets the template name. 18 | /// 19 | [DataMember(Name = "TemplateId")] 20 | public string TemplateId { get; set; } 21 | 22 | /// 23 | /// Gets or sets the template description. 24 | /// 25 | [DataMember(Name = "Description")] 26 | public string Description { get; set; } 27 | 28 | /// 29 | /// Gets or sets the template content. 30 | /// 31 | [DataMember(Name = "Content")] 32 | public string Content { get; set; } 33 | 34 | /// 35 | /// Gets or sets the template type. 36 | /// 37 | [DataMember(Name = "TemplateType")] 38 | public string TemplateType { get; set; } 39 | 40 | /// 41 | /// Gets or sets Application associated to the mail template item. 42 | /// 43 | [DataMember(Name = "Application")] 44 | public string Application { get; set; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Entities/NotificationAttachmentEntity.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Notification Attachment Entity. 10 | /// 11 | [DataContract] 12 | public class NotificationAttachmentEntity 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | public NotificationAttachmentEntity() 18 | { 19 | this.IsInline = false; 20 | } 21 | 22 | /// 23 | /// Gets or sets the name of the file. 24 | /// 25 | /// 26 | /// The name of the file. 27 | /// 28 | [DataMember(Name = "FileName")] 29 | public string FileName { get; set; } 30 | 31 | /// 32 | /// Gets or sets the file base64. 33 | /// 34 | [DataMember(Name = "FileBase64")] 35 | public string FileBase64 { get; set; } 36 | 37 | /// 38 | /// Gets or sets a value indicating whether this instance is inline. 39 | /// 40 | [DataMember(Name = "IsInline")] 41 | public bool IsInline { get; set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Entities/NotificationAttachmentReference.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Notification Attachment Reference. 10 | /// 11 | [DataContract] 12 | public class NotificationAttachmentReference 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | public NotificationAttachmentReference() 18 | { 19 | this.IsInline = false; 20 | } 21 | 22 | /// 23 | /// Gets or sets the name of the file. 24 | /// 25 | /// 26 | /// The name of the file. 27 | /// 28 | [DataMember(Name = "FileName")] 29 | public string FileName { get; set; } 30 | 31 | /// 32 | /// Gets or sets the file base64. 33 | /// 34 | [DataMember(Name = "FileReference")] 35 | public string FileReference { get; set; } 36 | 37 | /// 38 | /// Gets or sets a value indicating whether this instance is inline. 39 | /// 40 | [DataMember(Name = "IsInline")] 41 | public bool IsInline { get; set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Entities/NotificationItemStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | /// 7 | /// Status of a Notification Item. 8 | /// 9 | public enum NotificationItemStatus 10 | { 11 | /// 12 | /// Queued 13 | /// 14 | Queued, 15 | 16 | /// 17 | /// Processing 18 | /// 19 | Processing, 20 | 21 | /// 22 | /// Retrying 23 | /// 24 | Retrying, 25 | 26 | /// 27 | /// Failed 28 | /// 29 | Failed, 30 | 31 | /// 32 | /// Sent 33 | /// 34 | Sent, 35 | 36 | /// 37 | /// If MailOn is false, notification is considered as fake 38 | /// 39 | FakeMail, 40 | 41 | /// 42 | /// Invalid Notification. 43 | /// 44 | Invalid, 45 | 46 | /// 47 | /// Not Queued. 48 | /// 49 | NotQueued, 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Extensions/GraphResponseExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | /// 7 | /// Extensions of . 8 | /// 9 | public static class GraphResponseExtensions 10 | { 11 | /// 12 | /// Converts to . 13 | /// 14 | /// Graph Response. 15 | /// . 16 | public static NotificationBatchItemResponse ToNotificationBatchItemResponse(this GraphResponse graphResponse) => new NotificationBatchItemResponse() 17 | { 18 | NotificationId = graphResponse?.Id, 19 | Status = graphResponse.Status, 20 | Error = graphResponse?.Body?.Error?.Messsage, 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // This file is used by Code Analysis to maintain SuppressMessage 5 | // attributes that are applied to this project. 6 | // Project-level suppressions either have no target or are given 7 | // a specific target and scoped to a namespace, type, member, etc. 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | [assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Required for deserialization purpose.", Scope = "member", Target = "~P:NotificationService.Contracts.ApplicationAccounts.Accounts")] 11 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/AccountCredential.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | /// 7 | /// Account Credential. 8 | /// 9 | public class AccountCredential 10 | { 11 | /// 12 | /// Gets or sets the Account Name. 13 | /// 14 | public string AccountName { get; set; } 15 | 16 | /// 17 | /// Gets or sets the Primary Password of Account. 18 | /// 19 | public string PrimaryPassword { get; set; } 20 | 21 | /// 22 | /// Gets or sets the Secondary Password of Account. 23 | /// 24 | public string SecondaryPassword { get; set; } 25 | 26 | /// 27 | /// Gets or sets a value indicating whether this account is available for use or not. 28 | /// 29 | public bool IsEnabled { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/ApplicationAccounts.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | /// 10 | /// Mapping of Application to Accounts. 11 | /// 12 | public class ApplicationAccounts 13 | { 14 | /// 15 | /// Gets or sets Application Name. 16 | /// 17 | public string ApplicationName { get; set; } 18 | 19 | /// 20 | /// Gets or sets Valid App IDs associated to the application. 21 | /// 22 | public string ValidAppIds { get; set; } 23 | 24 | /// 25 | /// Gets the valid App Ids list associated to the application. 26 | /// 27 | public IList ValidAppIdsList => SplitToList(this.ValidAppIds); 28 | 29 | /// 30 | /// Gets or sets Accounts mapped to the Application. 31 | /// 32 | public List Accounts { get; set; } 33 | 34 | /// 35 | /// Gets or sets Email address which shall be set in the From address of the notifications. 36 | /// 37 | public string FromOverride { get; set; } 38 | 39 | /// 40 | /// Converts a comma-seperated string to a list of strings. 41 | /// 42 | /// String to be split. 43 | /// List of strings. 44 | private static IList SplitToList(string valuesAsSingleString) 45 | { 46 | var values = new List(); 47 | 48 | if (!string.IsNullOrWhiteSpace(valuesAsSingleString)) 49 | { 50 | values.AddRange(valuesAsSingleString.Split(Common.ApplicationConstants.SplitCharacter).Select(v => v.Trim())); 51 | } 52 | 53 | return values; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/EmailAddress.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.ComponentModel.DataAnnotations; 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Runtime.Serialization; 9 | 10 | /// 11 | /// Email Address wrapper entity for MS Graph. 12 | /// 13 | [ExcludeFromCodeCoverage] 14 | [DataContract] 15 | public class EmailAddress 16 | { 17 | /// 18 | /// Gets or sets email address. 19 | /// 20 | [DataMember(Name = "address")] 21 | [Required(ErrorMessage = "Email address is mandatory for recipient of email notifications.")] 22 | public string Address { get; set; } 23 | 24 | /// 25 | /// Gets or sets name of the person associated to the email address. 26 | /// 27 | [DataMember(Name = "name")] 28 | public string Name { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/EmailMessagePayload.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Payload to be sent to Graph API to send an email message. 10 | /// 11 | [DataContract] 12 | public class EmailMessagePayload 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// Email message to be sent to graph. 18 | public EmailMessagePayload(EmailMessage emailMessage) 19 | { 20 | this.Message = emailMessage; 21 | } 22 | 23 | /// 24 | /// Gets or sets the message to be sent to Graph. 25 | /// 26 | [DataMember(Name = "message", IsRequired = true)] 27 | public EmailMessage Message { get; set; } 28 | 29 | /// 30 | /// Gets or sets a value indicating whether the email message is saved in Sent items folder. 31 | /// 32 | [DataMember(Name = "saveToSentItems", IsRequired = false)] 33 | public bool SaveToSentItems { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/FileAttachment.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Diagnostics.CodeAnalysis; 7 | using System.Runtime.Serialization; 8 | 9 | /// 10 | /// File Attachment of MS Graph Message. 11 | /// 12 | [ExcludeFromCodeCoverage] 13 | [DataContract] 14 | public class FileAttachment 15 | { 16 | /// 17 | /// Gets the attachment type. 18 | /// 19 | [DataMember(Name = "@odata.type")] 20 | public string Type { get; } = "#microsoft.graph.fileAttachment"; 21 | 22 | /// 23 | /// Gets or sets base-64 encoded contents of the file. 24 | /// 25 | [DataMember(Name = "contentBytes", IsRequired = true)] 26 | public string ContentBytes { get; set; } 27 | 28 | /// 29 | /// Gets or sets name of the file. 30 | /// 31 | [DataMember(Name = "name", IsRequired = true)] 32 | public string Name { get; set; } 33 | 34 | /// 35 | /// Gets or sets a value indicating whether this an inline attachment or not. 36 | /// 37 | [DataMember(Name = "isInline", IsRequired = false)] 38 | public bool IsInline { get; set; } = false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/GraphBatchRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Collections.Generic; 7 | using System.ComponentModel.DataAnnotations; 8 | using System.Runtime.Serialization; 9 | 10 | /// 11 | /// Batch request to Graph API. 12 | /// 13 | [DataContract] 14 | public class GraphBatchRequest 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | public GraphBatchRequest() 20 | { 21 | this.Requests = new List(); 22 | } 23 | 24 | /// 25 | /// Gets or sets list of requests in Batch. 26 | /// 27 | [DataMember(Name = "requests")] 28 | [Required(ErrorMessage = "Requests collection is mandatory for graph batch request.")] 29 | public List Requests { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/GraphBatchResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Collections.Generic; 7 | using System.ComponentModel.DataAnnotations; 8 | using System.Diagnostics.CodeAnalysis; 9 | using System.Runtime.Serialization; 10 | 11 | /// 12 | /// Batch response from Graph API. 13 | /// 14 | [ExcludeFromCodeCoverage] 15 | [DataContract] 16 | public class GraphBatchResponse 17 | { 18 | /// 19 | /// Gets or sets responses for the requests in Batch. 20 | /// 21 | [DataMember(Name = "responses")] 22 | [Required(ErrorMessage = "Responses collection is mandatory for graph batch response.")] 23 | public List Responses { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/GraphRequest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.ComponentModel.DataAnnotations; 7 | using System.Runtime.Serialization; 8 | 9 | /// 10 | /// Http request to Graph API. 11 | /// 12 | [DataContract] 13 | public class GraphRequest 14 | { 15 | /// 16 | /// Gets or sets unique identifier of the request. 17 | /// 18 | [DataMember(Name = "id")] 19 | [Required(ErrorMessage = "Unique identifier is mandatory for graph request in batch.")] 20 | public string Id { get; set; } 21 | 22 | /// 23 | /// Gets or sets verb of the Http Request. 24 | /// 25 | [DataMember(Name = "method")] 26 | [Required(ErrorMessage = "Method/Verb is mandatory for graph request in batch.")] 27 | public string Method { get; set; } 28 | 29 | /// 30 | /// Gets or sets url of the Http Request. 31 | /// 32 | [DataMember(Name = "url")] 33 | [Required(ErrorMessage = "Url is mandatory for graph request in batch.")] 34 | public string Url { get; set; } 35 | 36 | /// 37 | /// Gets or sets body of the Http Request. 38 | /// 39 | [DataMember(Name = "body")] 40 | public object Body { get; set; } 41 | 42 | /// 43 | /// Gets or sets headers for the Http Request. 44 | /// 45 | [DataMember(Name = "headers")] 46 | public GraphRequestHeaders Headers { get; set; } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/GraphRequestHeaders.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Headers of Http request to Graph API. 10 | /// 11 | [DataContract] 12 | public class GraphRequestHeaders 13 | { 14 | /// 15 | /// Gets or sets content type of the body of Http request. 16 | /// 17 | [DataMember(Name = "Content-Type")] 18 | public string ContentType { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/GraphResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.ComponentModel.DataAnnotations; 7 | using System.Net; 8 | using System.Runtime.Serialization; 9 | 10 | /// 11 | /// Http response from Graph API. 12 | /// 13 | [DataContract] 14 | public class GraphResponse 15 | { 16 | /// 17 | /// Gets or sets unique identifier of the associated request. 18 | /// 19 | [DataMember(Name = "id")] 20 | [Required(ErrorMessage = "Unique identifier is mandatory for graph response in batch.")] 21 | public string Id { get; set; } 22 | 23 | /// 24 | /// Gets or sets status code of the Http Response. 25 | /// 26 | [DataMember(Name = "status")] 27 | [Required(ErrorMessage = "Status is mandatory for graph request in batch.")] 28 | public HttpStatusCode Status { get; set; } 29 | 30 | /// 31 | /// Gets or sets body of the Http Response. 32 | /// 33 | [DataMember(Name = "body")] 34 | public GraphResponseBody Body { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/GraphResponseBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.ComponentModel.DataAnnotations; 7 | using System.Runtime.Serialization; 8 | 9 | /// 10 | /// Body of Http response from Graph API. 11 | /// 12 | [DataContract] 13 | public class GraphResponseBody 14 | { 15 | /// 16 | /// Gets or sets error details if the associated request failed. 17 | /// 18 | [DataMember(Name = "error")] 19 | [Required(ErrorMessage = "Error is mandatory for graph response body.")] 20 | public GraphResponseError Error { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/GraphResponseError.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.ComponentModel.DataAnnotations; 7 | using System.Runtime.Serialization; 8 | 9 | /// 10 | /// Error details of Http response from Graph API. 11 | /// 12 | [DataContract] 13 | public class GraphResponseError 14 | { 15 | /// 16 | /// Gets or sets error code. 17 | /// 18 | [DataMember(Name = "code")] 19 | [Required(ErrorMessage = "Code is mandatory for graph error response in batch.")] 20 | public string Code { get; set; } 21 | 22 | /// 23 | /// Gets or sets error message. 24 | /// 25 | [DataMember(Name = "message")] 26 | [Required(ErrorMessage = "Message is mandatory for graph error response in batch.")] 27 | public string Messsage { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/ImportanceType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// ImportanceType Enum. 10 | /// 11 | [DataContract] 12 | public enum ImportanceType 13 | { 14 | /// 15 | /// ImportanceType Low. 16 | /// 17 | [EnumMember(Value = "low")] 18 | Low, 19 | 20 | /// 21 | /// ImportanceType Normal. 22 | /// 23 | [EnumMember(Value = "normal")] 24 | Normal, 25 | 26 | /// 27 | /// ImportanceType High. 28 | /// 29 | [EnumMember(Value = "high")] 30 | High, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/Address.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Location Address Model for Invite. 10 | /// 11 | [DataContract] 12 | public class Address 13 | { 14 | /// 15 | /// Gets or Sets Street. 16 | /// 17 | [DataMember(Name = "street")] 18 | public string Street { get; set; } 19 | 20 | /// 21 | /// Gets or Sets City. 22 | /// 23 | [DataMember(Name = "city")] 24 | public string City { get; set; } 25 | 26 | /// 27 | /// Gets or Sets State. 28 | /// 29 | [DataMember(Name = "state")] 30 | public string State { get; set; } 31 | 32 | /// 33 | /// Gets or Sets CountryOrRegion. 34 | /// 35 | [DataMember(Name = "countryOrRegion")] 36 | public string CountryOrRegion { get; set; } 37 | 38 | /// 39 | /// Gets or Sets PostalCode. 40 | /// 41 | [DataMember(Name = "postalCode")] 42 | public string PostalCode { get; set; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/Attendee.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Attendee Model for invite. 10 | /// 11 | [DataContract] 12 | public class Attendee 13 | { 14 | /// 15 | /// Gets or Sets EmailAddress. 16 | /// 17 | [DataMember(Name = "emailAddress", IsRequired = true)] 18 | public EmailAddress EmailAddress { get; set; } 19 | 20 | /// 21 | /// Gets or Sets Attendee Type. 22 | /// 23 | [DataMember(Name = "type")] 24 | public AttendeeType Type { get; set; } = AttendeeType.Optional; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/AttendeeType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// AttendeeType Enum. 10 | /// 11 | [DataContract] 12 | public enum AttendeeType 13 | { 14 | /// 15 | /// AttendeeType Required. 16 | /// 17 | [EnumMember(Value = "required")] 18 | Required, 19 | 20 | /// 21 | /// AttendeeType Optional 22 | /// 23 | [EnumMember(Value = "optional")] 24 | Optional, 25 | 26 | /// 27 | /// AttendeeType Resource. 28 | /// 29 | [EnumMember(Value = "resource")] 30 | Resource, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/DayOfTheWeek.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// DayOfTheWeek Enum. 10 | /// 11 | [DataContract] 12 | public enum DayOfTheWeek 13 | { 14 | /// 15 | /// DayOfTheWeek Sunday. 16 | /// 17 | [EnumMember(Value = "sunday")] 18 | Sunday, 19 | 20 | /// 21 | /// DayOfTheWeek Sunday. 22 | /// 23 | [EnumMember(Value = "monday")] 24 | Monday, 25 | 26 | /// 27 | /// DayOfTheWeek Sunday. 28 | /// 29 | [EnumMember(Value = "tuesday")] 30 | Tuesday, 31 | 32 | /// 33 | /// DayOfTheWeek Sunday. 34 | /// 35 | [EnumMember(Value = "wednesday")] 36 | Wednesday, 37 | 38 | /// 39 | /// DayOfTheWeek Sunday. 40 | /// 41 | [EnumMember(Value = "thursday")] 42 | Thursday, 43 | 44 | /// 45 | /// DayOfTheWeek Sunday. 46 | /// 47 | [EnumMember(Value = "friday")] 48 | Friday, 49 | 50 | /// 51 | /// DayOfTheWeek Sunday. 52 | /// 53 | [EnumMember(Value = "saturday")] 54 | Saturday, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/InviteDateTime.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// InviteDateTime Model. 10 | /// 11 | [DataContract] 12 | public class InviteDateTime 13 | { 14 | /// 15 | /// Gets or Sets Datetime in format ("2017-04-15T12:00:00"). 16 | /// 17 | [DataMember(Name = "dateTime", IsRequired = true)] 18 | public string DateTime { get; set; } 19 | 20 | /// 21 | /// Gets or Sets Timezone in decriptive formate like ("Pacific Standard Time"). 22 | /// 23 | [DataMember(Name = "timeZone")] 24 | public InviteTimeZone TimeZone { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/InviteResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Invite Response Model. 10 | /// 11 | [DataContract] 12 | public class InviteResponse 13 | { 14 | /// 15 | /// Gets or Sets Even Id for the invite Request. 16 | /// 17 | [DataMember(Name = "id")] 18 | public string EventId { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/InviteTimeZone.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// InviteTimeZone Enum. 10 | /// 11 | [DataContract] 12 | public enum InviteTimeZone 13 | { 14 | /// 15 | /// InviteTimeZone UTC. 16 | /// 17 | [EnumMember(Value = "UTC")] 18 | UTC, 19 | 20 | /// 21 | /// InviteTimeZone PST. 22 | /// 23 | [EnumMember(Value = "Pacific Standard Time")] 24 | PST, 25 | 26 | /// 27 | /// InviteTimeZone IST. 28 | /// 29 | [EnumMember(Value = "India Standard Time")] 30 | IST, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/Location.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Location Model for invite. 10 | /// 11 | [DataContract] 12 | public class Location 13 | { 14 | /// 15 | /// Gets or Sets DisplayName. 16 | /// 17 | [DataMember(Name = "displayName")] 18 | public string DisplayName { get; set; } 19 | 20 | /// 21 | /// Gets or Sets Locationtype. 22 | /// 23 | [DataMember(Name = "locationType")] 24 | public LocationType LocationType { get; set; } 25 | 26 | /// 27 | /// Gets or Sets Address. 28 | /// 29 | [DataMember(Name = "Address")] 30 | public Address Address { get; set; } 31 | 32 | /// 33 | /// Gets or Sets LocationEmailAddress. 34 | /// 35 | [DataMember(Name = "locationEmailAddress")] 36 | public string LocationEmailAddress { get; set; } 37 | 38 | /// 39 | /// Gets or Sets LocationUri. 40 | /// 41 | [DataMember(Name = "locationUri")] 42 | public string LocationUri { get; set; } 43 | 44 | /// 45 | /// Gets or Sets UniqueId. 46 | /// 47 | [DataMember(Name = "uniqueId")] 48 | public string UniqueId { get; set; } 49 | 50 | /// 51 | /// Gets or Sets UniqueType. 52 | /// 53 | [DataMember(Name = "uniqueIdType")] 54 | public string UniqueType { get; set; } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/LocationType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// LocationType Enum. 10 | /// 11 | [DataContract] 12 | public enum LocationType 13 | { 14 | /// 15 | /// LocationType Default. 16 | /// 17 | [EnumMember(Value = "default")] 18 | Default, 19 | 20 | /// 21 | /// LocationType ConferenceRoom. 22 | /// 23 | [EnumMember(Value = "conferenceRoom")] 24 | ConferenceRoom, 25 | 26 | /// 27 | /// LocationType HomeAddress. 28 | /// 29 | [EnumMember(Value = "homeAddress")] 30 | HomeAddress, 31 | 32 | /// 33 | /// LocationType BusinessAddress. 34 | /// 35 | [EnumMember(Value = "businessAddress")] 36 | BusinessAddress, 37 | 38 | /// 39 | /// LocationType GeoCoordinates. 40 | /// 41 | [EnumMember(Value = "geoCoordinates")] 42 | GeoCoordinates, 43 | 44 | /// 45 | /// LocationType PostalAddress. 46 | /// 47 | [EnumMember(Value = "postalAddress")] 48 | PostalAddress, 49 | 50 | /// 51 | /// LocationType LocalBusiness. 52 | /// 53 | [EnumMember(Value = "localBusiness")] 54 | LocalBusiness, 55 | 56 | /// 57 | /// LocationType Hotel. 58 | /// 59 | [EnumMember(Value = "hotel")] 60 | Hotel, 61 | 62 | /// 63 | /// LocationType Restaurant. 64 | /// 65 | [EnumMember(Value = "restaurant")] 66 | Restaurant, 67 | 68 | /// 69 | /// LocationType StreetAddress. 70 | /// 71 | [EnumMember(Value = "streetAddress")] 72 | StreetAddress, 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/OnlineMeetingInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Collections.Generic; 7 | using System.Runtime.Serialization; 8 | 9 | /// 10 | /// OnlineMeetinInfo Model. 11 | /// 12 | [DataContract] 13 | public class OnlineMeetingInfo 14 | { 15 | /// 16 | /// Gets or Sets ConferenceId. 17 | /// 18 | [DataMember(Name = "conferenceId")] 19 | public string ConferenceId { get; set; } 20 | 21 | /// 22 | /// Gets or Sets JoinUrl. 23 | /// 24 | [DataMember(Name = "joinUrl")] 25 | public string JoinUrl { get; set; } 26 | 27 | /// 28 | /// Gets or Sets Phones. 29 | /// 30 | [DataMember(Name = "phones")] 31 | public IList Phones { get; set; } 32 | 33 | /// 34 | /// Gets or Sets QuickDial. 35 | /// 36 | [DataMember(Name = "quickDial")] 37 | public string QuickDial { get; set; } 38 | 39 | /// 40 | /// Gets or Sets TollFreeNumbers. 41 | /// 42 | [DataMember(Name = "tollFreeNumbers")] 43 | public IList TollFreeNumbers { get; set; } 44 | 45 | /// 46 | /// Gets or Sets TollNumber. 47 | /// 48 | [DataMember(Name = "tollNumber")] 49 | public string TollNumber { get; set; } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/OnlineMeetingProviderType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// OnlineMeetingProviderType Model. 10 | /// 11 | [DataContract] 12 | public enum OnlineMeetingProviderType 13 | { 14 | /// 15 | /// OnlineMeetingProviderType TeamsForBusiness. 16 | /// 17 | [EnumMember(Value = "teamsForBusiness")] 18 | TeamsForBusiness, 19 | 20 | /// 21 | /// OnlineMeetingProviderType SkypeForBusiness. 22 | /// 23 | [EnumMember(Value = "skypeForBusiness")] 24 | SkypeForBusiness, 25 | 26 | /// 27 | /// OnlineMeetingProviderType SkypeForConsumer. 28 | /// 29 | [EnumMember(Value = "skypeForConsumer")] 30 | SkypeForConsumer, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/Organizer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Organizer Model. 10 | /// 11 | [DataContract] 12 | public class Organizer 13 | { 14 | /// 15 | /// Gets or Sets EmailAddress. 16 | /// 17 | [DataMember(Name = "emailAddress")] 18 | public EmailAddress EmailAddress { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/Phone.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Phone Model. 10 | /// 11 | [DataContract] 12 | public class Phone 13 | { 14 | /// 15 | /// Gets or Sets Number. 16 | /// 17 | [DataMember(Name = "number")] 18 | public string Number { get; set; } 19 | 20 | /// 21 | /// Gets or Sets PhoneType. 22 | /// 23 | [DataMember(Name = "type")] 24 | public PhoneType Type { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/PhoneType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// PhoneType Enum. 10 | /// 11 | [DataContract] 12 | public enum PhoneType 13 | { 14 | /// 15 | /// PhoneType Home. 16 | /// 17 | [EnumMember(Value = "home")] 18 | Home, 19 | 20 | /// 21 | /// PhoneType Business. 22 | /// 23 | [EnumMember(Value = "business")] 24 | Business, 25 | 26 | /// 27 | /// PhoneType Mobile. 28 | /// 29 | [EnumMember(Value = "mobile")] 30 | Mobile, 31 | 32 | /// 33 | /// PhoneType Other. 34 | /// 35 | [EnumMember(Value = "other")] 36 | Other, 37 | 38 | /// 39 | /// PhoneType Assistant. 40 | /// 41 | [EnumMember(Value = "assistant")] 42 | Assistant, 43 | 44 | /// 45 | /// PhoneType HomeFax. 46 | /// 47 | [EnumMember(Value = "homeFax")] 48 | HomeFax, 49 | 50 | /// 51 | /// PhoneType BusinessFax. 52 | /// 53 | [EnumMember(Value = "businessFax")] 54 | BusinessFax, 55 | 56 | /// 57 | /// PhoneType OtherFax. 58 | /// 59 | [EnumMember(Value = "otherFax")] 60 | OtherFax, 61 | 62 | /// 63 | /// PhoneType Pager. 64 | /// 65 | [EnumMember(Value = "pager")] 66 | Pager, 67 | 68 | /// 69 | /// PhoneType Radio. 70 | /// 71 | [EnumMember(Value = "radio")] 72 | Radio, 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/Recurrence.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Recurrence Model. 10 | /// 11 | [DataContract] 12 | public class Recurrence 13 | { 14 | /// 15 | /// Gets or Sets Pattern. 16 | /// 17 | [DataMember(Name = "pattern")] 18 | public RecurrencePattern Pattern { get; set; } 19 | 20 | /// 21 | /// Gets or Sets Range. 22 | /// 23 | [DataMember(Name = "range")] 24 | public RecurrenceRange Range { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/RecurrencePatternType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// RecurrencePatternType Enum. 10 | /// 11 | [DataContract] 12 | public enum RecurrencePatternType 13 | { 14 | /// 15 | /// RecurrencePatternType Daily. 16 | /// 17 | [EnumMember(Value = "daily")] 18 | Daily, 19 | 20 | /// 21 | /// RecurrencePatternType Weekly. 22 | /// 23 | [EnumMember(Value = "weekly")] 24 | Weekly, 25 | 26 | /// 27 | /// RecurrencePatternType AbsoluteMonthly. 28 | /// 29 | [EnumMember(Value = "absoluteMonthly")] 30 | Monthly, 31 | 32 | /// 33 | /// RecurrencePatternType AbsoluteYearly. 34 | /// 35 | [EnumMember(Value = "absoluteYearly")] 36 | Yearly, 37 | 38 | /// 39 | /// RecurrencePatternType RelativeYealry. 40 | /// 41 | [EnumMember(Value = "relativeYearly")] 42 | RelativeYearly, 43 | 44 | /// 45 | /// RecurrencePatternType RelativeMonthly. 46 | /// 47 | [EnumMember(Value = "relativeMonthly")] 48 | RelativeMonthly, 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/RecurrenceRange.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// RecurrenceRange Model. 10 | /// 11 | [DataContract] 12 | public class RecurrenceRange 13 | { 14 | /// 15 | /// Gets or Sets Type. 16 | /// 17 | [DataMember(Name = "type")] 18 | public RecurrenceRangeType Type { get; set; } 19 | 20 | /// 21 | /// Gets or Sets StartDate in format ("2017-09-04"). 22 | /// 23 | [DataMember(Name = "startDate")] 24 | public string StartDate { get; set; } 25 | 26 | /// 27 | /// Gets or Sets EndDate in format ("2017-09-04"). 28 | /// Required in case the type is "endDate". 29 | /// 30 | [DataMember(Name = "endDate")] 31 | public string EndDate { get; set; } 32 | 33 | /// 34 | /// Gets or Sets NumberOfOccurences. 35 | /// Required in case of type is "numbered". 36 | /// 37 | [DataMember(Name = "numberOfOccurrences")] 38 | public int? NumberOfOccurences { get; set; } 39 | 40 | /// 41 | /// Gets or Sets RecurrenceTimeZone. 42 | /// Required in case of type is "numbered". 43 | /// 44 | [DataMember(Name = "recurrenceTimeZone")] 45 | public int? RecurrenceTimeZone { get; set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Invite/RecurrenceRangeType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Graph.Invite 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// RecurrenceRangeType Enum. 10 | /// 11 | [DataContract] 12 | public enum RecurrenceRangeType 13 | { 14 | /// 15 | /// RecurrenceRangeType Numbered. 16 | /// given number of times the event will occur. 17 | /// 18 | [EnumMember(Value = "numbered")] 19 | Numbered, 20 | 21 | /// 22 | /// RecurrenceRangeType EndDate. 23 | /// ends with enddate. 24 | /// 25 | [EnumMember(Value = "endDate")] 26 | EndDate, 27 | 28 | /// 29 | /// RecurrenceRangeType NoEnd. 30 | /// never end after starting on start Date. 31 | /// 32 | [EnumMember(Value = "noEnd")] 33 | NoEnd, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/MessageBody.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Body of MS Graph Message. 10 | /// 11 | [DataContract] 12 | public class MessageBody 13 | { 14 | /// 15 | /// Gets or sets the content of the message body. 16 | /// 17 | [DataMember(Name = "content", IsRequired = true)] 18 | public string Content { get; set; } 19 | 20 | /// 21 | /// Gets or sets the content type of the message body. 22 | /// 23 | [DataMember(Name = "contentType", IsRequired = false)] 24 | public string ContentType { get; set; } = "Text"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/Recipient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Recipient of the MS Graph message. 10 | /// 11 | [DataContract] 12 | public class Recipient 13 | { 14 | /// 15 | /// Gets or sets email address of the recipient. 16 | /// 17 | [DataMember(Name = "emailAddress", IsRequired = true)] 18 | public EmailAddress EmailAddress { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Graph/SingleValueExtendedProperty.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | /// 7 | /// SingleValueExtendedProperty. 8 | /// 9 | public class SingleValueExtendedProperty 10 | { 11 | /// 12 | /// Gets or sets singleValueExtendedProperty. 13 | /// 14 | public string Id { get; set; } 15 | 16 | /// 17 | /// Gets or sets Value. 18 | /// 19 | public string Value { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/MailTemplate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Mail template contract. 10 | /// 11 | public class MailTemplate 12 | { 13 | /// 14 | /// Gets or sets the template name. 15 | /// 16 | [DataMember(Name = "templateId")] 17 | public string TemplateId { get; set; } 18 | 19 | /// 20 | /// Gets or sets the template description. 21 | /// 22 | [DataMember(Name = "description")] 23 | public string Description { get; set; } 24 | 25 | /// 26 | /// Gets or sets the template content. 27 | /// 28 | [DataMember(Name = "content")] 29 | public string Content { get; set; } 30 | 31 | /// 32 | /// Gets or sets the template type. 33 | /// 34 | [DataMember(Name = "templateType")] 35 | public string TemplateType { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/MailTemplateInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | 8 | /// 9 | /// Mail template Information. 10 | /// 11 | public class MailTemplateInfo 12 | { 13 | /// 14 | /// Gets or sets the template name. 15 | /// 16 | [DataMember(Name = "templateId")] 17 | public string TemplateId { get; set; } 18 | 19 | /// 20 | /// Gets or sets the template description. 21 | /// 22 | [DataMember(Name = "description")] 23 | public string Description { get; set; } 24 | 25 | /// 26 | /// Gets or sets the template type. 27 | /// 28 | [DataMember(Name = "templateType")] 29 | public string TemplateType { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/NotificationAttachment.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.ComponentModel.DataAnnotations; 7 | using System.Runtime.Serialization; 8 | 9 | /// 10 | /// Attachment to a notification item. 11 | /// 12 | [DataContract] 13 | public class NotificationAttachment 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public NotificationAttachment() 19 | { 20 | this.IsInline = false; 21 | } 22 | 23 | /// 24 | /// Gets or sets the name of the file. 25 | /// 26 | /// 27 | /// The name of the file. 28 | /// 29 | [DataMember(Name = "fileName")] 30 | [Required(ErrorMessage = "File name is mandatory for notification attachment.")] 31 | public string FileName { get; set; } 32 | 33 | /// 34 | /// Gets or sets the file base64. 35 | /// 36 | [DataMember(Name = "fileBase64")] 37 | [Required(ErrorMessage = "Base64 content is mandatory for notification attachment.")] 38 | public string FileBase64 { get; set; } 39 | 40 | /// 41 | /// Gets or sets a value indicating whether this instance is inline. 42 | /// 43 | [DataMember(Name = "isInline")] 44 | public bool IsInline { get; set; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/NotificationBatchItemResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Net; 7 | using System.Runtime.Serialization; 8 | 9 | /// 10 | /// Response to the Send Batch Item Notification Requests. 11 | /// 12 | [DataContract] 13 | public class NotificationBatchItemResponse 14 | { 15 | /// 16 | /// Gets or sets Notification Id. 17 | /// 18 | [DataMember(Name = "NotificationId")] 19 | public string NotificationId { get; set; } 20 | 21 | /// 22 | /// Gets or sets Status. 23 | /// 24 | [DataMember(Name = "Status")] 25 | public HttpStatusCode Status { get; set; } 26 | 27 | /// 28 | /// Gets or sets Error details if the item failed to be sent. 29 | /// 30 | [DataMember(Name = "Error")] 31 | public string Error { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/NotificationItemBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System; 7 | using System.ComponentModel.DataAnnotations; 8 | using System.Runtime.Serialization; 9 | 10 | /// 11 | /// Base class for Notification Items. 12 | /// 13 | [DataContract] 14 | public abstract class NotificationItemBase 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | protected NotificationItemBase() 20 | { 21 | this.SendOnUtcDate = DateTime.UtcNow; 22 | } 23 | 24 | /// 25 | /// Gets or sets the Notification Id. 26 | /// 27 | public string NotificationId { get; set; } 28 | 29 | /// 30 | /// Gets the type of the notify. 31 | /// 32 | [DataMember(Name = "notifType")] 33 | [Required(ErrorMessage = "Notification type is mandatory for a notification.")] 34 | public abstract NotificationType NotifyType { get; } 35 | 36 | /// 37 | /// Gets or sets the send/received on UTC date. 38 | /// 39 | [DataMember(Name = "sendOnUtcDate")] 40 | public DateTime SendOnUtcDate { get; set; } 41 | 42 | /// 43 | /// Gets or sets the TrackingId. 44 | /// 45 | [DataMember(Name = "trackingId")] 46 | public string TrackingId { get; set; } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/NotificationResponse.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | using System.Runtime.Serialization; 7 | using System.Text.Json.Serialization; 8 | 9 | /// 10 | /// Response to the Send Notification Requests. 11 | /// 12 | [DataContract] 13 | public class NotificationResponse 14 | { 15 | /// 16 | /// Gets or sets Notification Id. 17 | /// 18 | [DataMember(Name = "NotificationId")] 19 | public string NotificationId { get; set; } 20 | 21 | /// 22 | /// Gets or sets Tracking Id. 23 | /// 24 | [DataMember(Name = "TrackingId")] 25 | public string TrackingId { get; set; } 26 | 27 | /// 28 | /// Gets or sets Status. 29 | /// 30 | [DataMember(Name = "Status")] 31 | [JsonConverter(typeof(JsonStringEnumConverter))] 32 | public NotificationItemStatus Status { get; set; } 33 | 34 | /// 35 | /// Gets or sets ErrorMessage, if notification failed. 36 | /// 37 | [DataMember(Name = "ErrorMessage")] 38 | public string ErrorMessage { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/QueueNotificationItem.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts 5 | { 6 | /// 7 | /// Contract for the notification item in the queue. 8 | /// 9 | public class QueueNotificationItem 10 | { 11 | /// 12 | /// Gets or sets unique identifiers of the notification items. 13 | /// 14 | #pragma warning disable CA1819 // Properties should not return arrays 15 | public string[] NotificationIds { get; set; } 16 | #pragma warning restore CA1819 // Properties should not return arrays 17 | 18 | /// 19 | /// Gets or sets the name of application associate to the notification item. 20 | /// 21 | public string Application { get; set; } 22 | 23 | /// 24 | /// Gets or sets the type of the notification item - email or meeting invite. 25 | /// 26 | public NotificationType NotificationType { get; set; } 27 | 28 | /// 29 | /// Gets or sets the correlation identifier. 30 | /// 31 | /// 32 | /// The correlation identifier. 33 | /// 34 | public string CorrelationId { get; set; } 35 | 36 | /// 37 | /// Gets or sets a value indicating whether the IgnoreAlreadySent flag is set. 38 | /// 39 | public bool IgnoreAlreadySent { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Reports/MeetingInviteMessage.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Reports 5 | { 6 | using System.Collections.Generic; 7 | using System.Runtime.Serialization; 8 | 9 | /// 10 | /// MeetingNotification message for reporting. 11 | /// 12 | public class MeetingInviteMessage 13 | { 14 | /// 15 | /// Gets or sets the priority. 16 | /// 17 | [DataMember(Name = "Application")] 18 | public string Application { get; set; } 19 | 20 | /// 21 | /// Gets or sets from. 22 | /// 23 | [DataMember(Name = "from")] 24 | public string From { get; set; } 25 | 26 | /// 27 | /// Gets or sets to. 28 | /// 29 | [DataMember(Name = "requiredAttendees")] 30 | public string RequiredAttendees { get; set; } 31 | 32 | /// 33 | /// Gets or sets the cc. 34 | /// 35 | [DataMember(Name = "optionalAttendees")] 36 | public string OptionalAttendees { get; set; } 37 | 38 | /// 39 | /// Gets or sets the subject. 40 | /// 41 | [DataMember(Name = "subject")] 42 | public string Subject { get; set; } 43 | 44 | /// 45 | /// Gets or sets the body. 46 | /// 47 | [DataMember(Name = "body")] 48 | public string Body { get; set; } 49 | 50 | /// 51 | /// Gets or Sets NotificationId. 52 | /// 53 | [DataMember(Name = "NotificationId")] 54 | public string NotificationId { get; set; } 55 | 56 | /// 57 | /// Gets or sets attachments to the message. 58 | /// 59 | [DataMember(Name = "attachments", IsRequired = false)] 60 | public List Attachments { get; set; } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/Request/DateTimeRange.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models.Request 5 | { 6 | using System; 7 | using System.ComponentModel.DataAnnotations; 8 | using System.Runtime.Serialization; 9 | 10 | /// 11 | /// Model object for getting date range for resend notifications. 12 | /// 13 | public class DateTimeRange 14 | { 15 | /// 16 | /// Gets or Sets Start DateTime. 17 | /// 18 | [Required(ErrorMessage = "StartDate is a mandatory parameter.")] 19 | [DataMember(Name = "startDate")] 20 | public DateTime StartDate { get; set; } 21 | 22 | /// 23 | /// Gets or Sets End DateTime. 24 | /// 25 | [Required(ErrorMessage = "EndDate is a mandatory parameter.")] 26 | [DataMember(Name = "endDate")] 27 | public DateTime EndDate { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/TableEntityBase.cs: -------------------------------------------------------------------------------- 1 | namespace NotificationService.Contracts.Models 2 | { 3 | using Azure; 4 | using Azure.Data.Tables; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | [Serializable] 12 | public class TableEntityBase : ITableEntity 13 | { 14 | public string PartitionKey { get; set; } = ""; 15 | public string RowKey { get; set; } = ""; 16 | public DateTimeOffset? Timestamp { get; set; } 17 | public ETag ETag { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/Models/ValidationResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Contracts.Models 5 | { 6 | /// 7 | /// ValidationResult. 8 | /// 9 | public class ValidationResult 10 | { 11 | /// 12 | /// Gets or sets a value indicating whether this is result. 13 | /// 14 | /// 15 | /// true if validation is successful; otherwise, false. 16 | /// 17 | public bool Result { get; set; } 18 | 19 | /// 20 | /// Gets or sets the message. 21 | /// 22 | /// 23 | /// The message. 24 | /// 25 | public string Message { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Contracts/NotificationService.Contracts.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | False 6 | False 7 | False 8 | 9 | 10 | 11 | true 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | all 22 | runtime; build; native; contentfiles; analyzers; buildtransitive 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/CloudStorage/ICloudStorageClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data 5 | { 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Threading.Tasks; 9 | using Azure.Storage.Queues.Models; 10 | 11 | /// 12 | /// Interface to Azure Cloud Storage. 13 | /// 14 | public interface ICloudStorageClient 15 | { 16 | /// 17 | /// Queues the input messages to the input Cloud Queue. 18 | /// 19 | /// Cloud Queue to which the messages to be pushed. 20 | /// List of messages (serialized) to be queued. 21 | /// (Optional) Time after which the message(s) should appear in Storage queue. 22 | /// A representing the result of the asynchronous operation. 23 | Task QueueCloudMessages(IEnumerable messages); 24 | 25 | /// 26 | /// Uploads the content to the blob. 27 | /// 28 | /// Blob name. 29 | /// Blob content. 30 | /// Blob Uri. 31 | Task UploadBlobAsync(string blobName, string content); 32 | 33 | /// 34 | /// Downloads the content from the blob as a stream. 35 | /// 36 | /// Blob name. 37 | /// Blob content. 38 | Task DownloadBlobAsync(string blobName); 39 | 40 | /// 41 | /// Deletes the blob. 42 | /// 43 | /// Blob name. 44 | /// Returns true if delete suceeded. 45 | Task DeleteBlobsAsync(string blobName); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/CosmosDB/ICosmosDBQueryClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data 5 | { 6 | using System; 7 | using Microsoft.Azure.Cosmos; 8 | 9 | /// 10 | /// Query Client Interface for CosmosDB. 11 | /// 12 | public interface ICosmosDBQueryClient : IDisposable 13 | { 14 | /// 15 | /// Gets an instance of to perform the query operations. 16 | /// 17 | /// Name of the CosmosDB database. 18 | /// Name of the container within the CosmosDB database. 19 | /// . 20 | Container GetCosmosContainer(string databaseName, string containerName); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/Helper/AzureCredentialHelper.cs: -------------------------------------------------------------------------------- 1 | namespace NotificationService.Data.Helper 2 | { 3 | using Azure.Identity; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | public static class AzureCredentialHelper 11 | { 12 | public static readonly bool IsDeployed = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_RUN_FROM_PACKAGE")); 13 | public static readonly DefaultAzureCredential AzureCredentials = GetAzureCredentials(); 14 | 15 | private static DefaultAzureCredential GetAzureCredentials() 16 | { 17 | return new DefaultAzureCredential( 18 | new DefaultAzureCredentialOptions 19 | { 20 | // Prevent deployed instances from trying things that don't work and generally take too long 21 | ExcludeInteractiveBrowserCredential = IsDeployed, 22 | ExcludeVisualStudioCodeCredential = IsDeployed, 23 | ExcludeVisualStudioCredential = IsDeployed, 24 | ExcludeAzureCliCredential = IsDeployed, 25 | ExcludeManagedIdentityCredential = false, 26 | ExcludeEnvironmentCredential = true, 27 | ExcludeWorkloadIdentityCredential = true, 28 | Retry = 29 | { 30 | // Reduce retries and timeouts to get faster failures 31 | MaxRetries = 2, 32 | NetworkTimeout = TimeSpan.FromSeconds(5), 33 | MaxDelay = TimeSpan.FromSeconds(5) 34 | } 35 | } 36 | ); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/Interfaces/IMailTemplateRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data 5 | { 6 | using System.Collections.Generic; 7 | using System.Threading.Tasks; 8 | using NotificationService.Contracts.Entities; 9 | 10 | /// 11 | /// Repository Interface for Email Template Items. 12 | /// 13 | public interface IMailTemplateRepository 14 | { 15 | /// 16 | /// Saves the changes on mail template entities into database. 17 | /// 18 | /// . 19 | /// Sucess or failure. 20 | Task UpsertEmailTemplateEntities(MailTemplateEntity mailTemplateEntity); 21 | 22 | /// 23 | /// Gets the mail template entities from database. 24 | /// 25 | /// Application sourcing the email template. 26 | /// Mail template name. 27 | /// . 28 | Task GetMailTemplate(string applicationName, string templateName); 29 | 30 | /// 31 | /// All template entities from the table for an application would be returned. 32 | /// 33 | /// Application sourcing the email template. 34 | /// list of mail template entities . 35 | Task> GetAllTemplateEntities(string applicationName); 36 | 37 | /// 38 | /// Deletes Email template. 39 | /// 40 | /// Application sourcing the email template. 41 | /// Mail template name. 42 | /// status of delete template. 43 | Task DeleteMailTemplate(string applicationName, string templateName); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/Interfaces/IRepositoryFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data.Interfaces 5 | { 6 | /// 7 | /// Interface for the Repository Type. 8 | /// 9 | public interface IRepositoryFactory 10 | { 11 | /// 12 | /// Gets the Storage provider type to use. 13 | /// 14 | /// Storage provider type. 15 | /// Repository context. 16 | public IEmailNotificationRepository GetRepository(StorageType type); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/Interfaces/StorageType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data 5 | { 6 | /// 7 | /// IDBType. 8 | /// 9 | public enum StorageType 10 | { 11 | /// 12 | /// The asql 13 | /// 14 | ASQL, 15 | 16 | /// 17 | /// The storage account 18 | /// 19 | StorageAccount, 20 | 21 | /// 22 | /// The document database 23 | /// 24 | DocumentDB, 25 | } 26 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/Repositories/CustomCosmosLinqQuery.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data 5 | { 6 | using System.Linq; 7 | using Microsoft.Azure.Cosmos; 8 | using Microsoft.Azure.Cosmos.Linq; 9 | 10 | /// 11 | /// Custom Cosmos Linq Query. 12 | /// 13 | public class CustomCosmosLinqQuery : ICosmosLinqQuery 14 | { 15 | /// 16 | public FeedIterator GetFeedIterator(IQueryable query) 17 | { 18 | return query.ToFeedIterator(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/Repositories/ICosmosLinqQuery.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data 5 | { 6 | using System.Linq; 7 | using Microsoft.Azure.Cosmos; 8 | 9 | /// 10 | /// Custom cosmos Linq Query. 11 | /// 12 | public interface ICosmosLinqQuery 13 | { 14 | /// 15 | /// Gets the Feed Iterator for the input query. 16 | /// 17 | /// Type of entity in query. 18 | /// Query to evaluate. 19 | /// Feed Iterator instance. 20 | FeedIterator GetFeedIterator(IQueryable query); 21 | } 22 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/Repositories/RepositoryFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data.Repositories 5 | { 6 | using System; 7 | using NotificationService.Data.Interfaces; 8 | 9 | /// 10 | /// A factory class to return an instance of CosmosDb repository or Storage Account repository as per argument passed as StorageType. 11 | /// 12 | public class RepositoryFactory : IRepositoryFactory 13 | { 14 | private readonly IServiceProvider serviceProvider; 15 | 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// . 20 | public RepositoryFactory(IServiceProvider serviceProvider) 21 | { 22 | this.serviceProvider = serviceProvider; 23 | } 24 | 25 | /// 26 | /// A factory method for getting Repository instance based on type. 27 | /// 28 | /// StorageType parameter for type decision. 29 | /// . 30 | public IEmailNotificationRepository GetRepository(StorageType type) 31 | { 32 | switch (type) 33 | { 34 | //case StorageType.DocumentDB: 35 | // return (IEmailNotificationRepository)this.serviceProvider.GetService(typeof(EmailNotificationRepository)); 36 | case StorageType.StorageAccount: 37 | return (IEmailNotificationRepository)this.serviceProvider.GetService(typeof(TableStorageEmailRepository)); 38 | default: 39 | return null; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.Data/TableStorage/ITableStorageClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Data 5 | { 6 | using Azure; 7 | using Azure.Data.Tables; 8 | using NotificationService.Contracts.Models; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Threading.Tasks; 12 | 13 | /// 14 | /// Interface to Azure Cloud Storage. 15 | /// 16 | public interface ITableStorageClient 17 | { 18 | TableServiceClient GetTableServiceClient(string storageAccountUri); 19 | TableClient GetTableClient(TableServiceClient tableServiceClient, string tableName); 20 | Task AddOrUpdateAsync(string tableName, T entity) where T : TableEntityBase; 21 | Task AddsOrUpdatesAsync(string tableName, List entity) where T : TableEntityBase; 22 | Task InsertRecordsAsync(string tableName, List records) where T : TableEntityBase; 23 | Task> GetRecordsAsync(string tableName, string filter) where T : TableEntityBase; 24 | Task GetRecordAsync(string tableName, string partitionKey, string rowKey) where T : TableEntityBase; 25 | Task DeleteRecordAsync(string tableName, string partitionKey, string rowKey); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.FunctionalTests/BaseTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.FunctionalTests 5 | { 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using NUnit.Framework; 9 | 10 | /// 11 | /// Base class for all functional tests 12 | /// 13 | 14 | public class BaseTests 15 | { 16 | 17 | protected TokenUtility tokenUtility; 18 | private ServiceProvider serviceProvider; 19 | protected IConfiguration Configuration; 20 | 21 | [SetUp] 22 | protected void SetupTestBase() 23 | { 24 | Configuration = InitConfiguration(); 25 | 26 | var services = new ServiceCollection(); 27 | 28 | _ = services.AddOptions(); 29 | _ = services.AddSingleton(Configuration); 30 | _ = services.AddScoped(); 31 | 32 | serviceProvider = services.BuildServiceProvider(); 33 | 34 | // create a userBusiness object with DI 35 | tokenUtility = serviceProvider.GetRequiredService(); 36 | } 37 | 38 | public static IConfiguration InitConfiguration() 39 | { 40 | 41 | var builder = new ConfigurationBuilder() 42 | .AddJsonFile("appsettings.json"); 43 | 44 | IConfiguration Configuration = builder.Build(); 45 | 46 | 47 | return Configuration; 48 | } 49 | 50 | } 51 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService.FunctionalTests/FunctionalConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.FunctionalTests 5 | { 6 | public static class FunctionalConstants 7 | { 8 | public const string ToAddress = "ToAddress"; 9 | public const string ContentType = "application/json"; 10 | public const string Bearer = "Bearer"; 11 | public const string Application = "Application"; 12 | public const string NotificationServiceUrl = "NotificationServiceUrl"; 13 | public const string NotificationHandlerUrl = "NotificationHandlerUrl"; 14 | public const string RetryCount = "RetryCount"; 15 | public const string Authority = "Authority"; 16 | public const string ClientId = "ClientId"; 17 | public const string ClientSecret = "PlaceholderClientSecret"; 18 | public const string DelayTimeInMilliSeconds = "DelayTimeInMilliSeconds"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.FunctionalTests/NotificationService.FunctionalTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | 6 | false 7 | 8 | False 9 | 10 | False 11 | 12 | False 13 | 14 | 15 | 16 | 17 | PreserveNewest 18 | true 19 | PreserveNewest 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.FunctionalTests/TokenUtility.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.FunctionalTests 5 | { 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Identity.Client; 8 | using System.Threading.Tasks; 9 | 10 | public class TokenUtility 11 | { 12 | private IConfiguration Configuration; 13 | 14 | public TokenUtility(IConfiguration configuration) 15 | { 16 | this.Configuration = configuration; 17 | } 18 | 19 | 20 | public async Task GetTokenAsync() 21 | { 22 | var app = ConfidentialClientApplicationBuilder.Create(this.Configuration[FunctionalConstants.ClientId]) 23 | .WithClientSecret(this.Configuration[FunctionalConstants.ClientSecret]) 24 | .WithAuthority(this.Configuration[FunctionalConstants.Authority]) 25 | .Build(); 26 | 27 | var authResult = await app.AcquireTokenForClient( 28 | new[] { $"{this.Configuration[FunctionalConstants.ClientId]}/.default" }) 29 | .ExecuteAsync() 30 | .ConfigureAwait(false); 31 | return authResult.AccessToken; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.FunctionalTests/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.FunctionalTests/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Application": "__Application__", 3 | "NotificationServiceUrl": "__NotificationServiceUrl__", 4 | "NotificationHandlerUrl": "__NotificationHandlerUrl__", 5 | "ToAddress": "__ToAddress__", 6 | "RetryCount": "__RetryCount__", 7 | "DelayTimeInMilliSeconds": "__DelayTimeInMilliSeconds__", 8 | "Authority": "__Authority__", 9 | "ClientId": "__ClientId__", 10 | "ClientSecret": "__ClientSecret__" // [SuppressMessage("Microsoft.Security", "CS001:SecretInline", Justification="...")] 11 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService.IaaC/NotificationService.IaaC.deployproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | Release 10 | AnyCPU 11 | 12 | 13 | 14 | e15e4c46-c557-4d3c-a69d-04c0e73cb84b 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | False 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.IaaC/cspnotification.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "appName": { 6 | "value": "__appName__" 7 | }, 8 | "storageName": { 9 | "value": "__storageName__" 10 | }, 11 | "location": { 12 | "value": "__location__" 13 | }, 14 | "KeyVaultUrl": { 15 | "value": "__KeyVaultUrl__" 16 | }, 17 | "configStoreName": { 18 | "value": "__configStoreName__" 19 | }, 20 | "NotificationQueueName" : { 21 | "value": "__notificationQueueName__" 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService.LoadTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("NotificationService.LoadTests")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("NotificationService.LoadTests")] 12 | [assembly: AssemblyCopyright("Copyright © 2020")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("1698099c-7635-4e8f-8803-e44b223835c5")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | [assembly: AssemblyVersion("1.0.0.0")] 34 | [assembly: AssemblyFileVersion("1.0.0.0")] 35 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.LoadTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.SvCommon/APIConstants/ClaimTypeConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.SvCommon.APIConstants 5 | { 6 | /// 7 | /// The stores the undefined claim types. 8 | /// 9 | public static class ClaimTypeConstants 10 | { 11 | /// 12 | /// The object identifier claim type. 13 | /// 14 | public const string ObjectIdentifier = "http://schemas.microsoft.com/identity/claims/objectidentifier"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.SvCommon/PolicyRequirements/AppIdAuthorizeRequirement.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.SvCommon 5 | { 6 | using Microsoft.AspNetCore.Authorization; 7 | 8 | /// 9 | /// Authorization Requirement to validate the request with Application Valid Audiences. 10 | /// 11 | public class AppIdAuthorizeRequirement : IAuthorizationRequirement 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.SvCommon/PolicyRequirements/AppNameAuthorizeRequirement.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.SvCommon 5 | { 6 | using Microsoft.AspNetCore.Authorization; 7 | 8 | /// 9 | /// Authorization Requirement to validate if the request contains a valid Application name. 10 | /// 11 | public class AppNameAuthorizeRequirement : IAuthorizationRequirement 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/BusinessLibrary/Providers/MSGraphProviderTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.UnitTests.BusinessLibrary.Providers 5 | { 6 | using System.Net.Http; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.Options; 9 | using Moq; 10 | using NotificationService.Common; 11 | using NotificationService.Common.Logger; 12 | 13 | /// 14 | /// MSGraphProvider Unit Test Class. 15 | /// 16 | public class MSGraphProviderTestBase 17 | { 18 | /// 19 | /// sendEmailUrl private field. 20 | /// 21 | private readonly string sendEmailUrl = "v1/sendEmail"; 22 | 23 | /// 24 | /// Gets Test Application name. 25 | /// 26 | public string ApplicationName => "TestApp"; 27 | 28 | /// 29 | /// Gets or sets MSGraphSetting Configuration Mock. 30 | /// 31 | public IOptions MsGraphSetting { get; set; } 32 | 33 | /// 34 | /// Gets or sets Logger. 35 | /// 36 | public ILogger Logger { get; set; } 37 | 38 | /// 39 | /// Gets or sets Logger. 40 | /// 41 | public Mock MockedHttpClient { get; set; } 42 | 43 | /// 44 | /// Gets or sets Configuration. 45 | /// 46 | public IConfiguration Configuration { get; set; } 47 | 48 | /// 49 | /// Initialize test setup. 50 | /// 51 | protected void SetupTestBase() 52 | { 53 | this.MsGraphSetting = Options.Create(new MSGraphSetting() { EnableBatching = false, SendMailUrl = this.sendEmailUrl, BatchRequestLimit = 4, SendInviteUrl = "v1/events", BaseUrl = "https://graphtest.com/" }); 54 | this.Logger = new Mock().Object; 55 | this.MockedHttpClient = new Mock(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/BusinessLibrary/V1/EmailManager/ResendEmailNotificationsTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.UnitTests.BusinesLibrary.V1.EmailManager 5 | { 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Diagnostics.CodeAnalysis; 9 | using System.Threading.Tasks; 10 | using Azure.Storage.Queues.Models; 11 | 12 | using Moq; 13 | using NotificationService.Contracts; 14 | using NotificationService.UnitTests.BusinessLibrary.V1.EmailManager; 15 | using NUnit.Framework; 16 | 17 | /// 18 | /// Tests for ResendEmailNotifications method of Email Manager. 19 | /// 20 | [ExcludeFromCodeCoverage] 21 | public class ResendEmailNotificationsTests : EmailManagerTestsBase 22 | { 23 | /// 24 | /// Initialization for the tests. 25 | /// 26 | [SetUp] 27 | public void Setup() => this.SetupTestBase(); 28 | 29 | /// 30 | /// Tests for ResendEmailNotifications method for valid inputs. 31 | /// 32 | [Test] 33 | public void ResendEmailNotificationsTestValidInput() 34 | { 35 | Task> result = this.EmailHandlerManager.ResendNotifications(this.ApplicationName, new string[] { Guid.NewGuid().ToString() }); 36 | Assert.AreEqual(result.Status.ToString(), "RanToCompletion"); 37 | this.CloudStorageClient.Verify(csc => csc.QueueCloudMessages(It.IsAny>()), Times.Once); 38 | Assert.Pass(); 39 | } 40 | 41 | /// 42 | /// Tests for ResendEmailNotifications method for invalid inputs. 43 | /// 44 | [Test] 45 | public void ResendEmailNotificationsTestInvalidInput() 46 | { 47 | _ = Assert.ThrowsAsync(async () => await this.EmailHandlerManager.ResendNotifications(null, new string[] { Guid.NewGuid().ToString() })); 48 | _ = Assert.ThrowsAsync(async () => await this.EmailHandlerManager.ResendNotifications(this.ApplicationName, null)); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/Common/Exceptions/NotificationServiceException_Tests/NotificationServiceException_Ctor_Tests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | 5 | namespace NotificationService.UnitTests.Common.Exceptions.NotificationServiceException_Tests 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | using NotificationService.Common.Exceptions; 10 | using NUnit.Framework; 11 | 12 | [ExcludeFromCodeCoverage] 13 | public class NotificationServiceException_Ctor_Tests 14 | { 15 | [Test] 16 | public void Ctor_NoParameters() 17 | { 18 | var ex = new NotificationServiceException(); 19 | Assert.AreEqual(ex.Message, "Something went wrong!"); 20 | } 21 | 22 | [Test] 23 | public void Ctor_ValidMessage() 24 | { 25 | var ex = new NotificationServiceException("Test Message"); 26 | Assert.AreEqual(ex.Message, "Test Message"); 27 | } 28 | 29 | [Test] 30 | public void Ctor_ValidMessageInnerException() 31 | { 32 | var ex = new NotificationServiceException("Test Message", new Exception("Test Exception")); 33 | Assert.AreEqual(ex.Message, "Test Message"); 34 | Assert.AreEqual(ex.InnerException.Message, "Test Exception"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/Data/CloudStorage/CloudStorageClientTest.cs: -------------------------------------------------------------------------------- 1 | namespace NotificationService.UnitTests.Data.CloudStorage 2 | { 3 | using Azure; 4 | using Azure.Storage.Blobs; 5 | using Azure.Storage.Blobs.Models; 6 | using Moq; 7 | using NotificationService.Common.Encryption; 8 | using NotificationService.Common; 9 | using NotificationService.Contracts; 10 | using NotificationService.Data; 11 | using NotificationService.Data.Repositories; 12 | using NUnit.Framework; 13 | using System; 14 | using System.Collections.Generic; 15 | using System.IO; 16 | using System.Linq; 17 | using System.Text; 18 | using System.Threading; 19 | using System.Threading.Tasks; 20 | 21 | public class CloudStorageClientTest : CloudStorageClientSetup 22 | { 23 | public Mock EncryptionService { get; set; } 24 | 25 | /// 26 | /// Tests for GetBlobClientBlobServiceClientRefTest method for valid inputs. 27 | /// 28 | [Test] 29 | public void GetBlobClientBlobServiceClientRefTest() 30 | { 31 | var test = SUT.GetBlobServiceClient(this.storageAccountSetting.Value); 32 | Assert.IsNotNull(test.AccountName); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/Data/Repositories/EmailNotificationRepository/CreateEmailNotificationItemEntitiesTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.UnitTests.Data.Repositories 5 | { 6 | using System; 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Threading; 9 | using Moq; 10 | using NotificationService.Contracts; 11 | using NUnit.Framework; 12 | 13 | /// 14 | /// Tests for CreateEmailNotificationItemEntities method of Email Notification Repository. 15 | /// 16 | [ExcludeFromCodeCoverage] 17 | public class CreateEmailNotificationItemEntitiesTests : EmailNotificationRepositoryTestsBase 18 | { 19 | /// 20 | /// Initialization for the tests. 21 | /// 22 | [SetUp] 23 | public void Setup() => this.SetupTestBase(); 24 | 25 | /// 26 | /// Tests for CreateEmailNotificationItemEntities method for invalid inputs. 27 | /// 28 | [Test] 29 | public void CreateEmailNotificationItemEntitiesTestInvalidInput() 30 | { 31 | _ = Assert.ThrowsAsync(async () => await this.EmailNotificationRepository.CreateEmailNotificationItemEntities(null)); 32 | } 33 | 34 | /// 35 | /// Tests for CreateEmailNotificationItemEntities method for valid inputs. 36 | /// 37 | [Test] 38 | public void CreateEmailNotificationItemEntitiesTestValidInput() 39 | { 40 | var result = this.EmailNotificationRepository.CreateEmailNotificationItemEntities(this.NotificationEntities); 41 | Assert.AreEqual(result.Status.ToString(), "RanToCompletion"); 42 | this.CosmosDBQueryClient.Verify(cdq => cdq.GetCosmosContainer(It.IsAny(), this.MailHistoryContainerName), Times.Once); 43 | this.EmailHistoryContainer.Verify(container => container.CreateItemAsync(It.IsAny(), null, null, It.IsAny()), Times.Exactly(2)); 44 | Assert.Pass(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/Data/Repositories/EmailNotificationRepository/UpdateEmailNotificationItemEntitiesTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.UnitTests.Data.Repositories 5 | { 6 | using System; 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Threading; 9 | using Moq; 10 | using NotificationService.Contracts; 11 | using NUnit.Framework; 12 | 13 | /// 14 | /// Tests for UpdateEmailNotificationItemEntities method of Email Notification Repository. 15 | /// 16 | [ExcludeFromCodeCoverage] 17 | public class UpdateEmailNotificationItemEntitiesTests : EmailNotificationRepositoryTestsBase 18 | { 19 | /// 20 | /// Initialization for the tests. 21 | /// 22 | [SetUp] 23 | public void Setup() => this.SetupTestBase(); 24 | 25 | /// 26 | /// Tests for UpdateEmailNotificationItemEntities method for invalid inputs. 27 | /// 28 | [Test] 29 | public void UpdateEmailNotificationItemEntitiesTestInvalidInput() 30 | { 31 | _ = Assert.ThrowsAsync(async () => await this.EmailNotificationRepository.UpdateEmailNotificationItemEntities(null)); 32 | } 33 | 34 | /// 35 | /// Tests for UpdateEmailNotificationItemEntities method for valid inputs. 36 | /// 37 | [Test] 38 | public void UpdateEmailNotificationItemEntitiesTestValidInput() 39 | { 40 | var result = this.EmailNotificationRepository.UpdateEmailNotificationItemEntities(this.NotificationEntities); 41 | Assert.AreEqual(result.Status.ToString(), "RanToCompletion"); 42 | this.CosmosDBQueryClient.Verify(cdq => cdq.GetCosmosContainer(It.IsAny(), this.MailHistoryContainerName), Times.Once); 43 | this.EmailHistoryContainer.Verify(container => container.UpsertItemAsync(It.IsAny(), null, null, It.IsAny()), Times.Exactly(2)); 44 | Assert.Pass(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This file is used by Code Analysis to maintain SuppressMessage 3 | // attributes that are applied to this project. 4 | // Project-level suppressions either have no target or are given 5 | // a specific target and scoped to a namespace, type, member, etc. 6 | 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | [assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1615:Element return value should be documented", Justification = "Test Project should not follow this rule.", Scope = "member")] 10 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/Mocks/MockNotificationProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.UnitTests.Mocks 5 | { 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Threading.Tasks; 9 | using NotificationService.BusinessLibrary.Interfaces; 10 | using NotificationService.Contracts; 11 | using NotificationService.Contracts.Entities; 12 | 13 | /// 14 | /// Mock Notification Provider Class. 15 | /// 16 | /// 17 | public class MockNotificationProvider : INotificationProvider 18 | { 19 | /// 20 | #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously 21 | public async Task ProcessMeetingNotificationEntities(string applicationName, IList notificationEntities) 22 | #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously 23 | { 24 | foreach (var item in notificationEntities) 25 | { 26 | if (item.RequiredAttendees == "user@contoso.com") 27 | { 28 | item.Status = NotificationItemStatus.Sent; 29 | } 30 | } 31 | } 32 | 33 | /// 34 | public Task ProcessNotificationEntities(string applicationName, IList notificationEntities) => throw new NotImplementedException(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NotificationService/NotificationService.UnitTests/NotificationService.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | 6 | false 7 | 8 | False 9 | 10 | False 11 | 12 | False 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | all 23 | runtime; build; native; contentfiles; analyzers; buildtransitive 24 | 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers; buildtransitive 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /NotificationService/NotificationService/Controllers/v1/RootPingController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationService.Controllers 5 | { 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.Logging; 8 | 9 | /// 10 | /// The Root Ping Controller. 11 | /// 12 | public class RootPingController : Controller 13 | { 14 | /// 15 | /// The instance for . 16 | /// 17 | private readonly ILogger logger; 18 | 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// Constructor for Root Ping Controller. 22 | /// 23 | /// The instance for . 24 | public RootPingController(ILogger logger) 25 | { 26 | this.logger = logger; 27 | } 28 | 29 | /// 30 | /// Generates a success response as a ping. 31 | /// 32 | /// The instance for . 33 | [HttpGet("")] 34 | public IActionResult Ping() 35 | { 36 | this.logger.LogInformation($"Invoked {nameof(this.Ping)} method in {nameof(RootPingController)}."); 37 | return this.Ok(); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base 4 | WORKDIR /app 5 | EXPOSE 80 6 | EXPOSE 443 7 | 8 | FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build 9 | WORKDIR /src 10 | COPY ["NotificationService/NotificationService.csproj", "NotificationService/"] 11 | COPY ["NotificationService.Contracts/NotificationService.Contracts.csproj", "NotificationService.Contracts/"] 12 | COPY ["NotificationService.Common/NotificationService.Common.csproj", "NotificationService.Common/"] 13 | COPY ["NotificationService.BusinessLibrary/NotificationService.BusinessLibrary.csproj", "NotificationService.BusinessLibrary/"] 14 | COPY ["NotificationService.Data/NotificationService.Data.csproj", "NotificationService.Data/"] 15 | COPY ["NotificationService.SvCommon/NotificationService.SvCommon.csproj", "NotificationService.SvCommon/"] 16 | COPY ["NotificationProviders/DirectSend.Core/DirectSend.NetCore.csproj", "NotificationProviders/DirectSend.Core/"] 17 | COPY ["NotificationProviders/DirectSend.Shared/DirectSend.Shared.shproj", "NotificationProviders/DirectSend.Core/"] 18 | RUN dotnet restore "NotificationService/NotificationService.csproj" 19 | COPY . . 20 | WORKDIR "/src/NotificationService" 21 | RUN dotnet build "NotificationService.csproj" -c Release -o /app/build 22 | 23 | FROM build AS publish 24 | RUN dotnet publish "NotificationService.csproj" -c Release -o /app/publish 25 | 26 | FROM base AS final 27 | WORKDIR /app 28 | COPY --from=publish /app/publish . 29 | ENTRYPOINT ["dotnet", "NotificationService.dll"] -------------------------------------------------------------------------------- /NotificationService/NotificationService/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // This file is used by Code Analysis to maintain SuppressMessage 5 | // attributes that are applied to this project. 6 | // Project-level suppressions either have no target or are given 7 | // a specific target and scoped to a namespace, type, member, etc. 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | [assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Startup file method signature is always non-static.", Scope = "member", Target = "~M:NotificationService.Startup.Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder,Microsoft.AspNetCore.Hosting.IWebHostEnvironment)")] 11 | [assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Auto generated code.", Scope = "member", Target = "~M:NotificationService.Startup.#ctor(Microsoft.Extensions.Configuration.IConfiguration)")] 12 | [assembly: SuppressMessage("Design", "CA1052:Static holder types should be Static or NotInheritable", Justification = "Auto generated code.", Scope = "type", Target = "~T:NotificationService.Program")] 13 | [assembly: SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "The model validation will take care of it.", Scope = "member", Target = "~M:NotificationService.Controllers.V1.NotificationsController.PostNotifications(System.String,NotificationService.Contracts.Models.Web.Request.WebNotificationRequestItemsContainer)~System.Threading.Tasks.Task{Microsoft.AspNetCore.Mvc.IActionResult}")] 14 | -------------------------------------------------------------------------------- /NotificationService/NotificationService/Program.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | 5 | namespace NotificationService 6 | { 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Hosting; 9 | using System.Diagnostics.CodeAnalysis; 10 | 11 | /// 12 | /// Starting point of the service. 13 | /// 14 | [ExcludeFromCodeCoverage] 15 | public class Program 16 | { 17 | /// 18 | /// Main entry point for the application start. 19 | /// 20 | /// Arguments. 21 | public static void Main(string[] args) 22 | { 23 | CreateHostBuilder(args).Build().Run(); 24 | } 25 | 26 | /// 27 | /// Creates a web host builder. 28 | /// 29 | /// Arguments. 30 | /// An instance of . 31 | public static IHostBuilder CreateHostBuilder(string[] args) => 32 | Host.CreateDefaultBuilder(args) 33 | .ConfigureWebHostDefaults(webBuilder => 34 | { 35 | _ = webBuilder.UseStartup(); 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /NotificationService/NotificationService/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:53367", 7 | "sslPort": 44300 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "swagger", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "NotificationService": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "swagger", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 33 | "publishAllPorts": true, 34 | "useSSL": true 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /NotificationService/NotificationService/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "KeyVaultConfigRefreshDurationSeconds": "120", 3 | "KeyVaultUrl": "__KeyVaultUrl__" 4 | } -------------------------------------------------------------------------------- /NotificationService/NotificationService/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /NotificationService/NotificationsQueueProcessor/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /NotificationService/NotificationsQueueProcessor/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/azure-functions/dotnet:3.0 AS base 4 | WORKDIR /home/site/wwwroot 5 | EXPOSE 80 6 | 7 | FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build 8 | WORKDIR /src 9 | COPY ["NotificationsQueueProcessor/NotificationsQueueProcessor.csproj", "NotificationsQueueProcessor/"] 10 | COPY ["NotificationService.Common/NotificationService.Common.csproj", "NotificationService.Common/"] 11 | COPY ["NotificationProviders/DirectSend.Core/DirectSend.NetCore.csproj", "NotificationProviders/DirectSend.Core/"] 12 | COPY ["NotificationProviders/DirectSend.Shared/DirectSend.Shared.shproj", "NotificationProviders/DirectSend.Core/"] 13 | RUN dotnet restore "NotificationsQueueProcessor/NotificationsQueueProcessor.csproj" 14 | COPY . . 15 | WORKDIR "/src/NotificationsQueueProcessor" 16 | RUN dotnet build "NotificationsQueueProcessor.csproj" -c Release -o /app/build 17 | 18 | FROM build AS publish 19 | RUN dotnet publish "NotificationsQueueProcessor.csproj" -c Release -o /app/publish 20 | 21 | FROM base AS final 22 | WORKDIR /home/site/wwwroot 23 | COPY --from=publish /app/publish . 24 | ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ 25 | AzureFunctionsJobHost__Logging__Console__IsEnabled=true -------------------------------------------------------------------------------- /NotificationService/NotificationsQueueProcessor/IHttpClientHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace NotificationsQueueProcessor 5 | { 6 | using System.Net.Http; 7 | using System.Threading.Tasks; 8 | 9 | /// 10 | /// IHttpClientHelper. 11 | /// 12 | public interface IHttpClientHelper 13 | { 14 | /// 15 | /// Posts the asynchronous. 16 | /// 17 | /// The URL. 18 | /// The content. 19 | /// A representing the asynchronous operation. 20 | Task PostAsync(string url, HttpContent content); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /NotificationService/NotificationsQueueProcessor/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "NotificationsQueueProcessor": { 4 | "commandName": "Project" 5 | }, 6 | "Docker": { 7 | "commandName": "Docker", 8 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", 9 | "httpPort": 32693, 10 | "useSSL": false 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /NotificationService/NotificationsQueueProcessor/functionSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "KeyVaultConfigRefreshDurationSeconds": "120", 3 | "KeyVaultUrl": "__KeyVaultUrl__" 4 | } -------------------------------------------------------------------------------- /NotificationService/NotificationsQueueProcessor/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "functionTimeout": "-1", 4 | "extensions": { 5 | "queues": { 6 | "maxPollingInterval": "00:00:01", 7 | "visibilityTimeout": "00:00:30", 8 | "batchSize": 1, 9 | "maxDequeueCount": 5 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Carriers/Interfaces/IWebNotificationsCarrier.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace WebNotifications.Carriers.Interfaces 5 | { 6 | using System.Collections.Generic; 7 | using System.Threading.Tasks; 8 | using NotificationService.Contracts.Models.Web.Response; 9 | 10 | /// 11 | /// The interfaces provides a mechanism to send the notifications. 12 | /// 13 | public interface IWebNotificationsCarrier 14 | { 15 | /// 16 | /// Sends the notifications asynchronously. 17 | /// 18 | /// The instance for . 19 | /// The instance of , where T being , representing an asynchronous operation. 20 | Task> SendAsync(IEnumerable webNotifications); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Channels/INotificationsChannel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace WebNotifications.Channels 5 | { 6 | using System.Collections.Generic; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using NotificationService.Contracts.Models.Web.Response; 10 | 11 | /// 12 | /// The interface provides producer/consumer functionality for notifications. 13 | /// 14 | public interface INotificationsChannel 15 | { 16 | /// 17 | /// Adds the notification asynchronously. 18 | /// 19 | /// The notification. 20 | /// The cancellation token. 21 | /// The instance of representing an asynchronous operation. 22 | Task AddNotificationAsync(WebNotification notification, CancellationToken cancellationToken = default); 23 | 24 | /// 25 | /// Reads all notifications asynchronously. 26 | /// 27 | /// The cancellation token. 28 | /// The instance of . 29 | IAsyncEnumerable ReadAllNotificationsAsync(CancellationToken cancellationToken = default); 30 | } 31 | } -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Channels/Internals/ChannelProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace WebNotifications.Channels.Internals 5 | { 6 | using System; 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Threading.Channels; 9 | 10 | /// 11 | /// The class implements the mechanism to provision the channels. 12 | /// 13 | /// 14 | [ExcludeFromCodeCoverage] 15 | internal class ChannelProvider : IChannelProvider 16 | { 17 | /// 18 | public Channel ProvisionBoundedChannel(BoundedChannelOptions boundedChannelOptions) 19 | { 20 | // This method and interface introduced to increase testability of the code. 21 | if (boundedChannelOptions == null) 22 | { 23 | throw new ArgumentNullException(nameof(boundedChannelOptions)); 24 | } 25 | 26 | return Channel.CreateBounded(boundedChannelOptions); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Channels/Internals/IChannelProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace WebNotifications.Channels.Internals 5 | { 6 | using System.Threading.Channels; 7 | 8 | /// 9 | /// The provides mechanism to provide channels. 10 | /// 11 | public interface IChannelProvider 12 | { 13 | /// 14 | /// Provisions the bounded channel for notifications. 15 | /// 16 | /// The object type for which this channel is provisioned. 17 | /// The instance of . 18 | /// The instance of . 19 | Channel ProvisionBoundedChannel(BoundedChannelOptions boundedChannelOptions); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Controllers/v1/RootPingController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace WebNotifications.Controllers 5 | { 6 | using System.Diagnostics.CodeAnalysis; 7 | using Microsoft.AspNetCore.Mvc; 8 | using Microsoft.Extensions.Logging; 9 | using NotificationService.SvCommon.Common; 10 | 11 | /// 12 | /// The Root Ping Controller. 13 | /// 14 | [ExcludeFromCodeCoverage] 15 | public class RootPingController : WebAPICommonController 16 | { 17 | /// 18 | /// The instance for . 19 | /// 20 | private readonly ILogger logger; 21 | 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// Constructor for Root Ping Controller. 25 | /// 26 | /// The instance for . 27 | public RootPingController(ILogger logger) 28 | { 29 | this.logger = logger; 30 | } 31 | 32 | /// 33 | /// Generates a success response as a ping. 34 | /// 35 | /// The instance for . 36 | [HttpGet("")] 37 | public IActionResult Ping() 38 | { 39 | this.logger.LogInformation($"Invoked {nameof(this.Ping)} method in {nameof(RootPingController)}."); 40 | return this.Ok(); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /NotificationService/WebNotifications/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // This file is used by Code Analysis to maintain SuppressMessage 5 | // attributes that are applied to this project. 6 | // Project-level suppressions either have no target or are given 7 | // a specific target and scoped to a namespace, type, member, etc. 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | [assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "The background service must only log the errors to keep itself running.", Scope = "member", Target = "~M:WebNotifications.BackgroundServices.NotificationsCarrierService.ExecuteAsync(System.Threading.CancellationToken)~System.Threading.Tasks.Task")] 11 | [assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "The carrier must only log the errors.", Scope = "member", Target = "~M:WebNotifications.Carriers.WebNotificationsCarrier.SendInternalAsync(System.Collections.Generic.IEnumerable{NotificationService.Contracts.Models.Web.Response.WebNotification})~System.Threading.Tasks.Task{System.Collections.Generic.List{System.String}}")] 12 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Hubs/Interfaces/INotificationsClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace WebNotifications.Hubs.Interfaces 5 | { 6 | using System.Collections.Generic; 7 | using System.Threading.Tasks; 8 | using NotificationService.Contracts.Models.Web.Response; 9 | 10 | /// 11 | /// The interface provides mechanism for clients to respond to the web notifications. 12 | /// 13 | public interface INotificationsClient 14 | { 15 | /// 16 | /// Receives the notifications asynchronously. 17 | /// 18 | /// The instance for . 19 | /// The instance of representing an asynchronous operation. 20 | Task ReceiveNotificationsAsync(IEnumerable notifications); 21 | 22 | /// 23 | /// Receives the notification asynchronously. 24 | /// 25 | /// The instance of . 26 | /// The instance of representing an asynchronous operation. 27 | Task ReceiveNotificationAsync(WebNotification notification); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace WebNotifications 5 | { 6 | using System.Diagnostics.CodeAnalysis; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Hosting; 9 | 10 | /// 11 | /// The class with the Main method of the application. 12 | /// 13 | [ExcludeFromCodeCoverage] 14 | public class Program 15 | { 16 | /// 17 | /// Defines the entry point of the application. 18 | /// 19 | /// The arguments. 20 | public static void Main(string[] args) 21 | { 22 | CreateHostBuilder(args).Build().Run(); 23 | } 24 | 25 | /// 26 | /// Creates a web host builder. 27 | /// 28 | /// Arguments. 29 | /// An instance of . 30 | public static IHostBuilder CreateHostBuilder(string[] args) => 31 | Host.CreateDefaultBuilder(args) 32 | .ConfigureWebHostDefaults(webBuilder => 33 | { 34 | _ = webBuilder.UseStartup(); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:61720", 7 | "sslPort": 44358 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "swagger", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "WebNotifications": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "swagger", 23 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/Providers/UserObjectIdentifierProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace WebNotifications.Providers 5 | { 6 | using System; 7 | using Microsoft.AspNetCore.SignalR; 8 | using NotificationService.SvCommon.APIConstants; 9 | 10 | /// 11 | /// The class implements mechanism to identify user using object identifier. 12 | /// 13 | /// 14 | public class UserObjectIdentifierProvider : IUserIdProvider 15 | { 16 | /// 17 | /// Gets the user ID for the specified SignalR connection context. 18 | /// 19 | /// The instance of . 20 | /// 21 | /// The user object identifier for the specified connection context. 22 | /// 23 | /// connection. 24 | public string GetUserId(HubConnectionContext connection) 25 | { 26 | if (connection is null) 27 | { 28 | throw new ArgumentNullException(nameof(connection)); 29 | } 30 | 31 | string userObjectIdentifier = connection.User.FindFirst("oid")?.Value; 32 | if (string.IsNullOrWhiteSpace(userObjectIdentifier)) 33 | { 34 | userObjectIdentifier = connection.User.FindFirst(ClaimTypeConstants.ObjectIdentifier)?.Value; 35 | } 36 | 37 | return userObjectIdentifier; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/WebNotifications.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /NotificationService/WebNotifications/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "ApplicationInsights": { 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "Microsoft": "Error" 7 | } 8 | }, 9 | "LogLevel": { 10 | "Default": "Information", 11 | "Microsoft": "Warning", 12 | "Microsoft.Hosting.Lifetime": "Information" 13 | } 14 | }, 15 | "AllowedHosts": "*", 16 | "ApplicationInsights": { 17 | "InstrumentationKey": "__InstrumentationKey__" 18 | }, 19 | "EnvironmentSetting": { 20 | "EnvironmentType": "__EnvironmentType__" 21 | }, 22 | "BearerTokenAuthentication": { 23 | "ValidAudiences": "__BearerTokenAuthenticationValidAudiences__", 24 | "Authority": "__BearerTokenAuthenticationAuthority__", 25 | "Issuer": "__BearerTokenAuthenticationIssuer__" 26 | }, 27 | "UserTokenSetting": { 28 | "Authority": "__UserTokenSettingAuthority__", 29 | "ClientId": "__UserTokenSettingClientId__" 30 | }, 31 | "RetrySetting": { 32 | "MaxRetries": "__MaxRetries__", 33 | "TransientRetryCount": "__TransientRetryCount__" 34 | }, 35 | "KeyVault": { 36 | "ClientId": "__KeyVaultClientId__", 37 | "ClientSecret": "__KeyVaultClientSecret__", 38 | "SecretUri": "__KeyVaultSecretUri__" 39 | }, 40 | "CosmosDB": { 41 | "Uri": "__CosmosDBUri__", 42 | "Key": "__CosmosDBKey__", 43 | "Database": "__CosmosDBDatabase__", 44 | "Container": "__CosmosDBContainer__" 45 | }, 46 | "StorageAccount": { 47 | "ConnectionString": "__StorageAccountConnectionString__" 48 | }, 49 | "AllowedOrigins": "__CorsOrigins__" 50 | } -------------------------------------------------------------------------------- /NotificationService/stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | // ACTION REQUIRED: This file was automatically added to your project, but it 3 | // will not take effect until additional steps are taken to enable it. See the 4 | // following page for additional information: 5 | // 6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md 7 | 8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 9 | "settings": { 10 | "documentationRules": { 11 | "companyName": "Microsoft Corporation", 12 | "xmlHeader": false, 13 | "copyrightText": "Copyright (c) {companyName}.\nLicensed under the MIT License." 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 7 | feature request as a new Issue. 8 | 9 | For help and questions related to this project, please go through the README and the Wiki. Further clarity can be provided by the project maintainers through the issues channel. Please label the issue appropriately. 10 | -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------