Kavita Auth is a pain.

This commit is contained in:
glax 2023-06-03 21:26:29 +02:00
parent 7612411917
commit 496d502cd2
9 changed files with 109 additions and 48 deletions

View File

@ -210,7 +210,7 @@ app.MapDelete("/Queue/Dequeue", (string taskType, string? connectorName, string?
app.MapGet("/Settings/Get", () => taskManager.settings);
app.MapPost("/Settings/Update",
(string? downloadLocation, string? komgaUrl, string? komgaAuth, string? kavitaUrl, string? kavitaApiKey) =>
taskManager.UpdateSettings(downloadLocation, komgaUrl, komgaAuth, kavitaUrl, kavitaApiKey));
(string? downloadLocation, string? komgaUrl, string? komgaAuth, string? kavitaUrl, string? kavitaUsername, string? kavitaPassword) =>
taskManager.UpdateSettings(downloadLocation, komgaUrl, komgaAuth, kavitaUrl, kavitaUsername, kavitaPassword));
app.Run();

View File

@ -47,32 +47,32 @@ public static class Tranga_Cli
if (tmpUrlKomga.Length > 0)
{
Console.WriteLine("Username:");
string? tmpUser = Console.ReadLine();
while (tmpUser is null || tmpUser.Length < 1)
tmpUser = Console.ReadLine();
string? tmpKomgaUser = Console.ReadLine();
while (tmpKomgaUser is null || tmpKomgaUser.Length < 1)
tmpKomgaUser = Console.ReadLine();
Console.WriteLine("Password:");
string tmpPass = string.Empty;
string tmpKomgaPass = string.Empty;
ConsoleKey key;
do
{
var keyInfo = Console.ReadKey(intercept: true);
key = keyInfo.Key;
if (key == ConsoleKey.Backspace && tmpPass.Length > 0)
if (key == ConsoleKey.Backspace && tmpKomgaPass.Length > 0)
{
Console.Write("\b \b");
tmpPass = tmpPass[0..^1];
tmpKomgaPass = tmpKomgaPass[0..^1];
}
else if (!char.IsControl(keyInfo.KeyChar))
{
Console.Write("*");
tmpPass += keyInfo.KeyChar;
tmpKomgaPass += keyInfo.KeyChar;
}
} while (key != ConsoleKey.Enter);
settings.libraryManagers.RemoveWhere(lm => lm.GetType() == typeof(Komga));
settings.libraryManagers.Add(new Komga(tmpUrlKomga, tmpUser, tmpPass, logger));
settings.libraryManagers.Add(new Komga(tmpUrlKomga, tmpKomgaUser, tmpKomgaPass, logger));
}
Console.WriteLine($"Kavita BaseURL [{settings.libraryManagers.FirstOrDefault(lm => lm.GetType() == typeof(Kavita))?.baseUrl}]:");
@ -82,12 +82,32 @@ public static class Tranga_Cli
if (tmpUrlKavita.Length > 0)
{
Console.WriteLine("Username:");
string? tmpApiKey = Console.ReadLine();
while (tmpApiKey is null || tmpApiKey.Length < 1)
tmpApiKey = Console.ReadLine();
string? tmpKavitaUser = Console.ReadLine();
while (tmpKavitaUser is null || tmpKavitaUser.Length < 1)
tmpKavitaUser = Console.ReadLine();
Console.WriteLine("Password:");
string tmpKavitaPass = string.Empty;
ConsoleKey key;
do
{
var keyInfo = Console.ReadKey(intercept: true);
key = keyInfo.Key;
if (key == ConsoleKey.Backspace && tmpKavitaPass.Length > 0)
{
Console.Write("\b \b");
tmpKavitaPass = tmpKavitaPass[0..^1];
}
else if (!char.IsControl(keyInfo.KeyChar))
{
Console.Write("*");
tmpKavitaPass += keyInfo.KeyChar;
}
} while (key != ConsoleKey.Enter);
settings.libraryManagers.RemoveWhere(lm => lm.GetType() == typeof(Kavita));
settings.libraryManagers.Add(new Kavita(tmpUrlKavita, tmpApiKey, logger));
settings.libraryManagers.Add(new Kavita(tmpUrlKavita, tmpKavitaUser, tmpKavitaPass, logger));
}
logger.WriteLine("Tranga_CLI", "Loaded.");

View File

@ -17,7 +17,7 @@ public abstract class LibraryManager
public LibraryType libraryType { get; }
public string baseUrl { get; }
protected string auth { get; } //Base64 encoded, if you use your password everywhere, you have problems
public string auth { get; } //Base64 encoded, if you use your password everywhere, you have problems
protected Logger? logger;
/// <param name="baseUrl">Base-URL of Komga instance, no trailing slashes(/)</param>
@ -39,11 +39,10 @@ public abstract class LibraryManager
protected static class NetClient
{
public static Stream MakeRequest(string url, string auth, Logger? logger)
public static Stream MakeRequest(string url, string authScheme, string auth, Logger? logger)
{
HttpClientHandler clientHandler = new ();
HttpClient client = new(clientHandler);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth);
HttpClient client = new();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authScheme, auth);
HttpRequestMessage requestMessage = new ()
{
@ -55,22 +54,21 @@ public abstract class LibraryManager
logger?.WriteLine("LibraryManager", $"{(int)response.StatusCode} {response.StatusCode}: {response.ReasonPhrase}");
if(response.StatusCode is HttpStatusCode.Unauthorized && response.RequestMessage!.RequestUri!.AbsoluteUri != url)
return MakeRequest(response.RequestMessage!.RequestUri!.AbsoluteUri, auth, logger);
return MakeRequest(response.RequestMessage!.RequestUri!.AbsoluteUri, authScheme, auth, logger);
else if (response.IsSuccessStatusCode)
return response.Content.ReadAsStream();
else
return Stream.Null;
}
public static bool MakePost(string url, string auth, Logger? logger)
public static bool MakePost(string url, string authScheme, string auth, Logger? logger)
{
HttpClientHandler clientHandler = new ();
HttpClient client = new(clientHandler)
HttpClient client = new()
{
DefaultRequestHeaders =
{
{ "Accept", "application/json" },
{ "Authorization", new AuthenticationHeaderValue("Basic", auth).ToString() }
{ "Authorization", new AuthenticationHeaderValue(authScheme, auth).ToString() }
}
};
HttpRequestMessage requestMessage = new ()
@ -83,7 +81,7 @@ public abstract class LibraryManager
logger?.WriteLine("LibraryManager", $"{(int)response.StatusCode} {response.StatusCode}: {response.ReasonPhrase}");
if(response.StatusCode is HttpStatusCode.Unauthorized && response.RequestMessage!.RequestUri!.AbsoluteUri != url)
return MakePost(response.RequestMessage!.RequestUri!.AbsoluteUri, auth, logger);
return MakePost(response.RequestMessage!.RequestUri!.AbsoluteUri, authScheme, auth, logger);
else if (response.IsSuccessStatusCode)
return true;
else

View File

@ -1,20 +1,50 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Nodes;
using Logging;
using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace Tranga.LibraryManagers;
public class Kavita : LibraryManager
{
public Kavita(string baseUrl, string apiKey, Logger? logger) : base(baseUrl, apiKey, logger, LibraryType.Kavita)
public Kavita(string baseUrl, string username, string password, Logger? logger) : base(baseUrl, GetToken(baseUrl, username, password), logger, LibraryType.Kavita)
{
}
[JsonConstructor]
public Kavita(string baseUrl, string auth, Logger? logger) : base(baseUrl, auth, logger, LibraryType.Kavita)
{
}
private static string GetToken(string baseUrl, string username, string password)
{
HttpClient client = new()
{
DefaultRequestHeaders =
{
{ "Accept", "application/json" }
}
};
HttpRequestMessage requestMessage = new ()
{
Method = HttpMethod.Post,
RequestUri = new Uri($"{baseUrl}/api/Account/login"),
Content = new StringContent($"{{\"username\":\"{username}\",\"password\":\"{password}\"}}", System.Text.Encoding.UTF8, "application/json")
};
HttpResponseMessage response = client.Send(requestMessage);
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(response.Content.ReadAsStream());
if (result is not null)
return result!["token"]!.GetValue<string>();
else return "";
}
public override void UpdateLibrary()
{
logger?.WriteLine(this.GetType().ToString(), $"Updating Libraries");
foreach (KavitaLibrary lib in GetLibraries())
NetClient.MakePost($"{baseUrl}/api/Library/scan?libraryId={lib.id}", auth, logger);
NetClient.MakePost($"{baseUrl}/api/Library/scan?libraryId={lib.id}", "Bearer", auth, logger);
}
/// <summary>
@ -24,7 +54,7 @@ public class Kavita : LibraryManager
private IEnumerable<KavitaLibrary> GetLibraries()
{
logger?.WriteLine(this.GetType().ToString(), $"Getting Libraries");
Stream data = NetClient.MakeRequest($"{baseUrl}/api/Library", auth, logger);
Stream data = NetClient.MakeRequest($"{baseUrl}/api/Library", "Bearer", auth, logger);
if (data == Stream.Null)
{
logger?.WriteLine(this.GetType().ToString(), $"No libraries returned");
@ -42,7 +72,7 @@ public class Kavita : LibraryManager
foreach (JsonNode? jsonNode in result)
{
var jObject = (JsonObject?)jsonNode;
string libraryId = jObject!["id"]!.GetValue<string>();
int libraryId = jObject!["id"]!.GetValue<int>();
string libraryName = jObject!["name"]!.GetValue<string>();
ret.Add(new KavitaLibrary(libraryId, libraryName));
}
@ -52,10 +82,10 @@ public class Kavita : LibraryManager
private struct KavitaLibrary
{
public string id { get; }
public int id { get; }
public string name { get; }
public KavitaLibrary(string id, string name)
public KavitaLibrary(int id, string name)
{
this.id = id;
this.name = name;

View File

@ -25,7 +25,7 @@ public class Komga : LibraryManager
{
logger?.WriteLine(this.GetType().ToString(), $"Updating Libraries");
foreach (KomgaLibrary lib in GetLibraries())
NetClient.MakePost($"{baseUrl}/api/v1/libraries/{lib.id}/scan", auth, logger);
NetClient.MakePost($"{baseUrl}/api/v1/libraries/{lib.id}/scan", "Basic", auth, logger);
}
/// <summary>
@ -35,7 +35,7 @@ public class Komga : LibraryManager
private IEnumerable<KomgaLibrary> GetLibraries()
{
logger?.WriteLine(this.GetType().ToString(), $"Getting Libraries");
Stream data = NetClient.MakeRequest($"{baseUrl}/api/v1/libraries", auth, logger);
Stream data = NetClient.MakeRequest($"{baseUrl}/api/v1/libraries", "Basic", auth, logger);
if (data == Stream.Null)
{
logger?.WriteLine(this.GetType().ToString(), $"No libraries returned");

View File

@ -47,17 +47,17 @@ public class TaskManager
taskChecker.Start();
}
public void UpdateSettings(string? downloadLocation, string? komgaUrl, string? komgaAuth, string? kavitaUrl, string? kavitaApiKey)
public void UpdateSettings(string? downloadLocation, string? komgaUrl, string? komgaAuth, string? kavitaUrl, string? kavitaUsername, string? kavitaPassword)
{
if (komgaUrl is not null && komgaAuth is not null && komgaUrl.Length > 0 && komgaAuth.Length > 0)
{
settings.libraryManagers.RemoveWhere(lm => lm.GetType() == typeof(Komga));
settings.libraryManagers.Add(new Komga(komgaUrl, komgaAuth, logger));
}
if (kavitaUrl is not null && kavitaApiKey is not null && kavitaUrl.Length > 0 && kavitaApiKey.Length > 0)
if (kavitaUrl is not null && kavitaUsername is not null && kavitaPassword is not null && kavitaUrl.Length > 0 && kavitaUsername.Length > 0 && kavitaPassword.Length > 0)
{
settings.libraryManagers.RemoveWhere(lm => lm.GetType() == typeof(Kavita));
settings.libraryManagers.Add(new Kavita(kavitaUrl, kavitaApiKey, logger));
settings.libraryManagers.Add(new Kavita(kavitaUrl, kavitaUsername, kavitaPassword, logger));
}
if (downloadLocation is not null && downloadLocation.Length > 0)
settings.downloadLocation = downloadLocation;

View File

@ -104,8 +104,17 @@ function EnqueueTask(taskType, connectorName, publicationId){
PostData(uri);
}
function UpdateSettings(downloadLocation, komgaUrl, komgaAuth){
var uri = apiUri + `/Settings/Update?downloadLocation=${downloadLocation}&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`;
function UpdateSettings(downloadLocation, komgaUrl, komgaAuth, kavitaUrl, kavitaUser, kavitaPass){
var uri = apiUri + "/Settings/Update?"
if(downloadLocation != ""){
uri += "&downloadLocation="+downloadLocation;
}
if(komgaUrl != "" && komgaAuth != ""){
uri += `&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`;
}
if(kavitaUrl != "" && kavitaUser != "" && kavitaPass != ""){
uri += `&kavitaUrl=${kavitaUrl}&kavitaUsername=${kavitaUser}&kavitaPassword=${kavitaPass}`;
}
PostData(uri);
}

View File

@ -99,7 +99,8 @@
<span class="title">Kavita</span>
<div>Configured: <span id="kavitaConfigured">✅❌</span></div>
<label for="kavitaUrl"></label><input placeholder="URL" id="kavitaUrl" type="text">
<label for="kavitaApiKey"></label><input placeholder="API-Key" id="kavitaApiKey" type="text">
<label for="kavitaUsername"></label><input placeholder="Username" id="kavitaUsername" type="text">
<label for="kavitaPassword"></label><input placeholder="Password" id="kavitaPassword" type="password">
</kavita-settings>
<div>
<label for="libraryUpdateTime" style="margin-right: 5px;">Update Time</label><input id="libraryUpdateTime" type="time" value="00:01:00" step="10">

View File

@ -27,7 +27,8 @@ const settingKomgaUrl = document.querySelector("#komgaUrl");
const settingKomgaUser = document.querySelector("#komgaUsername");
const settingKomgaPass = document.querySelector("#komgaPassword");
const settingKavitaUrl = document.querySelector("#kavitaUrl");
const settingKavitaApi = document.querySelector("#kavitaApiKey");
const settingKavitaUser = document.querySelector("#kavitaUsername");
const settingKavitaPass = document.querySelector("#kavitaPassword");
const libraryUpdateTime = document.querySelector("#libraryUpdateTime");
const settingKomgaConfigured = document.querySelector("#komgaConfigured");
const settingKavitaConfigured = document.querySelector("#kavitaConfigured");
@ -243,7 +244,8 @@ function GetSettingsClick(){
settingKomgaUser.value = "";
settingKomgaPass.value = "";
settingKavitaUrl.value = "";
settingKavitaApi.value = "";
settingKavitaUser.value = "";
settingKavitaPass.value = "";
settingKomgaConfigured.innerText = "❌";
settingKavitaConfigured.innerText = "❌";
@ -254,12 +256,13 @@ function GetSettingsClick(){
json.libraryManagers.forEach(lm => {
if(lm.libraryType == 0){
settingKomgaUrl.placeholder = lm.baseUrl;
settingKomgaUser.placeholder = "Configured";
settingKomgaUser.placeholder = "User";
settingKomgaPass.placeholder = "***";
settingKomgaConfigured.innerText = "✅";
} else if(libraryType == 1){
} else if(lm.libraryType == 1){
settingKavitaUrl.placeholder = lm.baseUrl;
settingKavitaApi.placeholder = "***";
settingKavitaUser.placeholder = "User";
settingKavitaPass.placeholder = "***";
settingKavitaConfigured.innerText = "✅";
}
});
@ -282,8 +285,8 @@ function UpdateLibrarySettings(){
UpdateSettings("", settingKomgaUrl.placeholder, auth, "", "");
}
if(settingKavitaUrl.value != "" && settingKavitaApi != ""){
UpdateSettings("", "", "", settingKavitaUrl.value, settingKavitaApi.value);
if(settingKavitaUrl.value != "" && settingKavitaUser.value != "" && settingKavitaPass.value != ""){
UpdateSettings("", "", "", settingKavitaUrl.value, settingKavitaUser.value, settingKavitaPass.value);
}
CreateTask("UpdateLibraries", libraryUpdateTime.value, "","","");
setTimeout(() => GetSettingsClick(), 100);