using Sunfish.Auth;
using Sunfish.Config;
using Sunfish.Net;
namespace Sunfish.Cli;
/// <summary>
/// sunfish-cli admin status|enable|disable|passwd|allow LISTA: panel de administracion web.
/// sunfish-cli import-v2 [FICHERO]: importa la configuracion de Sunfish 2.0.
/// </summary>
internal static class AdminCommands
{
public static int RunAdmin(string[] args)
{
var (configPath, rest) = CommonOptions(args);
if (rest.Count == 0)
{
Console.Error.WriteLine(Texts.AdminUsage);
return 1;
}
string path = ConfigLocator.Find(configPath) ?? ConfigLocator.PortablePath;
var config = File.Exists(path) ? SunfishConfig.Load(path) : new SunfishConfig { FilePath = path };
var admin = config.Admin;
switch (rest[0])
{
case "status" when rest.Count == 1:
Console.WriteLine(admin.Enabled && admin.PasswordHash.Length > 0 ? Texts.AdminOn : Texts.AdminOffText);
Console.WriteLine(Texts.AdminAllowed(string.Join(", ", admin.AllowFrom)));
if (admin.Enabled)
Console.WriteLine(Strings.AdminUrl($"http://127.0.0.1:{config.Server.HttpPort}/$sunfish/admin/"));
return 0;
case "enable" when rest.Count == 1:
if (admin.PasswordHash.Length == 0)
{
Console.Error.WriteLine(Texts.AdminNeedsPassword);
if (UserCommands.AskNewPassword() is not { } first)
return 1;
admin.PasswordHash = Passwords.Hash(first);
}
admin.Enabled = true;
config.Save(path);
Console.WriteLine(Strings.AdminUrl($"http://127.0.0.1:{config.Server.HttpPort}/$sunfish/admin/") + " (" + WebUser + ")");
return 0;
case "disable" when rest.Count == 1:
admin.Enabled = false;
config.Save(path);
Console.WriteLine(Texts.AdminOffText);
return 0;
case "passwd" when rest.Count == 1:
if (UserCommands.AskNewPassword() is not { } password)
return 1;
admin.PasswordHash = Passwords.Hash(password);
config.Save(path);
Console.WriteLine(Texts.AdminPasswordSaved(path));
return 0;
case "allow" when rest.Count > 1:
var rules = string.Join(' ', rest.Skip(1)).Split([',', ' ', ';'], StringSplitOptions.RemoveEmptyEntries).ToList();
if (rules.FirstOrDefault(r => !AddressRules.IsValid(r)) is { } bad)
{
Console.Error.WriteLine(Strings.AdminBadAllow(bad));
return 1;
}
admin.AllowFrom = rules;
config.Save(path);
Console.WriteLine(Texts.AdminAllowed(string.Join(", ", rules)));
return 0;
default:
Console.Error.WriteLine(Texts.AdminUsage);
return 1;
}
}
private static string WebUser => Strings.Spanish ? "usuario: admin" : "user: admin";
public static int RunImport(string[] args)
{
var (configPath, rest) = CommonOptions(args);
string? source = rest.Count > 0 ? rest[0] : LegacyImport.Find();
if (source is null || !File.Exists(source))
{
Console.Error.WriteLine(Texts.ImportNotFound(LegacyImport.FileName));
return 1;
}
string? found = ConfigLocator.Find(configPath);
bool isNew = found is null || !File.Exists(found);
string path = found ?? configPath ?? ConfigLocator.PortablePath;
return Import(source, path, isNew) ? 0 : 1;
}
/// <summary>Importa <paramref name="source"/> en la configuracion de <paramref name="path"/> y lo explica.</summary>
public static bool Import(string source, string path, bool isNew)
{
var notes = new List<string>();
var imported = LegacyImport.FromV2(File.ReadAllText(source), notes);
if (imported is null)
{
Console.Error.WriteLine(Strings.ImportInvalid(source));
return false;
}
var config = isNew ? new SunfishConfig() : SunfishConfig.Load(path);
int count = LegacyImport.Merge(config, imported, isNew);
config.Save(path);
Console.WriteLine(Strings.ImportDone(count, path));
foreach (var note in notes)
Console.WriteLine(" - " + note);
return true;
}
private static (string? ConfigPath, List<string> Args) CommonOptions(string[] args)
{
string? configPath = null;
var rest = new List<string>();
for (int i = 0; i < args.Length; i++)
{
if (args[i] is "-c" or "--config" && i + 1 < args.Length)
configPath = args[++i];
else if (args[i] == "--lang" && i + 1 < args.Length)
Strings.Force(args[++i]);
else
rest.Add(args[i]);
}
return (configPath, rest);
}
}