requestTokenList(StandaloneSupport conquery, String userToken) {
- return conquery.getClient()
- .target(HierarchyHelper.hierarchicalPath(conquery.defaultApiURIBuilder(), ApiTokenResource.class, "listUserTokens"))
- .request(MediaType.APPLICATION_JSON_TYPE)
- .header("Authorization", "Bearer " + userToken)
- .get(new GenericType<>() {});
- }
-
- private ApiToken requestApiToken(StandaloneSupport conquery, String userToken, ApiTokenDataRepresentation.Request tokenRequest) {
- return conquery.getClient()
- .target(HierarchyHelper.hierarchicalPath(conquery.defaultApiURIBuilder(), ApiTokenResource.class, "createToken"))
- .request(MediaType.APPLICATION_JSON_TYPE)
- .header("Authorization", "Bearer " + userToken)
- .post(Entity.entity(tokenRequest, MediaType.APPLICATION_JSON_TYPE), ApiToken.class);
- }
-}
diff --git a/backend/src/test/java/com/bakdata/conquery/models/SerializationTests.java b/backend/src/test/java/com/bakdata/conquery/models/SerializationTests.java
index 2a6b4f3f50..18e949e1b3 100644
--- a/backend/src/test/java/com/bakdata/conquery/models/SerializationTests.java
+++ b/backend/src/test/java/com/bakdata/conquery/models/SerializationTests.java
@@ -5,11 +5,9 @@
import java.io.IOException;
import java.time.LocalDate;
-import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
-import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -36,9 +34,6 @@
import com.bakdata.conquery.io.jackson.Injectable;
import com.bakdata.conquery.io.jackson.MutableInjectableValues;
import com.bakdata.conquery.io.jackson.serializer.SerializationTestUtil;
-import com.bakdata.conquery.models.auth.apitoken.ApiToken;
-import com.bakdata.conquery.models.auth.apitoken.ApiTokenData;
-import com.bakdata.conquery.models.auth.apitoken.Scopes;
import com.bakdata.conquery.models.auth.entities.Group;
import com.bakdata.conquery.models.auth.entities.Role;
import com.bakdata.conquery.models.auth.entities.User;
@@ -80,7 +75,6 @@
import com.bakdata.conquery.models.identifiable.ids.specific.DatasetId;
import com.bakdata.conquery.models.identifiable.ids.specific.GroupId;
import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId;
-import com.bakdata.conquery.models.identifiable.ids.specific.UserId;
import com.bakdata.conquery.models.identifiable.mapping.EntityIdMap;
import com.bakdata.conquery.models.query.ManagedQuery;
import com.bakdata.conquery.models.query.entity.Entity;
@@ -102,7 +96,6 @@
import io.dropwizard.jersey.validation.Validators;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
-import org.apache.http.util.CharArrayBuffer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -124,7 +117,7 @@ public void dataset() throws IOException, JSONException {
@Test
public void passwordCredential() throws IOException, JSONException {
- PasswordCredential credential = new PasswordCredential("testPassword".toCharArray());
+ PasswordCredential credential = new PasswordCredential("testPassword");
SerializationTestUtil
.forType(PasswordCredential.class)
@@ -565,31 +558,6 @@ public void testFormQuery() throws IOException, JSONException {
.test(query);
}
- @Test
- public void testApiTokenData() throws JSONException, IOException {
- final CharArrayBuffer buffer = new CharArrayBuffer(5);
- buffer.append("testtest");
- final ApiToken apiToken = new ApiToken(buffer);
- final ApiTokenData
- apiTokenData =
- new ApiTokenData(
- UUID.randomUUID(),
- apiToken.hashToken(),
- "tokenName",
- new UserId("tokenUser"),
- LocalDate.now(),
- LocalDate.now().plus(1, ChronoUnit.DAYS),
- EnumSet.of(Scopes.DATASET),
- getMetaStorage()
- );
-
-
- SerializationTestUtil
- .forType(ApiTokenData.class)
- .objectMappers(getManagerInternalMapper(), getApiMapper())
- .test(apiTokenData);
- }
-
@Test
void testMapDictionary() throws IOException, JSONException {
diff --git a/backend/src/test/java/com/bakdata/conquery/models/auth/ApiTokenTest.java b/backend/src/test/java/com/bakdata/conquery/models/auth/ApiTokenTest.java
deleted file mode 100644
index 5c923e1da5..0000000000
--- a/backend/src/test/java/com/bakdata/conquery/models/auth/ApiTokenTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.bakdata.conquery.models.auth;
-
-import static com.bakdata.conquery.models.auth.apitoken.ApiTokenCreator.*;
-import static org.assertj.core.api.Assertions.*;
-
-import com.bakdata.conquery.models.auth.apitoken.ApiToken;
-import com.bakdata.conquery.models.auth.apitoken.ApiTokenCreator;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.http.util.CharArrayBuffer;
-import org.junit.jupiter.api.Test;
-
-import java.util.Random;
-
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
-
-@Slf4j
-public class ApiTokenTest {
-
- @Test
- public void checkToken () {
- final ApiTokenCreator apiTokenCreator = new ApiTokenCreator(new Random(1));
-
- final @NotNull @NotEmpty CharArrayBuffer buffer = apiTokenCreator.createToken().getToken();
-
- log.info("Testing token: {}", buffer);
-
- assertThat(buffer).hasSize(TOKEN_LENGTH + TOKEN_PREFIX.length() + 1);
-
- assertThat(buffer).matches(TOKEN_PREFIX + "_" + "[\\w\\d_]{"+ TOKEN_LENGTH +"}");
-
- assertThat(buffer.toString().substring(TOKEN_PREFIX.length()+2)).containsPattern("[a-zA-Z]");
- }
-}
diff --git a/backend/src/test/java/com/bakdata/conquery/models/auth/IdpDelegatingAccessTokenCreatorTest.java b/backend/src/test/java/com/bakdata/conquery/models/auth/IdpDelegatingAccessTokenCreatorTest.java
index d6a3dfb1fc..0d30bd9e8a 100644
--- a/backend/src/test/java/com/bakdata/conquery/models/auth/IdpDelegatingAccessTokenCreatorTest.java
+++ b/backend/src/test/java/com/bakdata/conquery/models/auth/IdpDelegatingAccessTokenCreatorTest.java
@@ -98,7 +98,7 @@ private static void initOIDCServer() {
@Test
public void vaildUsernamePassword() {
- String jwt = idpDelegatingAccessTokenCreator.createAccessToken(USER_1_NAME, USER_1_PASSWORD.toCharArray());
+ String jwt = idpDelegatingAccessTokenCreator.createAccessToken(USER_1_NAME, USER_1_PASSWORD);
assertThat(jwt).isEqualTo(USER_1_TOKEN);
}
@@ -107,7 +107,7 @@ public void vaildUsernamePassword() {
public void invaildUsernamePassword() {
log.info("This test will print an Error below.");
assertThatThrownBy(
- () -> idpDelegatingAccessTokenCreator.createAccessToken(USER_1_NAME, "bad_password".toCharArray()))
+ () -> idpDelegatingAccessTokenCreator.createAccessToken(USER_1_NAME, "bad_password"))
.isInstanceOf(IllegalStateException.class);
}
diff --git a/backend/src/test/java/com/bakdata/conquery/models/auth/LocalAuthRealmTest.java b/backend/src/test/java/com/bakdata/conquery/models/auth/LocalAuthRealmTest.java
index 3c2dd2d9fa..fa560e3c01 100644
--- a/backend/src/test/java/com/bakdata/conquery/models/auth/LocalAuthRealmTest.java
+++ b/backend/src/test/java/com/bakdata/conquery/models/auth/LocalAuthRealmTest.java
@@ -4,7 +4,6 @@
import java.io.File;
import java.nio.file.Files;
-import java.util.List;
import com.auth0.jwt.JWT;
import com.bakdata.conquery.apiv1.auth.PasswordCredential;
@@ -14,13 +13,13 @@
import com.bakdata.conquery.models.auth.conquerytoken.ConqueryTokenRealm;
import com.bakdata.conquery.models.auth.entities.User;
import com.bakdata.conquery.models.config.XodusConfig;
-import com.bakdata.conquery.models.identifiable.ids.specific.UserId;
import com.bakdata.conquery.util.NonPersistentStoreFactory;
+import com.password4j.BcryptFunction;
import io.dropwizard.jersey.validation.Validators;
import io.dropwizard.util.Duration;
import org.apache.commons.io.FileUtils;
-import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.BearerToken;
+import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.util.LifecycleUtils;
import org.junit.jupiter.api.AfterAll;
@@ -53,7 +52,16 @@ public void setupAll() throws Exception {
conqueryTokenRealm = new ConqueryTokenRealm(storage);
- realm = new LocalAuthenticationRealm(Validators.newValidator(), Jackson.BINARY_MAPPER, conqueryTokenRealm, "localtestRealm", tmpDir, new XodusConfig(), Duration.hours(1));
+ realm =
+ new LocalAuthenticationRealm(
+ Validators.newValidator(),
+ Jackson.BINARY_MAPPER, conqueryTokenRealm,
+ "localtestRealm",
+ tmpDir,
+ new XodusConfig(),
+ Duration.hours(4),
+ BcryptFunction.getInstance(4)
+ ); // 4 is minimum
LifecycleUtils.init(realm);
}
@@ -61,9 +69,9 @@ public void setupAll() throws Exception {
public void setupEach() {
// Create User in Realm
user1 = new User("TestUser", "Test User", storage);
- PasswordCredential user1Password = new PasswordCredential("testPassword".toCharArray());
+ PasswordCredential user1Password = new PasswordCredential("testPassword");
storage.addUser(user1);
- realm.addUser(user1, List.of(user1Password));
+ realm.addUser(user1, user1Password);
}
@AfterEach
@@ -81,32 +89,32 @@ public void cleanUpAll() {
@Test
public void testEmptyUsername() {
- assertThatThrownBy(() -> realm.createAccessToken("", "testPassword".toCharArray()))
+ assertThatThrownBy(() -> realm.createAccessToken("", "testPassword"))
.isInstanceOf(IncorrectCredentialsException.class).hasMessageContaining("Username was empty");
}
@Test
public void testEmptyPassword() {
- assertThatThrownBy(() -> realm.createAccessToken("TestUser", "".toCharArray()))
+ assertThatThrownBy(() -> realm.createAccessToken("TestUser", ""))
.isInstanceOf(IncorrectCredentialsException.class).hasMessageContaining("Password was empty");
}
@Test
public void testWrongPassword() {
- assertThatThrownBy(() -> realm.createAccessToken("TestUser", "wrongPassword".toCharArray()))
- .isInstanceOf(AuthenticationException.class).hasMessageContaining("Provided username or password was not valid.");
+ assertThatThrownBy(() -> realm.createAccessToken("TestUser", "wrongPassword"))
+ .isInstanceOf(IncorrectCredentialsException.class).hasMessageContaining("Password was was invalid for user");
}
@Test
public void testWrongUsername() {
- assertThatThrownBy(() -> realm.createAccessToken("NoTestUser", "testPassword".toCharArray()))
- .isInstanceOf(AuthenticationException.class).hasMessageContaining("Provided username or password was not valid.");
+ assertThatThrownBy(() -> realm.createAccessToken("NoTestUser", "testPassword"))
+ .isInstanceOf(CredentialsException.class).hasMessageContaining("No password hash was found for user");
}
@Test
public void testValidUsernamePassword() {
// Right username and password should yield a JWT
- String jwt = realm.createAccessToken("TestUser", "testPassword".toCharArray());
+ String jwt = realm.createAccessToken("TestUser", "testPassword");
assertThatCode(() -> JWT.decode(jwt)).doesNotThrowAnyException();
assertThat(conqueryTokenRealm.doGetAuthenticationInfo(new BearerToken(jwt)).getPrincipals().getPrimaryPrincipal())
@@ -116,13 +124,13 @@ public void testValidUsernamePassword() {
@Test
public void testUserUpdate() {
- realm.updateUser(user1, List.of(new PasswordCredential("newTestPassword".toCharArray())));
+ realm.updateUser(user1, new PasswordCredential("newTestPassword"));
// Wrong (old) password
- assertThatThrownBy(() -> realm.createAccessToken("TestUser", "testPassword".toCharArray()))
- .isInstanceOf(AuthenticationException.class).hasMessageContaining("Provided username or password was not valid.");
+ assertThatThrownBy(() -> realm.createAccessToken("TestUser", "testPassword"))
+ .isInstanceOf(IncorrectCredentialsException.class).hasMessageContaining("Password was was invalid for user");
// Right (new) password
- String jwt = realm.createAccessToken("TestUser", "newTestPassword".toCharArray());
+ String jwt = realm.createAccessToken("TestUser", "newTestPassword");
assertThatCode(() -> JWT.decode(jwt)).doesNotThrowAnyException();
}
@@ -130,8 +138,8 @@ public void testUserUpdate() {
public void testRemoveUser() {
realm.removeUser(user1);
// Wrong password
- assertThatThrownBy(() -> realm.createAccessToken("TestUser", "testPassword".toCharArray()))
- .isInstanceOf(AuthenticationException.class).hasMessageContaining("Provided username or password was not valid.");
+ assertThatThrownBy(() -> realm.createAccessToken("TestUser", "testPassword"))
+ .isInstanceOf(CredentialsException.class).hasMessageContaining("No password hash was found for user");
}
}
diff --git a/backend/src/test/java/com/bakdata/conquery/util/PasswordHelperTest.java b/backend/src/test/java/com/bakdata/conquery/util/PasswordHelperTest.java
new file mode 100644
index 0000000000..b6ae79e8c9
--- /dev/null
+++ b/backend/src/test/java/com/bakdata/conquery/util/PasswordHelperTest.java
@@ -0,0 +1,54 @@
+package com.bakdata.conquery.util;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.stream.Stream;
+
+import com.bakdata.conquery.models.auth.basic.PasswordHelper;
+import com.password4j.Argon2Function;
+import com.password4j.BcryptFunction;
+import com.password4j.CompressedPBKDF2Function;
+import com.password4j.HashingFunction;
+import com.password4j.ScryptFunction;
+import com.password4j.types.Argon2;
+import com.password4j.types.Bcrypt;
+import com.password4j.types.Hmac;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class PasswordHelperTest {
+
+
+ /**
+ * Arguments where generated with:
+ *
+ *
+ * import com.password4j.Password;
+ *
+ * class Scratch {
+ * public static void main(String[] args) {
+ * System.out.println(Password.hash("test").withArgon2().getResult());
+ * System.out.println(Password.hash("test").withScrypt().getResult());
+ * System.out.println(Password.hash("test").withBcrypt().getResult());
+ * System.out.println(Password.hash("test").withCompressedPBKDF2().getResult());
+ * }
+ * }
+ *
+ */
+ static Stream arguments() {
+ return Stream.of(
+ Arguments.arguments("$argon2id$v=19$m=15360,t=2,p=1$r35m/UGz8lq4ICjcNkb2GUcfYub07450QRTTapYwiJCQDOI9Maa0dlym/iL0AceTNNXgaxLUyGB5EfJoqr+Wng$WVnHZU8uwvufgWPlVh5T+MnTtX5Ry0hhCD0ej90L0Kk", Argon2Function.getInstance(15360, 2, 1, 32, Argon2.ID)),
+ Arguments.arguments("$100801$SBpPHCtLT+2FbJ2BS49J4sgRXfvduVm17U9yd0Ygky/3MgUgK1r4LMixKSQX4LQjSEuE6tV8ibABXXAr9tCZKA==$aPTssj2maVw34QgrhRIsUHu6irB1NrjiFpdpUXFHHA+XhjPG03PKrbj5CBXJx3cCUosU/IARQliSW2LWRLFtiw==", ScryptFunction.getInstance(65536, 8, 1, 64)),
+ Arguments.arguments("$2b$10$YMPj.MoAs81tO8HzrCYxnOujaPwbu5SGsSrdNyxdIJ9BlBIv9i0t.", BcryptFunction.getInstance(Bcrypt.B, 10)),
+ Arguments.arguments("$3$1331439861760256$+Rqke26gKhtP60UkVR2a3SfszrOkVrMiJ6LZUWvl2vI5OpW815zKiod8Sdz3aOcuajo6c1iKEXcWjk61emmgTw==$CiH0mwqibUZD5R5HqFNpaYCkWjiYcTQe0sjG+4ZYw/A=", CompressedPBKDF2Function.getInstance(Hmac.SHA256, 310000, 256))
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("arguments")
+ void test(String hash, HashingFunction hashProvider) {
+ assertThat(PasswordHelper.getHashingFunction(hash)).isEqualTo(hashProvider);
+
+ }
+}