Skip to content

Commit

Permalink
Merge pull request #252 from PinguApps/227-create-user-jwt
Browse files Browse the repository at this point in the history
Implemented create user jwt
  • Loading branch information
pingu2k4 authored Oct 8, 2024
2 parents 7089c1f + 6c05ca9 commit 3bb2639
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 10 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ string emailAddressOrErrorMessage = userResponse.Result.Match(
```

## ⌛ Progress
![Server & Client - 70 / 291](https://img.shields.io/badge/Server_&_Client-70%20%2F%20291-red?style=for-the-badge)
![Server & Client - 71 / 291](https://img.shields.io/badge/Server_&_Client-71%20%2F%20291-red?style=for-the-badge)

![Server - 26 / 201](https://img.shields.io/badge/Server-26%20%2F%20201-red?style=for-the-badge)
![Server - 27 / 201](https://img.shields.io/badge/Server-27%20%2F%20201-red?style=for-the-badge)

![Client - 44 / 90](https://img.shields.io/badge/Client-44%20%2F%2090-gold?style=for-the-badge)

Expand Down Expand Up @@ -207,7 +207,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match(
| [Create Phone Verification (Confirmation)](https://appwrite.io/docs/references/1.6.x/client-rest/account#updatePhoneVerification) ||| |

### Users
![Account - 15 / 41](https://img.shields.io/badge/Users-15%20%2F%2041-gold?style=for-the-badge)
![Account - 16 / 41](https://img.shields.io/badge/Users-16%20%2F%2041-gold?style=for-the-badge)

| Endpoint | Client | Server |
|:-:|:-:|:-:|
Expand All @@ -225,7 +225,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match(
| [Get User](https://appwrite.io/docs/references/1.6.x/server-rest/users#get) |||
| [Delete User](https://appwrite.io/docs/references/1.6.x/server-rest/users#delete) |||
| [Update Email](https://appwrite.io/docs/references/1.6.x/server-rest/users#updateEmail) |||
| [Create User JWT](https://appwrite.io/docs/references/1.6.x/server-rest/users#createJWT) || |
| [Create User JWT](https://appwrite.io/docs/references/1.6.x/server-rest/users#createJWT) || |
| [Update User Labels](https://appwrite.io/docs/references/1.6.x/server-rest/users#updateLabels) |||
| [List User Logs](https://appwrite.io/docs/references/1.6.x/server-rest/users#listLogs) |||
| [List User Memberships](https://appwrite.io/docs/references/1.6.x/server-rest/users#listMemberships) |||
Expand Down
5 changes: 2 additions & 3 deletions src/PinguApps.Appwrite.Playground/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ public App(Client.IAppwriteClient client, Server.Clients.IAppwriteClient server,

public async Task Run(string[] args)
{
var request = new UpdateUserLabelsRequest()
var request = new CreateUserJwtRequest()
{
UserId = "664aac1a00113f82e620",
Labels = ["test", "admin"]
};

var response = await _server.Users.UpdateUserLabels(request);
var response = await _server.Users.CreateUserJwt(request);

Console.WriteLine(response.Result.Match(
result => result.ToString(),
Expand Down
8 changes: 7 additions & 1 deletion src/PinguApps.Appwrite.Server/Clients/IUsersClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,13 @@ public interface IUsersClient
/// <param name="request">The request content</param>
/// <returns>The user</returns>
Task<AppwriteResult<User>> UpdateEmail(UpdateEmailRequest request);
[Obsolete("This method hasn't yet been implemented.", true)]

/// <summary>
/// Use this endpoint to create a JSON Web Token for user by its unique ID. You can use the resulting JWT to authenticate on behalf of the user. The JWT secret will become invalid if the session it uses gets deleted.
/// <para><see href="https://appwrite.io/docs/references/1.6.x/server-rest/users#createJWT">Appwrite Docs</see></para>
/// </summary>
/// <param name="request">The request content</param>
/// <returns>The jwt</returns>
Task<AppwriteResult<Jwt>> CreateUserJwt(CreateUserJwtRequest request);

/// <summary>
Expand Down
17 changes: 15 additions & 2 deletions src/PinguApps.Appwrite.Server/Clients/UsersClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,22 @@ public async Task<AppwriteResult<User>> UpdateEmail(UpdateEmailRequest request)
}
}

[ExcludeFromCodeCoverage]
/// <inheritdoc/>
public Task<AppwriteResult<Jwt>> CreateUserJwt(CreateUserJwtRequest request) => throw new NotImplementedException();
public async Task<AppwriteResult<Jwt>> CreateUserJwt(CreateUserJwtRequest request)
{
try
{
request.Validate(true);

var result = await _usersApi.CreateUserJwt(request.UserId, request);

return result.GetApiResponse();
}
catch (Exception e)
{
return e.GetExceptionResponse<Jwt>();
}
}

/// <inheritdoc/>
public async Task<AppwriteResult<User>> UpdateUserLabels(UpdateUserLabelsRequest request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ public class CreateUserJwtRequest : UserIdBaseRequest<CreateUserJwtRequest, Crea
/// Session ID. Use the string <c>recent</c> to use the most recent session. Defaults to the most recent session
/// </summary>
[JsonPropertyName("sessionId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? SessionId { get; set; }

/// <summary>
/// Time in seconds before JWT expires. Default duration is 900 seconds, and maximum is 3600 seconds
/// </summary>
[JsonPropertyName("duration")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Duration { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Net;
using PinguApps.Appwrite.Shared.Requests.Users;
using PinguApps.Appwrite.Shared.Tests;
using PinguApps.Appwrite.Shared.Utils;
using RichardSzalay.MockHttp;

namespace PinguApps.Appwrite.Server.Tests.Clients.Users;
public partial class UsersClientTests
{
public static TheoryData<CreateUserJwtRequest> CreateUserJwt_ValidRequestData =
[
new CreateUserJwtRequest
{
UserId = IdUtils.GenerateUniqueId()
},
new CreateUserJwtRequest
{
UserId = IdUtils.GenerateUniqueId(),
Duration = 1800,
SessionId = IdUtils.GenerateUniqueId()
}
];

[Theory]
[MemberData(nameof(CreateUserJwt_ValidRequestData))]
public async Task CreateUserJwt_ShouldReturnSuccess_WhenApiCallSucceeds(CreateUserJwtRequest request)
{
// Arrange
_mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/users/{request.UserId}/jwts")
.WithJsonContent(request)
.ExpectedHeaders()
.Respond(Constants.AppJson, Constants.JwtResponse);

// Act
var result = await _appwriteClient.Users.CreateUserJwt(request);

// Assert
Assert.True(result.Success);
}

[Fact]
public async Task CreateUserJwt_ShouldHandleException_WhenApiCallFails()
{
// Arrange
var request = new CreateUserJwtRequest
{
UserId = "user123"
};

_mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/users/{request.UserId}/jwts")
.WithJsonContent(request)
.ExpectedHeaders()
.Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError);

// Act
var result = await _appwriteClient.Users.CreateUserJwt(request);

// Assert
Assert.True(result.IsError);
Assert.True(result.IsAppwriteError);
}

[Fact]
public async Task CreateUserJwt_ShouldReturnErrorResponse_WhenExceptionOccurs()
{
// Arrange
var request = new CreateUserJwtRequest
{
UserId = "user123"
};

_mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/users/{request.UserId}/jwts")
.WithJsonContent(request)
.ExpectedHeaders()
.Throw(new HttpRequestException("An error occurred"));

// Act
var result = await _appwriteClient.Users.CreateUserJwt(request);

// Assert
Assert.False(result.Success);
Assert.True(result.IsInternalError);
Assert.Equal("An error occurred", result.Result.AsT2.Message);
}
}

0 comments on commit 3bb2639

Please sign in to comment.