diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1681efa32..e346b09e0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ see wiki for more information: [wiki](https://github.com/thmarx/cms/wiki)
* **FEATURE** Developer Experience [PR-440](https://github.com/CondationCMS/cms-server/pull/440)
* **FEATURE** Aliases for content [442](https://github.com/CondationCMS/cms-server/issues/442)
* **FEATURE** Add redirect support for aliases [454](https://github.com/CondationCMS/cms-server/issues/454)
+* **FEATURE** Switch password has to secure algorithm [472](https://github.com/CondationCMS/cms-server/issues/472)
### Developer experience
diff --git a/cms-auth/pom.xml b/cms-auth/pom.xml
index 0bda805cf..79a5caf7f 100644
--- a/cms-auth/pom.xml
+++ b/cms-auth/pom.xml
@@ -14,6 +14,10 @@
com.condation.cms
cms-api
+
+ com.condation.cms
+ cms-core
+
com.condation.cms
cms-filesystem
diff --git a/cms-auth/src/main/java/com/condation/cms/auth/services/UserService.java b/cms-auth/src/main/java/com/condation/cms/auth/services/UserService.java
index ca9b45f49..65daf256a 100644
--- a/cms-auth/src/main/java/com/condation/cms/auth/services/UserService.java
+++ b/cms-auth/src/main/java/com/condation/cms/auth/services/UserService.java
@@ -21,18 +21,21 @@
* .
* #L%
*/
-
-
import com.condation.cms.auth.utils.SecurityUtil;
+import com.condation.cms.core.configuration.GSONProvider;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
+import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
+import java.util.Base64;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -44,36 +47,58 @@
@Slf4j
@RequiredArgsConstructor
public class UserService {
+
private static final String FILENAME_PATTERN = "%s.realm";
-
+
private final static Splitter userSplitter = Splitter.on(":").trimResults();
private final static Splitter groupSplitter = Splitter.on(",").trimResults();
-
+
private final Path hostBase;
-
- public void addUser (Realm realm, String username, String password, String [] groups) throws IOException {
- var users = loadUsers(realm);
- users = new ArrayList<>(users.stream().filter(user -> !user.username.equals(username)).toList());
- users.add(new User(username, SecurityUtil.hash(password), groups));
+
+ public void addUser(Realm realm, String username, String password, String[] groups) throws IOException {
+ List users = loadUsers(realm);
+ users = new ArrayList<>(users.stream()
+ .filter(user -> !user.username().equals(username))
+ .toList());
+
+ byte[] salt = SecurityUtil.generateSalt();
+ String saltBase64 = Base64.getEncoder().encodeToString(salt);
+ String passwordHash = SecurityUtil.hashPBKDF2(password, salt);
+
+ Map data = new HashMap<>();
+ data.put("salt", saltBase64);
+
+ users.add(new User(username, passwordHash, groups, data));
saveUsers(realm, users);
}
-
- public void removeUser (Realm realm, String username) throws IOException {
+
+ public void removeUser(Realm realm, String username) throws IOException {
var users = loadUsers(realm);
users = new ArrayList<>(users.stream().filter(user -> !user.username.equals(username)).toList());
saveUsers(realm, users);
}
-
+
private static User fromString(final String userString) {
List userParts = userSplitter.splitToList(userString);
- var username = userParts.get(0);
- var passwordHash = userParts.get(1);
- var groups = Iterables.toArray(groupSplitter.split(userParts.get(2)), String.class);
+ String username = userParts.get(0);
+ String passwordHash = userParts.get(1);
+ String[] groups = Iterables.toArray(groupSplitter.split(userParts.get(2)), String.class);
+ Map data = new HashMap<>();
- return new User(username, passwordHash, groups);
+ if (userParts.size() >= 4) {
+ try {
+ String json = new String(Base64.getDecoder().decode(userParts.get(3)), StandardCharsets.UTF_8);
+ data = GSONProvider.GSON.fromJson(json, new TypeToken