Commits

Devin Martin  committed fcff6d3

Get time difference information.

  • Participants
  • Parent commits 878efe7

Comments (0)

Files changed (10)

-c40106be77a1ca27f666f6e652fae6680ef0b865 OtpSharp
+d39dbce0d9a9328f073332d7f87ba3524f1f6a42 OtpSharp

File AsyncOperation.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace KeeOtp
+{
+    /// <summary>
+    /// A helper class to help yout with async operations since we aren't using tasks to avoid any reliance on the TPL
+    /// </summary>
+    /// <remarks>
+    /// This is a crude replacement for tasks in the .net 4.0 TPL.  In order to make this plugin work on machines
+    /// that don't have .net 4.0 we are avoiding TPL usage.
+    /// </remarks>
+    class AsyncOperation
+    {
+        readonly SynchronizationContext context;
+        readonly Action asyncAction;
+        readonly Action continuation;
+        readonly Action<Exception> catchAction;
+        readonly Action finallyAction;
+
+        readonly object postSync = new object();
+
+        bool catchPosted = false;
+        bool finallyPosted = false;
+
+        public AsyncOperation(Action asyncAction, Action continuation, Action<Exception> catchAction, Action finallyAction)
+        {
+            context = SynchronizationContext.Current;
+
+            this.asyncAction = asyncAction;
+            this.continuation = continuation;
+            this.catchAction = catchAction;
+            this.finallyAction = finallyAction;
+        }
+
+        public void Run()
+        {
+            Action runAction = () =>
+            {
+                try
+                {
+                    if (asyncAction != null)
+                        asyncAction();
+                    if (continuation != null)
+                    {
+                        context.Post(state =>
+                        {
+                            try
+                            {
+                                continuation();
+                            }
+                            catch (Exception e)
+                            {
+                                PostCatchActionIfNeeded(e);
+                            }
+                            finally
+                            {
+                                PostFinallyActionIfNeeded();
+                            }
+                        }, null);
+                    }
+                }
+                catch (Exception e)
+                {
+                    PostCatchActionIfNeeded(e);
+                }
+                finally
+                {
+                    PostFinallyActionIfNeeded();
+                }
+            };
+
+            // grab a thread pool thread and run
+            runAction.BeginInvoke(null, null);
+        }
+
+        private void PostFinallyActionIfNeeded()
+        {
+            if (finallyAction != null)
+            {
+                lock (postSync)
+                {
+                    if (!finallyPosted)
+                    {
+                        finallyPosted = true;
+                        context.Post(state => finallyAction(), null);
+                    }
+                }
+            }
+        }
+
+        private void PostCatchActionIfNeeded(Exception e)
+        {
+            if (catchAction != null)
+            {
+                lock (postSync)
+                {
+                    if (!catchPosted)
+                    {
+                        catchPosted = true;
+                        context.Post(state => catchAction(e), null);
+                    }
+                }
+            }
+        }
+    }
+}

