2021-04-11 22:04:12 +00:00
|
|
|
|
using System;
|
2021-07-19 22:15:27 +00:00
|
|
|
|
using System.Collections.Generic;
|
2021-04-11 22:04:12 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net;
|
2021-09-27 12:42:46 +00:00
|
|
|
|
using System.Net.Http;
|
2021-04-11 22:04:12 +00:00
|
|
|
|
using System.Security.Claims;
|
2022-09-19 20:50:49 +00:00
|
|
|
|
using System.Text.Json;
|
2021-04-11 22:04:12 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2021-05-28 23:40:58 +00:00
|
|
|
|
using FluentFTP.Helpers;
|
2021-04-11 22:04:12 +00:00
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Nettle;
|
|
|
|
|
using Wabbajack.Common;
|
2022-04-02 16:01:38 +00:00
|
|
|
|
using Wabbajack.DTOs;
|
2021-09-27 12:42:46 +00:00
|
|
|
|
using Wabbajack.DTOs.GitHub;
|
|
|
|
|
using Wabbajack.DTOs.JsonConverters;
|
|
|
|
|
using Wabbajack.Networking.GitHub;
|
|
|
|
|
using Wabbajack.Paths.IO;
|
2022-04-02 16:01:38 +00:00
|
|
|
|
using Wabbajack.RateLimiter;
|
2021-11-27 20:03:14 +00:00
|
|
|
|
using Wabbajack.Server.DataModels;
|
2021-12-20 16:22:40 +00:00
|
|
|
|
using Wabbajack.Server.Extensions;
|
2021-07-20 05:08:12 +00:00
|
|
|
|
using Wabbajack.Server.Services;
|
2021-04-11 22:04:12 +00:00
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
namespace Wabbajack.BuildServer.Controllers;
|
|
|
|
|
|
|
|
|
|
[Authorize(Roles = "Author")]
|
|
|
|
|
[Route("/author_controls")]
|
|
|
|
|
public class AuthorControls : ControllerBase
|
2021-04-11 22:04:12 +00:00
|
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
|
private readonly HttpClient _client;
|
|
|
|
|
private readonly DTOSerializer _dtos;
|
|
|
|
|
private readonly Client _gitHubClient;
|
|
|
|
|
private readonly QuickSync _quickSync;
|
|
|
|
|
private readonly AppSettings _settings;
|
|
|
|
|
private readonly ILogger<AuthorControls> _logger;
|
2021-11-27 20:03:14 +00:00
|
|
|
|
private readonly AuthorFiles _authorFiles;
|
2022-04-02 16:01:38 +00:00
|
|
|
|
private readonly IResource<HttpClient> _limiter;
|
2021-10-23 16:51:17 +00:00
|
|
|
|
|
2021-11-27 20:03:14 +00:00
|
|
|
|
public AuthorControls(ILogger<AuthorControls> logger, QuickSync quickSync, HttpClient client,
|
|
|
|
|
AppSettings settings, DTOSerializer dtos, AuthorFiles authorFiles,
|
2022-04-02 16:01:38 +00:00
|
|
|
|
Client gitHubClient, IResource<HttpClient> limiter)
|
2021-10-23 16:51:17 +00:00
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
|
|
|
|
_quickSync = quickSync;
|
|
|
|
|
_client = client;
|
|
|
|
|
_settings = settings;
|
|
|
|
|
_dtos = dtos;
|
|
|
|
|
_gitHubClient = gitHubClient;
|
2021-11-27 20:03:14 +00:00
|
|
|
|
_authorFiles = authorFiles;
|
2022-04-02 16:01:38 +00:00
|
|
|
|
_limiter = limiter;
|
2021-10-23 16:51:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Route("login/{authorKey}")]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<IActionResult> Login(string authorKey)
|
|
|
|
|
{
|
|
|
|
|
Response.Cookies.Append(ApiKeyAuthenticationHandler.ApiKeyHeaderName, authorKey);
|
|
|
|
|
return Redirect($"{_settings.WabbajackBuildServerUri}author_controls/home");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Route("lists")]
|
|
|
|
|
[HttpGet]
|
|
|
|
|
public async Task<IActionResult> AuthorLists()
|
2021-04-11 22:04:12 +00:00
|
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
|
var user = User.FindFirstValue(ClaimTypes.Name);
|
2022-04-02 16:01:38 +00:00
|
|
|
|
var lists = (await LoadLists())
|
|
|
|
|
.Where(l => l.Maintainers.Contains(user))
|
|
|
|
|
.Select(l => l.NamespacedName)
|
|
|
|
|
.ToArray();
|
2021-10-23 16:51:17 +00:00
|
|
|
|
|
|
|
|
|
return Ok(lists);
|
|
|
|
|
}
|
2022-04-02 16:01:38 +00:00
|
|
|
|
|
|
|
|
|
public async Task<ModlistMetadata[]> LoadLists()
|
|
|
|
|
{
|
|
|
|
|
var repos = await LoadRepositories();
|
|
|
|
|
|
|
|
|
|
return await repos.PMapAll(async url =>
|
2022-09-19 20:50:49 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
2022-04-02 16:01:38 +00:00
|
|
|
|
{
|
2022-09-19 20:50:49 +00:00
|
|
|
|
return (await _client.GetFromJsonAsync<ModlistMetadata[]>(_limiter,
|
|
|
|
|
new HttpRequestMessage(HttpMethod.Get, url.Value),
|
|
|
|
|
_dtos.Options))!.Select(meta =>
|
|
|
|
|
{
|
|
|
|
|
meta.RepositoryName = url.Key;
|
|
|
|
|
return meta;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
catch (JsonException ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "While loading repository {Name} from {Url}", url.Key, url.Value);
|
|
|
|
|
return Enumerable.Empty<ModlistMetadata>();
|
|
|
|
|
}
|
|
|
|
|
})
|
2022-04-02 16:01:38 +00:00
|
|
|
|
.SelectMany(x => x)
|
|
|
|
|
.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<Dictionary<string, Uri>> LoadRepositories()
|
|
|
|
|
{
|
|
|
|
|
var repositories = await _client.GetFromJsonAsync<Dictionary<string, Uri>>(_limiter,
|
|
|
|
|
new HttpRequestMessage(HttpMethod.Get,
|
|
|
|
|
"https://raw.githubusercontent.com/wabbajack-tools/mod-lists/master/repositories.json"), _dtos.Options);
|
|
|
|
|
return repositories!;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-02 16:32:55 +00:00
|
|
|
|
[Route("whoami")]
|
|
|
|
|
[HttpGet]
|
|
|
|
|
public async Task<IActionResult> GetWhoAmI()
|
|
|
|
|
{
|
|
|
|
|
var user = User.FindFirstValue(ClaimTypes.Name);
|
|
|
|
|
return Ok(user!);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 22:04:12 +00:00
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
[Route("lists/download_metadata")]
|
|
|
|
|
[HttpPost]
|
|
|
|
|
public async Task<IActionResult> PostDownloadMetadata()
|
|
|
|
|
{
|
|
|
|
|
var user = User.FindFirstValue(ClaimTypes.Name);
|
|
|
|
|
var data = await _dtos.DeserializeAsync<UpdateRequest>(Request.Body);
|
|
|
|
|
try
|
2021-04-11 22:04:12 +00:00
|
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
|
await _gitHubClient.UpdateList(user, data);
|
2021-04-11 22:04:12 +00:00
|
|
|
|
}
|
2021-10-23 16:51:17 +00:00
|
|
|
|
catch (Exception ex)
|
2021-04-11 22:04:12 +00:00
|
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
|
_logger.LogError(ex, "During posting of download_metadata");
|
|
|
|
|
return BadRequest(ex);
|
2021-04-11 22:04:12 +00:00
|
|
|
|
}
|
2021-07-19 22:15:27 +00:00
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
return Ok(data);
|
|
|
|
|
}
|
2021-07-19 22:15:27 +00:00
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
private static async Task<string> HomePageTemplate(object o)
|
|
|
|
|
{
|
|
|
|
|
var data = await KnownFolders.EntryPoint.Combine(@"Controllers\Templates\AuthorControls.html")
|
|
|
|
|
.ReadAllTextAsync();
|
2021-12-20 16:31:10 +00:00
|
|
|
|
var func = NettleEngine.GetCompiler().Compile(data);
|
2021-10-23 16:51:17 +00:00
|
|
|
|
return func(o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Route("home")]
|
|
|
|
|
[Authorize("")]
|
|
|
|
|
public async Task<IActionResult> HomePage()
|
|
|
|
|
{
|
|
|
|
|
var user = User.FindFirstValue(ClaimTypes.Name);
|
2021-11-27 20:03:14 +00:00
|
|
|
|
var files = (await _authorFiles.AllAuthoredFiles())
|
|
|
|
|
.Where(af => af.Definition.Author == user)
|
2021-10-23 16:51:17 +00:00
|
|
|
|
.Select(af => new
|
2021-07-19 22:15:27 +00:00
|
|
|
|
{
|
2021-11-27 20:03:14 +00:00
|
|
|
|
Size = af.Definition.Size.FileSizeToString(),
|
|
|
|
|
OriginalSize = af.Definition.Size,
|
|
|
|
|
Name = af.Definition.OriginalFileName,
|
|
|
|
|
MangledName = af.Definition.MungedName,
|
|
|
|
|
UploadedDate = af.Updated
|
2021-10-23 16:51:17 +00:00
|
|
|
|
})
|
|
|
|
|
.OrderBy(f => f.Name)
|
|
|
|
|
.ThenBy(f => f.UploadedDate)
|
|
|
|
|
.ToList();
|
2021-04-11 22:04:12 +00:00
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
var result = HomePageTemplate(new
|
2021-04-11 22:04:12 +00:00
|
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
|
User = user,
|
|
|
|
|
TotalUsage = files.Select(f => f.OriginalSize).Sum().ToFileSizeString(),
|
|
|
|
|
WabbajackFiles = files.Where(f => f.Name.EndsWith(Ext.Wabbajack.ToString())),
|
|
|
|
|
OtherFiles = files.Where(f => !f.Name.EndsWith(Ext.Wabbajack.ToString()))
|
|
|
|
|
});
|
2021-04-11 22:04:12 +00:00
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
return new ContentResult
|
|
|
|
|
{
|
|
|
|
|
ContentType = "text/html",
|
|
|
|
|
StatusCode = (int) HttpStatusCode.OK,
|
|
|
|
|
Content = await result
|
|
|
|
|
};
|
2021-04-11 22:04:12 +00:00
|
|
|
|
}
|
2021-10-23 16:51:17 +00:00
|
|
|
|
}
|