forked from dotnet/maui-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Push notifications sample. (dotnet#492)
- Loading branch information
1 parent
c437fb7
commit 7adbd6b
Showing
60 changed files
with
2,034 additions
and
0 deletions.
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
...ebServices/PushNotificationsDemo/PushNotificationsAPI/Authentication/ApiKeyAuthHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.Extensions.Options; | ||
using System.Security.Claims; | ||
using System.Text.Encodings.Web; | ||
|
||
namespace PushNotificationsAPI.Authentication; | ||
|
||
public class ApiKeyAuthHandler : AuthenticationHandler<ApiKeyAuthOptions> | ||
{ | ||
const string ApiKeyIdentifier = "apikey"; | ||
|
||
public ApiKeyAuthHandler(IOptionsMonitor<ApiKeyAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder) | ||
: base(options, logger, encoder) | ||
{ | ||
} | ||
|
||
protected override Task<AuthenticateResult> HandleAuthenticateAsync() | ||
{ | ||
string key = string.Empty; | ||
|
||
if (Request.Headers[ApiKeyIdentifier].Any()) | ||
{ | ||
key = Request.Headers[ApiKeyIdentifier].FirstOrDefault(); | ||
} | ||
else if (Request.Query.ContainsKey(ApiKeyIdentifier)) | ||
{ | ||
if (Request.Query.TryGetValue(ApiKeyIdentifier, out var queryKey)) | ||
key = queryKey; | ||
} | ||
|
||
if (string.IsNullOrWhiteSpace(key)) | ||
return Task.FromResult(AuthenticateResult.Fail("No api key provided")); | ||
|
||
if (!string.Equals(key, Options.ApiKey, StringComparison.Ordinal)) | ||
return Task.FromResult(AuthenticateResult.Fail("Invalid api key.")); | ||
|
||
var identities = new List<ClaimsIdentity> | ||
{ | ||
new ClaimsIdentity("ApiKeyIdentity") | ||
}; | ||
|
||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(identities), Options.Scheme); | ||
|
||
return Task.FromResult(AuthenticateResult.Success(ticket)); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...ebServices/PushNotificationsDemo/PushNotificationsAPI/Authentication/ApiKeyAuthOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using Microsoft.AspNetCore.Authentication; | ||
|
||
namespace PushNotificationsAPI.Authentication; | ||
|
||
public class ApiKeyAuthOptions : AuthenticationSchemeOptions | ||
{ | ||
public const string DefaultScheme = "ApiKey"; | ||
public string Scheme => DefaultScheme; | ||
public string ApiKey { get; set; } | ||
} | ||
|
15 changes: 15 additions & 0 deletions
15
...hNotificationsDemo/PushNotificationsAPI/Authentication/AuthenticationBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Microsoft.AspNetCore.Authentication; | ||
|
||
namespace PushNotificationsAPI.Authentication; | ||
|
||
public static class AuthenticationBuilderExtensions | ||
{ | ||
public static AuthenticationBuilder AddApiKeyAuth(this AuthenticationBuilder builder, Action<ApiKeyAuthOptions> configureOptions) | ||
{ | ||
return builder | ||
.AddScheme<ApiKeyAuthOptions, ApiKeyAuthHandler>( | ||
ApiKeyAuthOptions.DefaultScheme, | ||
configureOptions); | ||
} | ||
} | ||
|
80 changes: 80 additions & 0 deletions
80
...ervices/PushNotificationsDemo/PushNotificationsAPI/Controllers/NotificationsController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Net; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using PushNotificationsAPI.Models; | ||
using PushNotificationsAPI.Services; | ||
|
||
namespace PushNotificationsAPI.Controllers; | ||
|
||
[Authorize] | ||
[ApiController] | ||
[Route("api/[controller]")] | ||
public class NotificationsController : ControllerBase | ||
{ | ||
readonly INotificationService _notificationService; | ||
|
||
public NotificationsController(INotificationService notificationService) | ||
{ | ||
_notificationService = notificationService; | ||
} | ||
|
||
[HttpPut] | ||
[Route("installations")] | ||
[ProducesResponseType((int)HttpStatusCode.OK)] | ||
[ProducesResponseType((int)HttpStatusCode.BadRequest)] | ||
[ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)] | ||
public async Task<IActionResult> UpdateInstallation( | ||
[Required] DeviceInstallation deviceInstallation) | ||
{ | ||
var success = await _notificationService | ||
.CreateOrUpdateInstallationAsync(deviceInstallation, HttpContext.RequestAborted); | ||
|
||
if (!success) | ||
return new UnprocessableEntityResult(); | ||
|
||
return new OkResult(); | ||
} | ||
|
||
[HttpDelete()] | ||
[Route("installations/{installationId}")] | ||
[ProducesResponseType((int)HttpStatusCode.OK)] | ||
[ProducesResponseType((int)HttpStatusCode.BadRequest)] | ||
[ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)] | ||
public async Task<ActionResult> DeleteInstallation( | ||
[Required][FromRoute] string installationId) | ||
{ | ||
// Probably want to ensure deletion even if the connection is broken | ||
var success = await _notificationService | ||
.DeleteInstallationByIdAsync(installationId, CancellationToken.None); | ||
|
||
if (!success) | ||
return new UnprocessableEntityResult(); | ||
|
||
return new OkResult(); | ||
} | ||
|
||
[HttpPost] | ||
[Route("requests")] | ||
[ProducesResponseType((int)HttpStatusCode.OK)] | ||
[ProducesResponseType((int)HttpStatusCode.BadRequest)] | ||
[ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)] | ||
public async Task<IActionResult> RequestPush( | ||
[Required] NotificationRequest notificationRequest) | ||
{ | ||
if ((notificationRequest.Silent && | ||
string.IsNullOrWhiteSpace(notificationRequest?.Action)) || | ||
(!notificationRequest.Silent && | ||
string.IsNullOrWhiteSpace(notificationRequest?.Text))) | ||
return new BadRequestResult(); | ||
|
||
var success = await _notificationService | ||
.RequestNotificationAsync(notificationRequest, HttpContext.RequestAborted); | ||
|
||
if (!success) | ||
return new UnprocessableEntityResult(); | ||
|
||
return new OkResult(); | ||
} | ||
} | ||
|
18 changes: 18 additions & 0 deletions
18
8.0/WebServices/PushNotificationsDemo/PushNotificationsAPI/Models/DeviceInstallation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
|
||
namespace PushNotificationsAPI.Models; | ||
|
||
public class DeviceInstallation | ||
{ | ||
[Required] | ||
public string InstallationId { get; set; } | ||
|
||
[Required] | ||
public string Platform { get; set; } | ||
|
||
[Required] | ||
public string PushChannel { get; set; } | ||
|
||
public IList<string> Tags { get; set; } = Array.Empty<string>(); | ||
} | ||
|
13 changes: 13 additions & 0 deletions
13
8.0/WebServices/PushNotificationsDemo/PushNotificationsAPI/Models/NotificationHubOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
|
||
namespace PushNotificationsAPI.Models; | ||
|
||
public class NotificationHubOptions | ||
{ | ||
[Required] | ||
public string Name { get; set; } | ||
|
||
[Required] | ||
public string ConnectionString { get; set; } | ||
} | ||
|
10 changes: 10 additions & 0 deletions
10
8.0/WebServices/PushNotificationsDemo/PushNotificationsAPI/Models/NotificationRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace PushNotificationsAPI.Models; | ||
|
||
public class NotificationRequest | ||
{ | ||
public string Text { get; set; } | ||
public string Action { get; set; } | ||
public string[] Tags { get; set; } = Array.Empty<string>(); | ||
public bool Silent { get; set; } | ||
} | ||
|
17 changes: 17 additions & 0 deletions
17
8.0/WebServices/PushNotificationsDemo/PushNotificationsAPI/Models/PushTemplates.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
namespace PushNotificationsAPI.Models; | ||
|
||
public class PushTemplates | ||
{ | ||
public class Generic | ||
{ | ||
public const string Android = "{ \"message\" : { \"notification\" : { \"title\" : \"PushDemo\", \"body\" : \"$(alertMessage)\"}, \"data\" : { \"action\" : \"$(alertAction)\" } } }"; | ||
public const string iOS = "{ \"aps\" : {\"alert\" : \"$(alertMessage)\"}, \"action\" : \"$(alertAction)\" }"; | ||
} | ||
|
||
public class Silent | ||
{ | ||
public const string Android = "{ \"data\" : {\"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\"} }"; | ||
//public const string Android = "{ \"message\" : { \"data\" : {\"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\"} } }"; | ||
public const string iOS = "{ \"aps\" : {\"content-available\" : 1, \"apns-priority\": 5, \"sound\" : \"\", \"badge\" : 0}, \"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\" }"; | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
8.0/WebServices/PushNotificationsDemo/PushNotificationsAPI/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using PushNotificationsAPI.Authentication; | ||
using PushNotificationsAPI.Services; | ||
using PushNotificationsAPI.Models; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
// Add services to the container. | ||
|
||
builder.Services.AddControllers(); | ||
|
||
builder.Services.AddAuthentication(options => | ||
{ | ||
options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme; | ||
options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme; | ||
}).AddApiKeyAuth(builder.Configuration.GetSection("Authentication").Bind); | ||
|
||
builder.Services.AddSingleton<INotificationService, NotificationHubService>(); | ||
builder.Services.AddOptions<NotificationHubOptions>() | ||
.Configure(builder.Configuration.GetSection("NotificationHub").Bind) | ||
.ValidateDataAnnotations(); | ||
|
||
var app = builder.Build(); | ||
|
||
// Configure the HTTP request pipeline. | ||
|
||
app.UseHttpsRedirection(); | ||
app.UseRouting(); | ||
app.UseAuthentication(); | ||
app.UseAuthorization(); | ||
app.MapControllers(); | ||
|
||
app.Run(); |
49 changes: 49 additions & 0 deletions
49
8.0/WebServices/PushNotificationsDemo/PushNotificationsAPI/Properties/launchSettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
{ | ||
"$schema": "http://json.schemastore.org/launchsettings.json", | ||
"iisSettings": { | ||
"windowsAuthentication": false, | ||
"anonymousAuthentication": true, | ||
"iisExpress": { | ||
"applicationUrl": "http://localhost:62106", | ||
"sslPort": 44341 | ||
} | ||
}, | ||
"profiles": { | ||
"http": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"launchUrl": "api/notifications", | ||
"applicationUrl": "http://localhost:5179", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"dotnetRunMessages": true | ||
}, | ||
"https": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"launchUrl": "api/notifications", | ||
"applicationUrl": "https://localhost:7020;http://localhost:5179", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"dotnetRunMessages": true | ||
}, | ||
"IIS Express": { | ||
"commandName": "IISExpress", | ||
"launchBrowser": true, | ||
"launchUrl": "api/notifications", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
}, | ||
"PushNotificationsAPI": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"applicationUrl": "https://localhost:29493;http://localhost:60313", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
8.0/WebServices/PushNotificationsDemo/PushNotificationsAPI/PushNotificationsAPI.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<UserSecretsId>719ad32f-4587-4748-9143-4ae68b445b07</UserSecretsId> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(RunConfiguration)' == 'https' " /> | ||
<PropertyGroup Condition=" '$(RunConfiguration)' == 'http' " /> | ||
|
||
<ItemGroup> | ||
<Folder Include="Authentication\" /> | ||
<Folder Include="Models\" /> | ||
<Folder Include="Services\" /> | ||
<Folder Include="Controllers\" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Azure.NotificationHubs" Version="4.2.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Compile Update="Models\PushTemplates.cs"> | ||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> | ||
</Compile> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Remove="Controllers\" /> | ||
</ItemGroup> | ||
</Project> |
11 changes: 11 additions & 0 deletions
11
8.0/WebServices/PushNotificationsDemo/PushNotificationsAPI/Services/INotificationService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using PushNotificationsAPI.Models; | ||
|
||
namespace PushNotificationsAPI.Services; | ||
|
||
public interface INotificationService | ||
{ | ||
Task<bool> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation, CancellationToken token); | ||
Task<bool> DeleteInstallationByIdAsync(string installationId, CancellationToken token); | ||
Task<bool> RequestNotificationAsync(NotificationRequest notificationRequest, CancellationToken token); | ||
} | ||
|
Oops, something went wrong.