-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #123 from PinguApps/90-feat-account-create-2fa-cha…
…llenge Implemented create 2fa challenge
- Loading branch information
Showing
13 changed files
with
341 additions
and
10 deletions.
There are no files selected for viewing
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
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
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
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
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
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 System.Runtime.Serialization; | ||
|
||
namespace PinguApps.Appwrite.Shared.Enums; | ||
|
||
/// <summary> | ||
/// The type of second factor | ||
/// </summary> | ||
public enum SecondFactor | ||
{ | ||
/// <summary> | ||
/// Email 2fa | ||
/// </summary> | ||
[EnumMember(Value = "email")] | ||
Email, | ||
/// <summary> | ||
/// Phone 2fa | ||
/// </summary> | ||
[EnumMember(Value = "phone")] | ||
Phone, | ||
/// <summary> | ||
/// Authenticator App 2fa | ||
/// </summary> | ||
[EnumMember(Value = "totp")] | ||
Totp, | ||
/// <summary> | ||
/// 2fa Recovery Code | ||
/// </summary> | ||
[EnumMember(Value = "recoveryCode")] | ||
RecoveryCode | ||
} |
18 changes: 18 additions & 0 deletions
18
src/PinguApps.Appwrite.Shared/Requests/Create2faChallengeRequest.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,18 @@ | ||
using System.Text.Json.Serialization; | ||
using PinguApps.Appwrite.Shared.Enums; | ||
using PinguApps.Appwrite.Shared.Requests.Validators; | ||
|
||
namespace PinguApps.Appwrite.Shared.Requests; | ||
public class Create2faChallengeRequest : BaseRequest<Create2faChallengeRequest, Create2faChallengeRequestValidator> | ||
{ | ||
/// <summary> | ||
/// Factor used for verification. Must be one of following: <list type="bullet"> | ||
/// <item><description>email</description></item> | ||
/// <item><description>phone</description></item> | ||
/// <item><description>totp</description></item> | ||
/// <item><description>recoveryCode</description></item> | ||
/// </list> | ||
/// </summary> | ||
[JsonPropertyName("factor")] | ||
public SecondFactor Factor { get; set; } | ||
} |
10 changes: 10 additions & 0 deletions
10
src/PinguApps.Appwrite.Shared/Requests/Validators/Create2faChallengeRequestValidator.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,10 @@ | ||
using FluentValidation; | ||
|
||
namespace PinguApps.Appwrite.Shared.Requests.Validators; | ||
public class Create2faChallengeRequestValidator : AbstractValidator<Create2faChallengeRequest> | ||
{ | ||
public Create2faChallengeRequestValidator() | ||
{ | ||
RuleFor(x => x.Factor).IsInEnum(); | ||
} | ||
} |
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,18 @@ | ||
using System; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace PinguApps.Appwrite.Shared.Responses; | ||
|
||
/// <summary> | ||
/// An Appwrite Mfa Challenge object | ||
/// </summary> | ||
/// <param name="Id">Token ID</param> | ||
/// <param name="CreatedAt">Token creation date in ISO 8601 format</param> | ||
/// <param name="UserId">User ID</param> | ||
/// <param name="Expire">Token expiration date in ISO 8601 format</param> | ||
public record MfaChallenge( | ||
[property: JsonPropertyName("$id")] string Id, | ||
[property: JsonPropertyName("$createdAt")] DateTime CreatedAt, | ||
[property: JsonPropertyName("userId")] string UserId, | ||
[property: JsonPropertyName("expire")] DateTime Expire | ||
); |
82 changes: 82 additions & 0 deletions
82
.../PinguApps.Appwrite.Client.Tests/Clients/Account/AccountClientTests.Create2faChallenge.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,82 @@ | ||
using System.Net; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using PinguApps.Appwrite.Shared.Requests; | ||
using PinguApps.Appwrite.Shared.Tests; | ||
using RichardSzalay.MockHttp; | ||
|
||
namespace PinguApps.Appwrite.Client.Tests.Clients.Account; | ||
public partial class AccountClientTests | ||
{ | ||
[Fact] | ||
public async Task Create2faChallenge_ShouldReturnSuccess_WhenApiCallSucceeds() | ||
{ | ||
// Arrange | ||
var request = new Create2faChallengeRequest(); | ||
|
||
var options = new JsonSerializerOptions(); | ||
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, false)); | ||
|
||
_mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account/mfa/challenge") | ||
.ExpectedHeaders(true) | ||
.WithJsonContent(request, options) | ||
.Respond(Constants.AppJson, Constants.MfaTypeResponse); | ||
|
||
_appwriteClient.SetSession(Constants.Session); | ||
|
||
// Act | ||
var result = await _appwriteClient.Account.Create2faChallenge(request); | ||
|
||
// Assert | ||
Assert.True(result.Success); | ||
} | ||
|
||
[Fact] | ||
public async Task Create2faChallenge_ShouldHandleException_WhenApiCallFails() | ||
{ | ||
// Arrange | ||
var request = new Create2faChallengeRequest(); | ||
|
||
var options = new JsonSerializerOptions(); | ||
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, false)); | ||
|
||
_mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account/mfa/challenge") | ||
.ExpectedHeaders(true) | ||
.WithJsonContent(request, options) | ||
.Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError); | ||
|
||
_appwriteClient.SetSession(Constants.Session); | ||
|
||
// Act | ||
var result = await _appwriteClient.Account.Create2faChallenge(request); | ||
|
||
// Assert | ||
Assert.True(result.IsError); | ||
Assert.True(result.IsAppwriteError); | ||
} | ||
|
||
[Fact] | ||
public async Task Create2faChallenge_ShouldReturnErrorResponse_WhenExceptionOccurs() | ||
{ | ||
// Arrange | ||
var request = new Create2faChallengeRequest(); | ||
|
||
var options = new JsonSerializerOptions(); | ||
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, false)); | ||
|
||
_mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/account/mfa/challenge") | ||
.ExpectedHeaders(true) | ||
.WithJsonContent(request, options) | ||
.Throw(new HttpRequestException("An error occurred")); | ||
|
||
_appwriteClient.SetSession(Constants.Session); | ||
|
||
// Act | ||
var result = await _appwriteClient.Account.Create2faChallenge(request); | ||
|
||
// Assert | ||
Assert.False(result.Success); | ||
Assert.True(result.IsInternalError); | ||
Assert.Equal("An error occurred", result.Result.AsT2.Message); | ||
} | ||
} |
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
98 changes: 98 additions & 0 deletions
98
tests/PinguApps.Appwrite.Shared.Tests/Requests/Create2faChallengeRequestTests.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,98 @@ | ||
using FluentValidation; | ||
using PinguApps.Appwrite.Shared.Enums; | ||
using PinguApps.Appwrite.Shared.Requests; | ||
|
||
namespace PinguApps.Appwrite.Shared.Tests.Requests; | ||
public class Create2faChallengeRequestTests | ||
{ | ||
[Fact] | ||
public void Constructor_InitializesWithExpectedValues() | ||
{ | ||
// Arrange & Act | ||
var request = new Create2faChallengeRequest(); | ||
|
||
// Assert | ||
Assert.Equal(SecondFactor.Email, request.Factor); | ||
} | ||
|
||
[Fact] | ||
public void Properties_CanBeSet() | ||
{ | ||
// Arrange | ||
var request = new Create2faChallengeRequest(); | ||
|
||
// Act | ||
request.Factor = SecondFactor.Phone; | ||
|
||
// Assert | ||
Assert.Equal(SecondFactor.Phone, request.Factor); | ||
} | ||
|
||
[Theory] | ||
[InlineData(SecondFactor.Email)] | ||
[InlineData(SecondFactor.Phone)] | ||
[InlineData(SecondFactor.Totp)] | ||
[InlineData(SecondFactor.RecoveryCode)] | ||
public void IsValid_WithValidInputs_ReturnsTrue(SecondFactor factor) | ||
{ | ||
// Arrange | ||
var request = new Create2faChallengeRequest | ||
{ | ||
Factor = factor | ||
}; | ||
|
||
// Act | ||
var isValid = request.IsValid(); | ||
|
||
// Assert | ||
Assert.True(isValid); | ||
} | ||
|
||
[Theory] | ||
[InlineData((SecondFactor)999)] | ||
public void IsValid_WithInvalidInputs_ReturnsFalse(SecondFactor factor) | ||
{ | ||
// Arrange | ||
var request = new Create2faChallengeRequest | ||
{ | ||
Factor = factor | ||
}; | ||
|
||
var ggg = (int)factor; | ||
|
||
// Act | ||
var isValid = request.IsValid(); | ||
|
||
// Assert | ||
Assert.False(isValid); | ||
} | ||
|
||
[Fact] | ||
public void Validate_WithThrowOnFailuresTrue_ThrowsValidationExceptionOnFailure() | ||
{ | ||
// Arrange | ||
var request = new Create2faChallengeRequest | ||
{ | ||
Factor = (SecondFactor)999 | ||
}; | ||
|
||
// Assert | ||
Assert.Throws<ValidationException>(() => request.Validate(true)); | ||
} | ||
|
||
[Fact] | ||
public void Validate_WithThrowOnFailuresFalse_ReturnsInvalidResultOnFailure() | ||
{ | ||
// Arrange | ||
var request = new Create2faChallengeRequest | ||
{ | ||
Factor = (SecondFactor)999 | ||
}; | ||
|
||
// Act | ||
var result = request.Validate(false); | ||
|
||
// Assert | ||
Assert.False(result.IsValid); | ||
} | ||
} |
Oops, something went wrong.