Skip to content

Commit

Permalink
reintroduce /settings resource
Browse files Browse the repository at this point in the history
  • Loading branch information
overheadhunter committed Jun 21, 2024
1 parent f50d6fb commit c25fd98
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.cryptomator.hub.api;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.cryptomator.hub.entities.Settings;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;

@Path("/settings")
public class SettingsResource {

@Inject
Settings.Repository settingsRepo;

@GET
@RolesAllowed("user")
@Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "get the billing information")
@APIResponse(responseCode = "200")
@Transactional
public SettingsDto get() {
return SettingsDto.fromEntity(settingsRepo.get());
}

@PUT
@RolesAllowed("admin")
@Consumes(MediaType.APPLICATION_JSON)
@Operation(summary = "update settings")
@APIResponse(responseCode = "204", description = "token set")
@APIResponse(responseCode = "400", description = "invalid settings")
@APIResponse(responseCode = "403", description = "only admins are allowed to update settings")
@Transactional
public Response put(@NotNull @Valid SettingsDto dto) {
var settings = settingsRepo.get();
settings.setWotMaxDepth(dto.wotMaxDepth);
settings.setWotIdVerifyLen(dto.wotIdVerifyLen);
settingsRepo.persist(settings);
return Response.status(Response.Status.NO_CONTENT).build();
}

public record SettingsDto(@JsonProperty("hubId") String hubId, @JsonProperty("wotMaxDepth") @Min(0) @Max(10) int wotMaxDepth, @JsonProperty("wotIdVerifyLen") @Min(0) int wotIdVerifyLen) {

public static SettingsDto fromEntity(Settings entity) {
return new SettingsDto(entity.getHubId(), entity.getWotMaxDepth(), entity.getWotIdVerifyLen());
}

}

}
127 changes: 127 additions & 0 deletions backend/src/test/java/org/cryptomator/hub/api/SettingsResourceIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package org.cryptomator.hub.api;

import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import io.quarkus.test.security.oidc.Claim;
import io.quarkus.test.security.oidc.OidcSecurity;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import static io.restassured.RestAssured.given;
import static io.restassured.RestAssured.when;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
@DisplayName("Resource /settings")
public class SettingsResourceIT {

@BeforeAll
public static void beforeAll() {
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
}

@Nested
@DisplayName("As admin")
@TestSecurity(user = "Admin", roles = {"user", "admin"})
@OidcSecurity(claims = {
@Claim(key = "sub", value = "admin")
})
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class AsAdmin {

@Test
@Order(1)
@DisplayName("GET /settings returns 200")
public void testGetInitial() {
when().get("/settings")
.then().statusCode(200)
.body("wotMaxDepth", is(3))
.body("wotIdVerifyLen", is(2));
}

@Test
@Order(2)
@DisplayName("PUT /settings returns 204 No Content")
public void testPut() {
var dto = new SettingsResource.SettingsDto("42", 5, 8);
given().contentType(ContentType.JSON).body(dto)
.when().put("/settings")
.then().statusCode(204);
}

@Test
@Order(3)
@DisplayName("GET /settings returns 200")
public void testGetModify() {
when().get("/settings")
.then().statusCode(200)
.body("wotMaxDepth", is(5))
.body("wotIdVerifyLen", is(8));
}

@Test
@Order(4)
@DisplayName("PUT /settings returns 204 No Content")
public void testPutBackToDefault() {
var dto = new SettingsResource.SettingsDto("42", 3, 2);
given().contentType(ContentType.JSON).body(dto)
.when().put("/settings")
.then().statusCode(204);
}


}

@Nested
@DisplayName("As normal user")
@TestSecurity(user = "User Name 1", roles = {"user"})
@OidcSecurity(claims = {
@Claim(key = "sub", value = "user1")
})
public class AsNormalUser {

@Test
@DisplayName("GET /settings returns 200")
public void testGet() {
when().get("/settings")
.then().statusCode(200);
}

@Test
@DisplayName("PUT /settings returns 403 Forbidden")
public void testPut() {
given().contentType(ContentType.JSON).body("")
.when().put("/settings")
.then().statusCode(403);
}

}

@Nested
@DisplayName("As unauthenticated user")
public class AsAnonymous {

@Test
@DisplayName("GET /billing returns 401 Unauthorized")
public void testGet() {
when().get("/settings")
.then().statusCode(401);
}

@Test
@DisplayName("PUT /settings returns 401 Unauthorized")
public void testPut() {
given().contentType(ContentType.JSON).body("")
.when().put("/settings")
.then().statusCode(401);
}

}
}

0 comments on commit c25fd98

Please sign in to comment.