mirror of
https://github.com/XFox111/SimpleOTP.git
synced 2026-04-22 08:00:45 +03:00
Updated validation methods signatures (#13)
Improved code coverage results
This commit is contained in:
@@ -36,7 +36,7 @@ OTPCode code = OTPService.GenerateCode(ref config);
|
||||
### Validate code
|
||||
```csharp
|
||||
int codeToValidate = 350386;
|
||||
bool isValid = OTPService.ValidateCode(codeToValidate, config, TimeSpan.FromSeconds(30)); // True
|
||||
bool isValid = OTPService.ValidateTotp(codeToValidate, config, TimeSpan.FromSeconds(30)); // True
|
||||
```
|
||||
|
||||
### Generate setup config
|
||||
|
||||
@@ -26,7 +26,8 @@ namespace SimpleOTP.Test.Models
|
||||
public void TestShortLinkGenerator()
|
||||
{
|
||||
OTPConfiguration config = OTPConfiguration.GenerateConfiguration("FoxDev Studio", "eugene@xfox111.net");
|
||||
System.Diagnostics.Debug.WriteLine(config.Id);
|
||||
var testId = config.Id;
|
||||
System.Diagnostics.Debug.WriteLine(testId);
|
||||
Uri uri = config.GetUri();
|
||||
Assert.AreEqual($"otpauth://totp/FoxDev+Studio:eugene@xfox111.net?secret={config.Secret}&issuer=FoxDev+Studio", uri.AbsoluteUri);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace SimpleOTP.Test
|
||||
OTPConfiguration config = OTPConfiguration.GetConfiguration("ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH", "FoxDev Studio", "eugene@xfox111.net");
|
||||
config.Period = TimeSpan.FromSeconds(3);
|
||||
using OTPFactory factory = new (config, 1500);
|
||||
System.Diagnostics.Debug.WriteLine(factory.Configuration);
|
||||
var testGetConfig = factory.Configuration;
|
||||
System.Diagnostics.Debug.WriteLine(testGetConfig);
|
||||
var code = factory.CurrentCode;
|
||||
|
||||
factory.Configuration = config;
|
||||
|
||||
@@ -66,13 +66,15 @@ namespace SimpleOTP.Test
|
||||
OTPService.GenerateCode(ref totpConfig, DateTime.UtcNow.AddSeconds(15)).Code,
|
||||
OTPService.GenerateCode(ref totpConfig, DateTime.UtcNow.AddSeconds(45)).Code,
|
||||
};
|
||||
Assert.IsFalse(OTPService.ValidateCode(codes[0], totpConfig));
|
||||
Assert.IsTrue(OTPService.ValidateCode(codes[1], totpConfig));
|
||||
Assert.IsTrue(OTPService.ValidateCode(codes[2], totpConfig));
|
||||
Assert.IsTrue(OTPService.ValidateCode(codes[3], totpConfig));
|
||||
Assert.IsFalse(OTPService.ValidateCode(codes[4], totpConfig));
|
||||
Assert.IsFalse(OTPService.ValidateTotp(codes[0], totpConfig));
|
||||
Assert.IsTrue(OTPService.ValidateTotp(codes[1], totpConfig));
|
||||
Assert.IsTrue(OTPService.ValidateTotp(codes[2], totpConfig));
|
||||
Assert.IsTrue(OTPService.ValidateTotp(codes[3], totpConfig));
|
||||
Assert.IsFalse(OTPService.ValidateTotp(codes[4], totpConfig));
|
||||
|
||||
Assert.IsTrue(OTPService.ValidateCode(codes[0], totpConfig, TimeSpan.FromSeconds(60)));
|
||||
Assert.IsTrue(OTPService.ValidateTotp(codes[0], totpConfig, TimeSpan.FromSeconds(60)));
|
||||
|
||||
Assert.ThrowsException<ArgumentException>(() => OTPService.ValidateTotp(0, hotpConfig));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -92,19 +94,21 @@ namespace SimpleOTP.Test
|
||||
};
|
||||
|
||||
hotpConfig.Counter = 10002;
|
||||
Assert.IsFalse(OTPService.ValidateCode(codes[0], ref hotpConfig, 1, true));
|
||||
Assert.IsFalse(OTPService.ValidateHotp(codes[0], ref hotpConfig, 1, true));
|
||||
Assert.AreEqual(10002, hotpConfig.Counter);
|
||||
Assert.IsTrue(OTPService.ValidateCode(codes[1], ref hotpConfig, 1, true));
|
||||
Assert.IsTrue(OTPService.ValidateHotp(codes[1], ref hotpConfig, 1, true));
|
||||
Assert.AreEqual(10001, hotpConfig.Counter);
|
||||
hotpConfig.Counter = 10002;
|
||||
Assert.IsTrue(OTPService.ValidateCode(codes[2], ref hotpConfig, 1, true));
|
||||
Assert.IsTrue(OTPService.ValidateHotp(codes[2], ref hotpConfig, 1, true));
|
||||
Assert.AreEqual(10002, hotpConfig.Counter);
|
||||
hotpConfig.Counter = 10002;
|
||||
Assert.IsTrue(OTPService.ValidateCode(codes[3], ref hotpConfig, 1, true));
|
||||
Assert.IsTrue(OTPService.ValidateHotp(codes[3], ref hotpConfig, 1, true));
|
||||
Assert.AreEqual(10003, hotpConfig.Counter);
|
||||
hotpConfig.Counter = 10002;
|
||||
Assert.IsFalse(OTPService.ValidateCode(codes[4], ref hotpConfig, 1, true));
|
||||
Assert.IsFalse(OTPService.ValidateHotp(codes[4], ref hotpConfig, 1, true));
|
||||
Assert.AreEqual(10002, hotpConfig.Counter);
|
||||
|
||||
Assert.ThrowsException<ArgumentException>(() => OTPService.ValidateHotp(0, ref totpConfig, 1, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-2
@@ -96,8 +96,10 @@ namespace SimpleOTP
|
||||
/// <param name="toleranceSpan">Counter span from which OTP codes remain valid.</param>
|
||||
/// <param name="resyncCounter">Defines whether method should resync <see cref="OTPConfiguration.Counter"/> of the <paramref name="target"/> or not after successful validation.</param>
|
||||
/// <returns><c>True</c> if code is valid, <c>False</c> if it isn't.</returns>
|
||||
public static bool ValidateCode(int otp, ref OTPConfiguration target, int toleranceSpan, bool resyncCounter)
|
||||
public static bool ValidateHotp(int otp, ref OTPConfiguration target, int toleranceSpan, bool resyncCounter)
|
||||
{
|
||||
if (target?.Type != OTPType.HOTP)
|
||||
throw new ArgumentException("Invalid configuration. This method only validates HOTP codes. For TOTP codes use OTPService.ValidateTotp()");
|
||||
long currentCounter = target.Counter;
|
||||
List<(int Code, long Counter)> codes = new ();
|
||||
for (long i = currentCounter - toleranceSpan; i <= currentCounter + toleranceSpan; i++)
|
||||
@@ -123,8 +125,10 @@ namespace SimpleOTP
|
||||
/// <param name="toleranceTime">Time span from which OTP codes remain valid.<br/>
|
||||
/// Default: 15 seconds.</param>
|
||||
/// <returns><c>True</c> if code is valid, <c>False</c> if it isn't.</returns>
|
||||
public static bool ValidateCode(int otp, OTPConfiguration target, TimeSpan? toleranceTime = null)
|
||||
public static bool ValidateTotp(int otp, OTPConfiguration target, TimeSpan? toleranceTime = null)
|
||||
{
|
||||
if (target?.Type != OTPType.TOTP)
|
||||
throw new ArgumentException("Invalid configuration. This method only validates TOTP codes. For HOTP codes use OTPService.ValidateHotp()");
|
||||
toleranceTime ??= TimeSpan.FromSeconds(15);
|
||||
DateTime now = DateTime.UtcNow;
|
||||
List<int> codes = new ();
|
||||
@@ -134,6 +138,16 @@ namespace SimpleOTP
|
||||
return codes.Any(i => i == otp);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ValidateHotp(int, ref OTPConfiguration, int, bool)"/>
|
||||
[Obsolete("Use ValidateHotp() instead.")]
|
||||
public static bool ValidateCode(int otp, ref OTPConfiguration target, int toleranceSpan, bool resyncCounter) =>
|
||||
ValidateHotp(otp, ref target, toleranceSpan, resyncCounter);
|
||||
|
||||
/// <inheritdoc cref="ValidateTotp(int, OTPConfiguration, TimeSpan?)"/>
|
||||
[Obsolete("Use ValidateTotp() instead.")]
|
||||
public static bool ValidateCode(int otp, OTPConfiguration target, TimeSpan? toleranceTime = null) =>
|
||||
ValidateTotp(otp, target, toleranceTime);
|
||||
|
||||
private static long GetCurrentCounter(DateTime date, int period) =>
|
||||
(long)(date - DateTime.UnixEpoch).TotalSeconds / period;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<PropertyGroup>
|
||||
<PackageId>SimpleOTP</PackageId>
|
||||
<AssemblyName>SimpleOTP</AssemblyName>
|
||||
<Version>1.0.0</Version>
|
||||
<Version>1.1.0</Version>
|
||||
<Description>.NET library for TOTP/HOTP implementation on server (ASP.NET) or client (Xamarin) side</Description>
|
||||
<Authors>Eugene Fox</Authors>
|
||||
<Company>FoxDev Studio</Company>
|
||||
@@ -21,17 +21,7 @@
|
||||
<RepositoryUrl>https://github.com/XFox111/SimpleOTP</RepositoryUrl>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<PackageTags>otp;totp;dotnet;hotp;authenticator;2fa;mfa;security;oath</PackageTags>
|
||||
<PackageReleaseNotes>.NET library for TOTP/HOTP implementation on server (ASP.NET) or client (Xamarin) side
|
||||
|
||||
Features
|
||||
- Generate and validate OTP codes
|
||||
- Support of TOTP (RFC 6238) and HOTP (RFC 4226) algorithms
|
||||
- Support of HMAC-SHA1, HMAC-SHA256 and HMAC-SHA512 hashing algorithms
|
||||
- Setup URI parser
|
||||
- Database-ready configuration models
|
||||
- Configuration generator for server-side implementation
|
||||
- QR code generator
|
||||
- No dependencies</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>- Updated OTP validation methods signatures: `ValidateCode()` is now deprecated and will be removed in future releases</PackageReleaseNotes>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
||||
Reference in New Issue
Block a user