This commit is contained in:
2023-02-19 00:43:43 +01:00
parent 9719a0c0fd
commit 1e66851113
146 changed files with 738 additions and 382 deletions

View File

@ -0,0 +1,129 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using PrivaPub.ClientModels;
using PrivaPub.ClientModels.User;
using PrivaPub.Extensions;
using PrivaPub.Resources;
using PrivaPub.Services;
using System.ComponentModel.DataAnnotations;
namespace PrivaPub.Controllers.ClientToServer
{
[ApiController,
Route("clientapi/admin")]
public class AdminController : ControllerBase
{
readonly IRootUsersService RootUsersService;
readonly ILogger<RootUserController> Logger;
readonly IStringLocalizer Localizer;
public AdminController(ILogger<RootUserController> logger,
IStringLocalizer<GenericRes> localizer,
IRootUsersService rootUsersService)
{
Logger = logger;
Localizer = localizer;
RootUsersService = rootUsersService;
}
[HttpDelete, Route("/clientapi/admin/remove/users"), Authorize(Policy = Policies.IsAdmin)]
public async Task<IActionResult> RemoveUsers([Required] UsersIds usersIds)
{
var result = new WebResult();
try
{
usersIds.UserIdList.Remove(User.GetUserId());
result = await RootUsersService.RemoveUserAsync(usersIds);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok();
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(RemoveUsers)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Authorize(Policy = Policies.IsAdmin), Route("/clientapi/admin/ban/users")]
public async Task<IActionResult> BanUsers([Required] UsersIds usersIds)
{
if (!ModelState.IsValid)
return BadRequest(usersIds);
var result = new WebResult();
try
{
//var isUserResult = await UsersService.UserIsAdminAsync(User.GetUserId());
//if (isUserResult.IsValid && !(bool)isUserResult.Data)
//if (isUserResult is { IsValid: true } and not { Data: bool })
// return Unauthorized();
usersIds.UserIdList.Remove(User.GetUserId());
result = await RootUsersService.BanUserAsync(usersIds);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok();
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(BanUsers)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Authorize(Policy = Policies.IsAdmin), Route("/clientapi/admin/unban/users")]
public async Task<IActionResult> UnbanUsers([Required] UsersIds usersIds)
{
if (!ModelState.IsValid)
return BadRequest(usersIds);
var result = new WebResult();
try
{
//var isUserResult = await UsersService.UserIsAdminAsync(User.GetUserId());
//if (isUserResult.IsValid && !(bool)isUserResult.Data)
// return Unauthorized();
usersIds.UserIdList.Remove(User.GetUserId());
result = await RootUsersService.UnbanUserAsync(usersIds);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok();
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(UnbanUsers)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
//[HttpGet, Authorize(Policy = Policies.IsAdmin)]
//public async Task<IActionResult> GetUsers()
//{
// var result = new WebResult();
// try
// {
// var isUserResult = await UsersService.UserIsAdminAsync(User.GetUserId());
// if (isUserResult.IsValid && !(bool)isUserResult.Data)
// return Unauthorized();
// result = await UsersService.GetUsersAsync();
// if (!result.IsValid)
// return StatusCode(result.StatusCode, result);
// return Ok(result.Data);
// }
// catch (Exception ex)
// {
// Logger.LogError(ex, $"{nameof(User)}.{nameof(GetUsers)}()");
// return BadRequest(result.Invalidate(ex.Message));
// }
//}
}
}

View File

@ -0,0 +1,55 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using PrivaPub.ClientModels;
using PrivaPub.ClientModels.Data;
using PrivaPub.Services.ClientToServer.Public;
namespace PrivaPub.Controllers.ClientToServer
{
[ApiController,
Route("clientapi/data")]
public class DataController : ControllerBase
{
readonly IDataService DataService;
readonly ILogger<DataController> Logger;
public DataController(IDataService dataService,
ILogger<DataController> logger)
{
DataService = dataService;
Logger = logger;
}
[HttpGet, Route("/clientapi/data/ping"), AllowAnonymous]
public async ValueTask<IActionResult> Ping() => NoContent();
[HttpGet, Route("/clientapi/data/current-version"), AllowAnonymous]
public IActionResult CurrentVersion() =>
Ok(DataService.GetCurrentVersion());
[HttpGet, Route("/clientapi/data/languages"), AllowAnonymous]
public async Task<IActionResult> Languages(CancellationToken cancellationToken)
{
var result = new WebResult();
try
{
var languages = await DataService.GetLanguages(cancellationToken);
var viewLanguages = new List<ViewLanguage>();
viewLanguages.AddRange(languages.Select(l => new ViewLanguage
{
Name = l.NativeName,
International2Code = l.International2Code
}).ToArray());
return Ok(viewLanguages);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(DataController)}.{nameof(Languages)}()");
return BadRequest(result.Invalidate(ex.Message, exception: ex));
}
}
}
}

View File

@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Mvc;
namespace PrivaPub.Controllers.ClientToServer
{
[ApiController,
Route("clientapi/moderator")]
public class ModeratorController : ControllerBase
{
}
}

View File

@ -0,0 +1,75 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using PrivaPub.ClientModels;
using PrivaPub.Extensions;
using PrivaPub.Resources;
using PrivaPub.Services.ClientToServer.Private;
using PrivaPub.ClientModels.User.Avatar;
namespace PrivaPub.Controllers.ClientToServer
{
[ApiController,
Route("clientapi/avatar/private"),
Authorize(Policy = Policies.IsUser)]
public class PrivateAvatarController : ControllerBase
{
readonly ILogger<PrivateAvatarController> _logger;
readonly IPrivateAvatarUsersService _privateAvatarUsersService;
readonly IStringLocalizer _localizer;
public PrivateAvatarController(IPrivateAvatarUsersService privateAvatarUsersService,
IStringLocalizer<GenericRes> localizer,
ILogger<PrivateAvatarController> logger)
{
_privateAvatarUsersService = privateAvatarUsersService;
_localizer = localizer;
_logger = logger;
}
[HttpPost, Route("/clientapi/avatar/private/insert")]
public async Task<IActionResult> InsertAvatar(InsertAvatarForm model)
{
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(_localizer["Invalid model."]));
try
{
model.RootId = User.GetUserId();
result = await _privateAvatarUsersService.InsertAvatar(model);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok(result.Data);
}
catch (Exception ex)
{
_logger.LogError(ex, $"{nameof(PrivateAvatarController)}.{nameof(InsertAvatar)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Route("/clientapi/avatar/private/update")]
public async Task<IActionResult> UpdateAvatar(UpdateAvatarForm model)
{
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(_localizer["Invalid model."]));
try
{
model.RootId = User.GetUserId();
result = await _privateAvatarUsersService.UpdateAvatar(model);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok(result.Data);
}
catch (Exception ex)
{
_logger.LogError(ex, $"{nameof(PrivateAvatarController)}.{nameof(UpdateAvatar)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
}
}

View File

@ -0,0 +1,404 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using PrivaPub.ClientModels;
using PrivaPub.ClientModels.Resources;
using PrivaPub.ClientModels.User;
using PrivaPub.Extensions;
using PrivaPub.Models.User;
using PrivaPub.Resources;
using PrivaPub.Services;
using PrivaPub.StaticServices;
using System.ComponentModel.DataAnnotations;
namespace PrivaPub.Controllers.ClientToServer
{
[ApiController,
Route("clientapi/user")]
public class RootUserController : ControllerBase
{
readonly IRootUsersService UsersService;
readonly AuthTokenManager AuthTokenManager;
readonly ILogger<RootUserController> Logger;
readonly IStringLocalizer Localizer;
public RootUserController(IRootUsersService usersService,
AuthTokenManager authTokenManager,
IStringLocalizer<GenericRes> localizer,
ILogger<RootUserController> logger)
{
UsersService = usersService;
AuthTokenManager = authTokenManager;
Localizer = localizer;
Logger = logger;
}
#region User endpoints
[HttpPost, Route("/clientapi/user/signup"), Authorize(Policy = Policies.IsUser), AllowAnonymous]
public async Task<IActionResult> SignUp(LoginForm signUpForm)
{
if (User.Identity?.IsAuthenticated ?? false) return Redirect("/");
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(Localizer["Invalid model."]));
try
{
result = await UsersService.SignUpAsync(signUpForm);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
(var user, var userSettings) = ((RootUser, ViewAvatarServer))result.Data;
var jwtUser = AuthTokenManager.GenerateToken(user, userSettings);
Logger.LogInformation(
$"{nameof(SignUp)}();IP:[{HttpContext.Connection?.RemoteIpAddress}];\nUser-Agent:[{Request.Headers["User-Agent"]}];\nUserId:[{user.ID}]");
return Ok(jwtUser);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(SignUp)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Route("/clientapi/user/login"), Authorize(Policy = Policies.IsUser), AllowAnonymous]
public async Task<IActionResult> Login(LoginForm loginForm)
{
if (User.Identity?.IsAuthenticated ?? false) return Redirect("/discussions");
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(Localizer["Invalid model."]));
try
{
result = await UsersService.LoginAsync(loginForm);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
var (user, userSettings) =
((RootUser, ViewAvatarServer))result.Data;
var jwtUser = AuthTokenManager.GenerateToken(user, userSettings);
Logger.LogInformation(
$"{nameof(Login)}();IP:[{HttpContext.Connection?.RemoteIpAddress}];\nUser-Agent:[{Request.Headers["User-Agent"]}];\nUserId:[{user.ID}]");
return Ok(jwtUser);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(Login)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
//[HttpPost, Authorize(Policy = Policies.IsUser), AllowAnonymous]
//public async Task<IActionResult> InvitationSignUp(InvitationLoginForm signUpForm)
//{
// if (User.Identity?.IsAuthenticated ?? false) return Redirect("/discussions");
// var result = new WebResult();
// if (!ModelState.IsValid)
// return BadRequest(result.Invalidate(Localizer["Invalid model."]));
// try
// {
// result = await DiscussionsService.GetInvitationConfiguration(signUpForm.InvitationCode, includePassword: true);
// if (!result.IsValid)
// return StatusCode(result.StatusCode, result);
// var configuration = result.Data as InvitationConfiguration;
// if (configuration.IsPasswordRequired && signUpForm.InvitationPassword != configuration.Password)
// {
// result.Invalidate(Localizer["Invalid password."], StatusCodes.Status406NotAcceptable);
// return StatusCode(result.StatusCode, result);
// }
// result = await UsersService.SignUpAsync(new LoginForm
// {
// Username = signUpForm.Username,
// Password = signUpForm.Password,
// LightThemeIndexColour = signUpForm.ThemeIndexColour,
// ThemeIsDarkMode = signUpForm.ThemeIsDarkMode,
// InvitationPassword = signUpForm.InvitationPassword
// }, signUpForm.InvitationCode, configuration.IsPasswordRequired);
// if (!result.IsValid)
// return StatusCode(result.StatusCode, result);
// (var user, var userSettings) = ((User, ViewUserSettings))result.Data;
// var jwtUser = AuthTokenManager.GenerateToken(user, userSettings);
// Logger.LogInformation(
// $"{nameof(InvitationSignUp)}();IP:[{HttpContext.Connection?.RemoteIpAddress}];\nUser-Agent:[{Request.Headers["User-Agent"]}];\nUserId:[{user.ID}]");
// return Ok(jwtUser);
// }
// catch (Exception ex)
// {
// Logger.LogError(ex, $"{nameof(User)}.{nameof(InvitationSignUp)}()");
// return BadRequest(result.Invalidate(ex.Message));
// }
//}
//[HttpPost, Authorize(Policy = Policies.IsUser), AllowAnonymous]
//public async Task<IActionResult> InvitationLogin(InvitationLoginForm loginForm)
//{
// if (User.Identity?.IsAuthenticated ?? false) return Redirect("/discussions" + loginForm.InvitationCode);
// var result = new WebResult();
// if (!ModelState.IsValid)
// return BadRequest(result.Invalidate(Localizer["Invalid model."]));
// try
// {
// result = await DiscussionsService.GetInvitationConfiguration(loginForm.InvitationCode, includePassword: true);
// if (!result.IsValid)
// return StatusCode(result.StatusCode, result);
// var configuration = result.Data as InvitationConfiguration;
// if (configuration.IsPasswordRequired && loginForm.InvitationPassword != configuration.Password)
// {
// result.Invalidate(Localizer["Invalid password."], StatusCodes.Status406NotAcceptable);
// return StatusCode(result.StatusCode, result);
// }
// result = await UsersService.LoginAsync(new LoginForm
// {
// Username = loginForm.Username,
// Password = loginForm.Password,
// ThemeIsDarkMode = loginForm.ThemeIsDarkMode,
// LightThemeIndexColour = loginForm.ThemeIndexColour,
// InvitationPassword = loginForm.InvitationPassword
// }, loginForm.InvitationCode);
// if (!result.IsValid)
// return StatusCode(result.StatusCode, result);
// var (user, userSettings/*, userCurrentTier*/) = ((User, ViewUserSettings/*, UserCurrentTier*/))result.Data;
// var jwtUser = AuthTokenManager.GenerateToken(user, userSettings, 0
// /*userCurrentTier == null ? default : (userCurrentTier.EndPeriod - DateTime.UtcNow).Days*/);
// Logger.LogInformation(
// $"{nameof(InvitationLogin)}();IP:[{HttpContext.Connection?.RemoteIpAddress}];\nUser-Agent:[{Request.Headers["User-Agent"]}];\nUserId:[{user.ID}]");
// return Ok(jwtUser);
// }
// catch (Exception ex)
// {
// Logger.LogError(ex, $"{nameof(User)}.{nameof(InvitationLogin)}()");
// return BadRequest(result.Invalidate(ex.Message));
// }
//}
[HttpGet, Route("/clientapi/user/logout"), Authorize(Policy = Policies.IsUser)]
public IActionResult Logout()
{
var result = new WebResult();
try
{
return Ok();
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(Logout)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Route("/clientapi/user/update"), Authorize(Policy = Policies.IsUser)]
public async Task<IActionResult> UpdateUser(UserForm userEmailForm)
{
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(Localizer["Invalid model."]));
try
{
result = await UsersService.UpdateUserAsync(userEmailForm, User.GetUserId());
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok();
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(UpdateUser)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Route("/clientapi/user/update/settings"), Authorize(Policy = Policies.IsUser)]
public async Task<IActionResult> UpdateUserSettings(ViewAvatarServer userSettings)
{
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(Localizer["Invalid model."]));
try
{
result = await UsersService.UpdateUserSettingsAsync(userSettings, User.GetUserId());
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok();
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(UpdateUserSettings)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Route("/clientapi/user/update/password"), Authorize(Policy = Policies.IsUser)]
public async Task<IActionResult> UpdatePassword(UserPasswordForm userPasswordForm)
{
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(Localizer["Invalid model."]));
try
{
result = await UsersService.UpdateUserPasswordAsync(userPasswordForm, User.GetUserId());
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok();
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(UpdatePassword)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
//[HttpGet, Authorize(Policy = Policies.IsUser)]
//public async Task<IActionResult> GetUser()
//{
// var result = new WebResult();
// try
// {
// result = await UsersService.GetUserAsync(User.GetUserId());
// if (!result.IsValid)
// return StatusCode(result.StatusCode, result);
// return Ok(result.Data);
// }
// catch (Exception ex)
// {
// Logger.LogError(ex, $"{nameof(User)}.{nameof(GetUser)}()");
// return BadRequest(result.Invalidate(ex.Message));
// }
//}
[HttpGet, Route("/clientapi/user/settings"), Authorize(Policy = Policies.IsUser)]
public async Task<IActionResult> GetUserSettings()
{
var result = new WebResult();
try
{
result = await UsersService.GetUserSettingsAsync(User.GetUserId());
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok(result.Data);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(GetUserSettings)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Route("/clientapi/user/recover/password"), AllowAnonymous]
public async Task<IActionResult> RecoverPassword(PasswordRecoveryForm passwordRecoveryForm)
{
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(Localizer["Invalid model."]));
try
{
var host = $"{Request.Scheme}://{Request.Host.Host}";
result = await UsersService.SetupAndSendRecoveryEmail(passwordRecoveryForm, host);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok(result);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(RecoverPassword)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Route("/clientapi/user/recover/valid"), AllowAnonymous]
public async Task<IActionResult> IsValidRecoveryCode(
[FromBody,
Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
Display(Name = "RecoveryCode", ResourceType = typeof(FieldsNameResource))]
string recoveryCode)
{
var result = new WebResult();
try
{
result = await UsersService.IsValidRecoveryCode(recoveryCode);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok(result.Data);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(IsValidRecoveryCode)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
[HttpPost, Route("/clientapi/user/recover/update/password"), AllowAnonymous]
public async Task<IActionResult> ChangePassword(NewPasswordForm newPasswordForm)
{
var result = new WebResult();
if (!ModelState.IsValid)
return BadRequest(result.Invalidate(Localizer["Invalid model."]));
try
{
result = await UsersService.ChangePassword(newPasswordForm);
if (!result.IsValid)
return StatusCode(result.StatusCode, result);
return Ok(result.Data);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(User)}.{nameof(ChangePassword)}()");
return BadRequest(result.Invalidate(ex.Message));
}
}
//[HttpDelete, Route("delete"), Authorize(Policy = Policies.IsUser)]
//public async Task<IActionResult> RemoveSelf()
//{
// var result = new WebResult();
// try
// {
// //result = await UsersService.RemoveUserAsync(User.GetUserId());
// if (!result.IsValid)
// return StatusCode(result.StatusCode, result);
// await HttpContext.SignOutAsync();
// return Ok();
// }
// catch (Exception ex)
// {
// Logger.LogError(ex, $"{nameof(User)}.{nameof(RemoveSelf)}()");
// return BadRequest(result.Invalidate(ex.Message));
// }
//}
#endregion User endpoints
#region Auth refresh
[HttpGet, Route("/clientapi/user/sniff/again"), Authorize(Policy = Policies.IsUser)]
public async Task<IActionResult> SniffAgain()
{
return Ok();
}
#endregion
}
}

View File

@ -0,0 +1,111 @@
using Markdig;
using Microsoft.AspNetCore.Mvc;
using PrivaPub.ClientModels.Resources;
using PrivaPub.Extensions;
using PrivaPub.Models.ActivityPub;
using PrivaPub.Models.Group;
using PrivaPub.Services;
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
namespace PrivaPub.Controllers.ServerToServer
{
[ApiController,
Route("peasants"), Produces("application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"; charset=utf-8")]
public class PeasantsController : ControllerBase
{
readonly IGroupUsersService _groupUsersService;
public PeasantsController(IGroupUsersService groupUsersService)
{
_groupUsersService = groupUsersService;
}
[HttpGet, Route("{actor}")]
public async Task<IActionResult> GetActor(
[Required(ErrorMessageResourceName = "Required",
ErrorMessageResourceType = typeof(FieldsNameResource))] string actor,
CancellationToken cancellation)
{
var getResult = await _groupUsersService.GetGroup(actor, cancellation);
if (!getResult.IsValid)
return StatusCode(getResult.StatusCode, getResult);
var actorResponse = new ActivityPubActor();
actorResponse.Context[1] = string.Format(actorResponse.Context[1].ToString(), HttpContext.Request.PathBase);
actorResponse.Id = HttpContext.GetHostWithPath();
actorResponse.ProfileURL = HttpContext.GetHostWithPath();
actorResponse.Inbox = $"{HttpContext.GetHostWithPath()}/mouth";
actorResponse.Outbox = $"{HttpContext.GetHostWithPath()}/anus";
actorResponse.Endpoints = new()
{
SharedInboxURL = $"{HttpContext.GetHostWithPath()}/human-centipede",
OAuthAuthorizationEndpoint = $"{HttpContext.GetHost()}/sniff/again",
};
actorResponse.PreferredUsername = actor;
actorResponse.Name = actor;
if (getResult.Data is DmGroup dmGroup)
{
actorResponse.Summary = Markdown.ToHtml(dmGroup.Description);
actorResponse.Published = dmGroup.CreationDate;
}
else if (getResult.Data is Group dbGroup)
{
actorResponse.Summary = Markdown.ToHtml(dbGroup.Description);
actorResponse.Published = dbGroup.CreationDate;
}
return Ok(actorResponse);
}
[HttpGet, Route("{actor}/anus")]
public async Task<IActionResult> Anus(
[FromQuery] bool? page,
[Required(ErrorMessageResourceName = "Required",
ErrorMessageResourceType = typeof(FieldsNameResource))] string actor)
{
if (!page.HasValue)
return Ok(new ActivityPubOrderedCollection
{
Id = HttpContext.Request.Path,
FirstItem = $"{HttpContext.GetHostWithPath()}?page=true",
});
return Ok();
}
[HttpPost, Route("{actor}/mouth")]
public async Task<IActionResult> Month(
[Required(ErrorMessageResourceName = "Required",
ErrorMessageResourceType = typeof(FieldsNameResource))] string actor,
[FromBody] JsonDocument json)
{
return Ok();
}
[HttpPost, Route("{actor}/human-centipede")]
public async Task<IActionResult> HumanCentipede(
[Required(ErrorMessageResourceName = "Required",
ErrorMessageResourceType = typeof(FieldsNameResource))] string actor,
[FromBody] JsonDocument json)
{
return Ok();
}
[HttpPost, Route("/human-centipede")]
public async Task<IActionResult> PublicHumanCentipede(
[FromBody] JsonDocument json)
{
return Ok();
}
}
}

View File

@ -0,0 +1,69 @@
using Markdig;
using Microsoft.AspNetCore.Mvc;
using PrivaPub.ClientModels.Resources;
using PrivaPub.Extensions;
using PrivaPub.Models.ActivityPub;
using PrivaPub.Models.Group;
using PrivaPub.Services;
using System.ComponentModel.DataAnnotations;
namespace PrivaPub.Controllers.ServerToServer
{
[ApiController,
Route("users"), Produces("application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"; charset=utf-8")]
public class UsersController : ControllerBase
{
readonly IRootUsersService _rootUsersService;
public UsersController(IRootUsersService rootUsersService)
{
_rootUsersService = rootUsersService;
}
[HttpGet, Route("{actor}")]
public async Task<IActionResult> GetActor(
[Required(ErrorMessageResourceName = "Required",
ErrorMessageResourceType = typeof(FieldsNameResource))] string actor,
CancellationToken cancellation)
{
var getResult = await _groupUsersService.GetGroup(actor, cancellation);
if (!getResult.IsValid)
return StatusCode(getResult.StatusCode, getResult);
var actorResponse = new ActivityPubActor();
actorResponse.Context[1] = string.Format(actorResponse.Context[1].ToString(), HttpContext.Request.PathBase);
actorResponse.Id = $"{HttpContext.GetHost()}/peasants/{actor}";
actorResponse.ProfileURL = $"{HttpContext.GetHost()}/peasants/{actor}";
actorResponse.Inbox = $"{HttpContext.GetHost()}/peasants/{actor}/mouth";
actorResponse.Outbox = $"{HttpContext.GetHost()}/peasants/{actor}/anus";
actorResponse.Endpoints = new()
{
SharedInboxURL = $"{HttpContext.GetHost()}/peasants/{actor}/human-centipede",
OAuthAuthorizationEndpoint = $"{HttpContext.GetHost()}/sniff/again",
};
actorResponse.PreferredUsername = actor;
actorResponse.Name = actor;
if (getResult.Data is DmGroup dmGroup)
{
actorResponse.Summary = Markdown.ToHtml(dmGroup.Description);
actorResponse.Published = dmGroup.CreationDate;
}
else if (getResult.Data is Group dbGroup)
{
actorResponse.Summary = Markdown.ToHtml(dbGroup.Description);
actorResponse.Published = dbGroup.CreationDate;
}
return Ok(actorResponse);
}
#region Admin
#endregion
}
}