chat: add initial GuildsController
This commit is contained in:
parent
7b4cbd4fb7
commit
727f2f6ba2
23 changed files with 248 additions and 38 deletions
|
@ -9,12 +9,12 @@ using Microsoft.AspNetCore.Mvc;
|
|||
namespace Foxchat.Identity.Controllers.Oauth;
|
||||
|
||||
[ApiController]
|
||||
[Authenticate]
|
||||
[ClientAuthenticate]
|
||||
[Route("/_fox/ident/oauth/apps")]
|
||||
public class AppsController(ILogger logger, IdentityContext db) : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateApplication([FromBody] Apps.CreateRequest req)
|
||||
public async Task<IActionResult> CreateApplication([FromBody] AppsApi.CreateRequest req)
|
||||
{
|
||||
var app = Application.Create(req.Name, req.Scopes, req.RedirectUris);
|
||||
db.Add(app);
|
||||
|
@ -22,7 +22,7 @@ public class AppsController(ILogger logger, IdentityContext db) : ControllerBase
|
|||
|
||||
logger.Information("Created new application {Name} with ID {Id} and client ID {ClientId}", app.Name, app.Id, app.ClientId);
|
||||
|
||||
return Ok(new Apps.CreateResponse(
|
||||
return Ok(new AppsApi.CreateResponse(
|
||||
app.Id, app.ClientId, app.ClientSecret, app.Name, app.Scopes, app.RedirectUris
|
||||
));
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class AppsController(ILogger logger, IdentityContext db) : ControllerBase
|
|||
{
|
||||
var app = HttpContext.GetApplicationOrThrow();
|
||||
|
||||
return Ok(new Apps.GetSelfResponse(
|
||||
return Ok(new AppsApi.GetSelfResponse(
|
||||
app.Id,
|
||||
app.ClientId,
|
||||
withSecret ? app.ClientSecret : null,
|
||||
|
|
|
@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore;
|
|||
namespace Foxchat.Identity.Controllers.Oauth;
|
||||
|
||||
[ApiController]
|
||||
[Authenticate]
|
||||
[ClientAuthenticate]
|
||||
[Route("/_fox/ident/oauth/password")]
|
||||
public class PasswordAuthController(ILogger logger, IdentityContext db, IClock clock) : ControllerBase
|
||||
{
|
||||
|
|
21
Foxchat.Identity/Controllers/UsersController.cs
Normal file
21
Foxchat.Identity/Controllers/UsersController.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using Foxchat.Core;
|
||||
using Foxchat.Core.Models;
|
||||
using Foxchat.Identity.Database;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Foxchat.Identity.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("/_fox/ident/users")]
|
||||
public class UsersController(ILogger logger, InstanceConfig config, IdentityContext db) : ControllerBase
|
||||
{
|
||||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> GetUser(Ulid id)
|
||||
{
|
||||
var user = await db.Accounts.FirstOrDefaultAsync(a => a.Id == id);
|
||||
if (user == null) throw new ApiError.NotFound("User not found.");
|
||||
|
||||
return Ok(new Users.User(user.Id.ToString(), user.Username, config.Domain, null));
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using Foxchat.Core.Middleware;
|
||||
using Foxchat.Identity.Middleware;
|
||||
|
||||
namespace Foxchat.Identity.Extensions;
|
||||
|
@ -8,15 +9,15 @@ public static class WebApplicationExtensions
|
|||
{
|
||||
return services
|
||||
.AddScoped<ErrorHandlerMiddleware>()
|
||||
.AddScoped<AuthenticationMiddleware>()
|
||||
.AddScoped<AuthorizationMiddleware>();
|
||||
.AddScoped<ClientAuthenticationMiddleware>()
|
||||
.AddScoped<ClientAuthorizationMiddleware>();
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseCustomMiddleware(this IApplicationBuilder app)
|
||||
{
|
||||
return app
|
||||
.UseMiddleware<ErrorHandlerMiddleware>()
|
||||
.UseMiddleware<AuthenticationMiddleware>()
|
||||
.UseMiddleware<AuthorizationMiddleware>();
|
||||
.UseMiddleware<ClientAuthenticationMiddleware>()
|
||||
.UseMiddleware<ClientAuthorizationMiddleware>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ using NodaTime;
|
|||
|
||||
namespace Foxchat.Identity.Middleware;
|
||||
|
||||
public class AuthenticationMiddleware(
|
||||
public class ClientAuthenticationMiddleware(
|
||||
IdentityContext db,
|
||||
IClock clock
|
||||
) : IMiddleware
|
||||
|
@ -16,7 +16,7 @@ public class AuthenticationMiddleware(
|
|||
public async Task InvokeAsync(HttpContext ctx, RequestDelegate next)
|
||||
{
|
||||
var endpoint = ctx.GetEndpoint();
|
||||
var metadata = endpoint?.Metadata.GetMetadata<AuthenticateAttribute>();
|
||||
var metadata = endpoint?.Metadata.GetMetadata<ClientAuthenticateAttribute>();
|
||||
|
||||
if (metadata == null)
|
||||
{
|
||||
|
@ -81,4 +81,4 @@ public static class HttpContextExtensions
|
|||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class AuthenticateAttribute : Attribute;
|
||||
public class ClientAuthenticateAttribute : Attribute;
|
|
@ -4,7 +4,7 @@ using NodaTime;
|
|||
|
||||
namespace Foxchat.Identity.Middleware;
|
||||
|
||||
public class AuthorizationMiddleware(
|
||||
public class ClientAuthorizationMiddleware(
|
||||
IdentityContext db,
|
||||
IClock clock
|
||||
) : IMiddleware
|
|
@ -1,86 +0,0 @@
|
|||
using System.Net;
|
||||
using Foxchat.Core;
|
||||
using Foxchat.Core.Models.Http;
|
||||
using Newtonsoft.Json;
|
||||
using ApiError = Foxchat.Core.ApiError;
|
||||
using HttpApiError = Foxchat.Core.Models.Http.ApiError;
|
||||
|
||||
namespace Foxchat.Identity.Middleware;
|
||||
|
||||
public class ErrorHandlerMiddleware(ILogger baseLogger) : IMiddleware
|
||||
{
|
||||
public async Task InvokeAsync(HttpContext ctx, RequestDelegate next)
|
||||
{
|
||||
try
|
||||
{
|
||||
await next(ctx);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var type = e.TargetSite?.DeclaringType ?? typeof(ErrorHandlerMiddleware);
|
||||
var typeName = e.TargetSite?.DeclaringType?.FullName ?? "<unknown>";
|
||||
var logger = baseLogger.ForContext(type);
|
||||
|
||||
if (ctx.Response.HasStarted)
|
||||
{
|
||||
logger.Error(e, "Error in {ClassName} ({Path}) after response started being sent", typeName, ctx.Request.Path);
|
||||
}
|
||||
|
||||
if (e is ApiError ae)
|
||||
{
|
||||
ctx.Response.StatusCode = (int)ae.StatusCode;
|
||||
ctx.Response.Headers.RequestId = ctx.TraceIdentifier;
|
||||
ctx.Response.ContentType = "application/json; charset=utf-8";
|
||||
if (ae is ApiError.OutgoingFederationError ofe)
|
||||
{
|
||||
await ctx.Response.WriteAsync(JsonConvert.SerializeObject(new HttpApiError
|
||||
{
|
||||
Status = (int)ofe.StatusCode,
|
||||
Code = ErrorCode.OutgoingFederationError,
|
||||
Message = ofe.Message,
|
||||
OriginalError = ofe.InnerError
|
||||
}));
|
||||
return;
|
||||
}
|
||||
else if (ae is ApiError.Forbidden fe)
|
||||
{
|
||||
await ctx.Response.WriteAsync(JsonConvert.SerializeObject(new HttpApiError
|
||||
{
|
||||
Status = (int)fe.StatusCode,
|
||||
Code = ErrorCode.Forbidden,
|
||||
Message = fe.Message,
|
||||
Scopes = fe.Scopes.Length > 0 ? fe.Scopes : null
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.Response.WriteAsync(JsonConvert.SerializeObject(new HttpApiError
|
||||
{
|
||||
Status = (int)ae.StatusCode,
|
||||
Code = ErrorCode.GenericApiError,
|
||||
Message = ae.Message,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
if (e is FoxchatError fce)
|
||||
{
|
||||
logger.Error(fce.Inner ?? fce, "Exception in {ClassName} ({Path})", typeName, ctx.Request.Path);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error(e, "Exception in {ClassName} ({Path})", typeName, ctx.Request.Path);
|
||||
}
|
||||
|
||||
ctx.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
ctx.Response.Headers.RequestId = ctx.TraceIdentifier;
|
||||
ctx.Response.ContentType = "application/json; charset=utf-8";
|
||||
await ctx.Response.WriteAsync(JsonConvert.SerializeObject(new HttpApiError
|
||||
{
|
||||
Status = (int)HttpStatusCode.InternalServerError,
|
||||
Code = ErrorCode.InternalServerError,
|
||||
Message = "Internal server error",
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue