forked from Archives/Athou_commafeed
add a setup landing page instead of creating a default admin account
This commit is contained in:
@@ -4,7 +4,7 @@ Official docker images for https://github.com/Athou/commafeed/
|
||||
|
||||
## Quickstart
|
||||
|
||||
Start CommaFeed with a H2 embedded database. Then login as `admin/admin` on http://localhost:8082/
|
||||
Start CommaFeed with a H2 embedded database. The app will be accessible on http://localhost:8082/
|
||||
|
||||
### docker
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import jakarta.enterprise.event.Observes;
|
||||
import jakarta.inject.Singleton;
|
||||
|
||||
import com.commafeed.backend.feed.FeedRefreshEngine;
|
||||
import com.commafeed.backend.service.db.DatabaseStartupService;
|
||||
import com.commafeed.backend.task.TaskScheduler;
|
||||
import com.commafeed.security.password.PasswordConstraintValidator;
|
||||
|
||||
@@ -16,7 +15,6 @@ import lombok.RequiredArgsConstructor;
|
||||
@RequiredArgsConstructor
|
||||
public class CommaFeedApplication {
|
||||
|
||||
private final DatabaseStartupService databaseStartupService;
|
||||
private final FeedRefreshEngine feedRefreshEngine;
|
||||
private final TaskScheduler taskScheduler;
|
||||
private final CommaFeedConfiguration config;
|
||||
@@ -24,8 +22,6 @@ public class CommaFeedApplication {
|
||||
public void start(@Observes StartupEvent ev) {
|
||||
PasswordConstraintValidator.setStrict(config.users().strictPasswordPolicy());
|
||||
|
||||
databaseStartupService.populateInitialData();
|
||||
|
||||
feedRefreshEngine.start();
|
||||
taskScheduler.start();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,5 @@ import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
public class CommaFeedConstants {
|
||||
public static final String USERNAME_ADMIN = "admin";
|
||||
public static final String USERNAME_DEMO = "demo";
|
||||
}
|
||||
|
||||
@@ -2,12 +2,16 @@ package com.commafeed;
|
||||
|
||||
import jakarta.annotation.Priority;
|
||||
import jakarta.validation.ValidationException;
|
||||
import jakarta.ws.rs.core.NewCookie;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
|
||||
import org.jboss.resteasy.reactive.RestResponse;
|
||||
import org.jboss.resteasy.reactive.RestResponse.ResponseBuilder;
|
||||
import org.jboss.resteasy.reactive.RestResponse.Status;
|
||||
import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
|
||||
|
||||
import com.commafeed.security.CookieService;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import io.quarkus.security.AuthenticationFailedException;
|
||||
import io.quarkus.security.UnauthorizedException;
|
||||
@@ -18,17 +22,18 @@ import lombok.RequiredArgsConstructor;
|
||||
@Priority(1)
|
||||
public class ExceptionMappers {
|
||||
|
||||
private final CookieService cookieService;
|
||||
private final CommaFeedConfiguration config;
|
||||
|
||||
@ServerExceptionMapper(UnauthorizedException.class)
|
||||
public RestResponse<UnauthorizedResponse> unauthorized(UnauthorizedException e) {
|
||||
return RestResponse.status(RestResponse.Status.UNAUTHORIZED,
|
||||
new UnauthorizedResponse(e.getMessage(), config.users().allowRegistrations()));
|
||||
return RestResponse.status(Status.UNAUTHORIZED, new UnauthorizedResponse(e.getMessage(), config.users().allowRegistrations()));
|
||||
}
|
||||
|
||||
@ServerExceptionMapper(AuthenticationFailedException.class)
|
||||
public RestResponse<AuthenticationFailed> authenticationFailed(AuthenticationFailedException e) {
|
||||
return RestResponse.status(RestResponse.Status.UNAUTHORIZED, new AuthenticationFailed(e.getMessage()));
|
||||
NewCookie logoutCookie = cookieService.buildLogoutCookie();
|
||||
return ResponseBuilder.create(Status.UNAUTHORIZED, new AuthenticationFailed(e.getMessage())).cookie(logoutCookie).build();
|
||||
}
|
||||
|
||||
@ServerExceptionMapper(ValidationException.class)
|
||||
|
||||
@@ -32,4 +32,8 @@ public class UserRoleDAO extends GenericDAO<UserRole> {
|
||||
public Set<Role> findRoles(User user) {
|
||||
return findAll(user).stream().map(UserRole::getRole).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public long countAdmins() {
|
||||
return query().select(ROLE.count()).from(ROLE).where(ROLE.role.eq(Role.ADMIN)).fetchOne();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.commafeed.backend.service;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
@@ -139,10 +138,6 @@ public class UserService {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void createAdminUser() {
|
||||
register(CommaFeedConstants.USERNAME_ADMIN, "admin", "admin@commafeed.com", Arrays.asList(Role.ADMIN, Role.USER), true);
|
||||
}
|
||||
|
||||
public void createDemoUser() {
|
||||
register(CommaFeedConstants.USERNAME_DEMO, "demo", "demo@commafeed.com", Collections.singletonList(Role.USER), true);
|
||||
}
|
||||
|
||||
@@ -25,23 +25,8 @@ public class DatabaseStartupService {
|
||||
private final UserService userService;
|
||||
private final CommaFeedConfiguration config;
|
||||
|
||||
public void populateInitialData() {
|
||||
long count = unitOfWork.call(userDAO::count);
|
||||
if (count == 0) {
|
||||
unitOfWork.run(this::initialData);
|
||||
}
|
||||
}
|
||||
|
||||
private void initialData() {
|
||||
log.info("populating database with default values");
|
||||
try {
|
||||
userService.createAdminUser();
|
||||
if (config.users().createDemoAccount()) {
|
||||
userService.createDemoUser();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
public boolean isInitialSetupRequired() {
|
||||
return unitOfWork.call(userDAO::count) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,4 +43,7 @@ public class ServerInfo implements Serializable {
|
||||
@Schema(required = true)
|
||||
private long forceRefreshCooldownDuration;
|
||||
|
||||
@Schema(required = true)
|
||||
private boolean initialSetupRequired;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.commafeed.frontend.model.request;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
|
||||
import com.commafeed.security.password.ValidPassword;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Schema(description = "Initial admin account setup request")
|
||||
@Data
|
||||
public class InitialSetupRequest implements Serializable {
|
||||
|
||||
@Schema(description = "admin username", required = true)
|
||||
private String name;
|
||||
|
||||
@Schema(description = "admin password", required = true)
|
||||
@ValidPassword
|
||||
private String password;
|
||||
|
||||
@Schema(description = "admin email")
|
||||
private String email;
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.commafeed.CommaFeedConstants;
|
||||
import com.commafeed.backend.dao.UserDAO;
|
||||
import com.commafeed.backend.dao.UserRoleDAO;
|
||||
import com.commafeed.backend.model.User;
|
||||
@@ -101,8 +100,8 @@ public class AdminREST {
|
||||
if (req.isAdmin() && !roles.contains(Role.ADMIN)) {
|
||||
userRoleDAO.persist(new UserRole(u, Role.ADMIN));
|
||||
} else if (!req.isAdmin() && roles.contains(Role.ADMIN)) {
|
||||
if (CommaFeedConstants.USERNAME_ADMIN.equals(u.getName())) {
|
||||
return Response.status(Status.FORBIDDEN).entity("You cannot remove the admin role from the admin user.").build();
|
||||
if (userRoleDAO.countAdmins() == 1) {
|
||||
return Response.status(Status.FORBIDDEN).entity("You cannot remove the admin role from the last admin user.").build();
|
||||
}
|
||||
for (UserRole userRole : userRoleDAO.findAll(u)) {
|
||||
if (userRole.getRole() == Role.ADMIN) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.commafeed.CommaFeedVersion;
|
||||
import com.commafeed.backend.HttpGetter;
|
||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||
import com.commafeed.backend.feed.ImageProxyUrl;
|
||||
import com.commafeed.backend.service.db.DatabaseStartupService;
|
||||
import com.commafeed.frontend.model.ServerInfo;
|
||||
import com.commafeed.security.Roles;
|
||||
|
||||
@@ -39,6 +40,7 @@ public class ServerREST {
|
||||
private final HttpGetter httpGetter;
|
||||
private final CommaFeedConfiguration config;
|
||||
private final CommaFeedVersion version;
|
||||
private final DatabaseStartupService databaseStartupService;
|
||||
|
||||
@Path("/get")
|
||||
@GET
|
||||
@@ -57,6 +59,7 @@ public class ServerREST {
|
||||
infos.setWebsocketPingInterval(config.websocket().pingInterval().toMillis());
|
||||
infos.setTreeReloadInterval(config.websocket().treeReloadInterval().toMillis());
|
||||
infos.setForceRefreshCooldownDuration(config.feedRefresh().forceRefreshCooldownDuration().toMillis());
|
||||
infos.setInitialSetupRequired(databaseStartupService.isInitialSetupRequired());
|
||||
return infos;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ import java.net.URISyntaxException;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
@@ -36,6 +38,7 @@ import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.CommaFeedConstants;
|
||||
import com.commafeed.backend.Digests;
|
||||
import com.commafeed.backend.Urls;
|
||||
import com.commafeed.backend.dao.UnitOfWork;
|
||||
import com.commafeed.backend.dao.UserDAO;
|
||||
import com.commafeed.backend.dao.UserRoleDAO;
|
||||
import com.commafeed.backend.dao.UserSettingsDAO;
|
||||
@@ -50,8 +53,10 @@ import com.commafeed.backend.model.UserSettings.ScrollMode;
|
||||
import com.commafeed.backend.service.MailService;
|
||||
import com.commafeed.backend.service.PasswordEncryptionService;
|
||||
import com.commafeed.backend.service.UserService;
|
||||
import com.commafeed.backend.service.db.DatabaseStartupService;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.frontend.model.UserModel;
|
||||
import com.commafeed.frontend.model.request.InitialSetupRequest;
|
||||
import com.commafeed.frontend.model.request.PasswordResetRequest;
|
||||
import com.commafeed.frontend.model.request.ProfileModificationRequest;
|
||||
import com.commafeed.frontend.model.request.RegistrationRequest;
|
||||
@@ -78,9 +83,11 @@ public class UserREST {
|
||||
private final UserSettingsDAO userSettingsDAO;
|
||||
private final UserService userService;
|
||||
private final PasswordEncryptionService encryptionService;
|
||||
private final DatabaseStartupService databaseStartupService;
|
||||
private final MailService mailService;
|
||||
private final CommaFeedConfiguration config;
|
||||
private final UriInfo uri;
|
||||
private final UnitOfWork unitOfWork;
|
||||
|
||||
@Path("/settings")
|
||||
@GET
|
||||
@@ -231,7 +238,7 @@ public class UserREST {
|
||||
public Response saveUserProfile(@Valid @Parameter(required = true) ProfileModificationRequest request) {
|
||||
User user = authenticationContext.getCurrentUser();
|
||||
if (CommaFeedConstants.USERNAME_DEMO.equals(user.getName())) {
|
||||
return Response.status(Status.FORBIDDEN).build();
|
||||
return Response.status(Status.FORBIDDEN).entity("the profile of the demo account cannot be modified").build();
|
||||
}
|
||||
|
||||
Optional<User> login = userService.login(user.getName(), request.getCurrentPassword());
|
||||
@@ -276,6 +283,31 @@ public class UserREST {
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/initialSetup")
|
||||
@PermitAll
|
||||
@POST
|
||||
@Transactional
|
||||
@Operation(
|
||||
summary = "Create the initial admin account",
|
||||
description = "This endpoint is only available when no users exist in the database")
|
||||
public Response initialSetup(@Valid @Parameter(required = true) InitialSetupRequest req) {
|
||||
boolean initialSetupRequired = databaseStartupService.isInitialSetupRequired();
|
||||
if (!initialSetupRequired) {
|
||||
return Response.status(Status.BAD_REQUEST).entity("Initial setup has already been completed").build();
|
||||
}
|
||||
|
||||
userService.register(req.getName(), req.getPassword(), req.getEmail(), List.of(Role.ADMIN, Role.USER), true);
|
||||
|
||||
if (config.users().createDemoAccount()) {
|
||||
User demo = userDAO.findByName(CommaFeedConstants.USERNAME_DEMO);
|
||||
if (demo == null) {
|
||||
userService.createDemoUser();
|
||||
}
|
||||
}
|
||||
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@Path("/passwordReset")
|
||||
@PermitAll
|
||||
@POST
|
||||
@@ -361,9 +393,15 @@ public class UserREST {
|
||||
@Operation(summary = "Delete the user account")
|
||||
public Response deleteUser() {
|
||||
User user = authenticationContext.getCurrentUser();
|
||||
if (CommaFeedConstants.USERNAME_ADMIN.equals(user.getName()) || CommaFeedConstants.USERNAME_DEMO.equals(user.getName())) {
|
||||
return Response.status(Status.FORBIDDEN).build();
|
||||
if (CommaFeedConstants.USERNAME_DEMO.equals(user.getName())) {
|
||||
return Response.status(Status.FORBIDDEN).entity("the demo account cannot be deleted").build();
|
||||
}
|
||||
|
||||
Set<Role> roles = userRoleDAO.findRoles(user);
|
||||
if (roles.contains(Role.ADMIN) && userRoleDAO.countAdmins() == 1) {
|
||||
return Response.status(Status.FORBIDDEN).entity("The last admin account cannot be deleted").build();
|
||||
}
|
||||
|
||||
userService.unregister(userDAO.findById(user.getId()));
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package com.commafeed.frontend.servlet;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.inject.Singleton;
|
||||
import jakarta.ws.rs.GET;
|
||||
@@ -11,26 +8,25 @@ import jakarta.ws.rs.core.NewCookie;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||
|
||||
import com.commafeed.security.CookieService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Path("/logout")
|
||||
@PermitAll
|
||||
@Singleton
|
||||
public class LogoutServlet {
|
||||
|
||||
private final UriInfo uri;
|
||||
private final String cookieName;
|
||||
|
||||
public LogoutServlet(UriInfo uri, @ConfigProperty(name = "quarkus.http.auth.form.cookie-name") String cookieName) {
|
||||
this.uri = uri;
|
||||
this.cookieName = cookieName;
|
||||
}
|
||||
private final CookieService cookieService;
|
||||
|
||||
@GET
|
||||
@Operation(hidden = true)
|
||||
public Response get() {
|
||||
NewCookie removeCookie = new NewCookie.Builder(cookieName).maxAge(0).expiry(Date.from(Instant.EPOCH)).path("/").build();
|
||||
NewCookie removeCookie = cookieService.buildLogoutCookie();
|
||||
return Response.temporaryRedirect(uri.getBaseUri()).cookie(removeCookie).build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.commafeed.security;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
import jakarta.inject.Singleton;
|
||||
import jakarta.ws.rs.core.NewCookie;
|
||||
|
||||
import io.quarkus.vertx.http.runtime.VertxHttpConfig;
|
||||
|
||||
@Singleton
|
||||
public class CookieService {
|
||||
|
||||
private final String cookieName;
|
||||
|
||||
public CookieService(VertxHttpConfig config) {
|
||||
this.cookieName = config.auth().form().cookieName();
|
||||
}
|
||||
|
||||
public NewCookie buildLogoutCookie() {
|
||||
return new NewCookie.Builder(cookieName).maxAge(0).expiry(Date.from(Instant.EPOCH)).path("/").build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,8 +6,6 @@ import jakarta.persistence.EntityManager;
|
||||
import org.hibernate.Session;
|
||||
import org.kohsuke.MetaInfServices;
|
||||
|
||||
import com.commafeed.backend.service.db.DatabaseStartupService;
|
||||
|
||||
import io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback;
|
||||
import io.quarkus.test.junit.callback.QuarkusTestMethodContext;
|
||||
|
||||
@@ -26,7 +24,5 @@ public class DatabaseReset implements QuarkusTestBeforeEachCallback {
|
||||
.getSessionFactory()
|
||||
.getSchemaManager()
|
||||
.truncateMappedObjects();
|
||||
|
||||
CDI.current().select(DatabaseStartupService.class).get().populateInitialData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.commafeed;
|
||||
|
||||
public class TestConstants {
|
||||
public static final String ADMIN_USERNAME = "admin";
|
||||
public static final String ADMIN_PASSWORD = "!Admin1234";
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.commafeed.e2e;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.microsoft.playwright.BrowserContext;
|
||||
import com.microsoft.playwright.Locator;
|
||||
import com.microsoft.playwright.Page;
|
||||
@@ -20,6 +22,11 @@ class AuthentificationIT {
|
||||
@InjectPlaywright
|
||||
private BrowserContext context;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
PlaywrightTestUtils.initialSetup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
context.clearCookies();
|
||||
@@ -29,7 +36,7 @@ class AuthentificationIT {
|
||||
void loginFail() {
|
||||
Page page = context.newPage();
|
||||
page.navigate(getLoginPageUrl());
|
||||
PlaywrightTestUtils.login(page, "admin", "wrong_password");
|
||||
PlaywrightTestUtils.login(page, TestConstants.ADMIN_USERNAME, "wrong_password");
|
||||
PlaywrightAssertions.assertThat(page.getByRole(AriaRole.ALERT)).containsText("wrong username or password");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.commafeed.e2e;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.microsoft.playwright.BrowserContext;
|
||||
import com.microsoft.playwright.Page;
|
||||
import com.microsoft.playwright.assertions.PlaywrightAssertions;
|
||||
import com.microsoft.playwright.options.AriaRole;
|
||||
|
||||
import io.quarkiverse.playwright.InjectPlaywright;
|
||||
import io.quarkiverse.playwright.WithPlaywright;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
|
||||
@QuarkusTest
|
||||
@WithPlaywright
|
||||
class InitialSetupIT {
|
||||
|
||||
@InjectPlaywright
|
||||
private BrowserContext context;
|
||||
|
||||
@Test
|
||||
void createAdminAccount() {
|
||||
Page page = context.newPage();
|
||||
page.navigate("http://localhost:8085");
|
||||
|
||||
page.getByPlaceholder("Admin User Name").fill(TestConstants.ADMIN_USERNAME);
|
||||
page.getByPlaceholder("Password").fill(TestConstants.ADMIN_PASSWORD);
|
||||
page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Create Admin Account")).click();
|
||||
|
||||
PlaywrightAssertions.assertThat(page).hasURL("http://localhost:8085/#/app/category/all");
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,28 @@
|
||||
package com.commafeed.e2e;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.request.InitialSetupRequest;
|
||||
import com.microsoft.playwright.Page;
|
||||
import com.microsoft.playwright.Page.GetByRoleOptions;
|
||||
import com.microsoft.playwright.options.AriaRole;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
public class PlaywrightTestUtils {
|
||||
|
||||
public static void initialSetup() {
|
||||
InitialSetupRequest req = new InitialSetupRequest();
|
||||
req.setName(TestConstants.ADMIN_USERNAME);
|
||||
req.setPassword(TestConstants.ADMIN_PASSWORD);
|
||||
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/user/initialSetup").then().statusCode(200);
|
||||
}
|
||||
|
||||
public static void login(Page page) {
|
||||
login(page, "admin", "admin");
|
||||
login(page, TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
public static void login(Page page, String username, String password) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.mockserver.integration.ClientAndServer;
|
||||
import org.mockserver.model.HttpRequest;
|
||||
import org.mockserver.model.HttpResponse;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.microsoft.playwright.BrowserContext;
|
||||
import com.microsoft.playwright.Locator;
|
||||
@@ -45,7 +46,8 @@ class ReadingIT {
|
||||
.withBody(IOUtils.toString(getClass().getResource("/feed/rss.xml"), StandardCharsets.UTF_8))
|
||||
.withDelay(TimeUnit.MILLISECONDS, 100));
|
||||
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
PlaywrightTestUtils.initialSetup();
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -21,10 +21,12 @@ import org.mockserver.integration.ClientAndServer;
|
||||
import org.mockserver.model.HttpRequest;
|
||||
import org.mockserver.model.HttpResponse;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Category;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.Subscription;
|
||||
import com.commafeed.frontend.model.request.AddCategoryRequest;
|
||||
import com.commafeed.frontend.model.request.InitialSetupRequest;
|
||||
import com.commafeed.frontend.model.request.SubscribeRequest;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
@@ -76,11 +78,20 @@ public abstract class BaseIT {
|
||||
mockServerClient.when(FEED_REQUEST).respond(HttpResponse.response().withBody(IOUtils.toString(resource, StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
protected void initialSetup(String userName, String password) {
|
||||
InitialSetupRequest req = new InitialSetupRequest();
|
||||
req.setName(userName);
|
||||
req.setPassword(password);
|
||||
req.setEmail(userName + "@commafeed.com");
|
||||
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/user/initialSetup").then().statusCode(200);
|
||||
}
|
||||
|
||||
protected List<HttpCookie> login() {
|
||||
List<Header> setCookieHeaders = RestAssured.given()
|
||||
.auth()
|
||||
.none()
|
||||
.formParams("j_username", "admin", "j_password", "admin")
|
||||
.formParams("j_username", TestConstants.ADMIN_USERNAME, "j_password", TestConstants.ADMIN_PASSWORD)
|
||||
.post("j_security_check")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
|
||||
@@ -8,9 +8,11 @@ import jakarta.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.ExceptionMappers.UnauthorizedResponse;
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.UserModel;
|
||||
import com.commafeed.frontend.model.request.MarkRequest;
|
||||
@@ -24,6 +26,11 @@ import io.restassured.http.ContentType;
|
||||
@QuarkusTest
|
||||
class SecurityIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@Test
|
||||
void notLoggedIn() {
|
||||
UnauthorizedResponse info = RestAssured.given()
|
||||
@@ -49,7 +56,13 @@ class SecurityIT extends BaseIT {
|
||||
|
||||
@Test
|
||||
void basicAuthLogin() {
|
||||
RestAssured.given().auth().preemptive().basic("admin", "admin").get("rest/user/profile").then().statusCode(HttpStatus.SC_OK);
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -57,7 +70,7 @@ class SecurityIT extends BaseIT {
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic("admin", "wrong-password")
|
||||
.basic(TestConstants.ADMIN_USERNAME, "wrong-password")
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
@@ -72,12 +85,12 @@ class SecurityIT extends BaseIT {
|
||||
void apiKey() {
|
||||
// create api key
|
||||
ProfileModificationRequest req = new ProfileModificationRequest();
|
||||
req.setCurrentPassword("admin");
|
||||
req.setCurrentPassword(TestConstants.ADMIN_PASSWORD);
|
||||
req.setNewApiKey(true);
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic("admin", "admin")
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/profile")
|
||||
@@ -88,7 +101,7 @@ class SecurityIT extends BaseIT {
|
||||
String apiKey = RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic("admin", "admin")
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
@@ -103,7 +116,7 @@ class SecurityIT extends BaseIT {
|
||||
long subscriptionId = RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic("admin", "admin")
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.body(subscribeRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/subscribe")
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.request.FeedModificationRequest;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
@@ -40,7 +41,8 @@ class WebSocketIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.UserModel;
|
||||
import com.commafeed.frontend.model.request.AdminSaveUserRequest;
|
||||
import com.commafeed.frontend.model.request.IDRequest;
|
||||
@@ -23,7 +24,8 @@ class AdminIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Category;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.Entry;
|
||||
@@ -35,7 +36,8 @@ import io.restassured.http.ContentType;
|
||||
class CategoryIT extends BaseIT {
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Entry;
|
||||
import com.commafeed.frontend.model.FeedInfo;
|
||||
import com.commafeed.frontend.model.Subscription;
|
||||
@@ -43,7 +44,8 @@ class FeedIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.backend.Digests;
|
||||
import com.commafeed.frontend.model.Entry;
|
||||
import com.commafeed.frontend.model.UserModel;
|
||||
@@ -28,11 +29,12 @@ class FeverIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
|
||||
// create api key
|
||||
ProfileModificationRequest req = new ProfileModificationRequest();
|
||||
req.setCurrentPassword("admin");
|
||||
req.setCurrentPassword(TestConstants.ADMIN_PASSWORD);
|
||||
req.setNewApiKey(true);
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/user/profile").then().statusCode(HttpStatus.SC_OK);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.frontend.model.request.PasswordResetRequest;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
@@ -29,7 +30,8 @@ class UserIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
|
||||
mailbox.clear();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
@@ -18,7 +19,8 @@ class CustomCodeIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -8,8 +8,10 @@ import jakarta.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
@@ -19,6 +21,11 @@ import io.restassured.http.Headers;
|
||||
@QuarkusTest
|
||||
class LogoutIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
List<HttpCookie> cookies = login();
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
@@ -17,7 +18,8 @@ class NextUnreadIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic("admin", "admin");
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
Reference in New Issue
Block a user