From d7f2348f0d746629933754a35d01627208eb8653 Mon Sep 17 00:00:00 2001 From: ultrasn0w <114.barth@gmail.com> Date: Tue, 19 Apr 2022 00:05:16 +0200 Subject: [PATCH] Register --- APP/APP.csproj | 6 +- APP/DTO/{SeasonAnime.cs => Anime.cs} | 18 +-- APP/DTO/Auth.cs | 10 ++ APP/DTO/Register.cs | 14 ++ APP/DTO/User.cs | 2 +- APP/DTO/Watch.cs | 10 ++ APP/DTO/WatchExtended.cs | 12 ++ APP/DTO/WatchUser.cs | 14 ++ APP/LogWin.Designer.cs | 66 +++++++++ APP/LogWin.cs | 10 ++ APP/LogWin.resx | 60 ++++++++ APP/Main.Designer.cs | 36 +++-- APP/Main.cs | 91 ++++++++++-- APP/RegisterWin.Designer.cs | 200 +++++++++++++++++++++++++++ APP/RegisterWin.cs | 125 +++++++++++++++++ APP/RegisterWin.resx | 60 ++++++++ APP/Utility/BackendComms.cs | 117 +++++++++++++++- APP/Utility/LogBoy.cs | 20 +++ APP/Utility/SaveBoy.cs | 77 +++++++++++ APP/Utility/StringAssemble.cs | 25 +++- 20 files changed, 924 insertions(+), 49 deletions(-) rename APP/DTO/{SeasonAnime.cs => Anime.cs} (71%) create mode 100644 APP/DTO/Auth.cs create mode 100644 APP/DTO/Register.cs create mode 100644 APP/DTO/Watch.cs create mode 100644 APP/DTO/WatchExtended.cs create mode 100644 APP/DTO/WatchUser.cs create mode 100644 APP/LogWin.Designer.cs create mode 100644 APP/LogWin.cs create mode 100644 APP/LogWin.resx create mode 100644 APP/RegisterWin.Designer.cs create mode 100644 APP/RegisterWin.cs create mode 100644 APP/RegisterWin.resx create mode 100644 APP/Utility/LogBoy.cs create mode 100644 APP/Utility/SaveBoy.cs diff --git a/APP/APP.csproj b/APP/APP.csproj index 18a249d..f6496b5 100644 --- a/APP/APP.csproj +++ b/APP/APP.csproj @@ -5,6 +5,7 @@ enable true enable + embedded ..\doge.ico Anime plan program ultrasn0w @@ -13,7 +14,6 @@ HANAMI net6.0-windows10.0.22000.0 10 - 7.0 @@ -22,10 +22,6 @@ - - - - True diff --git a/APP/DTO/SeasonAnime.cs b/APP/DTO/Anime.cs similarity index 71% rename from APP/DTO/SeasonAnime.cs rename to APP/DTO/Anime.cs index 781450f..dd6f39a 100644 --- a/APP/DTO/SeasonAnime.cs +++ b/APP/DTO/Anime.cs @@ -2,9 +2,9 @@ using System.Text.Json.Serialization; namespace APP.DTO; -public class SeasonAnime +public class Anime { - [JsonPropertyName("anime")] public long Anime { get; set; } + [JsonPropertyName("anime")] public int AnimeId { get; set; } [JsonPropertyName("title")] public string Title { get; set; } @@ -18,23 +18,23 @@ public class SeasonAnime [JsonPropertyName("imageThumb")] public string? ImageThumb { get; set; } - [JsonPropertyName("type")] public string Type { get; set; } + [JsonPropertyName("type")] public string? Type { get; set; } [JsonPropertyName("status")] public string Status { get; set; } - [JsonPropertyName("episodes")] public int Episodes { get; set; } + [JsonPropertyName("episodes")] public int? Episodes { get; set; } - [JsonPropertyName("synopsis")] public string? Synopsis { get; set; } + [JsonPropertyName("synopsis")] public string Synopsis { get; set; } [JsonPropertyName("genres")] public List? Genres { get; set; } - [JsonPropertyName("startDate")] public DateTime StartDate { get; set; } + [JsonPropertyName("startDate")] public DateTime? StartDate { get; set; } - [JsonPropertyName("endDate")] public DateTime EndDate { get; set; } + [JsonPropertyName("endDate")] public DateTime? EndDate { get; set; } - [JsonPropertyName("year")] public int Year { get; set; } + [JsonPropertyName("year")] public int? Year { get; set; } - [JsonPropertyName("season")] public string SeasonString { get; set; } + [JsonPropertyName("season")] public string? Season { get; set; } [JsonPropertyName("score")] public double Score { get; set; } diff --git a/APP/DTO/Auth.cs b/APP/DTO/Auth.cs new file mode 100644 index 0000000..12e80ee --- /dev/null +++ b/APP/DTO/Auth.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Serialization; + +namespace APP.DTO; + +public class Auth +{ + [JsonPropertyName("username")] public string Username { get; set; } + + [JsonPropertyName("secret")] public string Secret { get; set; } +} diff --git a/APP/DTO/Register.cs b/APP/DTO/Register.cs new file mode 100644 index 0000000..45baee9 --- /dev/null +++ b/APP/DTO/Register.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace APP.DTO; + +public class Register +{ + [JsonPropertyName("username")] public string Username { get; set; } + + [JsonPropertyName("malId")] public long MalId { get; set; } + + [JsonPropertyName("secret")] public string Secret { get; set; } + + [JsonPropertyName("sauce")] public string Sauce { get; set; } +} diff --git a/APP/DTO/User.cs b/APP/DTO/User.cs index 6cc3e15..69f59f9 100644 --- a/APP/DTO/User.cs +++ b/APP/DTO/User.cs @@ -12,7 +12,7 @@ public class User [JsonPropertyName("imageUrl")] public string ImageUrl { get; set; } - [JsonPropertyName("lastOnline")] public DateTime LastOnline { get; set; } + [JsonPropertyName("lastOnline")] public DateTimeOffset LastOnline { get; set; } [JsonPropertyName("gender")] public string? Gender { get; set; } diff --git a/APP/DTO/Watch.cs b/APP/DTO/Watch.cs new file mode 100644 index 0000000..f84f570 --- /dev/null +++ b/APP/DTO/Watch.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Serialization; + +namespace APP.DTO; + +public class Watch +{ + [JsonPropertyName("anime")] public int Anime { get; set; } + + [JsonPropertyName("users")] public List WatchUsers { get; set; } +} diff --git a/APP/DTO/WatchExtended.cs b/APP/DTO/WatchExtended.cs new file mode 100644 index 0000000..51af89e --- /dev/null +++ b/APP/DTO/WatchExtended.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace APP.DTO; + +public class WatchExtended +{ + [JsonPropertyName("anime")] public int Anime { get; set; } + + [JsonPropertyName("users")] public List Users { get; set; } + + [JsonPropertyName("data")] public Anime Data { get; set; } +} diff --git a/APP/DTO/WatchUser.cs b/APP/DTO/WatchUser.cs new file mode 100644 index 0000000..2f7e4f1 --- /dev/null +++ b/APP/DTO/WatchUser.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace APP.DTO; + +public class WatchUser +{ + [JsonPropertyName("username")] public string Username { get; set; } + + [JsonPropertyName("malId")] public int MalId { get; set; } + + [JsonPropertyName("progress")] public int? Progress { get; set; } + + [JsonPropertyName("updated")] public DateTimeOffset? Updated { get; set; } +} diff --git a/APP/LogWin.Designer.cs b/APP/LogWin.Designer.cs new file mode 100644 index 0000000..cd3d655 --- /dev/null +++ b/APP/LogWin.Designer.cs @@ -0,0 +1,66 @@ +namespace APP +{ + partial class LogWin + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.logBox = new System.Windows.Forms.RichTextBox(); + this.SuspendLayout(); + // + // logBox + // + this.logBox.BackColor = System.Drawing.Color.Black; + this.logBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.logBox.ForeColor = System.Drawing.Color.White; + this.logBox.Location = new System.Drawing.Point(0, 0); + this.logBox.Name = "logBox"; + this.logBox.ReadOnly = true; + this.logBox.Size = new System.Drawing.Size(800, 450); + this.logBox.TabIndex = 0; + this.logBox.Text = ""; + this.logBox.WordWrap = false; + // + // LogWin + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.logBox); + this.Name = "LogWin"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Log"; + this.ResumeLayout(false); + + } + + #endregion + + private RichTextBox logBox; + } +} \ No newline at end of file diff --git a/APP/LogWin.cs b/APP/LogWin.cs new file mode 100644 index 0000000..a69d92e --- /dev/null +++ b/APP/LogWin.cs @@ -0,0 +1,10 @@ +namespace APP; + +public partial class LogWin : Form +{ + public LogWin(string log) + { + InitializeComponent(); + logBox.Text = log; + } +} diff --git a/APP/LogWin.resx b/APP/LogWin.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/APP/LogWin.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/APP/Main.Designer.cs b/APP/Main.Designer.cs index 71ba0a3..5fc6d27 100644 --- a/APP/Main.Designer.cs +++ b/APP/Main.Designer.cs @@ -31,6 +31,7 @@ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main)); this.tabControl = new System.Windows.Forms.TabControl(); this.tabUser = new System.Windows.Forms.TabPage(); + this.userLabelInfoData = new System.Windows.Forms.Label(); this.userLinkLabel = new System.Windows.Forms.LinkLabel(); this.userLabelInfo = new System.Windows.Forms.Label(); this.userLabel = new System.Windows.Forms.Label(); @@ -41,7 +42,7 @@ this.menuStrip = new System.Windows.Forms.MenuStrip(); this.memeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.loginToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.userLabelInfoData = new System.Windows.Forms.Label(); + this.logToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.tabControl.SuspendLayout(); this.tabUser.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.userImage)).BeginInit(); @@ -76,6 +77,17 @@ this.tabUser.TabIndex = 0; this.tabUser.Text = "YOURNAME"; // + // userLabelInfoData + // + this.userLabelInfoData.AutoSize = true; + this.userLabelInfoData.ForeColor = System.Drawing.SystemColors.Control; + this.userLabelInfoData.Location = new System.Drawing.Point(374, 76); + this.userLabelInfoData.Name = "userLabelInfoData"; + this.userLabelInfoData.Size = new System.Drawing.Size(38, 15); + this.userLabelInfoData.TabIndex = 4; + this.userLabelInfoData.Text = "label1"; + this.userLabelInfoData.Visible = false; + // // userLinkLabel // this.userLinkLabel.AutoSize = true; @@ -166,7 +178,8 @@ this.menuStrip.BackColor = System.Drawing.Color.Gray; this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.memeToolStripMenuItem, - this.loginToolStripMenuItem}); + this.loginToolStripMenuItem, + this.logToolStripMenuItem}); this.menuStrip.Location = new System.Drawing.Point(0, 0); this.menuStrip.Name = "menuStrip"; this.menuStrip.Size = new System.Drawing.Size(828, 24); @@ -182,20 +195,16 @@ // loginToolStripMenuItem // this.loginToolStripMenuItem.Name = "loginToolStripMenuItem"; - this.loginToolStripMenuItem.Size = new System.Drawing.Size(49, 20); - this.loginToolStripMenuItem.Text = "Login"; + this.loginToolStripMenuItem.Size = new System.Drawing.Size(61, 20); + this.loginToolStripMenuItem.Text = "Register"; this.loginToolStripMenuItem.Click += new System.EventHandler(this.loginToolStripMenuItem_Click); // - // userLabelInfoData + // logToolStripMenuItem // - this.userLabelInfoData.AutoSize = true; - this.userLabelInfoData.ForeColor = System.Drawing.SystemColors.Control; - this.userLabelInfoData.Location = new System.Drawing.Point(374, 76); - this.userLabelInfoData.Name = "userLabelInfoData"; - this.userLabelInfoData.Size = new System.Drawing.Size(38, 15); - this.userLabelInfoData.TabIndex = 4; - this.userLabelInfoData.Text = "label1"; - this.userLabelInfoData.Visible = false; + this.logToolStripMenuItem.Name = "logToolStripMenuItem"; + this.logToolStripMenuItem.Size = new System.Drawing.Size(39, 20); + this.logToolStripMenuItem.Text = "Log"; + this.logToolStripMenuItem.Click += new System.EventHandler(this.logToolStripMenuItem_Click); // // Main // @@ -235,5 +244,6 @@ private Label userLabelInfo; private LinkLabel userLinkLabel; private Label userLabelInfoData; + private ToolStripMenuItem logToolStripMenuItem; } } \ No newline at end of file diff --git a/APP/Main.cs b/APP/Main.cs index 719080a..93ba6a4 100644 --- a/APP/Main.cs +++ b/APP/Main.cs @@ -6,23 +6,53 @@ namespace APP; public partial class Main : Form { + private Auth? _auth; + private bool _authSucc; private ImageList _imageListSeason; - private List? _seasonAnime; + private List? _seasonAnime; private User? _user; public Main() { InitializeComponent(); _imageListSeason = new ImageList(); - Load += OnLoad; + Load += OnLoadEv; } - private async void OnLoad(object? sender, EventArgs e) + private async void OnLoadEv(object? sender, EventArgs e) { - await UpdateData(); + _auth = await SaveBoy.ReadAuth(); + if (_auth != null) + { + // check if we exist + var users = await BackendComms.GetUser(); + if (users == null || users.All(u => u.Username != _auth.Username)) + { + // We dont exist + SaveBoy.DeleteAuth(); + _auth = null; + } + else + { + // try auth + if (await BackendComms.Auth(_auth.Username, _auth.Secret)) + { + // Login successful + loginToolStripMenuItem.Visible = false; + _authSucc = true; + await UpdateUser(); + } + else + { + _authSucc = false; + } + } + } + + await UpdateSeason(); } - private async Task UpdateData() + private async Task UpdateSeason() { _seasonAnime = await BackendComms.GetSeason(); if (_seasonAnime == null) @@ -40,8 +70,11 @@ public partial class Main : Form }); } } + } - _user = await BackendComms.GetUser("ultrasn0w"); + private async Task UpdateUser() + { + _user = await BackendComms.GetUser(_auth?.Username); if (_user == null) { ShowError("Fehler beim User abrufen"); @@ -57,7 +90,10 @@ public partial class Main : Form userLabelInfo.Visible = true; userLabelInfoData.Text = StringAssemble.UserData(_user); userLabelInfoData.Visible = true; - userImage.LoadAsync(_user.ImageUrl); + if (!string.IsNullOrWhiteSpace(_user.ImageUrl)) + { + userImage.LoadAsync(_user.ImageUrl); + } } } @@ -66,12 +102,38 @@ public partial class Main : Form MessageBox.Show(text, @"FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Error); } - private void loginToolStripMenuItem_Click(object sender, EventArgs e) + private async void loginToolStripMenuItem_Click(object sender, EventArgs e) { - // TODO search for user in backend + if (_authSucc) return; + var users = await BackendComms.GetUser(); + if (DoRegister(users)) + { + await UpdateUser(); + } } - private void userLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + private bool DoRegister(List? users) + { + // Register promt + var regWin = new RegisterWin(_auth, users); + regWin.ShowDialog(); + if (regWin.Cancelled) + { + regWin.Dispose(); + return false; + } + + _auth = new Auth + { + Username = regWin.Auth.Username, + Secret = regWin.Auth.Secret + }; + loginToolStripMenuItem.Visible = false; + regWin.Dispose(); + return true; + } + + private async void userLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (string.IsNullOrWhiteSpace(_user?.Url)) return; try @@ -85,7 +147,14 @@ public partial class Main : Form } catch (Exception ex) { - Console.Error.WriteLineAsync(ex.Message); + await Console.Error.WriteLineAsync(ex.Message); } } + + private void logToolStripMenuItem_Click(object sender, EventArgs e) + { + var logWin = new LogWin(LogBoy.GetLog()); + logWin.ShowDialog(); + logWin.Dispose(); + } } diff --git a/APP/RegisterWin.Designer.cs b/APP/RegisterWin.Designer.cs new file mode 100644 index 0000000..0540afc --- /dev/null +++ b/APP/RegisterWin.Designer.cs @@ -0,0 +1,200 @@ +namespace APP +{ + partial class RegisterWin + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.cancelButton = new System.Windows.Forms.Button(); + this.okButton = new System.Windows.Forms.Button(); + this.usernameBox = new System.Windows.Forms.TextBox(); + this.secretBox = new System.Windows.Forms.TextBox(); + this.secretBox2 = new System.Windows.Forms.TextBox(); + this.labelMain = new System.Windows.Forms.Label(); + this.labelSecret = new System.Windows.Forms.Label(); + this.labelSecret2 = new System.Windows.Forms.Label(); + this.checkUserButton = new System.Windows.Forms.Button(); + this.pwcheckLabel = new System.Windows.Forms.Label(); + this.pictureBox = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit(); + this.SuspendLayout(); + // + // cancelButton + // + this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.cancelButton.Location = new System.Drawing.Point(385, 166); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 6; + this.cancelButton.Text = "Abbruch"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); + // + // okButton + // + this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.okButton.Enabled = false; + this.okButton.Location = new System.Drawing.Point(304, 166); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(75, 23); + this.okButton.TabIndex = 5; + this.okButton.Text = "OK"; + this.okButton.UseVisualStyleBackColor = true; + this.okButton.Click += new System.EventHandler(this.okButton_Click); + // + // usernameBox + // + this.usernameBox.Location = new System.Drawing.Point(12, 27); + this.usernameBox.Name = "usernameBox"; + this.usernameBox.Size = new System.Drawing.Size(220, 23); + this.usernameBox.TabIndex = 1; + this.usernameBox.TextChanged += new System.EventHandler(this.usernameBox_TextChanged); + // + // secretBox + // + this.secretBox.Location = new System.Drawing.Point(12, 87); + this.secretBox.Name = "secretBox"; + this.secretBox.PasswordChar = 'ඞ'; + this.secretBox.Size = new System.Drawing.Size(220, 23); + this.secretBox.TabIndex = 3; + this.secretBox.TextChanged += new System.EventHandler(this.secretBox_TextChanged); + // + // secretBox2 + // + this.secretBox2.Location = new System.Drawing.Point(12, 131); + this.secretBox2.Name = "secretBox2"; + this.secretBox2.PasswordChar = 'ඞ'; + this.secretBox2.Size = new System.Drawing.Size(220, 23); + this.secretBox2.TabIndex = 4; + this.secretBox2.TextChanged += new System.EventHandler(this.secretBox2_TextChanged); + // + // labelMain + // + this.labelMain.AutoSize = true; + this.labelMain.ForeColor = System.Drawing.SystemColors.Control; + this.labelMain.Location = new System.Drawing.Point(12, 9); + this.labelMain.Name = "labelMain"; + this.labelMain.Size = new System.Drawing.Size(87, 15); + this.labelMain.TabIndex = 5; + this.labelMain.Text = "MAL username"; + // + // labelSecret + // + this.labelSecret.AutoSize = true; + this.labelSecret.ForeColor = System.Drawing.SystemColors.Control; + this.labelSecret.Location = new System.Drawing.Point(12, 69); + this.labelSecret.Name = "labelSecret"; + this.labelSecret.Size = new System.Drawing.Size(75, 15); + this.labelSecret.TabIndex = 6; + this.labelSecret.Text = "Neues Secret"; + // + // labelSecret2 + // + this.labelSecret2.AutoSize = true; + this.labelSecret2.ForeColor = System.Drawing.SystemColors.Control; + this.labelSecret2.Location = new System.Drawing.Point(12, 113); + this.labelSecret2.Name = "labelSecret2"; + this.labelSecret2.Size = new System.Drawing.Size(91, 15); + this.labelSecret2.TabIndex = 7; + this.labelSecret2.Text = "Nochmal Secret"; + // + // checkUserButton + // + this.checkUserButton.Enabled = false; + this.checkUserButton.Location = new System.Drawing.Point(238, 27); + this.checkUserButton.Name = "checkUserButton"; + this.checkUserButton.Size = new System.Drawing.Size(75, 23); + this.checkUserButton.TabIndex = 2; + this.checkUserButton.Text = "Check"; + this.checkUserButton.UseVisualStyleBackColor = true; + this.checkUserButton.Click += new System.EventHandler(this.checkUserButton_Click); + // + // pwcheckLabel + // + this.pwcheckLabel.AutoSize = true; + this.pwcheckLabel.Location = new System.Drawing.Point(238, 134); + this.pwcheckLabel.Name = "pwcheckLabel"; + this.pwcheckLabel.Size = new System.Drawing.Size(19, 15); + this.pwcheckLabel.TabIndex = 9; + this.pwcheckLabel.Text = "❌"; + // + // pictureBox + // + this.pictureBox.Location = new System.Drawing.Point(319, 12); + this.pictureBox.Name = "pictureBox"; + this.pictureBox.Size = new System.Drawing.Size(140, 140); + this.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox.TabIndex = 10; + this.pictureBox.TabStop = false; + this.pictureBox.Visible = false; + // + // RegisterWin + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(472, 201); + this.ControlBox = false; + this.Controls.Add(this.pictureBox); + this.Controls.Add(this.pwcheckLabel); + this.Controls.Add(this.checkUserButton); + this.Controls.Add(this.labelSecret2); + this.Controls.Add(this.labelSecret); + this.Controls.Add(this.labelMain); + this.Controls.Add(this.secretBox2); + this.Controls.Add(this.secretBox); + this.Controls.Add(this.usernameBox); + this.Controls.Add(this.okButton); + this.Controls.Add(this.cancelButton); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "RegisterWin"; + this.ShowIcon = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Register"; + ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private Button cancelButton; + private Button okButton; + private TextBox usernameBox; + private TextBox secretBox; + private TextBox secretBox2; + private Label labelMain; + private Label labelSecret; + private Label labelSecret2; + private Button checkUserButton; + private Label pwcheckLabel; + private PictureBox pictureBox; + } +} \ No newline at end of file diff --git a/APP/RegisterWin.cs b/APP/RegisterWin.cs new file mode 100644 index 0000000..244fee2 --- /dev/null +++ b/APP/RegisterWin.cs @@ -0,0 +1,125 @@ +using APP.DTO; +using APP.Utility; + +namespace APP; + +public partial class RegisterWin : Form +{ + private readonly Auth? _prevAuth; + private readonly List? _users; + private bool _exist; + private bool _uChecked; + private User? _user; + + public Auth Auth; + public bool Cancelled; + + public RegisterWin(Auth? prevAuth, List? existing) + { + _prevAuth = prevAuth; + _user = new User(); + _users = existing; + Cancelled = true; + Auth = new Auth(); + InitializeComponent(); + Load += OnLoadEv; + } + + private async Task PerformRegister(User user, Auth auth) + { + if (_exist) + { + // only try change login + return await BackendComms.Auth(auth.Username, auth.Secret); + } + + var register = new Register + { + Username = user.Username, + MalId = user.Id, + Secret = auth.Secret, + Sauce = StringAssemble.CalcSauce(user.Id, user.Username) + }; + var res = await BackendComms.Register(register); + return res != null; + } + + private void OnLoadEv(object? sender, EventArgs e) + { + // check if we exist + if (_users == null || _users.All(u => u.Username != _prevAuth?.Username)) return; + _exist = true; + usernameBox.Name = _prevAuth?.Username; + } + + private void cancelButton_Click(object sender, EventArgs e) + { + Cancelled = true; + Close(); + } + + private async void okButton_Click(object sender, EventArgs e) + { + if (_uChecked && _user != null && !string.IsNullOrEmpty(_user.Username) && !string.IsNullOrEmpty(secretBox.Text)) + { + // PERFORM ACTUAL REGISTER + Auth = new Auth + { + Username = _user.Username, + Secret = StringAssemble.CalcSha512(secretBox.Text) + }; + if (await PerformRegister(_user, Auth)) + { + await SaveBoy.SaveAuth(Auth); + Cancelled = false; + } + else + { + MessageBox.Show(_exist ? @"Passwortänderung hat nicht geklappt -> Frag Admin" : @"Registrieren hat nicht geklappt", @"FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + Close(); + } + + private async void checkUserButton_Click(object sender, EventArgs e) + { + _user = await BackendComms.GetUser(usernameBox.Text); + if (_user == null || string.IsNullOrEmpty(_user.Username) || _user.Id == 0) + { + MessageBox.Show(@"Benutzer gibts nicht", @"FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (!string.IsNullOrWhiteSpace(_user.ImageUrl)) + { + pictureBox.LoadAsync(_user.ImageUrl); + pictureBox.Visible = true; + } + + _exist = _users != null && _users.Any(u => u.Username == _user.Username); + MessageBox.Show($@"Hi {_user.Username} mit ID {_user.Id}", @"OK", MessageBoxButtons.OK, MessageBoxIcon.Information); + _uChecked = true; + } + + private void usernameBox_TextChanged(object sender, EventArgs e) + { + _uChecked = false; + pictureBox.Visible = false; + checkUserButton.Enabled = !string.IsNullOrWhiteSpace(usernameBox.Text); + } + + private void secretBox_TextChanged(object sender, EventArgs e) + { + var same = !string.IsNullOrWhiteSpace(secretBox.Text) && !string.IsNullOrWhiteSpace(secretBox2.Text) && secretBox.Text == secretBox2.Text; + pwcheckLabel.Text = same ? @"✅" : @"❌"; + okButton.Enabled = _uChecked && same; + } + + private void secretBox2_TextChanged(object sender, EventArgs e) + { + var same = !string.IsNullOrWhiteSpace(secretBox.Text) && !string.IsNullOrWhiteSpace(secretBox2.Text) && secretBox.Text == secretBox2.Text; + pwcheckLabel.Text = same ? @"✅" : @"❌"; + okButton.Enabled = _uChecked && same; + } +} diff --git a/APP/RegisterWin.resx b/APP/RegisterWin.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/APP/RegisterWin.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/APP/Utility/BackendComms.cs b/APP/Utility/BackendComms.cs index 8832a6e..7a6409d 100644 --- a/APP/Utility/BackendComms.cs +++ b/APP/Utility/BackendComms.cs @@ -1,4 +1,6 @@ using System.Net.Http.Json; +using System.Net.Mime; +using System.Text; using System.Text.Json; using APP.DTO; @@ -7,25 +9,126 @@ namespace APP.Utility; internal static class BackendComms { private const string ApiBaseUrl = "https://huso.hanami.family/api/"; + private const string AuthHeader = "X-HUSO-AUTH"; private static readonly HttpClient Client = new(); private static readonly JsonSerializerOptions JsonSerializerOptions = new() {PropertyNameCaseInsensitive = true}; - internal static async Task?> GetSeason() + internal static async Task?> GetSeason() { var resp = await Client.GetAsync(ApiBaseUrl + "season"); - if (!resp.IsSuccessStatusCode) return null; - return await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; } - internal static async Task GetUser(string username) + internal static async Task Auth(string username, string secret) + { + if (string.IsNullOrWhiteSpace(username)) + { + return false; + } + + using var msg = new HttpRequestMessage(HttpMethod.Get, ApiBaseUrl + "auth/" + username); + msg.Headers.Add(AuthHeader, secret); + var resp = await Client.SendAsync(msg); + if (!resp.IsSuccessStatusCode) + { + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + } + + return resp.IsSuccessStatusCode; + } + + internal static async Task GetAnime(long animeId) + { + var resp = await Client.GetAsync(ApiBaseUrl + "anime/" + animeId); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } + + internal static async Task?> SearchAnime(string query) + { + var resp = await Client.GetAsync(ApiBaseUrl + "animesearch?q=" + query); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } + + internal static async Task?> GetUser() + { + var resp = await Client.GetAsync(ApiBaseUrl + "user"); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } + + internal static async Task GetUser(string? username) { if (string.IsNullOrWhiteSpace(username)) { return null; } - var resp = await Client.GetAsync(ApiBaseUrl + "user/"+username); - if (!resp.IsSuccessStatusCode) return null; + + var resp = await Client.GetAsync(ApiBaseUrl + "user/" + username); + if (!resp.IsSuccessStatusCode) + { + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } + var users = await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); return users?.SingleOrDefault(); - } + } + + internal static async Task?> GetWatching() + { + var resp = await Client.GetAsync(ApiBaseUrl + "watch"); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } + + internal static async Task?> GetWatching(string? username) + { + if (string.IsNullOrWhiteSpace(username)) + { + return null; + } + + var resp = await Client.GetAsync(ApiBaseUrl + "watch/" + username); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } + + internal static async Task?> GetWatchingExtended() + { + var resp = await Client.GetAsync(ApiBaseUrl + "watchext"); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } + + internal static async Task?> GetWatchingExtended(string? username) + { + if (string.IsNullOrWhiteSpace(username)) + { + return null; + } + + var resp = await Client.GetAsync(ApiBaseUrl + "watchext/" + username); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync>(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } + + internal static async Task Register(Register register) + { + using var content = new StringContent(JsonSerializer.Serialize(register), Encoding.UTF8, MediaTypeNames.Application.Json); + using var resp = await Client.PostAsync(ApiBaseUrl + "register", content); + if (resp.IsSuccessStatusCode) return await resp.Content.ReadFromJsonAsync(JsonSerializerOptions); + LogBoy.AddToLog(resp.RequestMessage?.RequestUri + " " + resp.StatusCode); + return null; + } } diff --git a/APP/Utility/LogBoy.cs b/APP/Utility/LogBoy.cs new file mode 100644 index 0000000..45e33e0 --- /dev/null +++ b/APP/Utility/LogBoy.cs @@ -0,0 +1,20 @@ +using System.Text; + +namespace APP.Utility; + +internal static class LogBoy +{ + private static readonly StringBuilder Log = new(); + + internal static void AddToLog(string text) + { + Log.Append('[' + DateTime.Now.ToShortTimeString() + "] "); + Log.Append(text); + Log.AppendLine(); + } + + internal static string GetLog() + { + return Log.ToString(); + } +} diff --git a/APP/Utility/SaveBoy.cs b/APP/Utility/SaveBoy.cs new file mode 100644 index 0000000..e5afe2a --- /dev/null +++ b/APP/Utility/SaveBoy.cs @@ -0,0 +1,77 @@ +using System.Text.Json; +using APP.DTO; + +namespace APP.Utility; + +internal static class SaveBoy +{ + private static readonly string AuthFile = ".." + Path.DirectorySeparatorChar + "reg.json"; + + internal static async Task ReadAuth() + { + if (File.Exists(AuthFile)) + { + return await ReadFromFile(AuthFile); + } + + return null; + } + + internal static void DeleteAuth() + { + if (File.Exists(AuthFile)) + { + File.Delete(AuthFile); + } + } + + internal static async Task SaveAuth(Auth auth) + { + await WriteToFile(AuthFile, auth); + } + + private static async Task WriteToFile(string filePath, T objectToWrite) + { + try + { + await using var sw = new StreamWriter(filePath, false); + try + { + var res = JsonSerializer.Serialize(objectToWrite); + await sw.WriteAsync(res); + } + finally + { + sw.Close(); + } + } + catch (Exception ex) + { + await Console.Error.WriteLineAsync(ex.Message); + } + } + + private static async Task ReadFromFile(string filePath) + { + try + { + using var sr = new StreamReader(filePath); + try + { + var text = await sr.ReadToEndAsync(); + var res = JsonSerializer.Deserialize(text); + return res; + } + finally + { + sr.Close(); + } + } + catch (Exception ex) + { + await Console.Error.WriteLineAsync(ex.Message); + } + + return default; + } +} diff --git a/APP/Utility/StringAssemble.cs b/APP/Utility/StringAssemble.cs index 5bdb40d..87c92b5 100644 --- a/APP/Utility/StringAssemble.cs +++ b/APP/Utility/StringAssemble.cs @@ -1,11 +1,14 @@ +using System.Security.Cryptography; using System.Text; using APP.DTO; namespace APP.Utility; -public static class StringAssemble +internal static class StringAssemble { - public static string UserInfo(User? user) + private const string RegisterSecret = "綾波レイ"; + + internal static string UserInfo(User? user) { if (user == null) { @@ -31,7 +34,7 @@ public static class StringAssemble return sb.ToString(); } - public static string UserData(User? user) + internal static string UserData(User? user) { if (user == null) { @@ -56,4 +59,20 @@ public static class StringAssemble return sb.ToString(); } + + internal static string CalcSha512(string input) + { + var bytes = Encoding.UTF8.GetBytes(input); + using var hash = SHA512.Create(); + var hashedInputBytes = hash.ComputeHash(bytes); + var hashedInputStringBuilder = new StringBuilder(128); + foreach (var b in hashedInputBytes) + hashedInputStringBuilder.Append(b.ToString("X2")); + return hashedInputStringBuilder.ToString().ToLower(); + } + + internal static string CalcSauce(long malId, string username) + { + return CalcSha512(RegisterSecret + malId + username); + } }