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
|
### Validate code
|
||||||
```csharp
|
```csharp
|
||||||
int codeToValidate = 350386;
|
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
|
### Generate setup config
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ namespace SimpleOTP.Test.Models
|
|||||||
public void TestShortLinkGenerator()
|
public void TestShortLinkGenerator()
|
||||||
{
|
{
|
||||||
OTPConfiguration config = OTPConfiguration.GenerateConfiguration("FoxDev Studio", "eugene@xfox111.net");
|
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();
|
Uri uri = config.GetUri();
|
||||||
Assert.AreEqual($"otpauth://totp/FoxDev+Studio:eugene@xfox111.net?secret={config.Secret}&issuer=FoxDev+Studio", uri.AbsoluteUri);
|
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");
|
OTPConfiguration config = OTPConfiguration.GetConfiguration("ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH", "FoxDev Studio", "eugene@xfox111.net");
|
||||||
config.Period = TimeSpan.FromSeconds(3);
|
config.Period = TimeSpan.FromSeconds(3);
|
||||||
using OTPFactory factory = new (config, 1500);
|
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;
|
var code = factory.CurrentCode;
|
||||||
|
|
||||||
factory.Configuration = config;
|
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(15)).Code,
|
||||||
OTPService.GenerateCode(ref totpConfig, DateTime.UtcNow.AddSeconds(45)).Code,
|
OTPService.GenerateCode(ref totpConfig, DateTime.UtcNow.AddSeconds(45)).Code,
|
||||||
};
|
};
|
||||||
Assert.IsFalse(OTPService.ValidateCode(codes[0], totpConfig));
|
Assert.IsFalse(OTPService.ValidateTotp(codes[0], totpConfig));
|
||||||
Assert.IsTrue(OTPService.ValidateCode(codes[1], totpConfig));
|
Assert.IsTrue(OTPService.ValidateTotp(codes[1], totpConfig));
|
||||||
Assert.IsTrue(OTPService.ValidateCode(codes[2], totpConfig));
|
Assert.IsTrue(OTPService.ValidateTotp(codes[2], totpConfig));
|
||||||
Assert.IsTrue(OTPService.ValidateCode(codes[3], totpConfig));
|
Assert.IsTrue(OTPService.ValidateTotp(codes[3], totpConfig));
|
||||||
Assert.IsFalse(OTPService.ValidateCode(codes[4], 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>
|
/// <summary>
|
||||||
@@ -92,19 +94,21 @@ namespace SimpleOTP.Test
|
|||||||
};
|
};
|
||||||
|
|
||||||
hotpConfig.Counter = 10002;
|
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.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);
|
Assert.AreEqual(10001, hotpConfig.Counter);
|
||||||
hotpConfig.Counter = 10002;
|
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);
|
Assert.AreEqual(10002, hotpConfig.Counter);
|
||||||
hotpConfig.Counter = 10002;
|
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);
|
Assert.AreEqual(10003, hotpConfig.Counter);
|
||||||
hotpConfig.Counter = 10002;
|
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.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="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>
|
/// <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>
|
/// <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;
|
long currentCounter = target.Counter;
|
||||||
List<(int Code, long Counter)> codes = new ();
|
List<(int Code, long Counter)> codes = new ();
|
||||||
for (long i = currentCounter - toleranceSpan; i <= currentCounter + toleranceSpan; i++)
|
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/>
|
/// <param name="toleranceTime">Time span from which OTP codes remain valid.<br/>
|
||||||
/// Default: 15 seconds.</param>
|
/// Default: 15 seconds.</param>
|
||||||
/// <returns><c>True</c> if code is valid, <c>False</c> if it isn't.</returns>
|
/// <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);
|
toleranceTime ??= TimeSpan.FromSeconds(15);
|
||||||
DateTime now = DateTime.UtcNow;
|
DateTime now = DateTime.UtcNow;
|
||||||
List<int> codes = new ();
|
List<int> codes = new ();
|
||||||
@@ -134,6 +138,16 @@ namespace SimpleOTP
|
|||||||
return codes.Any(i => i == otp);
|
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) =>
|
private static long GetCurrentCounter(DateTime date, int period) =>
|
||||||
(long)(date - DateTime.UnixEpoch).TotalSeconds / period;
|
(long)(date - DateTime.UnixEpoch).TotalSeconds / period;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>SimpleOTP</PackageId>
|
<PackageId>SimpleOTP</PackageId>
|
||||||
<AssemblyName>SimpleOTP</AssemblyName>
|
<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>
|
<Description>.NET library for TOTP/HOTP implementation on server (ASP.NET) or client (Xamarin) side</Description>
|
||||||
<Authors>Eugene Fox</Authors>
|
<Authors>Eugene Fox</Authors>
|
||||||
<Company>FoxDev Studio</Company>
|
<Company>FoxDev Studio</Company>
|
||||||
@@ -21,17 +21,7 @@
|
|||||||
<RepositoryUrl>https://github.com/XFox111/SimpleOTP</RepositoryUrl>
|
<RepositoryUrl>https://github.com/XFox111/SimpleOTP</RepositoryUrl>
|
||||||
<NeutralLanguage>en-US</NeutralLanguage>
|
<NeutralLanguage>en-US</NeutralLanguage>
|
||||||
<PackageTags>otp;totp;dotnet;hotp;authenticator;2fa;mfa;security;oath</PackageTags>
|
<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
|
<PackageReleaseNotes>- Updated OTP validation methods signatures: `ValidateCode()` is now deprecated and will be removed in future releases</PackageReleaseNotes>
|
||||||
|
|
||||||
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>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
|||||||
Reference in New Issue
Block a user