-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(user): switched to method based consumes and produces
- Loading branch information
1 parent
bc6aaa8
commit 0284ee9
Showing
4 changed files
with
87 additions
and
129 deletions.
There are no files selected for viewing
98 changes: 0 additions & 98 deletions
98
src/main/java/dev/cloudeko/zenei/application/web/resource/AuthenticationResource.java
This file was deleted.
Oops, something went wrong.
107 changes: 87 additions & 20 deletions
107
src/main/java/dev/cloudeko/zenei/application/web/resource/UserResource.java
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 |
---|---|---|
@@ -1,32 +1,99 @@ | ||
package dev.cloudeko.zenei.application.web.resource; | ||
|
||
import jakarta.enterprise.context.ApplicationScoped; | ||
import jakarta.ws.rs.Consumes; | ||
import jakarta.ws.rs.Produces; | ||
import dev.cloudeko.zenei.application.web.model.request.SignupRequest; | ||
import dev.cloudeko.zenei.application.web.model.response.PrivateUserResponse; | ||
import dev.cloudeko.zenei.application.web.model.response.TokenResponse; | ||
import dev.cloudeko.zenei.domain.feature.*; | ||
import dev.cloudeko.zenei.domain.model.email.EmailAddressInput; | ||
import dev.cloudeko.zenei.domain.model.email.VerifyMagicLinkInput; | ||
import dev.cloudeko.zenei.domain.model.token.LoginPasswordInput; | ||
import dev.cloudeko.zenei.domain.model.token.RefreshTokenInput; | ||
import io.quarkus.security.Authenticated; | ||
import jakarta.transaction.Transactional; | ||
import jakarta.validation.Valid; | ||
import jakarta.ws.rs.*; | ||
import jakarta.ws.rs.core.Context; | ||
import jakarta.ws.rs.core.MediaType; | ||
import jakarta.ws.rs.core.Response; | ||
import jakarta.ws.rs.core.SecurityContext; | ||
import lombok.AllArgsConstructor; | ||
import org.eclipse.microprofile.openapi.annotations.tags.Tag; | ||
|
||
//@Path("/user") | ||
@ApplicationScoped | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
@Produces(MediaType.APPLICATION_JSON) | ||
@Tag(name = "User Service", description = "API for managing users") | ||
import java.net.URI; | ||
|
||
@Path("/user") | ||
@AllArgsConstructor | ||
@Tag(name = "User Service", description = "API for user authentication") | ||
public class UserResource { | ||
|
||
/*@Inject | ||
UserService userService; | ||
private final CreateUser createUser; | ||
private final FindUserByIdentifier findUserByIdentifier; | ||
|
||
@Inject | ||
CurrentIdentityAssociation identity; | ||
private final VerifyMagicLink verifyMagicLink; | ||
private final RefreshAccessToken refreshAccessToken; | ||
private final SendMagicLinkVerifyEmail sendMagicLinkVerifyEmail; | ||
private final LoginUserWithPassword loginUserWithPassword; | ||
|
||
@GET | ||
@Authenticated | ||
@APIResponse(responseCode = "200", description = "Web app retrieved successfully", content = @Content(schema = @Schema(implementation = User.class))) | ||
public Uni<Response> getCurrentUserInfo() { | ||
return identity.getDeferredIdentity() | ||
.onItem().ifNotNull() | ||
.transformToUni(securityIdentity -> userService.getUserByEmail(securityIdentity.getPrincipal().getName())) | ||
.onItem().ifNotNull().transform(user -> Response.ok().entity(user).build()) | ||
.onItem().ifNull().continueWith(Response.status(Response.SigninStatus.NOT_FOUND).build()); | ||
}*/ | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public Response getCurrentUserInfo(@Context SecurityContext securityContext) { | ||
final var userId = Long.parseLong(securityContext.getUserPrincipal().getName()); | ||
final var user = findUserByIdentifier.handle(userId); | ||
|
||
return Response.ok(new PrivateUserResponse(user)).build(); | ||
} | ||
|
||
@POST | ||
@Transactional | ||
@Produces(MediaType.APPLICATION_JSON) | ||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) | ||
public Response signup(@BeanParam @Valid SignupRequest request) { | ||
final var user = createUser.handle(request.toCreateUserInput()); | ||
final var emailAddress = user.getPrimaryEmailAddress(); | ||
|
||
if (!emailAddress.getEmailVerified() && emailAddress.getEmailVerificationToken() != null){ | ||
sendMagicLinkVerifyEmail.handle(new EmailAddressInput(emailAddress)); | ||
} | ||
|
||
if (request.getRedirectTo() != null) { | ||
return Response.temporaryRedirect(request.getRedirectTo()).build(); | ||
} | ||
|
||
return Response.ok(new PrivateUserResponse(user)).build(); | ||
} | ||
|
||
@POST | ||
@Transactional | ||
@Path("/verify-email") | ||
@Consumes(MediaType.MEDIA_TYPE_WILDCARD) | ||
public Response verifyEmail(@QueryParam("token") String token, @QueryParam("redirect_to") URI redirectTo) { | ||
verifyMagicLink.handle(new VerifyMagicLinkInput(token)); | ||
if (redirectTo != null) { | ||
return Response.temporaryRedirect(redirectTo).build(); | ||
} | ||
|
||
return Response.noContent().build(); | ||
} | ||
|
||
@POST | ||
@Transactional | ||
@Path("/token") | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public Response token(@QueryParam("grant_type") String grantType, | ||
@QueryParam("username") String username, | ||
@QueryParam("password") String password, | ||
@QueryParam("refresh_token") String refreshToken) { | ||
return switch (grantType) { | ||
case "password" -> { | ||
final var token = loginUserWithPassword.handle(new LoginPasswordInput(username, password)); | ||
yield Response.ok(new TokenResponse(token)).build(); | ||
} | ||
case "refresh_token" -> { | ||
final var token = refreshAccessToken.handle(new RefreshTokenInput(refreshToken)); | ||
yield Response.ok(new TokenResponse(token)).build(); | ||
} | ||
default -> Response.status(Response.Status.BAD_REQUEST).build(); | ||
}; | ||
} | ||
} |
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 |
---|---|---|
|
@@ -55,7 +55,6 @@ void testCreateUser() { | |
@DisplayName("Retrieve user information (GET /user) should return (200 OK)") | ||
void testGetUserInfo() { | ||
final var token = given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.queryParam("grant_type", "password") | ||
.queryParam("username", "[email protected]") | ||
.queryParam("password", "test-password") | ||
|
@@ -65,7 +64,6 @@ void testGetUserInfo() { | |
.extract().as(TokenResponse.class); | ||
|
||
given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.header("Authorization", "Bearer " + token.getAccessToken()) | ||
.get("/user") | ||
.then() | ||
|
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 |
---|---|---|
|
@@ -105,7 +105,6 @@ void testVerifyEmail() { | |
@DisplayName("Retrieve a access token using username and password (POST /user/token) should return (200 OK)") | ||
void testGetAccessToken() { | ||
given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.queryParam("grant_type", "password") | ||
.queryParam("username", "[email protected]") | ||
.queryParam("password", "test-password") | ||
|
@@ -123,7 +122,6 @@ void testGetAccessToken() { | |
@DisplayName("Try to retrieve a access token using invalid username and password (POST /user/token) should return (401 UNAUTHORIZED)") | ||
void testGetAccessTokenInvalid() { | ||
given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.queryParam("grant_type", "password") | ||
.queryParam("username", "[email protected]") | ||
.queryParam("password", "invalid-password") | ||
|
@@ -137,7 +135,6 @@ void testGetAccessTokenInvalid() { | |
@DisplayName("Retrieve a new access token using refresh token (POST /user/token) should return (200 OK)") | ||
void testGetAccessTokenUsingRefreshToken() { | ||
final var token = given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.queryParam("grant_type", "password") | ||
.queryParam("username", "[email protected]") | ||
.queryParam("password", "test-password") | ||
|
@@ -151,7 +148,6 @@ void testGetAccessTokenUsingRefreshToken() { | |
.extract().as(TokenResponse.class); | ||
|
||
given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.queryParam("grant_type", "refresh_token") | ||
.queryParam("refresh_token", token.getRefreshToken()) | ||
.post("/user/token") | ||
|
@@ -168,7 +164,6 @@ void testGetAccessTokenUsingRefreshToken() { | |
@DisplayName("Try to retrieve a new access token using invalid grant type (POST /user/token) should return (400 BAD_REQUEST)") | ||
void testGetAccessTokenUsingInvalidGrantType() { | ||
given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.queryParam("grant_type", "invalid-grant-type") | ||
.queryParam("username", "invalid-username") | ||
.queryParam("password", "invalid-password") | ||
|
@@ -182,7 +177,6 @@ void testGetAccessTokenUsingInvalidGrantType() { | |
@DisplayName("Try to retrieve a new access token using invalid refresh token (POST /user/token) should return (401 UNAUTHORIZED)") | ||
void testGetAccessTokenUsingInvalidRefreshToken() { | ||
given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.queryParam("grant_type", "refresh_token") | ||
.queryParam("refresh_token", "invalid-refresh-token") | ||
.post("/user/token") | ||
|
@@ -195,7 +189,6 @@ void testGetAccessTokenUsingInvalidRefreshToken() { | |
@DisplayName("Retrieve user information (GET /user) should return (200 OK)") | ||
void testGetUserInfo() { | ||
final var token = given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.queryParam("grant_type", "password") | ||
.queryParam("username", "[email protected]") | ||
.queryParam("password", "test-password") | ||
|
@@ -205,7 +198,6 @@ void testGetUserInfo() { | |
.extract().as(TokenResponse.class); | ||
|
||
given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.header("Authorization", "Bearer " + token.getAccessToken()) | ||
.get("/user") | ||
.then() | ||
|
@@ -225,7 +217,6 @@ void testGetUserInfo() { | |
@DisplayName("Retrieve user information without token (GET /user) should return (401 UNAUTHORIZED)") | ||
void testGetUserInfoWithoutToken() { | ||
given() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.get("/user") | ||
.then() | ||
.statusCode(Response.Status.UNAUTHORIZED.getStatusCode()); | ||
|