File KeeOtp.csproj

     <OldToolsVersion>4.0</OldToolsVersion>
     <UpgradeBackupLocation>
     </UpgradeBackupLocation>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <PublishUrl>publish\</PublishUrl>
     <Install>true</Install>
     <InstallFrom>Disk</InstallFrom>
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AsyncOperation.cs" />
     <Compile Include="OtpInformation.cs">
       <SubType>Form</SubType>
     </Compile>
 
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeeOtp", "KeeOtp.csproj", "{4C1BB6F8-D2CD-49C2-9053-21705681356C}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OtpSharp", "OtpSharp\OtpSharp\OtpSharp.csproj", "{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}"
 		{4C1BB6F8-D2CD-49C2-9053-21705681356C}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{4C1BB6F8-D2CD-49C2-9053-21705681356C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{4C1BB6F8-D2CD-49C2-9053-21705681356C}.Release|Any CPU.Build.0 = Release|Any CPU
-		{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}.Debug|Any CPU.ActiveCfg = Release35Client|Any CPU
+		{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}.Debug|Any CPU.Build.0 = Release35Client|Any CPU
+		{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}.Release|Any CPU.ActiveCfg = Release35Client|Any CPU
+		{DF432B25-4EBE-4C89-B7BD-0553CB6301B9}.Release|Any CPU.Build.0 = Release35Client|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

File OtpInformation.Designer.cs

             this.radioButtonEight = new System.Windows.Forms.RadioButton();
             this.buttonOk = new System.Windows.Forms.Button();
             this.buttonCancel = new System.Windows.Forms.Button();
+            this.radioButtonBase32 = new System.Windows.Forms.RadioButton();
+            this.radioButtonBase64 = new System.Windows.Forms.RadioButton();
+            this.radioButtonHex = new System.Windows.Forms.RadioButton();
             this.SuspendLayout();
             // 
             // textBoxKey
             // 
             // textBoxStep
             // 
-            this.textBoxStep.Location = new System.Drawing.Point(140, 65);
+            this.textBoxStep.Location = new System.Drawing.Point(140, 138);
             this.textBoxStep.Name = "textBoxStep";
             this.textBoxStep.Size = new System.Drawing.Size(23, 20);
             this.textBoxStep.TabIndex = 1;
             // 
             this.radioButtonSix.AutoSize = true;
             this.radioButtonSix.Checked = true;
-            this.radioButtonSix.Location = new System.Drawing.Point(140, 101);
+            this.radioButtonSix.Location = new System.Drawing.Point(140, 174);
             this.radioButtonSix.Name = "radioButtonSix";
             this.radioButtonSix.Size = new System.Drawing.Size(60, 17);
             this.radioButtonSix.TabIndex = 2;
             this.labelKey.AutoSize = true;
             this.labelKey.Location = new System.Drawing.Point(28, 15);
             this.labelKey.Name = "labelKey";
-            this.labelKey.Size = new System.Drawing.Size(110, 13);
+            this.labelKey.Size = new System.Drawing.Size(25, 13);
             this.labelKey.TabIndex = 3;
-            this.labelKey.Text = "Base32 Encoded Key";
+            this.labelKey.Text = "Key";
             // 
             // label2
             // 
             this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(28, 68);
+            this.label2.Location = new System.Drawing.Point(28, 141);
             this.label2.Name = "label2";
             this.label2.Size = new System.Drawing.Size(106, 13);
             this.label2.TabIndex = 4;
             // labelSize
             // 
             this.labelSize.AutoSize = true;
-            this.labelSize.Location = new System.Drawing.Point(79, 101);
+            this.labelSize.Location = new System.Drawing.Point(79, 174);
             this.labelSize.Name = "labelSize";
             this.labelSize.Size = new System.Drawing.Size(55, 13);
             this.labelSize.TabIndex = 5;
             // radioButtonEight
             // 
             this.radioButtonEight.AutoSize = true;
-            this.radioButtonEight.Location = new System.Drawing.Point(140, 124);
+            this.radioButtonEight.Location = new System.Drawing.Point(140, 197);
             this.radioButtonEight.Name = "radioButtonEight";
             this.radioButtonEight.Size = new System.Drawing.Size(60, 17);
             this.radioButtonEight.TabIndex = 6;
             // 
             this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
             this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
-            this.buttonOk.Location = new System.Drawing.Point(106, 167);
+            this.buttonOk.Location = new System.Drawing.Point(106, 236);
             this.buttonOk.Name = "buttonOk";
             this.buttonOk.Size = new System.Drawing.Size(75, 23);
             this.buttonOk.TabIndex = 7;
             // 
             this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
             this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
-            this.buttonCancel.Location = new System.Drawing.Point(187, 167);
+            this.buttonCancel.Location = new System.Drawing.Point(187, 236);
             this.buttonCancel.Name = "buttonCancel";
             this.buttonCancel.Size = new System.Drawing.Size(75, 23);
             this.buttonCancel.TabIndex = 8;
             this.buttonCancel.Text = "Cancel";
             this.buttonCancel.UseVisualStyleBackColor = true;
             // 
+            // radioButtonBase32
+            // 
+            this.radioButtonBase32.AutoSize = true;
+            this.radioButtonBase32.Location = new System.Drawing.Point(31, 57);
+            this.radioButtonBase32.Name = "radioButtonBase32";
+            this.radioButtonBase32.Size = new System.Drawing.Size(64, 17);
+            this.radioButtonBase32.TabIndex = 9;
+            this.radioButtonBase32.TabStop = true;
+            this.radioButtonBase32.Text = "Base 32";
+            this.radioButtonBase32.UseVisualStyleBackColor = true;
+            // 
+            // radioButtonBase64
+            // 
+            this.radioButtonBase64.AutoSize = true;
+            this.radioButtonBase64.Location = new System.Drawing.Point(31, 80);
+            this.radioButtonBase64.Name = "radioButtonBase64";
+            this.radioButtonBase64.Size = new System.Drawing.Size(64, 17);
+            this.radioButtonBase64.TabIndex = 10;
+            this.radioButtonBase64.TabStop = true;
+            this.radioButtonBase64.Text = "Base 64";
+            this.radioButtonBase64.UseVisualStyleBackColor = true;
+            // 
+            // radioButtonHex
+            // 
+            this.radioButtonHex.AutoSize = true;
+            this.radioButtonHex.Location = new System.Drawing.Point(31, 103);
+            this.radioButtonHex.Name = "radioButtonHex";
+            this.radioButtonHex.Size = new System.Drawing.Size(44, 17);
+            this.radioButtonHex.TabIndex = 11;
+            this.radioButtonHex.TabStop = true;
+            this.radioButtonHex.Text = "Hex";
+            this.radioButtonHex.UseVisualStyleBackColor = true;
+            // 
             // OtpInformation
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(274, 202);
+            this.ClientSize = new System.Drawing.Size(274, 271);
+            this.Controls.Add(this.radioButtonHex);
+            this.Controls.Add(this.radioButtonBase64);
+            this.Controls.Add(this.radioButtonBase32);
             this.Controls.Add(this.buttonCancel);
             this.Controls.Add(this.buttonOk);
             this.Controls.Add(this.radioButtonEight);
         private System.Windows.Forms.RadioButton radioButtonEight;
         private System.Windows.Forms.Button buttonOk;
         private System.Windows.Forms.Button buttonCancel;
+        private System.Windows.Forms.RadioButton radioButtonBase32;
+        private System.Windows.Forms.RadioButton radioButtonBase64;
+        private System.Windows.Forms.RadioButton radioButtonHex;
     }
 }

