Code Review Stuff
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
Chaoscaot 2023-12-19 20:49:37 +01:00
Ursprung efd7f27c60
Commit 9a3630b07c

Datei anzeigen

@ -25,18 +25,28 @@ import lombok.SneakyThrows;
import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class SteamwarUser { public class SteamwarUser {
private static final SecureRandom random = new SecureRandom(); private static final SecureRandom random = new SecureRandom();
private static final SecretKeyFactory factory;
static { static {
new SqlTypeMapper<>(UUID.class, "CHAR(36)", (rs, identifier) -> UUID.fromString(rs.getString(identifier)), (st, index, value) -> st.setString(index, value.toString())); try {
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
} catch (NoSuchAlgorithmException e) {
throw new SecurityException(e);
}
new SqlTypeMapper<>(UUID.class, "CHAR(36)", (rs, identifier) -> UUID.fromString(rs.getString(identifier)), (st, index, value) -> st.setString(index, value.toString()));
new SqlTypeMapper<>(Locale.class, "VARCHAR(32)", (rs, identifier) -> { new SqlTypeMapper<>(Locale.class, "VARCHAR(32)", (rs, identifier) -> {
String l = rs.getString(identifier); String l = rs.getString(identifier);
return l != null ? Locale.forLanguageTag(l) : null; return l != null ? Locale.forLanguageTag(l) : null;
@ -110,12 +120,13 @@ public class SteamwarUser {
return byDiscord.select(discordId); return byDiscord.select(discordId);
} }
public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer) { public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer, BiConsumer<String, String> nameUpdate) {
SteamwarUser user = get(uuid); SteamwarUser user = get(uuid);
if (user != null) { if (user != null) {
if (!user.userName.equals(name)) { if (!user.userName.equals(name)) {
updateName.update(name, user.id); updateName.update(name, user.id);
nameUpdate.accept(user.userName, name);
user.userName = name; user.userName = name;
} }
@ -288,44 +299,50 @@ public class SteamwarUser {
} }
} }
@SneakyThrows
public void setPassword(String password) { public void setPassword(String password) {
byte[] salt = new byte[16]; try {
random.nextBytes(salt); byte[] salt = new byte[16];
String saltString = Base64.getEncoder().encodeToString(salt); random.nextBytes(salt);
String saltString = Base64.getEncoder().encodeToString(salt);
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 512); byte[] hash = generateHash(password, salt);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); String hashString = Base64.getEncoder().encodeToString(hash);
byte[] hash = factory.generateSecret(spec).getEncoded(); this.password = hashString + ":" + saltString;
updatePassword.update(this.password, id);
String hashString = Base64.getEncoder().encodeToString(hash); } catch (Exception e) {
throw new SecurityException(e);
this.password = hashString + ":" + saltString; }
updatePassword.update(this.password, id);
} }
@SneakyThrows
public boolean verifyPassword(String password) { public boolean verifyPassword(String password) {
if (this.password == null) { try {
if (this.password == null) {
return false;
}
String[] parts = this.password.split(":");
if (parts.length != 2) {
SQLConfig.impl.getLogger().log(Level.SEVERE ,"Invalid password hash for user {0} ({1})", new Object[]{userName, id});
return false;
}
String hashString = parts[0];
byte[] realHash = Base64.getDecoder().decode(hashString);
String saltString = parts[1];
byte[] salt = Base64.getDecoder().decode(saltString);
byte[] hash = generateHash(password, salt);
return Arrays.equals(realHash, hash);
} catch (Exception e) {
SQLConfig.impl.getLogger().log(Level.SEVERE, "Error while verifying password for user " + userName + " (" + id + ")", e);
return false; return false;
} }
}
String[] parts = this.password.split(":"); private byte[] generateHash(String password, byte[] salt)
if (parts.length != 2) { throws InvalidKeySpecException {
SQLConfig.impl.getLogger().log(Level.SEVERE ,"Invalid password hash for user {0} ({1})", new Object[]{userName, id});
return false;
}
String hashString = parts[0];
byte[] realHash = Base64.getDecoder().decode(hashString);
String saltString = parts[1];
byte[] salt = Base64.getDecoder().decode(saltString);
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 512); PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 512);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); return factory.generateSecret(spec).getEncoded();
byte[] hash = factory.generateSecret(spec).getEncoded();
return Arrays.equals(realHash, hash);
} }
private void initPunishments() { private void initPunishments() {