From 1631ad652f32cf0e1f1edbd1c202fcc0c0bfc3b6 Mon Sep 17 00:00:00 2001 From: Armin Date: Thu, 29 Jun 2023 13:34:42 +0200 Subject: [PATCH] [RFR-641] Remove old authentication and user classes --- .../de/cyface/apitestutils/ApiServer.java | 50 +--- .../fixture/AuthenticationTestFixture.java | 50 ---- .../fixture/DatabaseConstants.java | 12 +- .../fixture/GeoLocationTestFixture.java | 38 ++- .../apitestutils/fixture/UserTestFixture.java | 59 ----- .../fixture/user/ActivatableTestUser.java | 75 ------ .../fixture/user/DirectTestUser.java | 53 ----- .../apitestutils/fixture/user/TestUser.java | 129 ----------- .../fixture/user/package-info.java | 32 --- .../api/AuthenticatedEndpointConfig.java | 206 ----------------- .../api/AuthenticationFailureHandler.java | 57 ----- .../java/de/cyface/api/Authenticator.java | 198 ---------------- .../java/de/cyface/api/EndpointConfig.java | 69 ------ .../java/de/cyface/api/FailureHandler.java | 5 +- api/src/main/java/de/cyface/api/Hasher.java | 75 ------ .../de/cyface/api/InvalidConfiguration.java | 62 ----- .../main/java/de/cyface/api/Parameter.java | 217 ------------------ .../java/de/cyface/api/AuthenticatorTest.java | 103 --------- .../test/java/de/cyface/api/HasherTest.java | 55 ----- 19 files changed, 31 insertions(+), 1514 deletions(-) delete mode 100644 api-test-environment/src/main/java/de/cyface/apitestutils/fixture/AuthenticationTestFixture.java delete mode 100644 api-test-environment/src/main/java/de/cyface/apitestutils/fixture/UserTestFixture.java delete mode 100644 api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/ActivatableTestUser.java delete mode 100644 api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/DirectTestUser.java delete mode 100644 api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/TestUser.java delete mode 100644 api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/package-info.java delete mode 100644 api/src/main/java/de/cyface/api/AuthenticatedEndpointConfig.java delete mode 100644 api/src/main/java/de/cyface/api/AuthenticationFailureHandler.java delete mode 100644 api/src/main/java/de/cyface/api/Authenticator.java delete mode 100644 api/src/main/java/de/cyface/api/EndpointConfig.java delete mode 100644 api/src/main/java/de/cyface/api/Hasher.java delete mode 100644 api/src/main/java/de/cyface/api/InvalidConfiguration.java delete mode 100644 api/src/main/java/de/cyface/api/Parameter.java delete mode 100644 api/src/test/java/de/cyface/api/AuthenticatorTest.java delete mode 100644 api/src/test/java/de/cyface/api/HasherTest.java diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/ApiServer.java b/api-test-environment/src/main/java/de/cyface/apitestutils/ApiServer.java index 0b15317..24d7f5c 100644 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/ApiServer.java +++ b/api-test-environment/src/main/java/de/cyface/apitestutils/ApiServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 Cyface GmbH + * Copyright 2019-2023 Cyface GmbH * * This file is part of the Cyface API Library. * @@ -21,8 +21,6 @@ import java.io.IOException; import java.net.ServerSocket; -import org.apache.commons.lang3.Validate; - import io.vertx.core.AsyncResult; import io.vertx.core.DeploymentOptions; import io.vertx.core.Future; @@ -42,7 +40,7 @@ * * @author Armin Schnabel * @author Klemens Muthmann - * @version 3.0.1 + * @version 4.0.0 * @since 1.0.0 */ public final class ApiServer { @@ -104,12 +102,8 @@ public void start(final Vertx vertx, final VertxTestContext testContext, final T port = socket.getLocalPort(); socket.close(); - final var privateTestKey = this.getClass().getResource("/private_key.pem"); - final var publicTestKey = this.getClass().getResource("/public.pem"); config.put("mongo.db", mongoDatabase.config()) .put("http.port", port) - .put("jwt.private", Validate.notNull(privateTestKey).getFile()) - .put("jwt.public", Validate.notNull(publicTestKey).getFile()) .put("http.host", HTTP_HOST) .put(httpEndpointParameterKey, httpEndpoint); final DeploymentOptions options = new DeploymentOptions().setConfig(config); @@ -118,20 +112,6 @@ public void start(final Vertx vertx, final VertxTestContext testContext, final T .succeeding(result -> resultHandler.handle(Future.succeededFuture(WebClient.create(vertx))))); } - /** - * Authenticates with the exporter server providing the received authentication token. - * - * @param client The client to use to access the server - * @param handler Handler called when the response has returned - */ - public void authenticate(final WebClient client, final Handler>> handler) { - final JsonObject body = new JsonObject(); - body.put("username", "admin"); - body.put("password", "secret"); - - client.post(port(), HTTP_HOST, httpEndpoint + "login").sendJsonObject(body, handler); - } - /** * Send an authenticated {@code GET} request to a test server instance * @@ -145,23 +125,15 @@ public void authenticate(final WebClient client, final Handler>> resultHandler) { - authenticate(client, testContext.succeeding(response -> { - final String authToken = response.getHeader("Authorization"); - - if (response.statusCode() == 200 && authToken != null) { - final HttpRequest builder = client - .get(port(), HTTP_HOST, httpEndpoint + endpoint) - .authentication(new TokenCredentials(authToken)); - if (headers.size() > 0) { - builder.putHeaders(headers); - } - builder.send(resultHandler); - } else { - testContext.failNow(new IllegalStateException(String.format( - "Unable to authenticate. Authentication request response status was %d with authentication token %s.", - response.statusCode(), authToken))); - } - })); + final String authToken = "eyTestToken"; + + final HttpRequest builder = client + .get(port(), HTTP_HOST, httpEndpoint + endpoint) + .authentication(new TokenCredentials(authToken)); + if (headers.size() > 0) { + builder.putHeaders(headers); + } + builder.send(resultHandler); } /** diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/AuthenticationTestFixture.java b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/AuthenticationTestFixture.java deleted file mode 100644 index 2a37630..0000000 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/AuthenticationTestFixture.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2020-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.apitestutils.fixture; - -import de.cyface.apitestutils.fixture.user.DirectTestUser; -import io.vertx.core.Future; -import io.vertx.core.Promise; -import io.vertx.ext.mongo.MongoClient; - -/** - * The test data used to test authentication requests to a Cyface exporter server. - * It provides users to authenticate with. Currently, this is a user "admin" with a password "secret" and the manager - * role. - * - * @author Klemens Muthmann - * @author Armin Schnabel - * @version 2.0.1 - * @since 1.0.0 - */ -@SuppressWarnings("unused") // API -public final class AuthenticationTestFixture implements TestFixture { - - @Override - public Future insertTestData(MongoClient mongoClient) { - - final Promise promise = Promise.promise(); - final var testUser = new DirectTestUser("admin", "secret", - "testGroup" + DatabaseConstants.GROUP_MANAGER_ROLE_SUFFIX); - final var insert = testUser.insert(mongoClient); - insert.onSuccess(promise::complete); - insert.onFailure(promise::fail); - return promise.future(); - } -} diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/DatabaseConstants.java b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/DatabaseConstants.java index 749f9fc..9c8f5ed 100644 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/DatabaseConstants.java +++ b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/DatabaseConstants.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 Cyface GmbH + * Copyright 2019-2023 Cyface GmbH * * This file is part of the Cyface API Library. * @@ -22,7 +22,7 @@ * Constants used in the database containing the compressed serialized data received from clients. * * @author Armin Schnabel - * @version 1.2.1 + * @version 1.3.0 * @since 1.0.0 */ public class DatabaseConstants { @@ -43,10 +43,6 @@ public class DatabaseConstants { * "myGroup"+{@code #GROUP_MANAGER_ROLE_PREFIX} */ public static final String USER_GROUP_ROLE_SUFFIX = "_user"; - /** - * The database collection name. - */ - public static final String COLLECTION_USER = "user"; /** * The database collection name. */ @@ -55,10 +51,6 @@ public class DatabaseConstants { * The database collection name. */ public static final String COLLECTION_CHUNKS = "fs.chunks"; - /** - * The database field name. - */ - public static final String USER_USERNAME_FIELD = "username"; /** * The database field name used to annotate the owner of data by its user id. */ diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/GeoLocationTestFixture.java b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/GeoLocationTestFixture.java index d4a903a..b76cb25 100644 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/GeoLocationTestFixture.java +++ b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/GeoLocationTestFixture.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 Cyface GmbH + * Copyright 2020-2023 Cyface GmbH * * This file is part of the Cyface API Library. * @@ -19,9 +19,9 @@ package de.cyface.apitestutils.fixture; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; -import de.cyface.apitestutils.fixture.user.DirectTestUser; import de.cyface.model.MeasurementIdentifier; import io.vertx.core.CompositeFuture; import io.vertx.core.Future; @@ -29,7 +29,7 @@ import io.vertx.ext.mongo.MongoClient; /** - * A fixture providing data to use for testing the raw geo-location export. + * A fixture providing data to use for testing the raw geographical location export. *

* Inserts a test {@link DatabaseConstants#GROUP_MANAGER_ROLE_SUFFIX} user and a test * {@link DatabaseConstants#USER_GROUP_ROLE_SUFFIX} user and references the group user as data owner in the created @@ -39,7 +39,7 @@ * * @author Klemens Muthmann * @author Armin Schnabel - * @version 4.0.1 + * @version 5.0.0 * @since 1.0.0 */ @SuppressWarnings("unused") // API @@ -74,29 +74,21 @@ public GeoLocationTestFixture(final List testMeasurementI @Override public Future insertTestData(MongoClient mongoClient) { - final var manager = new DirectTestUser(TEST_USER_NAME, "secret", - TEST_GROUP + DatabaseConstants.GROUP_MANAGER_ROLE_SUFFIX); - final var groupUser = new DirectTestUser(TEST_GROUP_USER_USERNAME, "secret", - TEST_GROUP + DatabaseConstants.USER_GROUP_ROLE_SUFFIX); - final var managerInsert = manager.insert(mongoClient); - final var userInsert = groupUser.insert(mongoClient); + // Insert of test group manager and -user removed after switching to OAuth + final var userId = UUID.randomUUID().toString(); final Promise promise = Promise.promise(); - userInsert.onSuccess(userId -> { - final var testDocuments = testMeasurementIdentifiers.stream().map( - id -> new TestMeasurementDocument(userId, id.getMeasurementIdentifier(), id.getDeviceIdentifier())) - .collect(Collectors.toList()); + final var testDocuments = testMeasurementIdentifiers.stream().map( + id -> new TestMeasurementDocument(userId, id.getMeasurementIdentifier(), id.getDeviceIdentifier())) + .collect(Collectors.toList()); - // noinspection rawtypes - final var futures = testDocuments.stream().map(d -> (Future)d.insert(mongoClient)) - .collect(Collectors.toList()); - futures.add(managerInsert); + // noinspection rawtypes + final var futures = testDocuments.stream().map(d -> (Future)d.insert(mongoClient)) + .collect(Collectors.toList()); - final CompositeFuture composition = CompositeFuture.all(futures); - composition.onSuccess(succeeded -> promise.complete(userId)); - composition.onFailure(promise::fail); - }); - userInsert.onFailure(promise::fail); + final CompositeFuture composition = CompositeFuture.all(futures); + composition.onSuccess(succeeded -> promise.complete(userId)); + composition.onFailure(promise::fail); return promise.future(); } diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/UserTestFixture.java b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/UserTestFixture.java deleted file mode 100644 index 1a13c50..0000000 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/UserTestFixture.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.apitestutils.fixture; - -import de.cyface.apitestutils.fixture.user.TestUser; -import io.vertx.core.Future; -import io.vertx.core.Promise; -import io.vertx.ext.mongo.MongoClient; - -/** - * A fixture providing data to use for testing the user activation endpoint. - * - * @author Armin Schnabel - * @version 2.0.1 - * @since 1.0.0 - */ -@SuppressWarnings("unused") // API -public final class UserTestFixture implements TestFixture { - - /** - * The measurements used during the test - */ - private final TestUser testUser; - - /** - * Creates a new completely initialized fixture for the test. - * - * @param user The user to add - */ - @SuppressWarnings("unused") // API - public UserTestFixture(final TestUser user) { - this.testUser = user; - } - - @Override - public Future insertTestData(final MongoClient mongoClient) { - final Promise promise = Promise.promise(); - final var insert = testUser.insert(mongoClient); - insert.onSuccess(promise::complete); - insert.onFailure(promise::fail); - return promise.future(); - } -} diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/ActivatableTestUser.java b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/ActivatableTestUser.java deleted file mode 100644 index 2c903a0..0000000 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/ActivatableTestUser.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.apitestutils.fixture.user; - -import org.apache.commons.lang3.Validate; - -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; - -/** - * A user for testing representing a user that was created via the user registration process and thus requires e-mail - * verification and activation. - * - * @author Klemens Muthmann - * @version 1.0.0 - * @since 1.0.0 - */ -public final class ActivatableTestUser extends TestUser { - - /** - * {@code True} if the user account is activated, {@code False} if the user signed up but did not activate the - * account. - */ - private final boolean activated; - /** - * The token to activate the user account if the user signed up. - */ - private final String activationToken; - - /** - * Creates a fully initialized instance of this class. - * - * @param username The name of the user to be created - * @param roles The roles this user has - * @param password The password used to authenticate the user - * @param activated {@code True} if the user account is activated, {@code False} if the user signed up but did not - * activate the account. - * @param activationToken The token to activate the user accounts. - */ - public ActivatableTestUser(final String username, final String password, final boolean activated, - final String activationToken, - final String... roles) { - super(username, password, roles); - Validate.notEmpty(activationToken); - - this.activated = activated; - this.activationToken = activationToken; - } - - @Override - protected JsonObject insertCommand() { - return new JsonObject() - .put("username", getUsername()) - .put("roles", new JsonArray(getRoles())) - .put("password", getHashedPassword()) - .put("activated", activated) - .put("activationToken", activationToken); - } -} diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/DirectTestUser.java b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/DirectTestUser.java deleted file mode 100644 index 08738c6..0000000 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/DirectTestUser.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.apitestutils.fixture.user; - -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; - -/** - * A test user created the old way via the administration API. Such a user requires no verification or registration - * E-Mail. - * - * @author Klemens Muthmann - * @author Armin Schnabel - * @version 1.0.1 - * @since 1.0.0 - */ -public class DirectTestUser extends TestUser { - - /** - * Creates a fully initialized instance of this class. - * - * @param username The name of the user to be created - * @param password The password used to authenticate the user - * @param roles The roles this user has - */ - public DirectTestUser(String username, String password, String... roles) { - super(username, password, roles); - } - - @Override - protected JsonObject insertCommand() { - return new JsonObject() - .put("username", getUsername()) - .put("roles", new JsonArray(getRoles())) - .put("password", getHashedPassword()); - } -} diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/TestUser.java b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/TestUser.java deleted file mode 100644 index 309728a..0000000 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/TestUser.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2020-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.apitestutils.fixture.user; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Base64; -import java.util.List; - -import org.apache.commons.lang3.Validate; - -import de.cyface.apitestutils.fixture.DatabaseConstants; -import de.cyface.apitestutils.fixture.MongoTestData; -import io.vertx.core.Future; -import io.vertx.core.Promise; -import io.vertx.core.json.JsonObject; -import io.vertx.ext.auth.HashingStrategy; -import io.vertx.ext.mongo.MongoClient; - -/** - * Base class for users to test data exports for. - * - * @author Klemens Muthmann - * @author Armin Schnabel - * @version 2.0.2 - * @since 1.0.0 - */ -public abstract class TestUser implements MongoTestData { - - /** - * The name of the user to be created. - */ - private final String username; - /** - * The roles this user has. - */ - private final List roles; - /** - * The password used to authenticate the user. - */ - private final String password; - - /** - * Creates a fully initialized instance of this class. - * - * @param username The name of the user to be created - * @param roles The roles this user has - * @param password The password used to authenticate the user - */ - public TestUser(final String username, final String password, final String... roles) { - Validate.notEmpty(username); - Validate.notEmpty(roles); - Validate.notEmpty(password); - - this.username = username; - this.roles = Arrays.asList(roles); - this.password = password; - } - - @Override - public Future insert(final MongoClient mongoClient) { - Validate.notNull(mongoClient); - final Promise promise = Promise.promise(); - - // Check if the user already exists - final var findUser = mongoClient.findOne(DatabaseConstants.COLLECTION_USER, - new JsonObject().put(DatabaseConstants.USER_USERNAME_FIELD, username), null); - findUser.onFailure(promise::fail); - findUser.onSuccess(id -> { - if (id == null) { - final var insertCommand = insertCommand(); - final var insertUser = mongoClient.insert(DatabaseConstants.COLLECTION_USER, insertCommand); - insertUser.onSuccess(promise::complete); - insertUser.onFailure(promise::fail); - } else { - promise.fail( - new IllegalStateException(String.format("User already existent: %s", id.encodePrettily()))); - } - }); - return promise.future(); - } - - /** - * @return The name of the user to be created. - */ - public String getUsername() { - return username; - } - - /** - * @return The roles this user has. - */ - protected List getRoles() { - return roles; - } - - /** - * @return The hashed and salted password of that user, as it would be present in the database. - */ - protected String getHashedPassword() { - final var salt = "cyface-salt"; - //noinspection SpellCheckingInspection - return HashingStrategy.load().hash("pbkdf2", - null, - Base64.getMimeEncoder().encodeToString(salt.getBytes(StandardCharsets.UTF_8)), - password); - } - - /** - * @return A MongoDB command to insert the user into the test database. - */ - protected abstract JsonObject insertCommand(); -} diff --git a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/package-info.java b/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/package-info.java deleted file mode 100644 index 80b0315..0000000 --- a/api-test-environment/src/main/java/de/cyface/apitestutils/fixture/user/package-info.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2020-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -/** - * This package contains classes to group data about Cyface user accounts required to build a test fixture. - * There are two different types of users. One is created via the normal user registration process and one directly via - * the internal Cyface management API. - * The first is represented in a test fixture via {@link de.cyface.apitestutils.fixture.user.ActivatableTestUser} - * instance, which is capable of simulating whether that use was already activated and which activation token to use. - * The second is represented as a {@link de.cyface.apitestutils.fixture.user.DirectTestUser} instance, which does not - * require any information about user activation. - * - * @author Klemens Muthmann - * @version 1.0.0 - * @since 1.0.0 - */ -package de.cyface.apitestutils.fixture.user; \ No newline at end of file diff --git a/api/src/main/java/de/cyface/api/AuthenticatedEndpointConfig.java b/api/src/main/java/de/cyface/api/AuthenticatedEndpointConfig.java deleted file mode 100644 index 4c57e7b..0000000 --- a/api/src/main/java/de/cyface/api/AuthenticatedEndpointConfig.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2020-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import static de.cyface.api.Authenticator.JWT_HASH_ALGORITHM; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Objects; - -import io.vertx.core.Future; -import io.vertx.core.Promise; -import io.vertx.core.Vertx; -import io.vertx.core.json.JsonObject; -import io.vertx.ext.auth.PubSecKeyOptions; -import io.vertx.ext.auth.jwt.JWTAuth; -import io.vertx.ext.auth.jwt.JWTAuthOptions; -import io.vertx.ext.auth.mongo.MongoAuthentication; -import io.vertx.ext.auth.mongo.MongoAuthenticationOptions; -import io.vertx.ext.mongo.MongoClient; - -/** - * Configuration parameters required to start the HTTP server which also handles routing. - * - * @author Armin Schnabel - * @version 2.0.1 - * @since 1.0.0 - */ -public interface AuthenticatedEndpointConfig extends EndpointConfig { - - /** - * The default number of seconds the JWT authentication token is valid after login. - *

- * Using 10 minutes as preparing a 15-hour measurement for upload took 2.5 minutes on a sample phone [CY-5699]. - */ - int DEFAULT_TOKEN_VALIDATION_TIME = 600; - /** - * If no salt value was provided this default value is used. - */ - String DEFAULT_CYFACE_SALT = "cyface-salt"; - /** - * The default data source name to use for user and data database if none is provided via configuration. - */ - String DEFAULT_MONGO_DATA_SOURCE_NAME = "cyface"; - - /** - * Creates a JWT auth provider. - * - * @param vertx The Vertx instance to get the parameters from - * @param publicKey The public key to be used for authentication - * @param privateKey The private key to be used for authentication - * @return The auth provider - */ - static JWTAuth createAuthProvider(final Vertx vertx, final String publicKey, final String privateKey) { - return JWTAuth.create(vertx, new JWTAuthOptions() - .addPubSecKey(new PubSecKeyOptions() - .setAlgorithm(JWT_HASH_ALGORITHM) - .setBuffer(publicKey)) - .addPubSecKey(new PubSecKeyOptions() - .setAlgorithm(JWT_HASH_ALGORITHM) - .setBuffer(privateKey))); - } - - /** - * Provides the value for the JWT audience information. - * - * @param host The host this service runs under - * @param endpoint The endpoint path this service runs under - * @return The JWT audience as a String - */ - static String jwtAudience(final String host, final String endpoint) { - return String.format("%s%s", host, endpoint); - } - - /** - * Provides the value for the JWT issuer information. - * - * @param host The host this service runs under - * @param endpoint The endpoint path this service runs under - * @return The JWT issuer as a String - */ - static String jwtIssuer(final String host, final String endpoint) { - return String.format("%s%s", host, endpoint); - } - - /** - * Extracts a key from a PEM key-file. - * - * @param vertx The Vertx instance to get the parameters from - * @param keyParameter The Vertx configuration parameter specifying the location of the file containing the key - * @return The extracted key, including the lines starting with `-----`, as required when using {@code RS256}. - * @throws FileNotFoundException If the key file was not found - * @throws IOException If the key file was not accessible - */ - static String extractKey(final Vertx vertx, final Parameter keyParameter) - throws FileNotFoundException, IOException { - final var keyFilePath = keyParameter.stringValue(vertx, null); - if (keyFilePath == null) { - return null; - } - - return Files.readString(Path.of(keyFilePath)); - } - - /** - * Loads the external encryption salt from the Vertx configuration. If no value was provided the default value - * {@code #DEFAULT_CYFACE_SALT} is used. - *

- * The salt is only needed to generate a hash, not to check a password against a hash as the salt is stored at the - * beginning of the hash. This way the salt can be changed without invalidating all previous hashes. - *

- * Asynchronous implementation as in Vert.X you can only access files asynchronously. - * - * @param vertx The current Vertx instance - * @return The {@code Future} which resolves to a value to be used as encryption salt if successful - */ - static Future loadSalt(final Vertx vertx) { - final Promise result = Promise.promise(); - final var salt = Parameter.SALT.stringValue(vertx); - final var saltPath = Parameter.SALT_PATH.stringValue(vertx); - if (salt == null && saltPath == null) { - result.complete(DEFAULT_CYFACE_SALT); - } else if (salt != null && saltPath != null) { - result.fail("Please provide either a salt value or a path to a salt file. " - + "Encountered both and can not decide which to use. Aborting!"); - } else if (salt != null) { - result.complete(salt); - } else { - final var fileSystem = vertx.fileSystem(); - fileSystem.readFile(saltPath, readFileResult -> { - if (readFileResult.failed()) { - result.fail(readFileResult.cause()); - } else { - final var loadedSalt = readFileResult.result().toString(StandardCharsets.UTF_8); - result.complete(loadedSalt); - } - }); - } - return result.future(); - } - - /** - * Creates a {@code MongoAuthentication} for a specific {@code MongoClient}. - * - * @param client A Mongo client to access the user Mongo database. - * @return The Authentication provider used to check for valid user accounts used to generate new JWT token. - */ - static MongoAuthentication buildMongoAuthProvider(final MongoClient client) { - final var authProperties = new MongoAuthenticationOptions(); - return MongoAuthentication.create(client, authProperties); - } - - /** - * Creates a shared Mongo database client for the provided configuration. - * - * @param vertx The Vertx instance to create the client from. - * @param config Configuration of the newly created client. For further information refer to - * {@link Parameter#MONGO_DB}. - * @return A MongoClient ready for usage. - */ - static MongoClient createSharedMongoClient(final Vertx vertx, final JsonObject config) { - Objects.requireNonNull(config, String.format( - "Unable to load Mongo user database configuration. " - + "Please provide a valid configuration using the %s parameter and at least as \"db_name\", " - + "a \"connection_string\" and a \"data_source_name\"! Also check if your database is running " - + "and accessible!", - Parameter.MONGO_DB.key())); - final var dataSourceName = config.getString("data_source_name", DEFAULT_MONGO_DATA_SOURCE_NAME); - return MongoClient.createShared(vertx, config, dataSourceName); - } - - MongoClient getDatabase(); - - MongoAuthentication getAuthProvider(); - - String getPublicKey(); - - String getPrivateKey(); - - JWTAuth getJwtAuthProvider(); - - String getIssuer(); - - String getAudience(); - - int getTokenExpirationTime(); -} diff --git a/api/src/main/java/de/cyface/api/AuthenticationFailureHandler.java b/api/src/main/java/de/cyface/api/AuthenticationFailureHandler.java deleted file mode 100644 index 23ca453..0000000 --- a/api/src/main/java/de/cyface/api/AuthenticationFailureHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2018-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.vertx.core.Handler; -import io.vertx.ext.web.RoutingContext; - -/** - * Handlers failures occurring during authentication and makes sure 401 is returned as HTTP status code on failed - * authentication attempts. - * - * @author Klemens Muthmann - * @version 1.0.3 - * @since 1.0.0 - */ -public final class AuthenticationFailureHandler implements Handler { - - /** - * Logger used by objects of this class. Configure it using src/main/resources/logback.xml. - */ - private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationFailureHandler.class); - - @Override - public void handle(final RoutingContext context) { - LOGGER.error("Received failure " + context.failed()); - LOGGER.error("Reason", context.failure()); - - final var response = context.response(); - final boolean closed = response.closed(); - final boolean ended = response.ended(); - final var errorCode = context.statusCode(); - if (!closed && !ended) { - LOGGER.error("Failing authentication request with {} since response was closed: {}, ended: {}", errorCode, - closed, ended); - context.response().setStatusCode(errorCode).end(); - } - } -} diff --git a/api/src/main/java/de/cyface/api/Authenticator.java b/api/src/main/java/de/cyface/api/Authenticator.java deleted file mode 100644 index c63e053..0000000 --- a/api/src/main/java/de/cyface/api/Authenticator.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2018-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import static io.vertx.ext.auth.impl.jose.JWS.RS256; - -import java.util.Collections; -import java.util.Locale; -import java.util.Objects; - -import org.apache.commons.lang3.Validate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.vertx.core.Handler; -import io.vertx.core.json.DecodeException; -import io.vertx.core.json.JsonObject; -import io.vertx.ext.auth.JWTOptions; -import io.vertx.ext.auth.jwt.JWTAuth; -import io.vertx.ext.auth.mongo.MongoAuthentication; -import io.vertx.ext.web.Router; -import io.vertx.ext.web.RoutingContext; -import io.vertx.ext.web.handler.BodyHandler; -import io.vertx.ext.web.handler.LoggerHandler; - -/** - * Handles authentication request on the Cyface Vert.X APIs. This is implemented with JSON Web Token (JWT). To get a - * valid token, the user is required to authenticate using username and password against the provided endpoint, which - * issues a new token. This token can then be used to transmit the actual request. - *

- * To create a new object of this class call the static factory method - * {@link #setupAuthentication(String, Router, AuthenticatedEndpointConfig)}. - * - * @author Klemens Muthmann - * @author Armin Schnabel - * @version 4.0.3 - * @since 1.0.0 - */ -public final class Authenticator implements Handler { - - /** - * The logger used by objects of this class. Configure it using src/main/resources/logback.xml. - */ - private static final Logger LOGGER = LoggerFactory.getLogger(Authenticator.class); - /** - * The hashing algorithm used for public and private keys to generate and check JWT tokens. - */ - public static final String JWT_HASH_ALGORITHM = RS256; - /** - * The number of bytes in one kilobyte. This is used to limit the amount of bytes accepted by an authentication - * request. - */ - public static final long BYTES_IN_ONE_KILOBYTE = 1024L; - /** - * Authenticator that uses the Mongo user database to store and retrieve credentials. - */ - private final transient MongoAuthentication authProvider; - /** - * Authenticator that checks for valid authentications against Java Web Tokens. - */ - private transient final JWTAuth jwtAuthProvider; - /** - * The institution which issued the generated JWT token. Usually something like the name of this - * server. - */ - private transient final String issuer; - /** - * The entity allowed processing requests authenticated with the generated JWT token. This might be - * a certain server installation or a certain part of an application. - */ - private transient final String audience; - /** - * The number of seconds the JWT authentication token is valid after login. - */ - private transient final int tokenValidationTime; - - /** - * Creates a new completely initialized Authenticator. - * - * @param authProvider Authenticator that uses the Mongo user database to store and retrieve credentials. - * @param jwtAuthProvider Authenticator that checks for valid authentications against Java Web Tokens - * @param issuer The institution which issued the generated JWT token. Usually something like the name of this - * server - * @param audience The entity allowed processing requests authenticated with the generated JWT token. This might be - * a certain server installation or a certain part of an application - * @param tokenValidationTime The number of seconds the JWT authentication token is valid after login. - */ - protected Authenticator(final MongoAuthentication authProvider, - final JWTAuth jwtAuthProvider, final String issuer, final String audience, - final int tokenValidationTime) { - Objects.requireNonNull(authProvider, "Parameter authProvider may not be null!"); - Objects.requireNonNull(jwtAuthProvider, "Parameter jwtAuthProvider may not be null!"); - Validate.notEmpty(issuer, "Parameter issuer must not be empty or null!"); - Validate.notEmpty(audience, "Parameter audience must not be empty or null!"); - Validate.isTrue(tokenValidationTime > 0, "Parameter tokenValidationTime must be greater than 0!"); - - this.authProvider = authProvider; - this.jwtAuthProvider = jwtAuthProvider; - this.issuer = issuer; - this.audience = audience; - this.tokenValidationTime = tokenValidationTime; - } - - @Override - public void handle(final RoutingContext ctx) { - try { - final var body = ctx.body().asJsonObject(); - // Ensure username, e.g. email-address, is not case-sensitive - final var caseSensitiveUsername = body.getString("username"); - final var username = caseSensitiveUsername.toLowerCase(Locale.GERMANY); - final var password = body.getString("password"); - final var credentials = new JsonObject().put("username", username).put("password", password); - LOGGER.debug("Receiving authentication request for user {}", username); - final var authentication = authProvider.authenticate(credentials); - authentication.onSuccess(user -> { - try { - final var principal = user.principal(); - if (activated(principal)) { - LOGGER.debug("Authentication successful for user {}", username); - - final var jwtOptions = new JWTOptions() - .setAlgorithm(JWT_HASH_ALGORITHM) - .setExpiresInSeconds(tokenValidationTime) - .setIssuer(issuer) - .setAudience(Collections.singletonList(audience)); - final var jwtBody = credentials.put("aud", audience).put("iss", issuer); - final var generatedToken = jwtAuthProvider.generateToken(jwtBody, jwtOptions); - LOGGER.trace("New JWT Token: {}", generatedToken); - - ctx.response().putHeader("Authorization", generatedToken).setStatusCode(200).end(); - } else { - LOGGER.error("Authentication failed, user not activated: {}", username); - ctx.fail(428); - } - } catch (RuntimeException e) { - ctx.fail(e); - } - }); - authentication.onFailure(e -> { - LOGGER.error("Unsuccessful authentication request for user {}", username); - ctx.fail(401, e); - }); - } catch (DecodeException e) { - LOGGER.error("Unable to decode authentication request!"); - ctx.fail(401, e); - } - } - - /** - * Checks if the user account is activated. - *

- * Only self-registered accounts need to be activated and, thus, contain the "activated" field. - * - * @param principal the underlying principal of the user to check - * @return {@code true} if the user account is activated - */ - static boolean activated(final JsonObject principal) { - return !principal.containsKey("activated") || principal.getBoolean("activated"); - } - - /** - * Setups up the login route. - * - * @param loginEndpoint The endpoint to be used for login. This endpoint is added to the current path of the - * provided router - * @param router The router to set up authentication on - * @param config The HTTP server configuration parameters required - */ - @SuppressWarnings("unused") // Part of the API - public static void setupAuthentication(final String loginEndpoint, final Router router, - final AuthenticatedEndpointConfig config) { - final var authenticator = new Authenticator(config.getAuthProvider(), - config.getJwtAuthProvider(), config.getIssuer(), config.getAudience(), - config.getTokenExpirationTime()); - router.route(loginEndpoint) - .consumes("application/json") - .handler(LoggerHandler.create()) - .handler(BodyHandler.create().setBodyLimit(2 * BYTES_IN_ONE_KILOBYTE)) - .handler(authenticator) - .failureHandler(new AuthenticationFailureHandler()); - } -} diff --git a/api/src/main/java/de/cyface/api/EndpointConfig.java b/api/src/main/java/de/cyface/api/EndpointConfig.java deleted file mode 100644 index c34309e..0000000 --- a/api/src/main/java/de/cyface/api/EndpointConfig.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2020-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import java.util.Objects; - -import io.vertx.core.Vertx; -import io.vertx.core.json.JsonObject; -import io.vertx.ext.mongo.MongoClient; - -/** - * Configuration parameters required to start the HTTP server which also handles routing. - * - * @author Armin Schnabel - * @version 1.0.1 - * @since 1.0.0 - */ -public interface EndpointConfig { - - /** - * The port on which the HTTP server should listen if no port was specified. - */ - int DEFAULT_HTTP_PORT = 8080; - /** - * The default data source name to use for user and data database if none is provided via configuration. - */ - String DEFAULT_MONGO_DATA_SOURCE_NAME = "cyface"; - - /** - * Creates a shared Mongo database client for the provided configuration. - * - * @param vertx The Vertx instance to create the client from. - * @param config Configuration of the newly created client. For further information refer to - * {@link Parameter#MONGO_DB}. - * @return A MongoClient ready for usage. - */ - static MongoClient createSharedMongoClient(final Vertx vertx, final JsonObject config) { - Objects.requireNonNull(config, String.format( - "Unable to load Mongo database configuration. " - + "Please provide a valid configuration using the %s parameter and at least as \"db_name\", " - + "a \"connection_string\" and a \"data_source_name\"! Also check if your database is running " - + "and accessible!", - Parameter.MONGO_DB.key())); - final var dataSourceName = config.getString("data_source_name", DEFAULT_MONGO_DATA_SOURCE_NAME); - return MongoClient.createShared(vertx, config, dataSourceName); - } - - int getHttpPort(); - - String getHost(); - - String getEndpoint(); -} diff --git a/api/src/main/java/de/cyface/api/FailureHandler.java b/api/src/main/java/de/cyface/api/FailureHandler.java index 8ead77b..16939fb 100644 --- a/api/src/main/java/de/cyface/api/FailureHandler.java +++ b/api/src/main/java/de/cyface/api/FailureHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 Cyface GmbH + * Copyright 2018-2023 Cyface GmbH * * This file is part of the Cyface API Library. * @@ -28,9 +28,10 @@ * * @author Klemens Muthmann * @author Armin Schnabel - * @version 1.1.1 + * @version 1.1.2 * @since 1.0.0 */ +@SuppressWarnings("unused") // Part of the API (used by collector, provider, ...) public final class FailureHandler implements Handler { /** diff --git a/api/src/main/java/de/cyface/api/Hasher.java b/api/src/main/java/de/cyface/api/Hasher.java deleted file mode 100644 index d6dfe60..0000000 --- a/api/src/main/java/de/cyface/api/Hasher.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2021-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import java.util.Arrays; -import java.util.Base64; -import java.util.Objects; - -import io.vertx.ext.auth.HashingStrategy; - -/** - * Used to properly hash passwords for storage to the database. - * - * @author Klemens Muthmann - * @version 1.0.1 - * @since 1.0.0 - */ -public class Hasher { - - /** - * The Vertx HashingStrategy used for hashing. - */ - private final HashingStrategy hashingStrategy; - /** - * A salt used to obfuscate the hashed password, making it harder to decrypt passwords if the database is - * compromised. - */ - private final byte[] salt; - - /** - * Creates a new completely initialized object of this class. - * - * @param hashingStrategy The Vertx HashingStrategy used for hashing - * @param salt A salt used to obfuscate the hashed password, making it harder to decrypt passwords if the database - * is compromised - */ - public Hasher(final HashingStrategy hashingStrategy, final byte[] salt) { - Objects.requireNonNull(hashingStrategy); - Objects.requireNonNull(salt); - - this.hashingStrategy = hashingStrategy; - this.salt = Arrays.copyOf(salt, salt.length); - } - - /** - * Hashes the provided password, according to this strategy instance. - * - * @param password The clear text password to hash - * @return The hashed and salted password - */ - public String hash(final String password) { - return hashingStrategy.hash("pbkdf2", // TODO: Is there a better option for Vert.X ? [CY-5601] - null, - // The salt is stored at the beginning of the resulting hash. - // This way the salt can be changed without invalidating all previous hashes. - Base64.getMimeEncoder().encodeToString(salt), - password); - } -} diff --git a/api/src/main/java/de/cyface/api/InvalidConfiguration.java b/api/src/main/java/de/cyface/api/InvalidConfiguration.java deleted file mode 100644 index 46e11c9..0000000 --- a/api/src/main/java/de/cyface/api/InvalidConfiguration.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2019-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import io.vertx.core.json.JsonObject; - -/** - * An exception that is thrown if an invalid application configuration was found during startup. - * - * @author Klemens Muthmann - * @version 1.0.1 - * @since 1.0.0 - */ -public final class InvalidConfiguration extends RuntimeException { - /** - * Used for serializing objects of this class. Only change this if the classes attribute set has been changed. - */ - private static final long serialVersionUID = 1956168971436087977L; - /** - * The invalid configuration that has been encountered. - */ - private final JsonObject encounteredConfiguration; - - /** - * Creates a new completely initialized object of this class. - * - * @param encounteredConfiguration The invalid configuration that has been encountered - */ - public InvalidConfiguration(final JsonObject encounteredConfiguration) { - super(); - this.encounteredConfiguration = encounteredConfiguration; - } - - @Override - public String getMessage() { - return String.format("Unable to start application with configuration:%n%s", - getEncounteredConfiguration().encodePrettily()); - } - - /** - * @return The invalid configuration that has been encountered - */ - private JsonObject getEncounteredConfiguration() { - return encounteredConfiguration; - } -} diff --git a/api/src/main/java/de/cyface/api/Parameter.java b/api/src/main/java/de/cyface/api/Parameter.java deleted file mode 100644 index b222115..0000000 --- a/api/src/main/java/de/cyface/api/Parameter.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2018-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.vertx.core.Vertx; -import io.vertx.core.json.JsonObject; - -/** - * An enumeration of parameters, that may be provided upon application startup, to configure the application. - * - * @author Klemens Muthmann - * @author Armin Schnabel - * @version 2.2.1 - * @since 1.0.0 - */ -public enum Parameter { - - /** - * The location of the PEM file containing the private key to issue new JWT tokens. - */ - JWT_PRIVATE_KEY_FILE_PATH("jwt.private"), - /** - * The location of the PEM file containing the public key to check JWT tokens for validity. - */ - JWT_PUBLIC_KEY_FILE_PATH("jwt.public"), - /** - * A parameter setting the hostname the API service is available at. - */ - HTTP_HOST("http.host"), - /** - * A parameter for the endpoint path the API V3 service is available at. - */ - HTTP_ENDPOINT("http.endpoint"), - /** - * The server port the API shall be available at. - */ - HTTP_PORT("http.port"), - /** - * Detailed connection information about the Mongo database. This database stores all the credentials of users - * capable of logging in to the systems and all data received via the REST-API. This should be a JSON object with - * supported parameters explained at: - * - * https://vertx.io/docs/vertx-mongo-client/java/#_configuring_the_client. - */ - MONGO_DB("mongo.db"), - /** - * The username of a default administration user created on system start. - */ - ADMIN_USER_NAME("admin.user"), - /** - * The password for the default administration user created on system start. - */ - ADMIN_PASSWORD("admin.password"), - /** - * Salt used by the Mongo authentication provider to encrypt all user passwords. - */ - SALT("salt"), - /** - * Path to a file containing the salt used to encrypt passwords in the database. - */ - SALT_PATH("salt.path"), - /** - * A parameter telling the system how long a new JWT token stays valid in seconds. - */ - TOKEN_EXPIRATION_TIME("jwt.expiration"), - /** - * A parameter telling the system the milliseconds to wait before removing cached uploads after last modification. - */ - UPLOAD_EXPIRATION_TIME("upload.expiration"), - /** - * A parameter telling the system how large measurement uploads may be. - */ - MEASUREMENT_PAYLOAD_LIMIT("measurement.payload.limit"), - /** - * The server port the management interface for the API shall be available at. - */ - MANAGEMENT_HTTP_PORT("http.port.management"), - /** - * A parameter telling the system, whether it should publish metrics using Micrometer to Prometheus or not. - */ - METRICS_ENABLED("metrics.enabled"); - - /** - * The logger used for objects of this class. You can change its configuration by changing the values in - * src/main/resources/vertx-default-jul-logging.properties. - */ - private static final Logger LOGGER = LoggerFactory.getLogger(Parameter.class); - - /** - * The parameter key used to load its value from the JSON configuration. - */ - private final String key; - - /** - * Creates a new completely initialized parameter. - * - * @param key The parameter key used to load its value from the JSON configuration. - */ - Parameter(final String key) { - this.key = key; - } - - /** - * @return The parameter key used to load its value from the JSON configuration. - */ - public String key() { - return key; - } - - /** - * Provides the string value of this parameter from the Vert.x configuration or the defaultValue if - * there was none. - * - * @param vertx The Vertx instance containing the configuration. - * @param defaultValue A default value if the parameter was missing. - * @return Either the value of the parameter as a String or the defaultValue. - */ - public String stringValue(final Vertx vertx, final String defaultValue) { - final var value = vertx.getOrCreateContext().config().getString(key); - final var ret = value == null ? defaultValue : value; - LOGGER.info("Using configuration value: {} for key: {}.", ret, key); - return ret; - } - - /** - * Provides the string value of this parameter from the Vert.x configuration or the null if there was - * none. - * - * @param vertx The Vertx instance containing the configuration. - * @return Either the value of the parameter as a String or null. - */ - public String stringValue(final Vertx vertx) { - final var ret = vertx.getOrCreateContext().config().getString(key); - LOGGER.info("Using configuration value: {} for key: {}.", ret, key); - return ret; - } - - /** - * Provides the integer value of this parameter from the Vert.x configuration or the defaultValue if - * there was none. - * - * @param vertx The Vertx instance containing the configuration. - * @param defaultValue A default value if the parameter was missing. - * @return Either the value of the parameter as an int or the defaultValue. - * @throws ClassCastException If the value was not an integer. - */ - public int intValue(final Vertx vertx, final int defaultValue) { - final var value = vertx.getOrCreateContext().config().getInteger(key); - final var ret = value == null ? defaultValue : value; - LOGGER.info("Using configuration value: {} for key: {}.", ret, key); - return ret; - } - - /** - * Provides the lon value of this parameter from the Vert.x configuration or the defaultValue if - * there was none. - * - * @param vertx The Vertx instance containing the configuration. - * @param defaultValue A default value if the parameter was missing. - * @return Either the value of the parameter as an int or the defaultValue. - * @throws ClassCastException If the value was not a long. - */ - public long longValue(final Vertx vertx, final long defaultValue) { - final var value = vertx.getOrCreateContext().config().getLong(key); - final var ret = value == null ? defaultValue : value; - LOGGER.info("Using configuration value: {} for key: {}.", ret, key); - return ret; - } - - /** - * Provides the JSON value of this parameter from the Vert.x configuration or the defaultValue if there - * was none. - * - * @param vertx The Vertx instance containing the configuration. - * @param defaultValue A default value if the parameter was missing. - * @return Either the value of the parameter as a JSON object or the defaultValue. - */ - public JsonObject jsonValue(final Vertx vertx, final JsonObject defaultValue) { - final var value = vertx.getOrCreateContext().config().getJsonObject(key); - final var ret = value == null ? defaultValue : value; - LOGGER.info("Read json value {} for key: {}.", ret, key); - return ret; - } - - /** - * Provides the JSON value of this parameter from the Vert.x configuration or the null if there was - * none. - * - * @param vertx The Vertx instance containing the configuration. - * @return Either the value of the parameter as a JSON object or the defaultValue. - */ - @SuppressWarnings("unused") - public JsonObject jsonValue(final Vertx vertx) { - final var value = vertx.getOrCreateContext().config().getJsonObject(key); - LOGGER.info("Read json value {} for key: {}.", value, key); - return value; - } -} diff --git a/api/src/test/java/de/cyface/api/AuthenticatorTest.java b/api/src/test/java/de/cyface/api/AuthenticatorTest.java deleted file mode 100644 index 44bcd7f..0000000 --- a/api/src/test/java/de/cyface/api/AuthenticatorTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2022-2023 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.junit.jupiter.api.Test; - -import io.vertx.core.Future; -import io.vertx.core.http.HttpServerResponse; -import io.vertx.core.json.JsonObject; -import io.vertx.ext.auth.jwt.JWTAuth; -import io.vertx.ext.auth.mongo.MongoAuthentication; -import io.vertx.ext.web.RequestBody; -import io.vertx.ext.web.RoutingContext; - -/** - * This class checks the inner workings of the {@link Authenticator}. - * - * @author Armin Schnabel - * @author Klemens Muthmann - * @version 1.1.1 - * @since 1.0.0 - */ -@SuppressWarnings({"SpellCheckingInspection"}) -public class AuthenticatorTest { - - /** - * Only self-registered accounts need to be activated and, thus, a missing "activated" field counts as activated. - */ - @Test - void testActivated() { - // Arrange - final var registeredPrincipal = new JsonObject().put("username", "guest").put("activated", false); - final var activatedPrincipal = new JsonObject().put("username", "guest").put("activated", true); - final var createdPrincipal = new JsonObject().put("username", "guest"); - - // Act - final var registeredResult = Authenticator.activated(registeredPrincipal); - final var activatedResult = Authenticator.activated(activatedPrincipal); - final var createdResult = Authenticator.activated(createdPrincipal); - - // Assert - assertFalse(registeredResult, "Check activation"); - assertTrue(activatedResult, "Check activation"); - assertTrue(createdResult, "Check activation"); - } - - /** - * Checks that usernames are handled ignoring letter casing. - */ - @Test - void testUsernameIsCaseInsensitive() { - // Arrange - final var mockAuthentication = mock(MongoAuthentication.class); - final var mockAuthProvider = mock(JWTAuth.class); - final var issuer = "de.cyface"; - final var audience = "de.cyface.api"; - final var tokenValidationTime = 1000; - final var mockContext = mock(RoutingContext.class); - final var mockResponse = mock(HttpServerResponse.class); - final var mockBody = mock(RequestBody.class); - final var mockAuthenticationResult = mock(Future.class); - final var testCredentials = new JsonObject().put("username", "Username").put("password", "password"); - final var expectedCredentials = new JsonObject().put("username", "username").put("password", "password"); - - when(mockContext.response()).thenReturn(mockResponse); - when(mockContext.body()).thenReturn(mockBody); - when(mockBody.asJsonObject()).thenReturn(testCredentials); - when(mockAuthentication.authenticate(any(JsonObject.class))).thenReturn(mockAuthenticationResult); - - final var oocut = new Authenticator(mockAuthentication, mockAuthProvider, issuer, audience, - tokenValidationTime); - - // Act - oocut.handle(mockContext); - - // Assert - verify(mockAuthentication).authenticate(eq(expectedCredentials)); - } -} diff --git a/api/src/test/java/de/cyface/api/HasherTest.java b/api/src/test/java/de/cyface/api/HasherTest.java deleted file mode 100644 index 4ddcab1..0000000 --- a/api/src/test/java/de/cyface/api/HasherTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2021-2022 Cyface GmbH - * - * This file is part of the Cyface API Library. - * - * The Cyface API Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Cyface API Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Cyface API Library. If not, see . - */ -package de.cyface.api; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.nio.charset.StandardCharsets; - -import org.junit.jupiter.api.Test; - -import io.vertx.ext.auth.HashingStrategy; - -/** - * @author Armin Schnabel - * @version 1.0.0 - * @since 1.0.0 - */ -@SuppressWarnings({"SpellCheckingInspection"}) -public class HasherTest { - - /** - * [DAT-624] The password hashes generated by the `management-API` on S2 have an old format: `F96C2614.....A167`. - * The hashes generated with the current `Hashes` have a new format: `$pbkdf2$U1VHQVI....`. Both work! - */ - @Test - void testHash() { - // Arrange - final var salt = "SUGAR"; - final var oocut = new Hasher(HashingStrategy.load(), salt.getBytes(StandardCharsets.UTF_8)); - - // Act - final var password = "secret"; - final var result = oocut.hash(password); - - // Assert - final var expected = "$pbkdf2$U1VHQVI=$ZK4ZDOf9i3AibLO23RwmTmwfSe4qCQl0Mxl1zSPPW1+tF593v3Ip5RjiWU8j6M251AYjic8V/lhLsxukCpi/Ig"; - assertEquals(expected, result, "Compare generated hashcode"); - } -}