using Sunfish.Auth;
using Sunfish.Config;
using Sunfish.Net;
namespace Sunfish.WinForms;
/// <summary>
/// Panel de administracion web: activarlo, contrasena (usuario "admin") y desde donde se permite.
/// Compacto y vertical, etiqueta encima de cada campo, como el dialogo de share.
/// </summary>
internal sealed class AdminDialog : Form
{
private const int FieldWidth = 230;
private readonly AdminSettings _admin;
private readonly CheckBox _enabled = new() { AutoSize = true, Margin = new Padding(3, 3, 3, 6) };
private readonly TextBox _password = new() { Width = FieldWidth, UseSystemPasswordChar = true };
private readonly TextBox _repeat = new() { Width = FieldWidth, UseSystemPasswordChar = true };
private readonly TextBox _allow = new() { Width = FieldWidth };
public AdminDialog(AdminSettings admin, int httpPort)
{
_admin = admin;
SuspendLayout();
AutoScaleDimensions = new SizeF(96F, 96F);
AutoScaleMode = AutoScaleMode.Dpi;
Text = Strings.AdminPanel;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = MinimizeBox = false;
ShowInTaskbar = false;
StartPosition = FormStartPosition.CenterParent;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
Padding = new Padding(8, 6, 8, 8);
_enabled.Text = Texts.AdminEnable;
_enabled.Checked = admin.Enabled;
_allow.Text = string.Join(", ", admin.AllowFrom);
var main = new FlowLayoutPanel
{
FlowDirection = FlowDirection.TopDown, AutoSize = true, WrapContents = false,
Location = new Point(Padding.Left, Padding.Top), Margin = new Padding(0),
};
main.Controls.Add(_enabled);
main.Controls.Add(Caption(admin.PasswordHash.Length > 0 ? Texts.AdminPasswordKeep : Strings.FieldPassword));
main.Controls.Add(_password);
main.Controls.Add(Caption(Strings.AdminRepeat));
main.Controls.Add(_repeat);
main.Controls.Add(Caption(Strings.AdminAllowFrom));
main.Controls.Add(_allow);
main.Controls.Add(new Label
{
Text = Texts.AdminHelp($"http://<IP>:{httpPort}/$sunfish/admin/"), AutoSize = true,
MaximumSize = new Size(FieldWidth, 0), ForeColor = SystemColors.GrayText, Margin = new Padding(3, 6, 3, 3),
});
var ok = new Button { Text = Texts.Ok, Size = new Size(80, 25), UseVisualStyleBackColor = true, Margin = new Padding(3, 0, 3, 0) };
ok.Click += (_, _) => Accept();
var cancel = new Button { Text = Texts.Cancel, Size = new Size(80, 25), DialogResult = DialogResult.Cancel, UseVisualStyleBackColor = true, Margin = new Padding(3, 0, 3, 0) };
var buttons = new FlowLayoutPanel { FlowDirection = FlowDirection.RightToLeft, Width = FieldWidth + 6, Height = 25, Margin = new Padding(0, 10, 0, 0) };
buttons.Controls.AddRange([cancel, ok]);
main.Controls.Add(buttons);
AcceptButton = ok;
CancelButton = cancel;
Controls.Add(main);
ResumeLayout(false);
PerformLayout();
}
private static Label Caption(string text) => new() { Text = text + ":", AutoSize = true, Margin = new Padding(3, 6, 3, 1) };
private void Accept()
{
var rules = _allow.Text.Split([',', ' ', ';'], StringSplitOptions.RemoveEmptyEntries).ToList();
var bad = rules.FirstOrDefault(r => !AddressRules.IsValid(r));
if (rules.Count == 0 || bad is not null)
{
MessageBox.Show(this, Strings.AdminBadAllow(bad ?? ""), Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (_password.Text != _repeat.Text)
{
MessageBox.Show(this, Strings.AdminPasswordMismatch, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (_enabled.Checked && _password.Text.Length == 0 && _admin.PasswordHash.Length == 0)
{
MessageBox.Show(this, Strings.ErrorPasswordEmpty, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
_admin.Enabled = _enabled.Checked;
_admin.AllowFrom = rules;
if (_password.Text.Length > 0)
_admin.PasswordHash = Passwords.Hash(_password.Text);
DialogResult = DialogResult.OK;
}
}