-
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.
- Loading branch information
Showing
50 changed files
with
8,467 additions
and
0 deletions.
There are no files selected for viewing
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,26 @@ | ||
trigger: | ||
branches: | ||
include: | ||
- develop | ||
- master | ||
paths: | ||
include: | ||
- /src/* | ||
|
||
resources: | ||
repositories: | ||
- repository: devops | ||
type: git | ||
name: pub/devops | ||
ref: master | ||
|
||
|
||
jobs: | ||
- template: dotnet-build-deploy.yml@devops | ||
parameters: | ||
versionPrefix: '0.1' | ||
projectName: 'Web1.Sse.ChatApi' | ||
hasUnitTests: false | ||
createZip: true | ||
createNugetPackage: false | ||
createGithubRelease: true |
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,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.9.34701.34 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web1.Sse.ChatApi", "Web1.Sse.ChatApi\Web1.Sse.ChatApi.csproj", "{A0064768-9AD1-46AC-9005-2F5B1501B784}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{A0064768-9AD1-46AC-9005-2F5B1501B784}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{A0064768-9AD1-46AC-9005-2F5B1501B784}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{A0064768-9AD1-46AC-9005-2F5B1501B784}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{A0064768-9AD1-46AC-9005-2F5B1501B784}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {9F52A468-AA55-44F7-B83A-320F7DFE70E4} | ||
EndGlobalSection | ||
EndGlobal |
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,9 @@ | ||
using Microsoft.AspNetCore.Builder; | ||
|
||
namespace Web1.Sse.ChatApi.Assets | ||
{ | ||
public interface IApiEndPoint | ||
{ | ||
void Map(WebApplication app); | ||
} | ||
} |
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,21 @@ | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using System.Linq; | ||
using System.Reflection; | ||
using Web1.Sse.ChatApi.Assets; | ||
|
||
namespace Web1.Sse.ChatApi.EndPoints | ||
{ | ||
public static class EndPointExtensions | ||
{ | ||
public static void UseApiEndPoints(this WebApplication app) | ||
{ | ||
var endpointTypes = Assembly.GetExecutingAssembly().ExportedTypes.Where(x => x.GetInterface(nameof(IApiEndPoint)) is not null); | ||
foreach (var endpointType in endpointTypes) | ||
{ | ||
IApiEndPoint endPoint = (IApiEndPoint)ActivatorUtilities.CreateInstance(app.Services, endpointType); | ||
endPoint.Map(app); | ||
} | ||
} | ||
} | ||
} |
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,39 @@ | ||
using Code2.Web.SseTyped; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Mvc; | ||
using System; | ||
using System.Linq; | ||
using System.Security.Claims; | ||
using Web1.Sse.ChatApi.Assets; | ||
using Web1.Sse.ChatApi.Models; | ||
using Web1.Sse.ChatApi.Services; | ||
|
||
namespace Web1.Sse.ChatApi.EndPoints | ||
{ | ||
public class MessagesEndPoint : IApiEndPoint | ||
{ | ||
public MessagesEndPoint(ISecurityService securityService, ISseService sseService) | ||
{ | ||
_securityService = securityService; | ||
_sseService = sseService; | ||
} | ||
|
||
private readonly ISseService _sseService; | ||
private readonly ISecurityService _securityService; | ||
|
||
public void Map(WebApplication app) | ||
{ | ||
app.MapPost("/messages", AddMessage); | ||
} | ||
|
||
public IResult AddMessage([FromBody] ChatMessage message, ClaimsPrincipal principal) | ||
{ | ||
message.FromUserId = _securityService.GetCurrentUserId(principal); | ||
message.Created = DateTime.Now; | ||
string[] userIds = message.ToUserIds.Select(x => x.ToString()).ToArray(); | ||
_sseService.Send(message, (properties) => userIds.Length == 0 || userIds.Contains(properties["userId"])); | ||
return Results.NoContent(); | ||
} | ||
} | ||
} |
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,91 @@ | ||
using Code2.Web.SseTyped; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Routing; | ||
using System; | ||
using System.Security.Claims; | ||
using Web1.Sse.ChatApi.Assets; | ||
using Web1.Sse.ChatApi.Models; | ||
using Web1.Sse.ChatApi.Services; | ||
|
||
namespace Web1.Sse.ChatApi.EndPoints | ||
{ | ||
public class UsersEndPoint : IApiEndPoint | ||
{ | ||
|
||
public UsersEndPoint(IUserRepository userRepository, ISseService sseService, ISecurityService securityService) | ||
{ | ||
_userRepository = userRepository; | ||
_sseService = sseService; | ||
_securityService = securityService; | ||
} | ||
|
||
private readonly IUserRepository _userRepository; | ||
private readonly ISseService _sseService; | ||
private readonly ISecurityService _securityService; | ||
|
||
public void Map(WebApplication app) | ||
{ | ||
app.MapPost("/users/login", Login).AllowAnonymous(); | ||
app.MapGet("/users", GetUsers); | ||
app.MapPut("/users/{userId}", UpdateUser); | ||
app.MapDelete("/users/{userId}", DeleteUser); | ||
} | ||
|
||
public IResult Login(LoginRequest loginRequest) | ||
{ | ||
try | ||
{ | ||
ChatUser user = new ChatUser { Name = loginRequest.Name }; | ||
int userId = _userRepository.Add(user); | ||
_sseService.Send(new SystemMessage(SystemMessage.UserAddedMessageType, user)); | ||
return Results.Ok(new LoginResponse { UserId = userId, Token = _securityService.GetToken(userId) }); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return Results.Problem(ex.Message); | ||
} | ||
} | ||
|
||
public IResult GetUsers() | ||
{ | ||
return Results.Ok(_userRepository.Get()); | ||
} | ||
|
||
public IResult UpdateUser(int userId, [FromBody] ChatUser user, ClaimsPrincipal principal) | ||
{ | ||
if (!IsCurrentUserId(userId, principal)) return Results.Problem("Invalid operation"); | ||
try | ||
{ | ||
_userRepository.Update(userId, user); | ||
_sseService.Send(new SystemMessage(SystemMessage.UserModifiedMessageType, user)); | ||
return Results.NoContent(); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return Results.Problem(ex.Message); | ||
} | ||
} | ||
|
||
public IResult DeleteUser(int userId, ClaimsPrincipal principal) | ||
{ | ||
if (!IsCurrentUserId(userId, principal)) return Results.Problem("Invalid operation"); | ||
try | ||
{ | ||
_userRepository.Delete(userId); | ||
_sseService.Send(new SystemMessage(SystemMessage.UserRemovedMessageType, new ChatUser { Id = userId })); | ||
return Results.NoContent(); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return Results.Problem(ex.Message); | ||
} | ||
} | ||
|
||
private bool IsCurrentUserId(int userId, ClaimsPrincipal principal) | ||
=> _securityService.GetCurrentUserId(principal) == userId; | ||
|
||
|
||
} | ||
} |
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; | ||
|
||
namespace Web1.Sse.ChatApi.Models | ||
{ | ||
public class ChatMessage | ||
{ | ||
public int Id { get; set; } | ||
public DateTime? Created { get; set; } | ||
public int FromUserId { get; set; } | ||
public int[] ToUserIds { get; set; } = Array.Empty<int>(); | ||
public string Text { get; set; } = string.Empty; | ||
} | ||
} |
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,8 @@ | ||
namespace Web1.Sse.ChatApi.Models | ||
{ | ||
public class ChatUser | ||
{ | ||
public int Id { get; set; } | ||
public string Name { get; set; } = string.Empty; | ||
} | ||
} |
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,7 @@ | ||
namespace Web1.Sse.ChatApi.Models | ||
{ | ||
public class LoginRequest | ||
{ | ||
public string Name { get; set; } = string.Empty; | ||
} | ||
} |
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,8 @@ | ||
namespace Web1.Sse.ChatApi.Models | ||
{ | ||
public class LoginResponse | ||
{ | ||
public int UserId { get; set; } | ||
public string Token { get; set; } = string.Empty; | ||
} | ||
} |
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,19 @@ | ||
namespace Web1.Sse.ChatApi.Models | ||
{ | ||
public class SystemMessage | ||
{ | ||
public SystemMessage(string messageType, object data) | ||
{ | ||
MessageType = messageType; | ||
Data = data; | ||
} | ||
|
||
public const string UserModifiedMessageType = "UserModified"; | ||
public const string UserAddedMessageType = "UserAdded"; | ||
public const string UserRemovedMessageType = "UserRemoved"; | ||
|
||
public string MessageType { get; set; } | ||
public object Data { get; private set; } | ||
|
||
} | ||
} |
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,31 @@ | ||
using Code2.Web.SseTyped; | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Web1.Sse.ChatApi.EndPoints; | ||
using Web1.Sse.ChatApi.Services; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
// Add services to the container. | ||
ISecurityService securityService = new SecurityService(builder.Configuration); | ||
builder.Services.AddSingleton<IUserRepository, UserRepository>(); | ||
builder.Services.AddSingleton<ISecurityService>(securityService); | ||
builder.Services.AddSseTyped(); | ||
builder.Services.AddCors(); | ||
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(securityService.ConfigureJwtBearer); | ||
builder.Services.AddAuthorization(securityService.ConfigureAuthorization); | ||
|
||
|
||
var app = builder.Build(); | ||
// Configure the HTTP request pipeline. | ||
|
||
app.UseCors(x => x.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); | ||
app.UseStaticFiles(); | ||
app.UseAuthentication(); | ||
app.UseAuthorization(); | ||
|
||
app.UseApiEndPoints(); | ||
app.UseSseTyped(rootPath: "/sse"); | ||
|
||
|
||
app.Run(); |
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,31 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/launchsettings.json", | ||
"iisSettings": { | ||
"windowsAuthentication": false, | ||
"anonymousAuthentication": true, | ||
"iisExpress": { | ||
"applicationUrl": "http://localhost:13675", | ||
"sslPort": 44315 | ||
} | ||
}, | ||
"profiles": { | ||
"Web1.Sse.ChatApi": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"launchUrl": "index.html", | ||
"applicationUrl": "http://localhost:5180", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
}, | ||
"IIS Express": { | ||
"commandName": "IISExpress", | ||
"launchBrowser": true, | ||
"launchUrl": "index.html", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
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,14 @@ | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using Microsoft.AspNetCore.Authorization; | ||
using System.Security.Claims; | ||
|
||
namespace Web1.Sse.ChatApi.Services | ||
{ | ||
public interface ISecurityService | ||
{ | ||
void ConfigureJwtBearer(JwtBearerOptions options); | ||
void ConfigureAuthorization(AuthorizationOptions options); | ||
string GetToken(int userId); | ||
int GetCurrentUserId(ClaimsPrincipal? principal); | ||
} | ||
} |
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,14 @@ | ||
using System; | ||
using Web1.Sse.ChatApi.Models; | ||
|
||
namespace Web1.Sse.ChatApi.Services | ||
{ | ||
public interface IUserRepository | ||
{ | ||
int Add(ChatUser user); | ||
void Delete(int userId); | ||
ChatUser[] Get(); | ||
ChatUser[] Get(Func<ChatUser, bool> filter); | ||
void Update(int userId, ChatUser user); | ||
} | ||
} |
Oops, something went wrong.