feat(api): pull SP avatars

This commit is contained in:
alyssa 2025-04-26 12:03:00 +00:00
parent 63d9b411ae
commit 6c0c7a5c99
10 changed files with 153 additions and 58 deletions

View file

@ -6,4 +6,5 @@ public class ApiConfig
public string? ClientId { get; set; }
public string? ClientSecret { get; set; }
public bool TrustAuth { get; set; } = false;
public string? AvatarServiceUrl { get; set; }
}

View file

@ -21,6 +21,12 @@ public class AuthorizationTokenHandlerMiddleware
&& int.TryParse(sidHeaders[0], out var systemId))
ctx.Items.Add("SystemId", new SystemId(systemId));
if (cfg.TrustAuth
&& ctx.Request.Headers.TryGetValue("X-PluralKit-AppId", out var aidHeaders)
&& aidHeaders.Count > 0
&& int.TryParse(aidHeaders[0], out var appId))
ctx.Items.Add("AppId", appId);
await _next.Invoke(ctx);
}
}

View file

@ -1,3 +1,7 @@
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
@ -50,6 +54,9 @@ public class MemberControllerV2: PKControllerBase
if (patch.Errors.Count > 0)
throw new ModelParseError(patch.Errors);
if (patch.AvatarUrl.Value != null)
patch.AvatarUrl = await TryUploadAvatar(patch.AvatarUrl.Value, system);
using var conn = await _db.Obtain();
using var tx = await conn.BeginTransactionAsync();
@ -110,6 +117,9 @@ public class MemberControllerV2: PKControllerBase
if (patch.Errors.Count > 0)
throw new ModelParseError(patch.Errors);
if (patch.AvatarUrl.Value != null)
patch.AvatarUrl = await TryUploadAvatar(patch.AvatarUrl.Value, system);
var newMember = await _repo.UpdateMember(member.Id, patch);
return Ok(newMember.ToJson(LookupContext.ByOwner, systemStr: system.Hid));
}
@ -129,4 +139,28 @@ public class MemberControllerV2: PKControllerBase
return NoContent();
}
private async Task<string> TryUploadAvatar(string avatarUrl, PKSystem system)
{
if (!avatarUrl.StartsWith("https://serve.apparyllis.com/")) return avatarUrl;
if (_config.AvatarServiceUrl == null) return avatarUrl;
if (!HttpContext.Items.TryGetValue("AppId", out var appId) || (int)appId != 1) return avatarUrl;
using var client = new HttpClient();
var response = await client.PostAsJsonAsync(_config.AvatarServiceUrl + "/pull",
new { url = avatarUrl, kind = "avatar", uploaded_by = (string)null, system_id = system.Uuid.ToString() });
if (response.StatusCode != HttpStatusCode.OK)
{
var error = await response.Content.ReadFromJsonAsync<ErrorResponse>();
throw new PKError(500, 0, $"Error uploading image to CDN: {error.Error}");
}
var success = await response.Content.ReadFromJsonAsync<SuccessResponse>();
return success.Url;
}
public record ErrorResponse(string Error);
public record SuccessResponse(string Url, bool New);
}