File OtpInformation.cs

 using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
-using System.Drawing;
-using System.Text;
 using System.Windows.Forms;
 using OtpSharp;
 

File OtpInformation.resx

     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
 </root>

File Troubleshooting.Designer.cs

             this.labelHeader = new System.Windows.Forms.Label();
             this.buttonPingGoogle = new System.Windows.Forms.Button();
             this.buttonTroubleshootingWebsite = new System.Windows.Forms.Button();
+            this.progressBarGettingTimeCorrection = new System.Windows.Forms.ProgressBar();
             this.SuspendLayout();
             // 
             // labelHeader
             this.buttonTroubleshootingWebsite.UseVisualStyleBackColor = true;
             this.buttonTroubleshootingWebsite.Click += new System.EventHandler(this.buttonTroubleshootingWebsite_Click);
             // 
+            // progressBarGettingTimeCorrection
+            // 
+            this.progressBarGettingTimeCorrection.Location = new System.Drawing.Point(16, 55);
+            this.progressBarGettingTimeCorrection.Name = "progressBarGettingTimeCorrection";
+            this.progressBarGettingTimeCorrection.Size = new System.Drawing.Size(338, 23);
+            this.progressBarGettingTimeCorrection.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
+            this.progressBarGettingTimeCorrection.TabIndex = 3;
+            this.progressBarGettingTimeCorrection.Visible = false;
+            // 
             // Troubleshooting
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.ClientSize = new System.Drawing.Size(366, 129);
+            this.Controls.Add(this.progressBarGettingTimeCorrection);
             this.Controls.Add(this.buttonTroubleshootingWebsite);
             this.Controls.Add(this.buttonPingGoogle);
             this.Controls.Add(this.labelHeader);
         private System.Windows.Forms.Label labelHeader;
         private System.Windows.Forms.Button buttonPingGoogle;
         private System.Windows.Forms.Button buttonTroubleshootingWebsite;
