diff --git a/MConnectSDK/MConnectClient.cs b/MConnectSDK/MConnectClient.cs index 93953b4..ff43aa0 100644 --- a/MConnectSDK/MConnectClient.cs +++ b/MConnectSDK/MConnectClient.cs @@ -37,6 +37,10 @@ namespace MConnectSDK /// Oggetto accesso memoria... /// protected memLayer ML; + /// + /// Ultimo token response ottenuto + /// + protected tokenResponse tokResp; /// /// Inizializzazione classe specificando tutti i parametri @@ -53,6 +57,47 @@ namespace MConnectSDK ML = new memLayer(_currParam); } + /// + /// AccessToken + /// + protected string access_token + { + get + { + string answ = ""; + if (ML.connRedis.IsConnected) + { + // cerco i TOKEN in REDIS... + answ = ML.getRSV(ML.redHash("token:access")); + } + return answ; + } + set + { + ML.setRSV(ML.redHash("token:access"), value); + } + } + /// + /// RefreshToken + /// + protected string refresh_token + { + get + { + string answ = ""; + if (ML.connRedis.IsConnected) + { + // cerco i TOKEN in REDIS... + answ = ML.getRSV(ML.redHash("token:refresh")); + } + return answ; + } + set + { + ML.setRSV(ML.redHash("token:refresh"), value); + } + } + /// /// Metodo di INIT della classe di comunicazione /// @@ -60,90 +105,124 @@ namespace MConnectSDK public requestStatus init() { // init output - requestStatus answ = new requestStatus(); - // verifico REDIS in primis x i MIEI dati - checkAlive(); + requestStatus reqSt = preCheckStatus(); + return reqSt; + } + /// + /// Effettua test preliminare stato... + /// + /// + private requestStatus preCheckStatus() + { + requestStatus answ = new requestStatus() + { + // init in stato ND... + isHmiEnrolled = false, + cloudConnection = false, + localConnection = false, + source = comSource.offline, + callSuccess = false + }; + // verifico REDIS in primis + answ.localConnection = checkRedisAlive(); + if (answ.localConnection) + { + // cerco i TOKEN in REDIS... + answ.isHmiEnrolled = (refresh_token != null && refresh_token.ToString() != ""); + answ.source = comSource.local; + } - - - // verifico se sono in modalità testing o in produzione + // verifico chiamata server... if (_currParam.testMode) { // Fingo che tutto vada bene e di conseguenza setto risposta... - answ = new requestStatus - { - // non sono INIZIALMENTE enrolled... - isHmiEnrolled = false, - cloudConnection = true, - localConnection = true, - source = comSource.cloud, - callSuccess = true - }; + answ.cloudConnection = true; + answ.source = comSource.cloud; + answ.callSuccess = true; + // attesa random... Random r = new Random(); - Thread.Sleep(1000 + r.Next(0, 500)); + Thread.Sleep(100 + r.Next(0, 100)); } else { - // !!!TBD: test status connessioni, tentativo call su cloud... + /// TBD !!!FARE!!! le vere chiamate di testing remoto... } return answ; } + /// /// Controlla stato server alive /// - private void checkAlive() + private bool checkRedisAlive() { bool newStatus = ML.connRedis.IsConnected; // controllo se cambia lo stato... string message = ""; if (redServAlive != newStatus) { - message = newStatus ? "Server REDIS tornato ONLINE! salvo aggiornamento di stato" : "Server REDIS offline, impossibile inviare aggiornamenti."; + message = newStatus ? "Server REDIS ONLINE!" : "Server REDIS offline"; lg.Info(message); redServAlive = newStatus; if (newStatus) { - checkRedisStatusAndSend(); + setWatchdog(); } } + return newStatus; } /// /// Aggiorna stato redis server + invio dati pending /// - private void checkRedisStatusAndSend() + private void setWatchdog() { // verifico eventuali invii pending... SE connesso... if (redServAlive) { - // salvo in REDIS + // salvo in REDIS che sto trasmettendo... + ML.setRSV(ML.redHash("WatchDog"), DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff")); + //ML.setRSV(ML.redHash("CliStatus"), "INIT"); } -#if false - // aggiorno stato redis - checkAlive(); -#endif } - public requestStatus tryAuthorize() + /// + /// Recupera lo USER_CODE da msotrare x auth (anche con QR) + /// + /// + public userAuthData tryAuthorize() { // init output - requestStatus answ = new requestStatus(); - // verifico se sono in modalità testing o in produzione - if (_currParam.testMode) + userAuthData answ = new userAuthData(); + // init altro + requestStatus reqSt = preCheckStatus(); + tokResp = new tokenResponse(); + // verifico autorizzazione... se non c'è TENTO auth... + if (!reqSt.isHmiEnrolled) { - // Fingo che tutto vada bene e di conseguenza setto risposta... - answ = new requestStatus + // attesa come richiesto... + Thread.Sleep(tokResp.interval); + + // verifico chiamata server... + if (_currParam.testMode) { - // non sono INIZIALMENTE enrolled... - isHmiEnrolled = false, - cloudConnection = true, - localConnection = true, - source = comSource.cloud, - callSuccess = true - }; - } - else - { - // !!!TBD: test status connessioni, tentativo call su cloud... + Random r = new Random(); + + tokResp = new tokenResponse() + { + device_code = "TEST-DEV", + user_code = string.Format("{0:000000}", r.Next(1, 999999)), + verification_uri = "localhost:3000/client-auth/verification", + interval = 1000, + expires_in = 60000 + }; + } + else + { + /// TBD !!!FARE!!! le vere chiamate di testing remoto... + } + // riporto in risposta i dati... + answ.userCode = tokResp.user_code; + answ.qrCode = string.Format(@"https://smart.maestroconnect.com/deviceauth/{0}", tokResp.user_code); } + // ritorno! return answ; } } diff --git a/MConnectSDK/Utils.cs b/MConnectSDK/Utils.cs index c8510b4..8737400 100644 --- a/MConnectSDK/Utils.cs +++ b/MConnectSDK/Utils.cs @@ -24,7 +24,7 @@ /// /// Redis Module per storage /// - public string module = "MCCSDK"; + public string module = "MCC"; } /// @@ -55,6 +55,46 @@ } + /// + /// Classe della rispsota del token in fase di OAuth + /// + public class tokenResponse + { + /// + /// Device code(needed in step 3) + /// + public string device_code; + /// + /// User code(needed in step 2) + /// + public string user_code; + /// + /// called to complete authorization workflow + /// + public string verification_uri; + /// + /// Intervallo di refresh della chiamata proposto (msec) + /// + public int interval = 1000; + /// + /// Expire di validità della risposta (msec) + /// + public int expires_in = 60000; + } + /// + /// Classe che contiene id ati x user auth da mostrare da HMI + /// + public class userAuthData + { + /// + /// Codice di auth da mostrare a video + /// + public string userCode; + /// + /// QR-Code completo + /// + public string qrCode; + } /// /// Enum delle sorgenti di comunicazione /// diff --git a/TestClient/MainForm.Designer.cs b/TestClient/MainForm.Designer.cs index de590ad..c341fcb 100644 --- a/TestClient/MainForm.Designer.cs +++ b/TestClient/MainForm.Designer.cs @@ -33,9 +33,8 @@ this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar(); this.lblClock = new System.Windows.Forms.ToolStripStatusLabel(); this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.chkEnrolled = new System.Windows.Forms.CheckBox(); - this.chkLocalOk = new System.Windows.Forms.CheckBox(); - this.chkCloudOk = new System.Windows.Forms.CheckBox(); + this.txtClientID = new System.Windows.Forms.TextBox(); + this.label7 = new System.Windows.Forms.Label(); this.txtConnParam = new System.Windows.Forms.TextBox(); this.label4 = new System.Windows.Forms.Label(); this.chkTestMode = new System.Windows.Forms.CheckBox(); @@ -54,16 +53,14 @@ this.label5 = new System.Windows.Forms.Label(); this.lblReqStatus = new System.Windows.Forms.Label(); this.lblRetData = new System.Windows.Forms.Label(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.pictBox = new System.Windows.Forms.PictureBox(); this.label6 = new System.Windows.Forms.Label(); this.lblConsole = new System.Windows.Forms.Label(); - this.txtClientID = new System.Windows.Forms.TextBox(); - this.label7 = new System.Windows.Forms.Label(); this.statusStrip1.SuspendLayout(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictBox)).BeginInit(); this.SuspendLayout(); // // statusStrip1 @@ -104,9 +101,6 @@ this.groupBox1.AutoSize = true; this.groupBox1.Controls.Add(this.txtClientID); this.groupBox1.Controls.Add(this.label7); - this.groupBox1.Controls.Add(this.chkEnrolled); - this.groupBox1.Controls.Add(this.chkLocalOk); - this.groupBox1.Controls.Add(this.chkCloudOk); this.groupBox1.Controls.Add(this.txtConnParam); this.groupBox1.Controls.Add(this.label4); this.groupBox1.Controls.Add(this.chkTestMode); @@ -119,42 +113,21 @@ this.groupBox1.TabStop = false; this.groupBox1.Text = "Connection Parameters"; // - // chkEnrolled + // txtClientID // - this.chkEnrolled.AutoSize = true; - this.chkEnrolled.Location = new System.Drawing.Point(665, 58); - this.chkEnrolled.Name = "chkEnrolled"; - this.chkEnrolled.Size = new System.Drawing.Size(110, 21); - this.chkEnrolled.TabIndex = 18; - this.chkEnrolled.Text = "Enroll Status"; - this.chkEnrolled.UseVisualStyleBackColor = true; - this.chkEnrolled.Click += new System.EventHandler(this.chkEnrolled_Click); + this.txtClientID.Location = new System.Drawing.Point(354, 30); + this.txtClientID.Name = "txtClientID"; + this.txtClientID.Size = new System.Drawing.Size(168, 22); + this.txtClientID.TabIndex = 20; // - // chkLocalOk + // label7 // - this.chkLocalOk.AutoSize = true; - this.chkLocalOk.Checked = true; - this.chkLocalOk.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkLocalOk.Location = new System.Drawing.Point(805, 29); - this.chkLocalOk.Name = "chkLocalOk"; - this.chkLocalOk.Size = new System.Drawing.Size(108, 21); - this.chkLocalOk.TabIndex = 17; - this.chkLocalOk.Text = "Local Status"; - this.chkLocalOk.UseVisualStyleBackColor = true; - this.chkLocalOk.Click += new System.EventHandler(this.chkLocalOk_Click); - // - // chkCloudOk - // - this.chkCloudOk.AutoSize = true; - this.chkCloudOk.Checked = true; - this.chkCloudOk.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkCloudOk.Location = new System.Drawing.Point(665, 29); - this.chkCloudOk.Name = "chkCloudOk"; - this.chkCloudOk.Size = new System.Drawing.Size(110, 21); - this.chkCloudOk.TabIndex = 16; - this.chkCloudOk.Text = "Cloud Status"; - this.chkCloudOk.UseVisualStyleBackColor = true; - this.chkCloudOk.Click += new System.EventHandler(this.chkCloudOk_Click); + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(295, 33); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(56, 17); + this.label7.TabIndex = 19; + this.label7.Text = "ClientID"; // // txtConnParam // @@ -251,6 +224,7 @@ this.btnTryAuth.TabIndex = 16; this.btnTryAuth.Text = "tryAuthorize"; this.btnTryAuth.UseVisualStyleBackColor = true; + this.btnTryAuth.Click += new System.EventHandler(this.btnTryAuth_Click); // // btnInit // @@ -287,7 +261,7 @@ this.tableLayoutPanel1.Controls.Add(this.label5, 2, 0); this.tableLayoutPanel1.Controls.Add(this.lblReqStatus, 0, 1); this.tableLayoutPanel1.Controls.Add(this.lblRetData, 1, 1); - this.tableLayoutPanel1.Controls.Add(this.pictureBox1, 2, 1); + this.tableLayoutPanel1.Controls.Add(this.pictBox, 2, 1); this.tableLayoutPanel1.Controls.Add(this.label6, 3, 0); this.tableLayoutPanel1.Controls.Add(this.lblConsole, 3, 1); this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 225); @@ -343,14 +317,14 @@ this.lblRetData.TabIndex = 4; this.lblRetData.Text = "..."; // - // pictureBox1 + // pictBox // - this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; - this.pictureBox1.Location = new System.Drawing.Point(395, 52); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(288, 402); - this.pictureBox1.TabIndex = 5; - this.pictureBox1.TabStop = false; + this.pictBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.pictBox.Location = new System.Drawing.Point(395, 52); + this.pictBox.Name = "pictBox"; + this.pictBox.Size = new System.Drawing.Size(288, 402); + this.pictBox.TabIndex = 5; + this.pictBox.TabStop = false; // // label6 // @@ -373,22 +347,6 @@ this.lblConsole.TabIndex = 7; this.lblConsole.Text = "..."; // - // txtClientID - // - this.txtClientID.Location = new System.Drawing.Point(354, 30); - this.txtClientID.Name = "txtClientID"; - this.txtClientID.Size = new System.Drawing.Size(168, 22); - this.txtClientID.TabIndex = 20; - // - // label7 - // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(295, 33); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(56, 17); - this.label7.TabIndex = 19; - this.label7.Text = "ClientID"; - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); @@ -407,7 +365,7 @@ this.groupBox2.ResumeLayout(false); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictBox)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -427,9 +385,6 @@ private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.Button btnInit; private System.Windows.Forms.Button btnResetParam; - private System.Windows.Forms.CheckBox chkCloudOk; - private System.Windows.Forms.CheckBox chkLocalOk; - private System.Windows.Forms.CheckBox chkEnrolled; private System.Windows.Forms.Button btnTryUserLogin; private System.Windows.Forms.Button btnGetUserList; private System.Windows.Forms.Button btnGetOrgCode; @@ -440,7 +395,7 @@ private System.Windows.Forms.Label label5; private System.Windows.Forms.Label lblReqStatus; private System.Windows.Forms.Label lblRetData; - private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.PictureBox pictBox; private System.Windows.Forms.Label label6; private System.Windows.Forms.Label lblConsole; private System.Windows.Forms.TextBox txtClientID; diff --git a/TestClient/MainForm.cs b/TestClient/MainForm.cs index 0502326..177bad2 100644 --- a/TestClient/MainForm.cs +++ b/TestClient/MainForm.cs @@ -16,7 +16,11 @@ namespace TestClient private DateTime previousTime = DateTime.Now; protected MConnectClient MCC; + /// + /// Risposta BASE della classe di comunicazione + /// protected requestStatus reqStatus; + protected bool doingAuth; public MainForm() { @@ -36,9 +40,7 @@ namespace TestClient { // controllo se visualizzare parametri di testing... bool showTP = chkTestMode.Checked; - chkCloudOk.Visible = showTP; - chkLocalOk.Visible = showTP; - chkEnrolled.Visible = showTP; + //chkCloudOk.Visible = showTP; } private async Task updateClockAsync() @@ -69,7 +71,25 @@ namespace TestClient previousTime = timeNow; } + /// + /// Reset parametri... + /// + /// + /// + private void btnResetParam_Click(object sender, EventArgs e) + { + txtMConnectID.Text = "MCID-0000-1234-5678"; + txtClientID.Text = "HMI_TEST_CLI"; + chkTestMode.Checked = true; + txtConnParam.Text = "127.0.0.1,abortConnect=false,ssl=false"; + fixDisplay(); + } + /// + /// Simulazione INIT + /// + /// + /// private async void btnInit_Click(object sender, EventArgs e) { confParam param = new confParam @@ -78,12 +98,14 @@ namespace TestClient redisConnAdmin = txtConnParam.Text + ",allowAdmin=true", testMode = chkTestMode.Checked }; + // salvo NON In auth... + doingAuth = false; // init in modalità Task based... await Task.Run(() => - { - var initObj = doInitAsync(param); - }); + { + var initObj = doInitAsync(param); + }); // aggiorno log console StringBuilder sb = new StringBuilder(); @@ -121,18 +143,87 @@ namespace TestClient sb.AppendLine("-------------------------"); lblReqStatus.Text = sb.ToString(); sb.AppendLine(""); - sb.AppendLine(string.Format("{0:HH.mm.ss.fff} | END INIT", DateTime.Now)); + sb.AppendLine(string.Format("{0:HH.mm.ss.fff} | END", DateTime.Now)); sb.AppendLine("--------------------------------------------------"); lblConsole.Text += sb.ToString(); + + // se NON enrolled --> abilita tryAuth... + btnTryAuth.Enabled = !reqStatus.isHmiEnrolled; } - private void btnResetParam_Click(object sender, EventArgs e) + /// + /// Simulazione auth (SE non abilitato) + /// + /// + /// + private async void btnTryAuth_Click(object sender, EventArgs e) { - txtMConnectID.Text = "MCID-0000-1234-5678"; - txtClientID.Text = "HMI_TEST_CLI"; - chkTestMode.Checked = true; - txtConnParam.Text = "127.0.0.1,abortConnect=false,ssl=false"; - fixDisplay(); + // salvo NON In auth... + doingAuth = true; + // init in modalità Task based... + await Task.Run(() => + { + var initObj = doOAuthCycle(); + }); + + // aggiorno log console + StringBuilder sb = new StringBuilder(); + sb.AppendLine("--------------------------------------------------"); + sb.AppendLine(string.Format("{0:HH.mm.ss.fff} | START OAuth process", DateTime.Now)); + sb.AppendLine(""); + lblConsole.Text = sb.ToString(); + } + + private async Task doOAuthCycle() + { + // fino a quanod NON è auth --> cicla... + while (!reqStatus.isHmiEnrolled && doingAuth) + { + await Task.Run(() => + { + synchronizationContext.Post(new SendOrPostCallback(o => + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("--------------------------------------------------"); + sb.AppendLine(string.Format("{0:HH.mm.ss.fff} | Try OAuth process", DateTime.Now)); + sb.AppendLine(""); + lblConsole.Text = sb.ToString(); + }), ""); + + reqStatus = MCC.init(); + userAuthData authData = MCC.tryAuthorize(); + + synchronizationContext.Post(new SendOrPostCallback(o => + { + refreshRequestStatus(); + // mostro i dati SPECIFICI x AUTH... + updateAuthData(authData); + }), ""); + if (reqStatus.isHmiEnrolled) + { + doingAuth = false; + } + else + { + Thread.Sleep(500); + } + }); + } + } + /// + /// Mostra info x USER AUTH + /// + /// + private void updateAuthData(userAuthData authData) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("--------------------------------------------------"); + sb.AppendLine(string.Format("user_code: {0}", authData.userCode)); + sb.AppendLine(""); + lblRetData.Text = sb.ToString(); + // mostro QR-code + Zen.Barcode.CodeQrBarcodeDraw qrcode = Zen.Barcode.BarcodeDrawFactory.CodeQr; + pictBox.Image = qrcode.Draw(authData.qrCode, 50); } private void chkCloudOk_Click(object sender, EventArgs e) @@ -154,5 +245,6 @@ namespace TestClient { fixDisplay(); } + } } diff --git a/TestClient/TestClient.csproj b/TestClient/TestClient.csproj index 56381d6..0c45496 100644 --- a/TestClient/TestClient.csproj +++ b/TestClient/TestClient.csproj @@ -70,6 +70,9 @@ + + ..\packages\Zen.Barcode.Rendering.Framework.3.1.10729.1\lib\Zen.Barcode.Core.dll + diff --git a/TestClient/packages.config b/TestClient/packages.config index 2d76856..ee7c56a 100644 --- a/TestClient/packages.config +++ b/TestClient/packages.config @@ -3,4 +3,5 @@ + \ No newline at end of file