-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6fb3547
commit d40d73a
Showing
38 changed files
with
2,266 additions
and
1 deletion.
There are no files selected for viewing
Binary file not shown.
43 changes: 43 additions & 0 deletions
43
thirdparty/Google.Authenticator/Google.Authenticator.Tests/AuthCodeTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using System.Text; | ||
using Shouldly; | ||
using Xunit; | ||
|
||
namespace Google.Authenticator.Tests | ||
{ | ||
public class AuthCodeTest | ||
{ | ||
[Fact] | ||
public void BasicAuthCodeTest() | ||
{ | ||
var secretKey = "PJWUMZKAUUFQKJBAMD6VGJ6RULFVW4ZH"; | ||
var expected = "551508"; | ||
|
||
var tfa = new TwoFactorAuthenticator(); | ||
|
||
var currentTime = 1416643820; | ||
|
||
// I actually think you are supposed to divide the time by 30 seconds? | ||
// Maybe need an overload that takes a DateTime? | ||
var actual = tfa.GeneratePINAtInterval(secretKey, currentTime, 6); | ||
|
||
actual.ShouldBe(expected); | ||
} | ||
|
||
[Fact] | ||
public void Base32AuthCodeTest() | ||
{ | ||
var secretKey = Base32Encoding.ToString(Encoding.UTF8.GetBytes("PJWUMZKAUUFQKJBAMD6VGJ6RULFVW4ZH")); | ||
var expected = "551508"; | ||
|
||
var tfa = new TwoFactorAuthenticator(); | ||
|
||
var currentTime = 1416643820; | ||
|
||
// I actually think you are supposed to divide the time by 30 seconds? | ||
// Maybe need an overload that takes a DateTime? | ||
var actual = tfa.GeneratePINAtInterval(secretKey, currentTime, 6, true); | ||
|
||
actual.ShouldBe(expected); | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
thirdparty/Google.Authenticator/Google.Authenticator.Tests/GeneratePinTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using Xunit; | ||
using Shouldly; | ||
using System.Text; | ||
using System.Net.NetworkInformation; | ||
|
||
namespace Google.Authenticator.Tests | ||
{ | ||
public class GeneratePinTests | ||
{ | ||
[Fact] | ||
public void OverloadsReturnSamePIN() | ||
{ | ||
var secret = "JBSWY3DPEHPK3PXP"; | ||
var secretAsBytes = Encoding.UTF8.GetBytes(secret); | ||
var secretAsBase32 = Base32Encoding.ToString(secretAsBytes); | ||
long counter = 54615912; | ||
var expected = "508826"; | ||
|
||
var subject = new TwoFactorAuthenticator(); | ||
|
||
var pinFromString = subject.GeneratePINAtInterval(secret, counter); | ||
var pinFromBytes = subject.GeneratePINAtInterval(secretAsBytes, counter); | ||
var pinFromBase32 = subject.GeneratePINAtInterval(secretAsBase32, counter, secretIsBase32: true); | ||
|
||
pinFromString.ShouldBe(expected); | ||
pinFromBytes.ShouldBe(expected); | ||
pinFromBase32.ShouldBe(expected); | ||
} | ||
} | ||
} | ||
|
||
// private long GetCurrentCounter(DateTime now, DateTime epoch, int timeStep) => | ||
//(long) (now - epoch).TotalSeconds / timeStep; |
29 changes: 29 additions & 0 deletions
29
thirdparty/Google.Authenticator/Google.Authenticator.Tests/Google.Authenticator.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>netcoreapp3.1;net452;net5.0</TargetFrameworks> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> | ||
<PackageReference Include="Shouldly" Version="3.0.2" /> | ||
<PackageReference Include="xunit" Version="2.4.1" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
<PackageReference Include="coverlet.collector" Version="3.1.0"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
<PackageReference Include="ZXing.Net" Version="0.16.7" /> | ||
</ItemGroup> | ||
<ItemGroup Condition="'$(TargetFramework)' != 'net452'"> | ||
<PackageReference Include="ZXing.Net.Bindings.Magick" Version="0.16.9" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="..\Google.Authenticator\Google.Authenticator.csproj" /> | ||
</ItemGroup> | ||
</Project> |
64 changes: 64 additions & 0 deletions
64
thirdparty/Google.Authenticator/Google.Authenticator.Tests/QRCodeTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using Xunit; | ||
using Shouldly; | ||
using System.Diagnostics; | ||
using System; | ||
using ZXing; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
|
||
namespace Google.Authenticator.Tests | ||
{ | ||
public class QRCodeTest | ||
{ | ||
[Theory] | ||
[InlineData("issuer", "otpauth://totp/issuer:[email protected]?secret=ONSWG4TFOQ&issuer=issuer")] | ||
[InlineData("Foo & Bar", "otpauth://totp/Foo%20%26%20Bar:[email protected]?secret=ONSWG4TFOQ&issuer=Foo%20%26%20Bar")] | ||
[InlineData("个", "otpauth://totp/%E4%B8%AA:[email protected]?secret=ONSWG4TFOQ&issuer=%E4%B8%AA")] | ||
public void CanGenerateQRCode(string issuer, string expectedUrl) | ||
{ | ||
var subject = new TwoFactorAuthenticator(); | ||
var setupCodeInfo = subject.GenerateSetupCode( | ||
issuer, | ||
"[email protected]", | ||
"secret", | ||
false, | ||
2); | ||
|
||
var actualUrl = ExtractUrlFromQRImage(setupCodeInfo.QrCodeSetupImageUrl); | ||
|
||
actualUrl.ShouldBe(expectedUrl); | ||
} | ||
|
||
private static string ExtractUrlFromQRImage(string qrCodeSetupImageUrl) | ||
{ | ||
var headerLength = "data:image/png;base64,".Length; | ||
var rawImageData = qrCodeSetupImageUrl.Substring(headerLength, qrCodeSetupImageUrl.Length - headerLength); | ||
var imageData = Convert.FromBase64String(rawImageData); | ||
|
||
//var reader = new BarcodeReaderGeneric(); | ||
//reader.Options.PossibleFormats = new List<BarcodeFormat> { | ||
// BarcodeFormat.QR_CODE | ||
//}; | ||
|
||
#if NETFRAMEWORK | ||
var reader = new BarcodeReader(); | ||
reader.Options.PossibleFormats = new List<BarcodeFormat> { | ||
BarcodeFormat.QR_CODE | ||
}; | ||
using (var ms = new MemoryStream(imageData)) | ||
{ | ||
var image = new System.Drawing.Bitmap(ms); | ||
return reader.Decode(image).Text; | ||
} | ||
#else | ||
var reader = new BarcodeReaderGeneric(); | ||
reader.Options.PossibleFormats = new List<BarcodeFormat> { | ||
BarcodeFormat.QR_CODE | ||
}; | ||
var image = new ImageMagick.MagickImage(imageData); | ||
var wrappedImage = new ZXing.Magick.MagickImageLuminanceSource(image); | ||
return reader.Decode(wrappedImage).Text; | ||
#endif | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
thirdparty/Google.Authenticator/Google.Authenticator.Tests/SetupCodeTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using Xunit; | ||
using Shouldly; | ||
using System.Text; | ||
|
||
namespace Google.Authenticator.Tests | ||
{ | ||
public class SetupCodeTests | ||
{ | ||
[Fact] | ||
public void ByteAndStringGeneratesSameSetupCode() | ||
{ | ||
var secret = "12345678901234567890123456789012"; | ||
var secretAsByteArray = Encoding.UTF8.GetBytes(secret); | ||
var secretAsBase32 = Base32Encoding.ToString(secretAsByteArray); | ||
var issuer = "Test"; | ||
var accountName = "TestAccount"; | ||
var expected = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZA"; | ||
|
||
var subject = new TwoFactorAuthenticator(); | ||
|
||
var setupCodeFromString = subject.GenerateSetupCode(issuer, accountName, secret, false); | ||
var setupCodeFromByteArray = subject.GenerateSetupCode(issuer, accountName, secretAsByteArray, 3, false); | ||
var setupCodeFromBase32 = subject.GenerateSetupCode(issuer, accountName, secretAsBase32, true); | ||
|
||
setupCodeFromString.ManualEntryKey.ShouldBe(expected); | ||
setupCodeFromByteArray.ManualEntryKey.ShouldBe(expected); | ||
setupCodeFromBase32.ManualEntryKey.ShouldBe(expected); | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
thirdparty/Google.Authenticator/Google.Authenticator.Tests/ValidationTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using Xunit; | ||
using Shouldly; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System; | ||
|
||
namespace Google.Authenticator.Tests | ||
{ | ||
public class ValidationTests | ||
{ | ||
const string secret = "ggggjhG&^*&^jfSSSddd"; | ||
private readonly static byte[] secretAsBytes = Encoding.UTF8.GetBytes(secret); | ||
private readonly static string secretAsBase32 = Base32Encoding.ToString(secretAsBytes); | ||
|
||
[Theory] | ||
[MemberData(nameof(GetPins))] | ||
public void ValidateWorksWithDifferentSecretTypes(string pin, int irrelevantNumberToAvoidDuplicatePinsBeingRemoved) | ||
{ | ||
// We can't directly test that the different overloads for GetCurrentPIN creates the same result, | ||
// as the time difference may may cause different PINS to be created. | ||
// So instead we generate the PINs by each method and validate each one by each method. | ||
var subject = new TwoFactorAuthenticator(); | ||
|
||
subject.ValidateTwoFactorPIN(secret, pin, false); | ||
subject.ValidateTwoFactorPIN(secret, pin, TimeSpan.FromMinutes(irrelevantNumberToAvoidDuplicatePinsBeingRemoved), false); | ||
subject.ValidateTwoFactorPIN(secretAsBytes, pin); | ||
subject.ValidateTwoFactorPIN(secretAsBytes, pin, TimeSpan.FromMinutes(irrelevantNumberToAvoidDuplicatePinsBeingRemoved)); | ||
subject.ValidateTwoFactorPIN(secretAsBase32, pin, true); | ||
subject.ValidateTwoFactorPIN(secretAsBase32, pin, TimeSpan.FromMinutes(irrelevantNumberToAvoidDuplicatePinsBeingRemoved), true); | ||
} | ||
|
||
public static IEnumerable<object[]> GetPins() | ||
{ | ||
var subject = new TwoFactorAuthenticator(); | ||
|
||
yield return new object[] { subject.GetCurrentPIN(secret), 2 }; | ||
yield return new object[] { subject.GetCurrentPIN(secret, DateTime.UtcNow), 3 }; | ||
yield return new object[] { subject.GetCurrentPIN(secretAsBytes), 4 }; | ||
yield return new object[] { subject.GetCurrentPIN(secretAsBytes, DateTime.UtcNow), 5 }; | ||
yield return new object[] { subject.GetCurrentPIN(secretAsBase32, true), 6 }; | ||
yield return new object[] { subject.GetCurrentPIN(secretAsBase32, DateTime.UtcNow, true), 7 }; | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
thirdparty/Google.Authenticator/Google.Authenticator.WebSample/Default.aspx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Google.Authenticator.WebSample.Default" %> | ||
|
||
<!DOCTYPE html> | ||
|
||
<html xmlns="http://www.w3.org/1999/xhtml"> | ||
<head runat="server"> | ||
<title>Google Authenticator Sample</title> | ||
<style type="text/css"> | ||
body | ||
{ | ||
font-family: Arial; | ||
font-size: 14px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<form id="form1" runat="server"> | ||
<div> | ||
<strong>Account Secret Key (randomly generated):</strong> <asp:Label runat="server" ID="lblSecretKey"></asp:Label> | ||
<hr /> | ||
<strong>Setup QR Code:</strong><br /> | ||
<asp:Image ID="imgQrCode" runat="server" /><br /> | ||
<br /> | ||
<strong>Manual Setup Code: </strong> <asp:Label runat="server" ID="lblManualSetupCode"></asp:Label> | ||
<hr /> | ||
Validate Code: <asp:TextBox runat="server" ID="txtCode"></asp:TextBox> <asp:Button runat="server" ID="btnValidate" Text="Validate My Code!" OnClick="btnValidate_Click" /><br /><asp:Label runat="server" Font-Bold="true" ID="lblValidationResult"></asp:Label> | ||
</div> | ||
</form> | ||
</body> | ||
</html> |
48 changes: 48 additions & 0 deletions
48
thirdparty/Google.Authenticator/Google.Authenticator.WebSample/Default.aspx.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Web; | ||
using System.Web.UI; | ||
using System.Web.UI.WebControls; | ||
|
||
namespace Google.Authenticator.WebSample | ||
{ | ||
public partial class Default : System.Web.UI.Page | ||
{ | ||
protected void Page_Load(object sender, EventArgs e) | ||
{ | ||
if (string.IsNullOrEmpty(Request.QueryString["key"])) | ||
{ | ||
Response.Redirect("~/default.aspx?key=" + Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10)); | ||
} | ||
|
||
this.lblSecretKey.Text = Request.QueryString["key"]; | ||
|
||
TwoFactorAuthenticator tfa = new TwoFactorAuthenticator(); | ||
var setupInfo = tfa.GenerateSetupCode("我 & You", "[email protected]", Request.QueryString["key"], false, 10); | ||
|
||
string qrCodeImageUrl = setupInfo.QrCodeSetupImageUrl; | ||
string manualEntrySetupCode = setupInfo.ManualEntryKey; | ||
|
||
this.imgQrCode.ImageUrl = qrCodeImageUrl; | ||
this.lblManualSetupCode.Text = manualEntrySetupCode; | ||
} | ||
|
||
protected void btnValidate_Click(object sender, EventArgs e) | ||
{ | ||
TwoFactorAuthenticator tfa = new TwoFactorAuthenticator(); | ||
var result = tfa.ValidateTwoFactorPIN(Request.QueryString["key"], this.txtCode.Text); | ||
|
||
if (result) | ||
{ | ||
this.lblValidationResult.Text = this.txtCode.Text + " is a valid PIN at UTC time " + DateTime.UtcNow.ToString(); | ||
this.lblValidationResult.ForeColor = System.Drawing.Color.Green; | ||
} | ||
else | ||
{ | ||
this.lblValidationResult.Text = this.txtCode.Text + " is not a valid PIN at UTC time " + DateTime.UtcNow.ToString(); | ||
this.lblValidationResult.ForeColor = System.Drawing.Color.Red; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.