+        private System.Windows.Forms.ProgressBar progressBarGettingTimeCorrection;
     }
 }

File Troubleshooting.cs

 using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
 using System.Diagnostics;
-using System.Drawing;
-using System.Linq;
-using System.Net;
-using System.Text;
+using System.Threading;
 using System.Windows.Forms;
+using OtpSharp;
 
 namespace KeeOtp
 {
 
         private void buttonPingGoogle_Click(object sender, EventArgs e)
         {
-            try
+            // this is kind of an odd flow.
+
+            TimeCorrection timeCorrection = null;
+
+            // set up the asyn operation complete with continuation, catch and finally delegates
+            // the async operation will use the synchronization context to post the continuation,
+            // catch, and finally delegates to run on the UI thread.  Since we are creating this object
+            // on the UI thread it will use the UI synchronization context.
+            AsyncOperation getTimeCorrectionOperation = new AsyncOperation(() => // on background threadpool thread
             {
-                using (var wc = new WebClient())
-                {
-                    wc.DownloadData("https://www.google.com");
-                    var dateHeader = wc.ResponseHeaders.Get("Date");
-                    var date = DateTime.Parse(dateHeader);
+                timeCorrection = Ntp.GetTimeCorrectionFromGoogle();
+            },
+            () => // continuation on UI thread
+            {
+                var offset = timeCorrection.CorrectionFactor;
 
-                    var offset = date.ToUniversalTime() - DateTime.UtcNow;
+                var totalSeconds = Math.Abs(offset.TotalSeconds);
+                if (totalSeconds == 0)
+                    MessageBox.Show("Your time is perfect according to Google's servers");
+                else if (totalSeconds <= 5)
+                    MessageBox.Show("Your time is off by five seconds or less from Google's servers.  You should be just fine.");
+                else if (totalSeconds <= 30)
+                    MessageBox.Show(string.Format("Your time is off by {0} seconds from Google's servers.  You are probably OK but correcting couldn't hurt.", totalSeconds));
+                else
+                    MessageBox.Show(string.Format("Your time is off by {0} seconds from Google's servers.  Try correcting the difference and try again.", totalSeconds));
+            },
+            ex => MessageBox.Show(ex.Message, "Error"), // catch on UI thread
+            () => // finally on UI thread
+            {
+                this.buttonPingGoogle.Visible = true;
+                this.progressBarGettingTimeCorrection.Visible = false;
+            });
 
-                    if (offset.TotalSeconds == 0)
-                        MessageBox.Show("Your time is perfect according to Google's servers");
-                    else if (offset.TotalSeconds <= 5)
-                        MessageBox.Show("Your time is off by five seconds or less from Google's servers.  You should be just fine.");
-                    else
-                        MessageBox.Show(string.Format("Your time is off by {0} seconds from Google's servers.  Try correcting the difference and try again.", offset.TotalSeconds));
-                }
-            }
-            catch (Exception ex)
-            {
-                MessageBox.Show(ex.Message, "Error");
-            }
+
+            this.buttonPingGoogle.Visible = false;
+            this.progressBarGettingTimeCorrection.Visible = true;
+
+            getTimeCorrectionOperation.Run();
         }
 
         private void buttonTroubleshootingWebsite_Click(object sender, EventArgs e)

File Troubleshooting.resx

     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
 </root>