feat: log in with tumblr
This commit is contained in:
parent
d30ebacc72
commit
3338243cea
10 changed files with 342 additions and 9 deletions
|
@ -53,14 +53,12 @@ public partial class RemoteAuthService
|
|||
throw new FoxnounsError("Invalid Discord OAuth response");
|
||||
}
|
||||
|
||||
DiscordTokenResponse? token = await resp.Content.ReadFromJsonAsync<DiscordTokenResponse>(
|
||||
ct
|
||||
);
|
||||
OauthTokenResponse? token = await resp.Content.ReadFromJsonAsync<OauthTokenResponse>(ct);
|
||||
if (token == null)
|
||||
throw new FoxnounsError("Discord token response was null");
|
||||
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, _discordUserUri);
|
||||
req.Headers.Add("Authorization", $"{token.token_type} {token.access_token}");
|
||||
req.Headers.Add("Authorization", $"{token.TokenType} {token.AccessToken}");
|
||||
|
||||
HttpResponseMessage resp2 = await _httpClient.SendAsync(req, ct);
|
||||
resp2.EnsureSuccessStatusCode();
|
||||
|
|
111
Foxnouns.Backend/Services/Auth/RemoteAuthService.Tumblr.cs
Normal file
111
Foxnouns.Backend/Services/Auth/RemoteAuthService.Tumblr.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Foxnouns.Backend.Services.Auth;
|
||||
|
||||
public partial class RemoteAuthService
|
||||
{
|
||||
private readonly Uri _tumblrTokenUri = new("https://api.tumblr.com/v2/oauth2/token");
|
||||
private readonly Uri _tumblrUserUri = new("https://api.tumblr.com/v2/user/info");
|
||||
|
||||
public async Task<RemoteUser> RequestTumblrTokenAsync(
|
||||
string code,
|
||||
CancellationToken ct = default
|
||||
)
|
||||
{
|
||||
var redirectUri = $"{config.BaseUrl}/auth/callback/tumblr";
|
||||
HttpResponseMessage resp = await _httpClient.PostAsync(
|
||||
_tumblrTokenUri,
|
||||
new FormUrlEncodedContent(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "client_id", config.TumblrAuth.ClientId! },
|
||||
{ "client_secret", config.TumblrAuth.ClientSecret! },
|
||||
{ "grant_type", "authorization_code" },
|
||||
{ "code", code },
|
||||
{ "scope", "basic" },
|
||||
{ "redirect_uri", redirectUri },
|
||||
}
|
||||
),
|
||||
ct
|
||||
);
|
||||
if (!resp.IsSuccessStatusCode)
|
||||
{
|
||||
string respBody = await resp.Content.ReadAsStringAsync(ct);
|
||||
_logger.Error(
|
||||
"Received error status {StatusCode} when exchanging OAuth token: {ErrorBody}",
|
||||
(int)resp.StatusCode,
|
||||
respBody
|
||||
);
|
||||
throw new FoxnounsError("Invalid Tumblr OAuth response");
|
||||
}
|
||||
|
||||
OauthTokenResponse? token = await resp.Content.ReadFromJsonAsync<OauthTokenResponse>(ct);
|
||||
if (token == null)
|
||||
throw new FoxnounsError("Tumblr token response was null");
|
||||
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, _tumblrUserUri);
|
||||
req.Headers.Add("Authorization", $"Bearer {token.AccessToken}");
|
||||
|
||||
HttpResponseMessage resp2 = await _httpClient.SendAsync(req, ct);
|
||||
if (!resp2.IsSuccessStatusCode)
|
||||
{
|
||||
string respBody = await resp2.Content.ReadAsStringAsync(ct);
|
||||
_logger.Error(
|
||||
"Received error status {StatusCode} when exchanging OAuth token: {ErrorBody}",
|
||||
(int)resp2.StatusCode,
|
||||
respBody
|
||||
);
|
||||
throw new FoxnounsError("Invalid Tumblr user response");
|
||||
}
|
||||
|
||||
TumblrData? data = await resp2.Content.ReadFromJsonAsync<TumblrData>(ct);
|
||||
if (data == null)
|
||||
throw new FoxnounsError("Tumblr user response was null");
|
||||
|
||||
TumblrBlog? blog = data.Response.User.Blogs.FirstOrDefault(b => b.Primary);
|
||||
if (blog == null)
|
||||
throw new FoxnounsError("Tumblr user doesn't have a primary blog");
|
||||
|
||||
return new RemoteUser(blog.Uuid, blog.Name);
|
||||
}
|
||||
|
||||
private record OauthTokenResponse(
|
||||
[property: JsonPropertyName("access_token")] string AccessToken,
|
||||
[property: JsonPropertyName("token_type")] string TokenType
|
||||
);
|
||||
|
||||
// tumblr why
|
||||
private record TumblrData(
|
||||
[property: JsonPropertyName("meta")] TumblrMeta Meta,
|
||||
[property: JsonPropertyName("response")] TumblrResponse Response
|
||||
);
|
||||
|
||||
private record TumblrMeta(
|
||||
[property: JsonPropertyName("status")] int Status,
|
||||
[property: JsonPropertyName("msg")] string Message
|
||||
);
|
||||
|
||||
private record TumblrResponse([property: JsonPropertyName("user")] TumblrUser User);
|
||||
|
||||
private record TumblrUser([property: JsonPropertyName("blogs")] TumblrBlog[] Blogs);
|
||||
|
||||
private record TumblrBlog(
|
||||
[property: JsonPropertyName("name")] string Name,
|
||||
[property: JsonPropertyName("primary")] bool Primary,
|
||||
[property: JsonPropertyName("uuid")] string Uuid
|
||||
);
|
||||
}
|
|
@ -19,7 +19,6 @@ using Foxnouns.Backend.Database.Models;
|
|||
using Foxnouns.Backend.Extensions;
|
||||
using Foxnouns.Backend.Utils;
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Foxnouns.Backend.Services.Auth;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue