diff --git a/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java b/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java index 60d69108635ab4312b26d8e2b425ef554f1f80c2..2d8ea030453eb2c1591e6c74a10c9c4a48747c2d 100644 --- a/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java +++ b/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java @@ -72,9 +72,8 @@ public class ADConnector implements AuthenticationSource { endpoint.setUserAccountName( ADConnector.settings.getRealm() + "\\" - + settings - .getUsername()); // * You can use the user's Distinguished Name as - // well + + settings.getUsername()); // * You can use the user's Distinguished Name as + // well endpoint.setPassword(settings.getPassword()); return endpoint; } diff --git a/ad-connector/src/main/java/net/jami/jams/ad/connector/service/UserProfileService.java b/ad-connector/src/main/java/net/jami/jams/ad/connector/service/UserProfileService.java index 1e1bf0d78d5f93e75d43daddcd9c8279faca79b7..95c6bb00f6f1c84921a7abf885ff4d8901cdec2b 100644 --- a/ad-connector/src/main/java/net/jami/jams/ad/connector/service/UserProfileService.java +++ b/ad-connector/src/main/java/net/jami/jams/ad/connector/service/UserProfileService.java @@ -43,8 +43,6 @@ import lombok.extern.slf4j.Slf4j; import net.jami.datastore.main.DataStore; import net.jami.jams.ad.connector.ADConnector; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.UserProfile; import java.util.*; @@ -138,12 +136,7 @@ public class UserProfileService { .map(UserProfileService::profileFromResponse) .collect(Collectors.toList()); for (UserProfile p : profilesFromResponse) { - StatementList statementList = new StatementList(); - StatementElement st = new StatementElement("username", "=", p.getUsername(), ""); - statementList.addStatement(st); - - if (dataStore.getUserProfileDao().getObjects(statementList).isEmpty()) - dataStore.getUserProfileDao().storeObject(p); + dataStore.getUserProfileDao().insertIfNotExists(p); } return profilesFromResponse; diff --git a/authentication-module/src/main/java/net/jami/jams/authmodule/TokenController.java b/authentication-module/src/main/java/net/jami/jams/authmodule/TokenController.java index 27ee8f4184abb190413ef883a697ce132376e27a..30eef877f425d2af48516cf8bd50bc6f66e32982 100644 --- a/authentication-module/src/main/java/net/jami/jams/authmodule/TokenController.java +++ b/authentication-module/src/main/java/net/jami/jams/authmodule/TokenController.java @@ -72,7 +72,6 @@ public class TokenController { SignedJWT signedJWT = new SignedJWT(jwsHeader, jwtClaims); try { signedJWT.sign(new RSASSASigner(signingKey)); - UserAuthenticationModule.datastore.getJwtDao().storeObject(signedJWT); authTokenResponse.setAccess_token(signedJWT.serialize()); authTokenResponse.setExpires_in(30 * 60L); authTokenResponse.setToken_type("Bearer"); diff --git a/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java b/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java index 89a515a4b0472341a996e672f3c34526708c6603..0f3dc031398f879d360663a815089cfe4da42338 100644 --- a/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java +++ b/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java @@ -33,8 +33,6 @@ import net.jami.jams.common.authmodule.AuthModuleKey; import net.jami.jams.common.authmodule.AuthTokenResponse; import net.jami.jams.common.authmodule.AuthenticationModule; import net.jami.jams.common.cryptoengineapi.CertificateAuthority; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.jami.NameServer; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.User; @@ -55,6 +53,7 @@ import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; @Slf4j @@ -159,11 +158,8 @@ public class UserAuthenticationModule implements AuthenticationModule { public AuthTokenResponse authenticateUser(String username, String password) { AuthTokenResponse res = null; String hashPass = ""; - if (datastore.userExists(username)) { - StatementList statementList = new StatementList(); - StatementElement statementElement = new StatementElement("username", "=", username, ""); - statementList.addStatement(statementElement); - User user = datastore.getUserDao().getObjects(statementList).get(0); + if (datastore.getUserDao().getByUsername(username).isPresent()) { + User user = datastore.getUserDao().getByUsername(username).orElseThrow(); if ((user.getUserType() == AuthenticationSourceType.LOCAL)) hashPass = PasswordUtil.hashPassword(password, Base64.decodeBase64(user.getSalt())); else hashPass = password; @@ -174,12 +170,11 @@ public class UserAuthenticationModule implements AuthenticationModule { .authenticate(username, hashPass)) return tokenController.getToken(user, null); } - // The second case is much more violent, because we don't know in advance "where" this user - // comes - // from, so we have to infer (this is only really true for "users", all others are usually - // pre-marked) - // This is also the case when we store the user into the DAO - because he never existed - // before. + // The second case is much more violent, because we don't know in + // advance "where" this user comes from, so we have to infer + // (this is only really true for "users", all others are usually pre-marked) + // This is also the case when we store the user into the DAO + // - because he never existed before. for (AuthModuleKey key : authenticationSources.keySet()) { if (authenticationSources.get(key).authenticate(username, password)) { User user = new User(); @@ -211,10 +206,7 @@ public class UserAuthenticationModule implements AuthenticationModule { if (crl.getRevokedCertificate(clientCert.getSerialNumber()) != null) return null; String username = X509Utils.extractDNFromCertificate(clientCert).get("CN"); // We need to extract the deviceId from the certificate - StatementList statementList = new StatementList(); - StatementElement statementElement = new StatementElement("username", "=", username, ""); - statementList.addStatement(statementElement); - User user = datastore.getUserDao().getObjects(statementList).get(0); + User user = datastore.getUserDao().getByUsername(username).orElseThrow(); return tokenController.getToken( user, X509Utils.extractDNFromCertificate(deviceCert).get("UID")); } catch (Exception e) { @@ -261,14 +253,8 @@ public class UserAuthenticationModule implements AuthenticationModule { @Override public char[] getOTP(String username) { - if (datastore.userExists(username)) { - StatementList statementList = new StatementList(); - StatementElement statementElement = new StatementElement("username", "=", username, ""); - statementList.addStatement(statementElement); - User user = datastore.getUserDao().getObjects(statementList).get(0); - return (user.getPassword()).toCharArray(); - } - return new char[0]; + Optional<User> user = datastore.getUserDao().getByUsername(username); + return user.map(u -> u.getPassword().toCharArray()).orElse(new char[0]); } @Override diff --git a/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java b/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java index 0e7f88265b66f1e135465cb5dad5cfe34a797e8d..bd3cee618fc168761cbe83b08f4746d66418ca6a 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/AbstractDao.java @@ -27,89 +27,113 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.DeleteStatementBuilder; -import net.jami.jams.common.dao.SelectStatementBuilder; -import net.jami.jams.common.dao.StatementConstraints; -import net.jami.jams.common.dao.StatementList; -import net.jami.jams.common.dao.UpdateStatementBuilder; import net.jami.jams.common.dao.connectivity.SQLConnection; +import net.jami.jams.common.serialization.database.DatabaseObject; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Slf4j public abstract class AbstractDao<T> { @Getter @Setter private String tableName; - @Getter @Setter private Class<T> tClass; + @Getter @Setter protected Class<T> tClass; public abstract boolean storeObject(T object); - public List<T> getObjects(StatementList constraints) { - List<T> result = new ArrayList<>(); + protected ResultSet executeQuery(String query) { + return executeQuery(query, new ArrayList<>()); + } + + protected ResultSet executeQuery(String query, String param) { + return executeQuery(query, List.of(param)); + } + + protected ResultSet executeQuery(String query, List<String> params) { SQLConnection connection = DataStore.connectionPool.getConnection(); try { - PreparedStatement ps = - SelectStatementBuilder.buildStatement(tableName, constraints, null, connection); - ResultSet rs = ps.executeQuery(); - while (rs.next()) { - result.add(tClass.getConstructor(ResultSet.class).newInstance(rs)); + PreparedStatement ps = connection.getConnection().prepareStatement(query); + for (int i = 0; i < params.size(); i++) { + ps.setString(i + 1, params.get(i)); } - return result; + return ps.executeQuery(); } catch (Exception e) { - log.error("An error has occurred while trying to fetch an object: " + e); + log.error("An error has occurred while trying to fetch an object:"); + e.printStackTrace(); return null; } finally { DataStore.connectionPool.returnConnection(connection); } } - public List<T> getObjects( - StatementList constraints, StatementConstraints statementConstraints) { + protected Optional<T> getFirstObjectFromResultSet(ResultSet rs) { + try { + if (rs.next()) { + T obj = tClass.getConstructor(ResultSet.class).newInstance(rs); + rs.close(); + return Optional.of(obj); + } + } catch (Exception e) { + log.error( + "An error has occurred while trying to get the first result from the database:"); + e.printStackTrace(); + } + + return Optional.empty(); + } + + protected List<T> getObjectsFromResultSet(ResultSet rs) { List<T> result = new ArrayList<>(); - SQLConnection connection = DataStore.connectionPool.getConnection(); + try { - PreparedStatement ps = - SelectStatementBuilder.buildStatement( - tableName, constraints, statementConstraints, connection); - ResultSet rs = ps.executeQuery(); while (rs.next()) { result.add(tClass.getConstructor(ResultSet.class).newInstance(rs)); } - return result; + + rs.close(); } catch (Exception e) { - log.error("An error has occurred while trying to fetch a device: " + e); - return null; - } finally { - DataStore.connectionPool.returnConnection(connection); + log.error("An error has occurred while trying to get results from the database:"); + e.printStackTrace(); } + + return result; } - public boolean updateObject(StatementList update, StatementList constraints) { + protected boolean executeUpdate(String query, List<String> params) { SQLConnection connection = DataStore.connectionPool.getConnection(); + try { - PreparedStatement ps = - UpdateStatementBuilder.buildStatement( - tableName, update, constraints, connection); - return ps.execute(); + PreparedStatement ps = connection.getConnection().prepareStatement(query); + + for (int i = 0; i < params.size(); i++) { + ps.setString(i + 1, params.get(i)); + } + + return ps.executeUpdate() != 0; } catch (Exception e) { - log.error("An error has occurred while trying to fetch a device: " + e); + log.error("An error has occurred while trying to execute update:"); + e.printStackTrace(); return false; } finally { DataStore.connectionPool.returnConnection(connection); } } - public boolean deleteObject(StatementList delete) { + protected boolean executeInsert(String query, DatabaseObject object) { SQLConnection connection = DataStore.connectionPool.getConnection(); + try { - PreparedStatement ps = - DeleteStatementBuilder.buildStatement(tableName, delete, connection); + PreparedStatement ps = connection.getConnection().prepareStatement(query); + + ps = object.getInsert(ps); + return ps.executeUpdate() != 0; } catch (Exception e) { - log.error("An error has occurred while trying to fetch a device: " + e); + log.error("An error has occurred while trying to execute insert:"); + e.printStackTrace(); return false; } finally { DataStore.connectionPool.returnConnection(connection); diff --git a/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java b/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java index 63e839c46be4ea2f491283120afae9edafdf5985..c42385e1c9e4335451b6ff5121b05cc47318fd07 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/ContactDao.java @@ -26,12 +26,11 @@ package net.jami.datastore.dao; import lombok.extern.slf4j.Slf4j; import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.contacts.Contact; import java.sql.PreparedStatement; -import java.sql.SQLException; +import java.sql.ResultSet; import java.util.List; @Slf4j @@ -42,24 +41,18 @@ public class ContactDao extends AbstractDao<Contact> { this.setTClass(Contact.class); } + public List<Contact> getByOwner(String owner) { + ResultSet rs = executeQuery("SELECT * FROM contacts WHERE owner = ?", owner); + return getObjectsFromResultSet(rs); + } + // Not used because the strategy here is different. @Override public boolean storeObject(Contact object) { - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - String insert = - "INSERT INTO contacts (owner, uri, displayName, `timestamp`, status) VALUES " - + "(?, ?, ?, ?, ?)"; - PreparedStatement ps = connection.getConnection().prepareStatement(insert); - object.getInsert(ps); - ps.executeQuery(); - return true; - } catch (Exception e) { - log.error("Could not update contacts!"); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + String query = + "INSERT INTO contacts (owner, uri, displayName, timestamp, status)" + + " VALUES (?, ?, ?, ?, ?)"; + return executeInsert(query, object); } public boolean storeContactList(List<Contact> contactList) { @@ -86,23 +79,8 @@ public class ContactDao extends AbstractDao<Contact> { } } - @Override - public boolean deleteObject(StatementList constraints) { - SQLConnection connection = DataStore.connectionPool.getConnection(); - - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement("DELETE FROM contacts WHERE owner = ? AND uri = ?"); - ps.setString(1, constraints.getStatements().get(0).getValue()); - ps.setString(2, constraints.getStatements().get(1).getValue()); - return ps.executeUpdate() != 0; - } catch (SQLException e) { - log.error("Could not delete contact: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public boolean deleteObject(String owner, String uri) { + String query = "DELETE FROM contacts WHERE owner = ? AND uri = ?"; + return executeUpdate(query, List.of(owner, uri)); } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java b/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java index fb1310820a206016a9dad4087542247262f50c01..79b085ded151d9f5cdd18d026d52d1d8047a7993 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/DeviceDao.java @@ -25,12 +25,11 @@ package net.jami.datastore.dao; import lombok.extern.slf4j.Slf4j; -import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementList; -import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.devices.Device; -import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.List; +import java.util.Optional; @Slf4j public class DeviceDao extends AbstractDao<Device> { @@ -40,51 +39,30 @@ public class DeviceDao extends AbstractDao<Device> { this.setTClass(Device.class); } - @Override - public boolean storeObject(Device object) { - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "INSERT INTO devices " - + "(deviceId, owner, displayName, certificate, privatekey) " - + "VALUES " - + "(?, ?, ?, ?, ?)"); - ps = object.getInsert(ps); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to store a user: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public List<Device> getByOwner(String owner) { + ResultSet rs = executeQuery("SELECT * FROM devices WHERE owner = ?", List.of(owner)); + return getObjectsFromResultSet(rs); } - @Override - public boolean updateObject(StatementList update, StatementList constraints) { - String deviceName = update.getStatements().get(0).getValue(); - String user = update.getStatements().get(1).getValue(); - String deviceId = update.getStatements().get(2).getValue(); + public Optional<Device> getByDeviceIdAndOwner(String deviceId, String owner) { + // TODO deviceId is the primary key, owner is possibly a useless field + String query = "SELECT * FROM devices WHERE deviceId = ? AND owner = ?"; + ResultSet rs = executeQuery(query, List.of(deviceId, owner)); + return getFirstObjectFromResultSet(rs); + } - SQLConnection connection = DataStore.connectionPool.getConnection(); + @Override + public boolean storeObject(Device object) { + String query = + "INSERT INTO devices " + + "(deviceId, owner, displayName, certificate, privatekey) " + + "VALUES " + + "(?, ?, ?, ?, ?)"; + return executeInsert(query, object); + } - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "UPDATE devices SET displayName = ? WHERE owner = ? AND deviceId = ?"); - ps.setString(1, deviceName); - ps.setString(2, user); - ps.setString(3, deviceId); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to update a user: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public boolean updateObject(String deviceName, String username, String deviceId) { + String query = "UPDATE devices SET displayName = ? WHERE owner = ? AND deviceId = ?"; + return executeUpdate(query, List.of(deviceName, username, deviceId)); } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java b/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java index 301b00973ac2cb45ce0e2cee3fc8668d8d9daec6..1c1c2b0622c17a13ad6f1f5a9a1d36c22458ce13 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java @@ -2,13 +2,11 @@ package net.jami.datastore.dao; import lombok.extern.slf4j.Slf4j; -import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementList; -import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.user.Group; -import java.sql.PreparedStatement; -import java.sql.SQLException; +import java.sql.ResultSet; +import java.util.List; +import java.util.Optional; @Slf4j public class GroupDao extends AbstractDao<Group> { @@ -18,69 +16,29 @@ public class GroupDao extends AbstractDao<Group> { this.setTClass(Group.class); } - @Override - public boolean storeObject(Group object) { - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "INSERT INTO groups " - + "(id, name, blueprint) VALUES (?, ?, ?)"); - ps = object.getInsert(ps); - return ps.executeUpdate() != 0; - } catch (SQLException e) { - log.error("An error has occurred while trying to store a group: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public List<Group> getAll() { + ResultSet rs = executeQuery("SELECT * FROM groups"); + return getObjectsFromResultSet(rs); } - @Override - public boolean updateObject(StatementList update, StatementList constraints) { - - String id = update.getStatements().get(0).getValue(); - String name = update.getStatements().get(1).getValue(); - String blueprint = update.getStatements().get(2).getValue(); - - SQLConnection connection = DataStore.connectionPool.getConnection(); - - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "UPDATE groups SET name = ?, blueprint = ? WHERE id = ?"); - ps.setString(1, name); - ps.setString(2, blueprint); - ps.setString(3, id); - return ps.executeUpdate() != 0; - } catch (SQLException e) { - log.error("An error has occurred while trying to update a group: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public Optional<Group> getById(String id) { + ResultSet rs = executeQuery("SELECT * FROM groups WHERE id = ?", List.of(id)); + return getFirstObjectFromResultSet(rs); } @Override - public boolean deleteObject(StatementList constraints) { + public boolean storeObject(Group object) { + String query = "INSERT INTO groups " + "(id, name, blueprint) VALUES (?, ?, ?)"; + return executeInsert(query, object); + } - String id = constraints.getStatements().get(0).getValue(); - SQLConnection connection = DataStore.connectionPool.getConnection(); + public boolean updateObject(String id, String name, String blueprint) { + String query = "UPDATE groups SET name = ?, blueprint = ? WHERE id = ?"; + return executeUpdate(query, List.of(id, name, blueprint)); + } - try { - PreparedStatement ps = - connection.getConnection().prepareStatement("DELETE FROM groups WHERE id = ?"); - ps.setString(1, id); - return ps.executeUpdate() != 0; - } catch (SQLException e) { - log.error("An error has occurred while trying to delete a group: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public boolean deleteObject(String id) { + String query = "DELETE FROM groups WHERE id = ?"; + return executeUpdate(query, List.of(id)); } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/JwtDao.java b/datastore/src/main/java/net/jami/datastore/dao/JwtDao.java deleted file mode 100644 index b22ce1d55c1e978f401bae1e28ba21a261c77d6f..0000000000000000000000000000000000000000 --- a/datastore/src/main/java/net/jami/datastore/dao/JwtDao.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Authors: William Enright <william.enright@savoirfairelinux.com> - * Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com> - * Johnny Flores <johnny.flores@savoirfairelinux.com> - * Mohammed Raza <mohammed.raza@savoirfairelinux.com> - * Felix Sidokhine <felix.sidokhine@savoirfairelinux.com> - * - * - * This program 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. - * - * This program 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 this program. If not, see <https://www.gnu.org/licenses/>. - */ - -package net.jami.datastore.dao; - -import com.nimbusds.jwt.SignedJWT; - -import lombok.extern.slf4j.Slf4j; - -import net.jami.jams.common.dao.StatementList; - -import java.util.List; - -@Slf4j -public class JwtDao extends AbstractDao<SignedJWT> { - - private static final String SQL_STORE_TOKEN = - "INSERT INTO tokens (userid,deviceId,token) VALUES (?,?,?)"; - private static final String SQL_DELETE_TOKEN = - "DELETE FROM tokens WHERE userid = ? AND deviceId = ?"; - private static final String SQL_GET_TOKEN = "SELECT COUNT(token) FROM tokens WHERE token = ?"; - - public JwtDao() { - this.setTableName("tokens"); - this.setTClass(SignedJWT.class); - } - - @Override - public boolean storeObject(SignedJWT object) { - // TODO: Implement this. - return true; - } - - public boolean validateToken(SignedJWT signedJWT) { - // TODO: Implement this. - return true; - } - - // This method is not needed because we are only concerned with the existence of a token, - // we never actually look them up. - @Override - public List<SignedJWT> getObjects(StatementList constraints) { - return null; - } - - // TODO: Implement this method. - @Override - public boolean deleteObject(StatementList delete) { - return false; - } -} diff --git a/datastore/src/main/java/net/jami/datastore/dao/PolicyDao.java b/datastore/src/main/java/net/jami/datastore/dao/PolicyDao.java index f26411982b8d41af47baa7a5e7c59303299774e1..3084dcd0d2dbeec6e9b4eadc91ef96858638649d 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/PolicyDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/PolicyDao.java @@ -2,13 +2,11 @@ package net.jami.datastore.dao; import lombok.extern.slf4j.Slf4j; -import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementList; -import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.user.Policy; -import java.sql.PreparedStatement; -import java.sql.SQLException; +import java.sql.ResultSet; +import java.util.List; +import java.util.Optional; @Slf4j public class PolicyDao extends AbstractDao<Policy> { @@ -18,69 +16,41 @@ public class PolicyDao extends AbstractDao<Policy> { this.setTClass(Policy.class); } - @Override - public boolean storeObject(Policy object) { - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "INSERT INTO policies " + "(name, policyData) VALUES (?, ?)"); - ps = object.getInsert(ps); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to store a blueprint: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public List<Policy> getAll() { + ResultSet rs = executeQuery("SELECT * FROM policies"); + return getObjectsFromResultSet(rs); } - @Override - public boolean updateObject(StatementList update, StatementList constraints) { - String name = update.getStatements().get(0).getValue(); - String policyData = update.getStatements().get(1).getValue(); - String oldName = constraints.getStatements().get(0).getValue(); - - SQLConnection connection = DataStore.connectionPool.getConnection(); + public Optional<Policy> getByName(String name) { + String q = "SELECT * FROM policies WHERE name = ?"; + ResultSet rs = executeQuery(q, List.of(name)); + return getFirstObjectFromResultSet(rs); + } - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "UPDATE policies SET name = ?, policyData = ? WHERE name = ?"); - ps.setString(1, name); - ps.setString(2, policyData); - ps.setString(3, oldName); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to update a blueprint: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public Optional<Policy> getByUsername(String username) { + // TODO this can return multiple policies + String query = + "SELECT * FROM usergroupmappings ugm" + + " JOIN groups g ON ugm.groupid = g.id" + + " JOIN policies p ON g.blueprint = p.name" + + " WHERE ugm.username = ?"; + ResultSet rs = executeQuery(query, List.of(username)); + return getFirstObjectFromResultSet(rs); } @Override - public boolean deleteObject(StatementList constraints) { + public boolean storeObject(Policy object) { + String query = "INSERT INTO policies (name, policyData) VALUES (?, ?)"; + return executeInsert(query, object); + } - String name = constraints.getStatements().get(0).getValue(); - SQLConnection connection = DataStore.connectionPool.getConnection(); + public boolean updateObject(String name, String policyData) { + String query = "UPDATE policies SET policyData = ? WHERE name = ?"; + return executeUpdate(query, List.of(policyData, name)); + } - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement("DELETE FROM policies WHERE name = ?"); - ps.setString(1, name); - return ps.executeUpdate() != 0; - } catch (SQLException e) { - log.error("An error has occurred while trying to delete a blueprint: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public boolean deleteObject(String name) { + String query = "DELETE FROM policies WHERE name = ?"; + return executeUpdate(query, List.of(name)); } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java b/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java index 6babcfc935048b87a476c8fbbef57059ae8ff661..53da8855e3dba6b5142072c095a183d1a96c679c 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/SystemDao.java @@ -25,12 +25,10 @@ package net.jami.datastore.dao; import lombok.extern.slf4j.Slf4j; -import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementList; -import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.system.SystemAccount; -import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.Optional; @Slf4j public class SystemDao extends AbstractDao<SystemAccount> { @@ -40,30 +38,20 @@ public class SystemDao extends AbstractDao<SystemAccount> { this.setTClass(SystemAccount.class); } - @Override - public boolean storeObject(SystemAccount object) { - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "INSERT INTO system " - + "(entity,certificate,privatekey)" - + "VALUES " - + "(?, ?, ?)"); - ps = object.getInsert(ps); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to store a system entity: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public Optional<SystemAccount> getCA() { + ResultSet rs = executeQuery("SELECT * FROM system WHERE entity = 'CA'"); + return getFirstObjectFromResultSet(rs); + } + + public Optional<SystemAccount> getOCSP() { + ResultSet rs = executeQuery("SELECT * FROM system WHERE entity = 'OCSP'"); + return getFirstObjectFromResultSet(rs); } @Override - public boolean updateObject(StatementList update, StatementList constraints) { - return false; + public boolean storeObject(SystemAccount object) { + String query = + "INSERT INTO system " + "(entity,certificate,privatekey)" + "VALUES " + "(?, ?, ?)"; + return executeInsert(query, object); } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserDao.java index 6be8ca590e777ec6d754b805ca4bebb14546a20d..75772d94003fda2b55fb00c2ed728b1242fb730e 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/UserDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/UserDao.java @@ -25,12 +25,11 @@ package net.jami.datastore.dao; import lombok.extern.slf4j.Slf4j; -import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementList; -import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.user.User; -import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.List; +import java.util.Optional; @Slf4j public class UserDao extends AbstractDao<User> { @@ -40,74 +39,45 @@ public class UserDao extends AbstractDao<User> { this.setTClass(User.class); } - @Override - public boolean storeObject(User object) { - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "INSERT INTO users " - + "(username, password, userType, realm, ethAddress, ethKey, jamiId,certificate, privatekey, accessLevel, needsPasswordReset, salt) " - + " VALUES " - + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - ps = object.getInsert(ps); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to store a user: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public List<User> getAll() { + ResultSet rs = executeQuery("SELECT * FROM users"); + return getObjectsFromResultSet(rs); } - public boolean updateUserCertificate(String username, String certificate) { - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "UPDATE users SET certificate = ? WHERE username = ?"); - ps.setString(1, certificate); - ps.setString(2, username); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to update a user certificate: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public Optional<User> getByUsername(String username) { + ResultSet rs = executeQuery("SELECT * FROM users WHERE username = ?", username); + return getFirstObjectFromResultSet(rs); } - @Override - public boolean updateObject(StatementList update, StatementList constraints) { + public List<User> getByJamiId(String jamiId) { + ResultSet rs = executeQuery("SELECT * FROM users WHERE jamiId = ?", jamiId); + return getObjectsFromResultSet(rs); + } - String pw = update.getStatements().get(0).getValue(); - String salt = ""; - if (update.getStatements().size() > 1) salt = update.getStatements().get(1).getValue(); + @Override + public boolean storeObject(User object) { + String query = + "INSERT INTO users " + + "(username, password, userType, realm, ethAddress, ethKey, jamiId,certificate, privatekey, accessLevel, needsPasswordReset, salt) " + + " VALUES " + + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - String user = constraints.getStatements().get(0).getValue(); + return executeInsert(query, object); + } - SQLConnection connection = DataStore.connectionPool.getConnection(); + public boolean updateUserCertificate(String username, String certificate) { + String query = "UPDATE users SET certificate = ? WHERE username = ?"; + return executeUpdate(query, List.of(certificate, username)); + } - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "UPDATE users SET password = ?, salt = ? WHERE username = ?"); - ps.setString(1, pw); - ps.setString(2, salt); - ps.setString(3, user); + public boolean updateObject(String password, String username) { + String query = + "UPDATE users SET password = ?, needsPasswordReset = 'true' WHERE username = ?"; + return executeUpdate(query, List.of(password, username)); + } - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to update a user: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public boolean updateObject(String password, String salt, String username) { + String query = "UPDATE users SET password = ?, salt = ? WHERE username = ?"; + return executeUpdate(query, List.of(password, salt, username)); } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java index 98afdfcbcb8eeeeaf3c7f0cff9f33396815013d9..e585421e41544df5ae94e2020a44a81b5de83850 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java @@ -2,13 +2,11 @@ package net.jami.datastore.dao; import lombok.extern.slf4j.Slf4j; -import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementList; -import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.user.UserGroupMapping; -import java.sql.PreparedStatement; -import java.sql.SQLException; +import java.sql.ResultSet; +import java.util.List; +import java.util.Optional; @Slf4j public class UserGroupMappingsDao extends AbstractDao<UserGroupMapping> { @@ -18,60 +16,38 @@ public class UserGroupMappingsDao extends AbstractDao<UserGroupMapping> { this.setTClass(UserGroupMapping.class); } - @Override - public boolean storeObject(UserGroupMapping object) { + public List<UserGroupMapping> getByGroupId(String groupId) { + ResultSet rs = executeQuery("SELECT * FROM usergroupmappings WHERE groupId = ?", groupId); + return getObjectsFromResultSet(rs); + } - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "INSERT INTO usergroupmappings " - + "(username, groupId)" - + " VALUES " - + "(?,?)"); - ps = object.getInsert(ps); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to store a user profile: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public List<UserGroupMapping> getByUsername(String username) { + ResultSet rs = executeQuery("SELECT * FROM usergroupmappings WHERE username = ?", username); + return getObjectsFromResultSet(rs); } - @Override - public boolean deleteObject(StatementList constraints) { + public Optional<UserGroupMapping> getByGroupIdAndUsername(String groupId, String username) { + // TODO The primary key should be (groupId, username) + String query = "SELECT * FROM usergroupmappings WHERE groupId = ? AND username = ?"; + List<String> params = List.of(groupId, username); + ResultSet rs = executeQuery(query, params); + return getFirstObjectFromResultSet(rs); + } - String username = constraints.getStatements().get(0).getValue(); - String groupId = constraints.getStatements().get(1).getValue(); - SQLConnection connection = DataStore.connectionPool.getConnection(); + @Override + public boolean storeObject(UserGroupMapping object) { + String query = + "INSERT INTO usergroupmappings " + "(username, groupId)" + " VALUES " + "(?, ?)"; + return executeInsert(query, object); + } - try { - if (username.equals("*")) { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "DELETE FROM usergroupmappings WHERE groupId = ?"); - ps.setString(1, groupId); - return ps.executeUpdate() != 0; - } else { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "DELETE FROM usergroupmappings WHERE username = ? AND groupId = ?"); - ps.setString(1, username); - ps.setString(2, groupId); - return ps.executeUpdate() != 0; - } - } catch (SQLException e) { - log.error("An error has occurred while trying to delete a group member: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); + public boolean deleteObject(String username, String groupId) { + if (username.equals("*")) { + String query = "DELETE FROM usergroupmappings WHERE groupId = ?"; + return executeUpdate(query, List.of(groupId)); } + + String query = "DELETE FROM usergroupmappings WHERE username = ? AND groupId = ?"; + return executeUpdate(query, List.of(username, groupId)); } } diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java index fd025a6347bd26ec3a40a60a0b53d2a59012134b..242c59accdb3642156c2dd58d722db8fb12940a1 100644 --- a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java +++ b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java @@ -25,65 +25,93 @@ package net.jami.datastore.dao; import lombok.extern.slf4j.Slf4j; -import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementList; -import net.jami.jams.common.dao.connectivity.SQLConnection; import net.jami.jams.common.objects.user.UserProfile; -import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; @Slf4j public class UserProfileDao extends AbstractDao<UserProfile> { - // Fis this to include the fields from AD/LDAP. + // Fix this to include the fields from AD/LDAP. public UserProfileDao() { this.setTableName("local_directory"); this.setTClass(UserProfile.class); } - @Override - public boolean storeObject(UserProfile object) { + public void insertIfNotExists(UserProfile userProfile) throws SQLException { + String query = + "INSERT INTO local_directory" + + " (username, firstName, lastName, email, profilePicture, organization, phoneNumber, phoneNumberExtension, faxNumber, mobileNumber)" + + " SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?" + + " FROM local_directory" + + " WHERE NOT EXISTS (SELECT 1 FROM local_directory WHERE username = ?)"; + + List<String> params = new ArrayList<>(); + params.add(userProfile.getUsername()); + params.add(userProfile.getFirstName()); + params.add(userProfile.getLastName()); + params.add(userProfile.getEmail()); + params.add(userProfile.getProfilePicture()); + params.add(userProfile.getOrganization()); + params.add(userProfile.getPhoneNumber()); + params.add(userProfile.getPhoneNumberExtension()); + params.add(userProfile.getFaxNumber()); + params.add(userProfile.getMobileNumber()); + params.add(userProfile.getUsername()); + + this.executeUpdate(query, params); + } + + public List<UserProfile> getAllUserProfile() { + ResultSet rs = executeQuery("SELECT * FROM local_directory"); + return getObjectsFromResultSet(rs); + } - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "INSERT INTO local_directory " - + "(username, firstName, lastName, email, profilePicture, organization, phoneNumber, phoneNumberExtension, faxNumber, mobileNumber)" - + " VALUES " - + "(?,?,?,?,?,?,?,?,?,?)"); - ps = object.getInsert(ps); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to store a user profile: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public List<UserProfile> searchUsername(String username) { + String query = "SELECT * FROM local_directory WHERE username LIKE ?"; + ResultSet rs = executeQuery(query, username + "%"); + return getObjectsFromResultSet(rs); + } + + public List<UserProfile> searchFullName(String name) { + String query = "SELECT * FROM local_directory WHERE firstName LIKE ? OR lastName ?"; + name = name + "%"; + ResultSet rs = executeQuery(query, List.of(name, name)); + return getObjectsFromResultSet(rs); + } + + public Optional<UserProfile> getByUsername(String username) { + ResultSet rs = executeQuery("SELECT * FROM local_directory WHERE username = ?", username); + return getFirstObjectFromResultSet(rs); } @Override - public boolean updateObject(StatementList update, StatementList constraints) { + public boolean storeObject(UserProfile object) { + String query = + "INSERT INTO local_directory " + + "(firstName, lastName, email, profilePicture, organization, phoneNumber, phoneNumberExtension, faxNumber, mobileNumber, username)" + + " VALUES " + + "(?,?,?,?,?,?,?,?,?,?)"; + return executeInsert(query, object); + } - SQLConnection connection = DataStore.connectionPool.getConnection(); - try { - PreparedStatement ps = - connection - .getConnection() - .prepareStatement( - "UPDATE local_directory SET firstname = ?, lastName = ?, email = ?, profilePicture = ?, organization = ?, phoneNumber = ?, phoneNumberExtension = ?, faxNumber = ?, mobileNumber = ? WHERE username = ?"); - for (int i = 1; i < update.getStatements().size(); i++) { - ps.setString(i, update.getStatements().get(i).getValue()); - } - ps.setString(update.getStatements().size(), update.getStatements().get(0).getValue()); - return ps.executeUpdate() != 0; - } catch (Exception e) { - log.error("An error has occurred while trying to update a user profile: " + e); - return false; - } finally { - DataStore.connectionPool.returnConnection(connection); - } + public boolean updateUserProfile(UserProfile userProfile) { + String query = + "UPDATE local_directory SET" + + " firstname = ?," + + " lastName = ?," + + " email = ?," + + " profilePicture = ?," + + " organization = ?," + + " phoneNumber = ?," + + " phoneNumberExtension = ?," + + " faxNumber = ?," + + " mobileNumber = ?" + + " WHERE username = ?"; + return executeInsert(query, userProfile); } } diff --git a/datastore/src/main/java/net/jami/datastore/main/DataStore.java b/datastore/src/main/java/net/jami/datastore/main/DataStore.java index 507cafafd32087358ce6e020f844ba60eb7a2e52..80e9491e47102073eea3d4a22227900c715ae015 100644 --- a/datastore/src/main/java/net/jami/datastore/main/DataStore.java +++ b/datastore/src/main/java/net/jami/datastore/main/DataStore.java @@ -28,7 +28,6 @@ import lombok.Setter; import net.jami.datastore.dao.ContactDao; import net.jami.datastore.dao.DeviceDao; import net.jami.datastore.dao.GroupDao; -import net.jami.datastore.dao.JwtDao; import net.jami.datastore.dao.PolicyDao; import net.jami.datastore.dao.SystemDao; import net.jami.datastore.dao.UserDao; @@ -37,8 +36,6 @@ import net.jami.datastore.dao.UserProfileDao; import net.jami.jams.common.authentication.AuthenticationSource; import net.jami.jams.common.authentication.AuthenticationSourceInfo; import net.jami.jams.common.authentication.AuthenticationSourceType; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.dao.connectivity.ConnectionPool; import net.jami.jams.common.objects.user.User; import net.jami.jams.common.objects.user.UserProfile; @@ -61,7 +58,6 @@ public class DataStore implements AuthenticationSource { private DeviceDao deviceDao; private SystemDao systemDao; private ContactDao contactDao; - private JwtDao jwtDao; private UserProfileDao userProfileDao; private UserGroupMappingsDao userGroupMappingsDao; public static final Integer RESULTS_PER_PAGE = 24; @@ -78,19 +74,10 @@ public class DataStore implements AuthenticationSource { deviceDao = new DeviceDao(); systemDao = new SystemDao(); contactDao = new ContactDao(); - jwtDao = new JwtDao(); userProfileDao = new UserProfileDao(); userGroupMappingsDao = new UserGroupMappingsDao(); } - public boolean userExists(String username) { - StatementList statementList = new StatementList(); - StatementElement statementElement = new StatementElement("username", "=", username, ""); - statementList.addStatement(statementElement); - List<User> userList = userDao.getObjects(statementList); - return (userList.size() == 1); - } - @Override public boolean createUser(User user) { return userDao.storeObject(user); @@ -101,20 +88,17 @@ public class DataStore implements AuthenticationSource { String queryString, String field, Optional<Integer> page) { List<UserProfile> userList; - if (!queryString.equals("*")) { - StatementList statementList = new StatementList(); - String startQueryString = queryString.concat("%"); + if (queryString.equals("*")) { + userList = userProfileDao.getAllUserProfile(); + } else { if (field.equals("LOGON_NAME")) { - statementList.addStatement( - new StatementElement("username", "LIKE", startQueryString, "")); + userList = userProfileDao.searchUsername(queryString); } else if (field.equals("FULL_TEXT_NAME")) { - statementList.addStatement( - new StatementElement("firstName", "LIKE", startQueryString, "OR")); - statementList.addStatement( - new StatementElement("lastName", "LIKE", startQueryString, "")); + userList = userProfileDao.searchFullName(queryString); + } else { + throw new IllegalArgumentException("Invalid field"); } - userList = userProfileDao.getObjects(statementList); - } else userList = userProfileDao.getObjects(null); + } if (userList == null) userList = new ArrayList<>(); @@ -137,11 +121,7 @@ public class DataStore implements AuthenticationSource { @Override public UserProfile getUserProfile(String username) { - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("username", "=", username, "")); - List<UserProfile> userList = userProfileDao.getObjects(statementList); - if (userList.size() != 1) return null; - else return userList.get(0); + return userProfileDao.getByUsername(username).orElse(null); } @Override @@ -150,26 +130,7 @@ public class DataStore implements AuthenticationSource { } public boolean updateUserProfile(UserProfile userProfile) { - - StatementList update = new StatementList(); - update.addStatement(new StatementElement("username", "=", userProfile.getUsername(), "")); - update.addStatement(new StatementElement("firstName", "=", userProfile.getFirstName(), "")); - update.addStatement(new StatementElement("lastName", "=", userProfile.getLastName(), "")); - update.addStatement(new StatementElement("email", "=", userProfile.getEmail(), "")); - update.addStatement( - new StatementElement("profilePicture", "=", userProfile.getProfilePicture(), "")); - update.addStatement( - new StatementElement("organization", "=", userProfile.getOrganization(), "")); - update.addStatement( - new StatementElement("phoneNumber", "=", userProfile.getPhoneNumber(), "")); - update.addStatement( - new StatementElement( - "phoneNumberExtension", "=", userProfile.getPhoneNumberExtension(), "")); - update.addStatement(new StatementElement("faxNumber", "=", userProfile.getFaxNumber(), "")); - update.addStatement( - new StatementElement("mobileNumber", "=", userProfile.getMobileNumber(), "")); - - return userProfileDao.updateObject(update, null); + return userProfileDao.updateUserProfile(userProfile); } public boolean updateUserCertificate(User user) { @@ -179,12 +140,10 @@ public class DataStore implements AuthenticationSource { @Override public boolean authenticate(String username, String password) { - StatementList statementList = new StatementList(); - StatementElement statementElement = new StatementElement("username", "=", username, ""); - statementList.addStatement(statementElement); - List<User> userList = userDao.getObjects(statementList); - if (userList.size() != 1 || userList.get(0).getPassword() == null) return false; - return userList.get(0).getPassword().equals(password); + return userDao.getByUsername(username) + .map(user -> user.getPassword()) + .orElse("") + .equals(password); } @Override diff --git a/datastore/src/test/java/net/jami/datastore/dao/DAOTest.java b/datastore/src/test/java/net/jami/datastore/dao/DAOTest.java index 5d465c9aa573bbd79c8c8452027dfd88926044de..dcf39d91aeb5528322351a79fc58bc4e9d30efd4 100644 --- a/datastore/src/test/java/net/jami/datastore/dao/DAOTest.java +++ b/datastore/src/test/java/net/jami/datastore/dao/DAOTest.java @@ -26,8 +26,6 @@ import lombok.extern.slf4j.Slf4j; import net.jami.datastore.main.DataStore; import net.jami.jams.common.authentication.AuthenticationSourceType; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.devices.Device; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.User; @@ -87,9 +85,7 @@ class DAOTest { UserDao userDAO = new UserDao(); userDAO.storeObject(user); - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("username", "=", "fsidokhine", "")); - User user1 = userDAO.getObjects(statementList).get(0); + User user1 = userDAO.getByUsername("fsidokhine").get(); Assertions.assertNotNull(user1); Assertions.assertEquals(user1.getAccessLevel(), AccessLevel.ADMIN); } @@ -110,9 +106,7 @@ class DAOTest { UserDao userDAO = new UserDao(); userDAO.storeObject(user); - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("username", "=", "TestUser", "")); - User user1 = userDAO.getObjects(statementList).get(0); + User user1 = userDAO.getByUsername("TestUser").get(); Assertions.assertNotNull(user1); Assertions.assertEquals(user1.getAccessLevel(), AccessLevel.USER); @@ -121,7 +115,7 @@ class DAOTest { X509Utils.getPEMStringFromCertificate( X509Utils.getCertificateFromPEMString(refreshedCertificate))); - User user2 = userDAO.getObjects(statementList).get(0); + User user2 = userDAO.getByUsername("TestUser").get(); Assertions.assertNotEquals(user1.getCertificate(), user2.getCertificate()); } @@ -135,9 +129,7 @@ class DAOTest { DeviceDao deviceDAO = new DeviceDao(); deviceDAO.storeObject(device); - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("owner", "=", "fsidokhine", "")); - Device device1 = deviceDAO.getObjects(statementList).get(0); + Device device1 = deviceDAO.getByOwner("fsidokhine").get(0); Assertions.assertNotNull(device1); } @@ -155,9 +147,7 @@ class DAOTest { UserDao userDAO = new UserDao(); userDAO.storeObject(user); - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("username", "=", "admin", "")); - User user1 = userDAO.getObjects(statementList).get(0); + User user1 = userDAO.getByUsername("admin").get(); Assertions.assertNotNull(user1); Assertions.assertEquals(user1.getAccessLevel(), AccessLevel.ADMIN); } diff --git a/jami-nameserver/src/main/java/net/jami/jams/nameserver/LocalNameServer.java b/jami-nameserver/src/main/java/net/jami/jams/nameserver/LocalNameServer.java index ce44aa428be7f1a41413e26f87aa3236c00eb74b..765fe786c83ad29c8910c7aaa83da2419cac3d91 100644 --- a/jami-nameserver/src/main/java/net/jami/jams/nameserver/LocalNameServer.java +++ b/jami-nameserver/src/main/java/net/jami/jams/nameserver/LocalNameServer.java @@ -27,8 +27,6 @@ import lombok.extern.slf4j.Slf4j; import net.jami.datastore.main.DataStore; import net.jami.jams.common.authmodule.AuthModuleKey; import net.jami.jams.common.authmodule.AuthenticationModule; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.jami.NameLookupResponse; import net.jami.jams.common.jami.NameRegistrationRequest; import net.jami.jams.common.jami.NameServer; @@ -37,6 +35,7 @@ import net.jami.jams.common.objects.user.User; import net.jami.jams.common.objects.user.UserProfile; import java.util.List; +import java.util.Optional; @Slf4j public class LocalNameServer implements NameServer { @@ -62,12 +61,8 @@ public class LocalNameServer implements NameServer { @Override public NameLookupResponse getAddressFromName(String username) { - NameLookupResponse nameLookupResponse = null; - StatementList statementList = new StatementList(); - StatementElement statementElement = new StatementElement("username", "=", username, ""); - statementList.addStatement(statementElement); - List<User> results = dataStore.getUserDao().getObjects(statementList); - if (results.size() == 0) { + Optional<User> result = dataStore.getUserDao().getByUsername(username); + if (result.isEmpty()) { // Reattempt resolution via directory lookups. final User user = new User(); for (AuthModuleKey key : authenticationModule.getAuthSources().keySet()) { @@ -87,22 +82,19 @@ public class LocalNameServer implements NameServer { } if (user.getUsername() == null) return null; // resolve again in the database to be sure. - results = dataStore.getUserDao().getObjects(statementList); - if (results.size() == 0) return null; + result = dataStore.getUserDao().getByUsername(username); + if (result.isEmpty()) return null; } - nameLookupResponse = new NameLookupResponse(); - nameLookupResponse.setName(results.get(0).getUsername()); - nameLookupResponse.setAddr(results.get(0).getJamiId()); + NameLookupResponse nameLookupResponse = new NameLookupResponse(); + nameLookupResponse.setName(result.get().getUsername()); + nameLookupResponse.setAddr(result.get().getJamiId()); return nameLookupResponse; } @Override public String getNameFromAddress(String address) { - StatementList statementList = new StatementList(); - StatementElement statementElement = new StatementElement("jamiId", "=", address, ""); - statementList.addStatement(statementElement); - List<User> results = dataStore.getUserDao().getObjects(statementList); - if (results.size() == 0) return null; + List<User> results = dataStore.getUserDao().getByJamiId(address); + if (results.isEmpty()) return null; return results.get(0).getUsername(); } diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java index d176275bbf3b8af3557a05e4259edaabe4bf6315..86f7437f086229b7cc8e57dfe468d85c623f6259 100644 --- a/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java +++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/csr/builders/UserBuilder.java @@ -56,11 +56,10 @@ public class UserBuilder { keyPairGenerator.initialize(4096); KeyPair keyPair = keyPairGenerator.generateKeyPair(); - user.getX509Fields() - .setUid( - Hex.encodeHexString( - MessageDigest.getInstance(MessageDigestAlgorithms.SHA_1) - .digest(keyPair.getPublic().getEncoded()))); + byte[] digest = + MessageDigest.getInstance(MessageDigestAlgorithms.SHA_1) + .digest(keyPair.getPublic().getEncoded()); + user.getX509Fields().setUid(Hex.encodeHexString(digest)); X509v3CertificateBuilder builder = new X509v3CertificateBuilder( @@ -90,13 +89,13 @@ public class UserBuilder { } public static User refreshUser(User user, long userLifeTime) { - try { - long now = System.currentTimeMillis(); - - user.setX509Fields(new X509Fields()); - user.getX509Fields().setCommonName(user.getUsername()); - user.getX509Fields().setUid(user.getJamiId()); + long now = System.currentTimeMillis(); + X509Fields x509 = new X509Fields(); + x509.setCommonName(user.getUsername()); + x509.setUid(user.getJamiId()); + user.setX509Fields(x509); + try { X509v3CertificateBuilder builder = new X509v3CertificateBuilder( new JcaX509CertificateHolder(JamsCA.CA.getCertificate()).getSubject(), diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/ocsp/OCSPWorker.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/ocsp/OCSPWorker.java index 3b064f6aac7008cca130657d06b9daeb9c3bf60a..463f7081dd61f70688bc5c4c04a75a1b155ea5f3 100644 --- a/jams-ca/src/main/java/net/jami/jams/ca/workers/ocsp/OCSPWorker.java +++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/ocsp/OCSPWorker.java @@ -96,7 +96,7 @@ public class OCSPWorker extends X509Worker<String> { if (validateRequest(ocspRequest) != null) throw new OCSPException( "Request is not valid"); // this means the request is invalid and we should - // notify the client. + // notify the client. // If the request was valid, we move on to other things. BasicOCSPRespBuilder responseBuilder = new BasicOCSPRespBuilder(responderID); // Add appropriate extensions diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java b/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java deleted file mode 100644 index b89eb731ba9a7d819a416300cfb2fdf109f129b9..0000000000000000000000000000000000000000 --- a/jams-common/src/main/java/net/jami/jams/common/dao/DeleteStatementBuilder.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Authors: William Enright <william.enright@savoirfairelinux.com> - * Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com> - * Johnny Flores <johnny.flores@savoirfairelinux.com> - * Mohammed Raza <mohammed.raza@savoirfairelinux.com> - * Felix Sidokhine <felix.sidokhine@savoirfairelinux.com> - * - * - * This program 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. - * - * This program 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 this program. If not, see <https://www.gnu.org/licenses/>. - */ -package net.jami.jams.common.dao; - -import net.jami.jams.common.dao.connectivity.SQLConnection; - -import java.sql.PreparedStatement; - -public class DeleteStatementBuilder { - - public static PreparedStatement buildStatement( - String table, StatementList statementElements, SQLConnection connection) - throws Exception { - PreparedStatement ps = null; - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("DELETE FROM ").append(table); - if (statementElements != null) { - stringBuilder.append(" WHERE "); - for (StatementElement statementElement : statementElements.getStatements()) { - stringBuilder - .append(statementElement.getColumn()) - .append(" ") - .append(statementElement.getOperator()) - .append(" ") - .append("?") - .append(" ") - .append(statementElement.getNextStatementRelation()) - .append(" "); - } - ps = connection.getConnection().prepareStatement(stringBuilder.toString()); - int i = 1; - for (StatementElement statementElement : statementElements.getStatements()) { - ps.setString(i, statementElement.getValue()); - i++; - } - } else { - ps = connection.getConnection().prepareStatement(stringBuilder.toString()); - } - return ps; - } -} diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/SelectStatementBuilder.java b/jams-common/src/main/java/net/jami/jams/common/dao/SelectStatementBuilder.java deleted file mode 100644 index cd591e9c794b086550405c7116e30b73cee653c0..0000000000000000000000000000000000000000 --- a/jams-common/src/main/java/net/jami/jams/common/dao/SelectStatementBuilder.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Authors: William Enright <william.enright@savoirfairelinux.com> - * Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com> - * Johnny Flores <johnny.flores@savoirfairelinux.com> - * Mohammed Raza <mohammed.raza@savoirfairelinux.com> - * Felix Sidokhine <felix.sidokhine@savoirfairelinux.com> - * - * - * This program 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. - * - * This program 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 this program. If not, see <https://www.gnu.org/licenses/>. - */ -package net.jami.jams.common.dao; - -import net.jami.jams.common.dao.connectivity.SQLConnection; - -import java.sql.PreparedStatement; - -public class SelectStatementBuilder { - - public static PreparedStatement buildStatement( - String table, - StatementList statementElements, - StatementConstraints statementConstraints, - SQLConnection connection) - throws Exception { - PreparedStatement ps = null; - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("SELECT * FROM ").append(table); - if (statementElements != null) { - stringBuilder.append(" WHERE "); - for (StatementElement statementElement : statementElements.getStatements()) { - - stringBuilder - .append("lower(" + statementElement.getColumn() + ")") - .append(" ") - .append(statementElement.getOperator()) - .append(" ") - .append("?") - .append(" ") - .append(statementElement.getNextStatementRelation()) - .append(" "); - } - ps = connection.getConnection().prepareStatement(stringBuilder.toString()); - int i = 1; - for (StatementElement statementElement : statementElements.getStatements()) { - ps.setString(i, (statementElement.getValue()).toLowerCase()); - i++; - } - } else { - if (statementConstraints != null) { - stringBuilder - .append(" LIMIT ") - .append(statementConstraints.getRowCount()) - .append(" OFFSET ") - .append(statementConstraints.getOffset()); - } - ps = connection.getConnection().prepareStatement(stringBuilder.toString()); - } - return ps; - } -} diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/StatementConstraints.java b/jams-common/src/main/java/net/jami/jams/common/dao/StatementConstraints.java deleted file mode 100644 index f2f2294c1c1871f3b976f6397c45bbefc602b109..0000000000000000000000000000000000000000 --- a/jams-common/src/main/java/net/jami/jams/common/dao/StatementConstraints.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Authors: William Enright <william.enright@savoirfairelinux.com> - * Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com> - * Johnny Flores <johnny.flores@savoirfairelinux.com> - * Mohammed Raza <mohammed.raza@savoirfairelinux.com> - * Felix Sidokhine <felix.sidokhine@savoirfairelinux.com> - * - * - * This program 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. - * - * This program 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 this program. If not, see <https://www.gnu.org/licenses/>. - */ -package net.jami.jams.common.dao; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class StatementConstraints { - - private Long rowCount; - private Long offset; -} diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/StatementElement.java b/jams-common/src/main/java/net/jami/jams/common/dao/StatementElement.java deleted file mode 100644 index 6e1446b2bace8e0f66368d199a22f51d4f18c693..0000000000000000000000000000000000000000 --- a/jams-common/src/main/java/net/jami/jams/common/dao/StatementElement.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Authors: William Enright <william.enright@savoirfairelinux.com> - * Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com> - * Johnny Flores <johnny.flores@savoirfairelinux.com> - * Mohammed Raza <mohammed.raza@savoirfairelinux.com> - * Felix Sidokhine <felix.sidokhine@savoirfairelinux.com> - * - * - * This program 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. - * - * This program 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 this program. If not, see <https://www.gnu.org/licenses/>. - */ -package net.jami.jams.common.dao; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -public class StatementElement { - private String column; - private String operator; - private String value; - private String nextStatementRelation; -} diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/StatementList.java b/jams-common/src/main/java/net/jami/jams/common/dao/StatementList.java deleted file mode 100644 index 8767fda06cd9d49eefa355534e4273028cb7d093..0000000000000000000000000000000000000000 --- a/jams-common/src/main/java/net/jami/jams/common/dao/StatementList.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Authors: William Enright <william.enright@savoirfairelinux.com> - * Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com> - * Johnny Flores <johnny.flores@savoirfairelinux.com> - * Mohammed Raza <mohammed.raza@savoirfairelinux.com> - * Felix Sidokhine <felix.sidokhine@savoirfairelinux.com> - * - * - * This program 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. - * - * This program 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 this program. If not, see <https://www.gnu.org/licenses/>. - */ -package net.jami.jams.common.dao; - -import lombok.Getter; -import lombok.Setter; - -import java.util.ArrayList; -import java.util.List; - -@Getter -@Setter -public class StatementList { - - private List<StatementElement> statements = new ArrayList<>(); - - public void addStatement(StatementElement statementElement) { - statements.add(statementElement); - } -} diff --git a/jams-common/src/main/java/net/jami/jams/common/dao/UpdateStatementBuilder.java b/jams-common/src/main/java/net/jami/jams/common/dao/UpdateStatementBuilder.java deleted file mode 100644 index 8743e00efc85c9704959e15bec92be9c62cee0f5..0000000000000000000000000000000000000000 --- a/jams-common/src/main/java/net/jami/jams/common/dao/UpdateStatementBuilder.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Authors: William Enright <william.enright@savoirfairelinux.com> - * Ndeye Anna Ndiaye <anna.ndiaye@savoirfairelinux.com> - * Johnny Flores <johnny.flores@savoirfairelinux.com> - * Mohammed Raza <mohammed.raza@savoirfairelinux.com> - * Felix Sidokhine <felix.sidokhine@savoirfairelinux.com> - * - * - * This program 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. - * - * This program 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 this program. If not, see <https://www.gnu.org/licenses/>. - */ -package net.jami.jams.common.dao; - -import net.jami.jams.common.dao.connectivity.SQLConnection; - -import java.sql.PreparedStatement; - -public class UpdateStatementBuilder { - public static PreparedStatement buildStatement( - String table, - StatementList updateElements, - StatementList conditionalElements, - SQLConnection connection) - throws Exception { - PreparedStatement ps = null; - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("UPDATE ").append(table).append(" SET "); - for (int i = 0; i < updateElements.getStatements().size(); i++) { - StatementElement statementElement = updateElements.getStatements().get(i); - stringBuilder.append(statementElement.getColumn()).append(" = ").append("?"); - if (i != updateElements.getStatements().size() - 1) stringBuilder.append(","); - } - stringBuilder.append(" WHERE "); - for (StatementElement statementElement : conditionalElements.getStatements()) { - stringBuilder - .append(statementElement.getColumn()) - .append(" ") - .append(statementElement.getOperator()) - .append(" ") - .append("?") - .append(" ") - .append(statementElement.getNextStatementRelation()); - } - ps = connection.getConnection().prepareStatement(stringBuilder.toString()); - // Now we have to feed this all the elements it should have. - updateElements.getStatements().addAll(conditionalElements.getStatements()); - int i = 1; - for (StatementElement statementElement : updateElements.getStatements()) { - ps.setString(i, statementElement.getValue()); - i++; - } - return ps; - } -} diff --git a/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java b/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java index 609fa345c2de89aff70b1105218191b3417c9a19..fdfbb1afda08d7208bfd46352a38e45e34a48438 100644 --- a/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java +++ b/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java @@ -122,16 +122,16 @@ public class UserProfile implements DatabaseObject { @Override public PreparedStatement getInsert(PreparedStatement ps) throws Exception { - ps.setString(1, username); - ps.setString(2, firstName); - ps.setString(3, lastName); - ps.setString(4, email); - ps.setString(5, profilePicture); - ps.setString(6, organization); - ps.setString(7, phoneNumber); - ps.setString(8, phoneNumberExtension); - ps.setString(9, faxNumber); - ps.setString(10, mobileNumber); + ps.setString(1, firstName); + ps.setString(2, lastName); + ps.setString(3, email); + ps.setString(4, profilePicture); + ps.setString(5, organization); + ps.setString(6, phoneNumber); + ps.setString(7, phoneNumberExtension); + ps.setString(8, faxNumber); + ps.setString(9, mobileNumber); + ps.setString(10, username); return ps; } diff --git a/jams-common/src/test/java/net/jami/jams/common/objects/contacts/ContactTest.java b/jams-common/src/test/java/net/jami/jams/common/objects/contacts/ContactTest.java index 2a953419e1229e2f1ab4d3f3bc7586a286e228e6..601a34f3f015f80750a012a2f52705b68494bb11 100644 --- a/jams-common/src/test/java/net/jami/jams/common/objects/contacts/ContactTest.java +++ b/jams-common/src/test/java/net/jami/jams/common/objects/contacts/ContactTest.java @@ -25,8 +25,8 @@ class ContactTest { @Test public void deserialize() { String str = - "[{\"uri\":\"tcp://def@local\",\"added\":1594742298377,\"banned\":false,\"confirmed\":true,\"confirmed\":6a61013979964f70c8fb9183a8b238d58a1846ed}," - + "{\"uri\":\"tcp://abc@19293.com\",\"removed\":1594742298377,\"banned\":true,\"confirmed\":true,\"confirmed\":2b61024119964f70c8fb9183a8b238d58a1846ed}]"; + "[{\"uri\":\"tcp://def@local\",\"added\":1594742298377,\"banned\":false,\"confirmed\":true,\"conversationId\":\"6a61013979964f70c8fb9183a8b238d58a1846ed\"}," + + "{\"uri\":\"tcp://abc@19293.com\",\"removed\":1594742298377,\"banned\":true,\"confirmed\":true,\"conversationId\":\"2b61024119964f70c8fb9183a8b238d58a1846e\"}]"; Contact[] contacts = JsonIterator.deserialize(str, Contact[].class); Assertions.assertEquals(2, contacts.length); } diff --git a/jams-server/src/main/java/net/jami/jams/server/Server.java b/jams-server/src/main/java/net/jami/jams/server/Server.java index 40488b8ca56d009ab80012f362c2344c83c5a081..4a750d075bcc53ab1c5399f95870d09d5bd4169d 100644 --- a/jams-server/src/main/java/net/jami/jams/server/Server.java +++ b/jams-server/src/main/java/net/jami/jams/server/Server.java @@ -46,7 +46,7 @@ import net.jami.jams.server.startup.CryptoEngineLoader; import net.jami.jams.server.update.JAMSUpdater; import net.jami.jams.server.update.UpdateInterface; -import java.awt.*; +import java.awt.Desktop; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; diff --git a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java index ccc9a9123045fcf460b4c5c9474b13f40bbe54a4..ed742f18b53f7bf110ee941ee14985c6aa0ce4d2 100644 --- a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java +++ b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java @@ -32,21 +32,15 @@ import lombok.extern.slf4j.Slf4j; import net.jami.jams.authmodule.UserAuthenticationModule; import net.jami.jams.common.authmodule.AuthModuleKey; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.devices.Device; import net.jami.jams.common.objects.requests.DeviceRegistrationRequest; import net.jami.jams.common.objects.responses.DeviceRegistrationResponse; -import net.jami.jams.common.objects.user.Group; -import net.jami.jams.common.objects.user.Policy; import net.jami.jams.common.objects.user.User; -import net.jami.jams.common.objects.user.UserGroupMapping; import net.jami.jams.common.objects.user.UserProfile; import net.jami.jams.dht.DeviceReceiptGenerator; import java.security.cert.X509Certificate; import java.util.Date; -import java.util.List; import java.util.Optional; @Slf4j @@ -55,9 +49,7 @@ public class RegisterDeviceFlow { public static DeviceRegistrationResponse registerDevice( String username, DeviceRegistrationRequest registrationRequest) { try { - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("username", "=", username, "")); - User user = dataStore.getUserDao().getObjects(statementList).get(0); + User user = dataStore.getUserDao().getByUsername(username).orElseThrow(); UserProfile userProfile = userAuthenticationModule @@ -66,11 +58,6 @@ public class RegisterDeviceFlow { .searchUserProfiles(username, "LOGON_NAME", Optional.empty()) .get(0); - if (user == null) { - log.error( - "Tried to enroll a device, but could not find a user, this is impossible!"); - } - // Renew user certificate if expired with same private key if (!user.getCertificate().getNotAfter().after(new Date())) { user = UserAuthenticationModule.certificateAuthority.getRefreshedCertificate(user); @@ -88,10 +75,8 @@ public class RegisterDeviceFlow { } dataStore.getDeviceDao().storeObject(device); - Group group = getGroupByUsername(username); - DeviceRegistrationResponse response = new DeviceRegistrationResponse(); - String policyData = getPolicyData(group); + String policyData = getPolicyData(username); if (policyData != null) { response.setPolicyData(policyData); } @@ -124,39 +109,17 @@ public class RegisterDeviceFlow { } } - public static Group getGroupByUsername(String username) { - Group group = new Group(); - - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("username", "=", username, "")); - List<UserGroupMapping> userGroupMappings = - dataStore.getUserGroupMappingsDao().getObjects(statementList); - - if (userGroupMappings != null && !userGroupMappings.isEmpty()) { - UserGroupMapping mapping = userGroupMappings.get(0); - statementList = new StatementList(); - statementList.addStatement(new StatementElement("id", "=", mapping.getGroupId(), "")); - group = dataStore.getGroupDao().getObjects(statementList).get(0); - } - - return group; - } - - public static String getPolicyData(Group group) { - if (!group.isEmpty() && group.hasBlueprint()) { - StatementElement statementElement = - new StatementElement("name", "=", group.getBlueprint(), ""); - StatementList statementList = new StatementList(); - statementList.addStatement(statementElement); - try { - Policy policy = dataStore.getPolicyDao().getObjects(statementList).get(0); - return policy.getPolicyData(); - } catch (Exception e) { - log.warn( - "No policy available for user - not adding a policy component to response"); - } + public static String getPolicyData(String username) { + String policy = + dataStore + .getPolicyDao() + .getByUsername(username) + .map(p -> p.getPolicyData()) + .orElse(null); + if (policy == null) { + log.warn("No policy available for user - not adding a policy component to response"); } - return null; + return policy; } } diff --git a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeDeviceFlow.java b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeDeviceFlow.java index 410d2a73238cc2ad38263f41235caf1ed57f8bba..1d0a112fa41a9d9b41b97751d1b25b094e832f91 100644 --- a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeDeviceFlow.java +++ b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeDeviceFlow.java @@ -27,14 +27,13 @@ import static net.jami.jams.server.Server.dataStore; import lombok.extern.slf4j.Slf4j; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.devices.Device; import net.jami.jams.common.objects.requests.RevocationRequest; import net.jami.jams.common.objects.requests.RevocationType; import net.jami.jams.common.objects.responses.DeviceRevocationResponse; import java.math.BigInteger; +import java.util.Optional; @Slf4j public class RevokeDeviceFlow { @@ -42,17 +41,15 @@ public class RevokeDeviceFlow { public static DeviceRevocationResponse revokeDevice(String username, String deviceId) { DeviceRevocationResponse response = new DeviceRevocationResponse(); try { - StatementList statementList = new StatementList(); - StatementElement st1 = new StatementElement("owner", "=", username, "AND"); - StatementElement st2 = new StatementElement("deviceId", "=", deviceId, ""); - statementList.addStatement(st1); - statementList.addStatement(st2); - Device device = dataStore.getDeviceDao().getObjects(statementList).get(0); - if (device == null) { + Optional<Device> result = + dataStore.getDeviceDao().getByDeviceIdAndOwner(deviceId, username); + if (result.isEmpty()) { log.error("Could not find device!"); return null; } + Device device = result.get(); + BigInteger serialNumber = device.getCertificate().getSerialNumber(); RevocationRequest request = new RevocationRequest(serialNumber, RevocationType.DEVICE); diff --git a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeUserFlow.java b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeUserFlow.java index a71932981cca339e49e9f2b44c825130f7fea04b..0b2a1c93e653788fe6b1416234a00b719efce56f 100644 --- a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeUserFlow.java +++ b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RevokeUserFlow.java @@ -27,8 +27,6 @@ import static net.jami.jams.server.Server.dataStore; import lombok.extern.slf4j.Slf4j; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.requests.RevocationRequest; import net.jami.jams.common.objects.requests.RevocationType; import net.jami.jams.common.objects.responses.DeviceRevocationResponse; @@ -40,10 +38,7 @@ public class RevokeUserFlow { public static DeviceRevocationResponse revokeUser(String username) { DeviceRevocationResponse response = new DeviceRevocationResponse(); try { - StatementList statementList = new StatementList(); - StatementElement st1 = new StatementElement("username", "=", username, ""); - statementList.addStatement(st1); - User user = dataStore.getUserDao().getObjects(statementList).get(0); + User user = dataStore.getUserDao().getByUsername(username).get(); if (user == null) { log.error("Could not find user!"); return null; diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/LoginServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/LoginServlet.java index 349402305608f62781a3f310dbbbaf7967482a74..1ba1ba3c9e7aab92b46fe6f5184b7576f1aaacb3 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/LoginServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/LoginServlet.java @@ -37,15 +37,13 @@ import jakarta.servlet.http.HttpServletResponse; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.authmodule.AuthTokenResponse; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.User; import net.jami.jams.common.serialization.tomcat.TomcatCustomErrorHandler; import net.jami.jams.server.servlets.api.auth.login.LoginRequest; import java.io.IOException; import java.security.cert.X509Certificate; -import java.util.List; +import java.util.Optional; @WebServlet("/api/login") // This method returns the token which is used for all the next calls to the @@ -86,19 +84,15 @@ public class LoginServlet extends HttpServlet { req.getInputStream().readAllBytes(), LoginRequest.class); if (object.getUsername() != null && object.getPassword() != null) { res = processUsernamePasswordAuth(object.getUsername(), object.getPassword()); - StatementList statementList = new StatementList(); - StatementElement statementElement = - new StatementElement("username", "=", object.getUsername(), ""); - statementList.addStatement(statementElement); - List<User> users = dataStore.getUserDao().getObjects(statementList); - if (users.size() != 0 + Optional<User> user = dataStore.getUserDao().getByUsername(object.getUsername()); + if (user.isPresent() && certificateAuthority.getLatestCRL().get() != null - && !users.get(0).getAccessLevelName().equals("ADMIN") + && !user.get().getAccessLevelName().equals("ADMIN") && certificateAuthority .getLatestCRL() .get() .getRevokedCertificate( - users.get(0).getCertificate().getSerialNumber()) + user.get().getCertificate().getSerialNumber()) != null) { TomcatCustomErrorHandler.sendCustomError( resp, 401, "Invalid credentials provided!"); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/contacts/ContactServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/contacts/ContactServlet.java index fd1df0c1b1b4965680c26f621ba8fe1e3041be5c..6149f3873ff28e93b7de044cfb115ffe97d3bfbd 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/contacts/ContactServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/contacts/ContactServlet.java @@ -35,8 +35,6 @@ import jakarta.servlet.http.HttpServletResponse; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.contacts.Contact; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.serialization.tomcat.TomcatCustomErrorHandler; @@ -69,10 +67,8 @@ public class ContactServlet extends HttpServlet { @JsonContent protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - StatementList statementList = new StatementList(); - statementList.addStatement( - new StatementElement("owner", "=", req.getParameter("username"), "")); - List<Contact> contactList = dataStore.getContactDao().getObjects(statementList); + List<Contact> contactList = + dataStore.getContactDao().getByOwner(req.getParameter("username")); resp.getOutputStream().write(JsonStream.serialize(contactList).getBytes()); } @@ -96,6 +92,7 @@ public class ContactServlet extends HttpServlet { Scanner s = new Scanner(req.getInputStream()).useDelimiter("\\A"); String res = s.hasNext() ? s.next() : ""; final JSONObject obj = new JSONObject(res); + Contact contact = new Contact(); // TODO: Replace with mergetool. contact.setDisplayName(obj.get("displayName").toString()); @@ -103,13 +100,13 @@ public class ContactServlet extends HttpServlet { contact.setStatus('A'); contact.setOwner(req.getParameter("username")); contact.setUri(obj.get("uri").toString()); - StatementList statementList = new StatementList(); - statementList.addStatement( - new StatementElement("owner", "=", req.getParameter("username"), "")); - List<Contact> localList = dataStore.getContactDao().getObjects(statementList); + + List<Contact> localList = + dataStore.getContactDao().getByOwner(req.getParameter("username")); List<Contact> remoteList = new ArrayList<>(); remoteList.add(contact); List<Contact> result = ContactMerger.mergeContacts(localList, remoteList); + if (dataStore.getContactDao().storeContactList(result)) resp.setStatus(200); else TomcatCustomErrorHandler.sendCustomError( @@ -131,22 +128,9 @@ public class ContactServlet extends HttpServlet { @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - StatementList statementList = new StatementList(); - statementList.addStatement( - new StatementElement("owner", "=", req.getParameter("username"), "AND")); - statementList.addStatement(new StatementElement("uri", "=", req.getParameter("uri"), "")); - /* - * List<Contact> remoteList = - * dataStore.getContactDao().getObjects(statementList); - * remoteList.get(0).setStatus('D'); - * remoteList.get(0).setTimestamp(System.currentTimeMillis()); statementList = - * new StatementList(); statementList.addStatement(new - * StatementElement("owner","=",req.getParameter("username").toString(),"")); - * List<Contact> localList = - * dataStore.getContactDao().getObjects(statementList); List<Contact> result = - * ContactMerger.mergeContacts(localList,remoteList); - */ - if (dataStore.getContactDao().deleteObject(statementList)) resp.setStatus(200); + String owner = req.getParameter("username"); + String uri = req.getParameter("uri"); + if (dataStore.getContactDao().deleteObject(owner, uri)) resp.setStatus(200); else TomcatCustomErrorHandler.sendCustomError( resp, 500, "could not delete a contact due to server-side error"); @@ -170,16 +154,16 @@ public class ContactServlet extends HttpServlet { @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - StatementList statementList = new StatementList(); - statementList.addStatement( - new StatementElement("owner", "=", req.getParameter("username"), "")); - List<Contact> localList = dataStore.getContactDao().getObjects(statementList); + List<Contact> localList = + dataStore.getContactDao().getByOwner(req.getParameter("username")); List<Contact> remoteList = Arrays.asList( JsonIterator.deserialize( req.getInputStream().readAllBytes(), Contact[].class)); + remoteList.forEach(contact -> contact.setOwner(req.getParameter("username"))); List<Contact> result = ContactMerger.mergeContacts(localList, remoteList); + if (!dataStore.getContactDao().storeContactList(result)) TomcatCustomErrorHandler.sendCustomError(resp, 500, "Could not store contacts!"); else resp.getOutputStream().write(JsonStream.serialize(result).getBytes()); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java index 100bf578d6759d04fa0b782b5f42c34d6594e4f3..656f3c2295a7992f6ac9738320636514784cf7e5 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java @@ -33,8 +33,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; +import net.jami.jams.common.objects.devices.Device; import net.jami.jams.common.objects.responses.DeviceRevocationResponse; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.server.core.workflows.RevokeDeviceFlow; @@ -51,16 +50,9 @@ public class DeviceServlet extends HttpServlet { throws ServletException, IOException { String username = req.getParameter("username"); String deviceId = req.getParameter("deviceId"); - StatementList statementList = new StatementList(); - StatementElement st1 = new StatementElement("owner", "=", username, "AND"); - StatementElement st2 = new StatementElement("deviceId", "=", deviceId, ""); - statementList.addStatement(st1); - statementList.addStatement(st2); - resp.getOutputStream() - .write( - JsonStream.serialize( - dataStore.getDeviceDao().getObjects(statementList).get(0)) - .getBytes()); + Device device = + dataStore.getDeviceDao().getByDeviceIdAndOwner(deviceId, username).orElseThrow(); + resp.getOutputStream().write(JsonStream.serialize(device).getBytes()); } // Update device data. @@ -71,15 +63,9 @@ public class DeviceServlet extends HttpServlet { String username = req.getParameter("username"); String deviceId = req.getParameter("deviceId"); String deviceName = req.getParameter("deviceName"); - StatementList update = new StatementList(); - StatementElement st0 = new StatementElement("deviceName", "=", deviceName, ""); - update.addStatement(st0); - StatementList constraint = new StatementList(); - StatementElement st1 = new StatementElement("owner", "=", username, "AND"); - StatementElement st2 = new StatementElement("deviceId", "=", deviceId, ""); - update.addStatement(st1); - update.addStatement(st2); - if (dataStore.getDeviceDao().updateObject(update, constraint)) resp.setStatus(200); + + if (dataStore.getDeviceDao().updateObject(deviceName, username, deviceId)) + resp.setStatus(200); else resp.sendError(500, "could not update the device's information!"); } @@ -88,9 +74,9 @@ public class DeviceServlet extends HttpServlet { @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - DeviceRevocationResponse devResponse = - RevokeDeviceFlow.revokeDevice( - req.getParameter("username"), req.getParameter("deviceId")); + String username = req.getParameter("username"); + String deviceId = req.getParameter("deviceId"); + DeviceRevocationResponse devResponse = RevokeDeviceFlow.revokeDevice(username, deviceId); if (devResponse != null) resp.getOutputStream().write(JsonStream.serialize(devResponse).getBytes()); else resp.sendError(500, "An exception has occurred while trying to revoke a device!"); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java index 4697c5a13b411283e179dbfe3b84bdcca5c5e072..a4b3de098e427d593196a1c9e55f67ece2b050b3 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java @@ -35,8 +35,6 @@ import jakarta.servlet.http.HttpServletResponse; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.devices.Device; import net.jami.jams.common.objects.user.AccessLevel; @@ -53,9 +51,7 @@ public class DevicesServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("owner", "=", username, "")); - List<Device> devices = dataStore.getDeviceDao().getObjects(statementList); + List<Device> devices = dataStore.getDeviceDao().getByOwner(username); if (certificateAuthority.getLatestCRL() != null) { devices.forEach( device -> { diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java index 9726601219fc277455dec6f89ef40e8d96afe6c7..faba679520c30fb998e5d799e27bee402611bc8f 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java @@ -41,8 +41,6 @@ import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; import net.jami.jams.common.authentication.AuthenticationSourceType; import net.jami.jams.common.authmodule.AuthModuleKey; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.User; import net.jami.jams.common.objects.user.UserProfile; @@ -97,16 +95,12 @@ public class DirectoryEntryServlet extends HttpServlet { // Check if he is AD/LDAP - then return a 500, because we can't update those profile datas. UserProfile userProfile = JsonIterator.deserialize(req.getInputStream().readAllBytes(), UserProfile.class); - StatementList select = new StatementList(); - StatementElement st = new StatementElement("username", "=", userProfile.getUsername(), ""); - select.addStatement(st); - User targetUser = dataStore.getUserDao().getObjects(select).get(0); - select = new StatementList(); - st = new StatementElement("username", "=", req.getAttribute("username").toString(), ""); - select.addStatement(st); + String username = req.getAttribute("username").toString(); - User callingUser = dataStore.getUserDao().getObjects(select).get(0); + User targetUser = + dataStore.getUserDao().getByUsername(userProfile.getUsername()).orElseThrow(); + User callingUser = dataStore.getUserDao().getByUsername(username).orElseThrow(); if (targetUser.getUserType() != AuthenticationSourceType.LOCAL) { resp.sendError( @@ -117,16 +111,14 @@ public class DirectoryEntryServlet extends HttpServlet { if (callingUser.getAccessLevel() == AccessLevel.ADMIN || (callingUser.getAccessLevel() == AccessLevel.USER && callingUser.getUsername().equals(targetUser.getUsername()))) { - select = new StatementList(); - select.addStatement( - new StatementElement("username", "=", userProfile.getUsername(), "")); if (dataStore.updateUserProfile(userProfile)) resp.setStatus(200); else resp.sendError(500, "Could not update the users's profile information"); - } else { - resp.sendError( - 403, - "The user is either not an admin account or is attempting to edit a profile that is not his own!"); + + return; } + resp.sendError( + 403, + "The user is either not an admin account or is attempting to edit a profile that is not his own!"); } @Override diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java index 489de813ba62cba5657f29c594dc7e4dc7ccef95..e6e0c6686a4039022403a9b5e96f4db9be45b85b 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java @@ -14,14 +14,13 @@ import lombok.extern.slf4j.Slf4j; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.Group; import org.json.JSONObject; import java.io.IOException; +import java.util.Optional; import java.util.stream.Collectors; @WebServlet("/api/admin/group/*") @@ -33,18 +32,13 @@ public class GroupServlet extends HttpServlet { @JsonContent protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - Group singleGroup = null; String id = req.getPathInfo().replace("/", ""); - StatementList statementList = new StatementList(); - StatementElement st = new StatementElement("id", "=", id, ""); + Optional<Group> singleGroup = dataStore.getGroupDao().getById(id); - statementList.addStatement(st); - if (!dataStore.getGroupDao().getObjects(statementList).isEmpty()) - singleGroup = dataStore.getGroupDao().getObjects(statementList).get(0); - - if (singleGroup != null) { - resp.getOutputStream().write(JsonStream.serialize(singleGroup).getBytes()); + if (singleGroup.isPresent()) { + resp.getOutputStream() + .write(JsonStream.serialize(singleGroup.orElseThrow()).getBytes()); resp.setStatus(200); } else { log.info("No group with this id was found!"); @@ -56,7 +50,6 @@ public class GroupServlet extends HttpServlet { @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) @JsonContent protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException { - String id = req.getPathInfo().replace("/", ""); final JSONObject obj = @@ -68,20 +61,7 @@ public class GroupServlet extends HttpServlet { String name = obj.getString("name"); String blueprint = obj.getString("blueprint"); - StatementList update = new StatementList(); - - StatementElement st0 = new StatementElement("id", "=", id, ""); - update.addStatement(st0); - - StatementElement st1 = new StatementElement("name", "=", name, ""); - update.addStatement(st1); - - StatementElement st2 = new StatementElement("blueprint", "=", blueprint, ""); - update.addStatement(st2); - - StatementList constraint = new StatementList(); - - if (dataStore.getGroupDao().updateObject(update, constraint)) resp.setStatus(200); + if (dataStore.getGroupDao().updateObject(id, name, blueprint)) resp.setStatus(200); else resp.sendError(500, "Could not update group!"); } @@ -89,20 +69,10 @@ public class GroupServlet extends HttpServlet { @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) @JsonContent protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException { - String id = req.getPathInfo().replace("/", ""); + String groupId = req.getPathInfo().replace("/", ""); - StatementElement statementElement = new StatementElement("id", "=", id, ""); - - StatementList constraint = new StatementList(); - constraint.addStatement(statementElement); - if (dataStore.getGroupDao().deleteObject(constraint)) { - StatementElement statementElement1 = new StatementElement("username", "=", "*", ""); - StatementElement statementElement2 = new StatementElement("groupId", "=", id, ""); - StatementList constraintMapping = new StatementList(); - constraintMapping.addStatement(statementElement1); - constraintMapping.addStatement(statementElement2); - if (dataStore.getUserGroupMappingsDao().deleteObject(constraintMapping)) - resp.setStatus(200); + if (dataStore.getGroupDao().deleteObject(groupId)) { + if (dataStore.getUserGroupMappingsDao().deleteObject("*", groupId)) resp.setStatus(200); else resp.sendError(500, "Could not delete the group mappings successfully!"); } else { resp.sendError(500, "Could not delete the group successfully!"); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java index 9b5d34e6ea155cac6a6590eb7d08b851973f0de7..38c7b761d1945d42cda581eb4007a026261d26ff 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java @@ -30,7 +30,7 @@ public class GroupsServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - List<Group> groups = dataStore.getGroupDao().getObjects(null); + List<Group> groups = dataStore.getGroupDao().getAll(); if (!groups.isEmpty()) { resp.getOutputStream().write(JsonStream.serialize(groups).getBytes()); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyProfileServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyProfileServlet.java index 174ededdcc3af4d4d12bd2e108e65723abaa4641..06c5f0ceab1c077aefd7a4792b243745dd27165a 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyProfileServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyProfileServlet.java @@ -14,13 +14,12 @@ import lombok.extern.slf4j.Slf4j; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.Policy; import java.io.IOException; import java.util.List; +import java.util.Optional; @WebServlet("/api/admin/policy/*") @Slf4j @@ -31,29 +30,26 @@ public class PolicyProfileServlet extends HttpServlet { @JsonContent protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - - List<Policy> policies; String name = req.getPathInfo().replace("/", ""); + getPolicyAndSendResponse(resp, name); + } - if (!name.equals("*")) { - StatementList statementList = new StatementList(); - StatementElement st = new StatementElement("name", "=", name, ""); - statementList.addStatement(st); - if (!dataStore.getPolicyDao().getObjects(statementList).isEmpty()) { - resp.getOutputStream() - .write( - JsonStream.serialize( - dataStore - .getPolicyDao() - .getObjects(statementList) - .get(0)) - .getBytes()); - resp.setStatus(200); - } - } else { - policies = dataStore.getPolicyDao().getObjects(null); + public static void getPolicyAndSendResponse(HttpServletResponse resp, String name) + throws IOException { + if (name.equals("*")) { + List<Policy> policies = dataStore.getPolicyDao().getAll(); resp.getOutputStream().write(JsonStream.serialize(policies).getBytes()); resp.setStatus(200); + return; + } + + Optional<Policy> policy = dataStore.getPolicyDao().getByName(name); + if (policy.isPresent()) { + byte[] bytes = JsonStream.serialize(policy.orElseThrow()).getBytes(); + resp.getOutputStream().write(bytes); + resp.setStatus(200); + } else { + resp.sendError(404, "{\"message\": \"No policy found.\"}"); } } } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyServlet.java index 09ca1d93a6ab62080f168ff62c2107c3d431c38b..c4b8369075258ab49ecdf4f65466f930f5132bb3 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/PolicyServlet.java @@ -2,8 +2,6 @@ package net.jami.jams.server.servlets.api.admin.group; import static net.jami.jams.server.Server.dataStore; -import com.jsoniter.output.JsonStream; - import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; @@ -14,15 +12,12 @@ import lombok.extern.slf4j.Slf4j; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.Policy; import org.json.JSONObject; import java.io.IOException; -import java.util.List; import java.util.Scanner; @Slf4j @@ -34,27 +29,8 @@ public class PolicyServlet extends HttpServlet { @JsonContent protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - - List<Policy> policies; String name = req.getParameter("name"); - - if (!name.equals("*")) { - StatementList statementList = new StatementList(); - StatementElement st = new StatementElement("name", "=", name, ""); - statementList.addStatement(st); - policies = dataStore.getPolicyDao().getObjects(statementList); - if (!policies.isEmpty()) { - resp.getOutputStream().write(JsonStream.serialize(policies.get(0)).getBytes()); - resp.setStatus(200); - } else { - resp.setStatus(404); // 404 status code for Not Found - resp.getWriter().write("{\"message\": \"No policy found.\"}"); - } - } else { - policies = dataStore.getPolicyDao().getObjects(null); - resp.getOutputStream().write(JsonStream.serialize(policies).getBytes()); - resp.setStatus(200); - } + PolicyProfileServlet.getPolicyAndSendResponse(resp, name); } @Override @@ -65,17 +41,9 @@ public class PolicyServlet extends HttpServlet { Scanner s = new Scanner(req.getInputStream()).useDelimiter("\\A"); String result = s.hasNext() ? s.next() : ""; final JSONObject obj = new JSONObject(result); - final String jsonString = obj.toString(); + final String policyData = obj.toString(); - StatementList update = new StatementList(); - StatementElement st0 = new StatementElement("name", "=", name, ""); - update.addStatement(st0); - StatementElement st2 = new StatementElement("policyData", "=", jsonString, ""); - update.addStatement(st2); - StatementList constraint = new StatementList(); - StatementElement st3 = new StatementElement("name", "=", name, ""); - constraint.addStatement(st3); - if (dataStore.getPolicyDao().updateObject(update, constraint)) resp.setStatus(200); + if (dataStore.getPolicyDao().updateObject(name, policyData)) resp.setStatus(200); else resp.sendError(500, "could not update the group's name!"); } @@ -102,10 +70,10 @@ public class PolicyServlet extends HttpServlet { protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException { String name = req.getParameter("name"); - StatementElement statementElement = new StatementElement("name", "=", name, ""); - StatementList constraint = new StatementList(); - constraint.addStatement(statementElement); - if (dataStore.getPolicyDao().deleteObject(constraint)) resp.setStatus(200); + if (dataStore.getPolicyDao().deleteObject(name)) { + resp.setStatus(200); + return; + } resp.sendError(500, "Could not delete the blueprint successfully!"); } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java index 6a9462a31b1881d6270ea901f1555ae780195b77..ab32114b5eca71bb68a98e72c81b357fa0e0ca02 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java @@ -13,8 +13,6 @@ import lombok.extern.slf4j.Slf4j; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.UserGroupMapping; @@ -22,6 +20,7 @@ import org.json.JSONObject; import java.io.IOException; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; @WebServlet("/api/admin/group/members/*") @@ -47,13 +46,7 @@ public class UserGroupServlet extends HttpServlet { String groupId = req.getPathInfo().replace("/", ""); - StatementList statementList = new StatementList(); - StatementElement st = new StatementElement("groupId", "=", groupId, ""); - - statementList.addStatement(st); - - List<UserGroupMapping> result = - dataStore.getUserGroupMappingsDao().getObjects(statementList); + List<UserGroupMapping> result = dataStore.getUserGroupMappingsDao().getByGroupId(groupId); if (result.isEmpty()) resp.sendError(404, "No users found for this group!"); else { @@ -77,17 +70,15 @@ public class UserGroupServlet extends HttpServlet { String username = obj.getString("username"); - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("groupId", "=", groupId, "AND")); - statementList.addStatement(new StatementElement("username", "=", username, "")); + Optional<UserGroupMapping> existingMapping = + dataStore.getUserGroupMappingsDao().getByGroupIdAndUsername(groupId, username); - if (!dataStore.getUserGroupMappingsDao().getObjects(statementList).isEmpty()) { + if (existingMapping.isPresent()) { resp.sendError(409, "The user already part of the group!"); return; } UserGroupMapping mapping = new UserGroupMapping(); - mapping.setGroupId(groupId); mapping.setUsername(username); @@ -111,13 +102,7 @@ public class UserGroupServlet extends HttpServlet { String username = obj.getString("username"); - StatementElement statementElement1 = new StatementElement("username", "=", username, "AND"); - StatementElement statementElement2 = new StatementElement("groupId", "=", groupId, ""); - - StatementList constraint = new StatementList(); - constraint.addStatement(statementElement1); - constraint.addStatement(statementElement2); - if (dataStore.getUserGroupMappingsDao().deleteObject(constraint)) { + if (dataStore.getUserGroupMappingsDao().deleteObject(username, groupId)) { resp.setStatus(200); } else { resp.sendError(500, "Could not delete mapping between user and group!"); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java index 8dfbdba37f6283c98c0f3a8c0a12fae149da71f8..796e78d560f5eb2f4c07c3e53121aa81a9f2d63b 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java @@ -13,8 +13,6 @@ import lombok.extern.slf4j.Slf4j; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.UserGroupMapping; @@ -45,13 +43,7 @@ public class UserGroupsServlet extends HttpServlet { String username = req.getPathInfo().replace("/", ""); - StatementList statementList = new StatementList(); - StatementElement st = new StatementElement("username", "=", username, ""); - - statementList.addStatement(st); - - List<UserGroupMapping> result = - dataStore.getUserGroupMappingsDao().getObjects(statementList); + List<UserGroupMapping> result = dataStore.getUserGroupMappingsDao().getByUsername(username); if (result.isEmpty()) resp.sendError(404, "No groups found for this user!"); else { diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java index ee33defd64935b43326ebff7442ace41e10c0e53..0e7ab354f88edb78224595565f7bc4ba7c979ac1 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java @@ -39,8 +39,6 @@ import net.jami.jams.authmodule.PasswordUtil; import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.annotations.ScopedServletMethod; import net.jami.jams.common.authentication.AuthenticationSourceType; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.devices.Device; import net.jami.jams.common.objects.responses.DeviceRevocationResponse; import net.jami.jams.common.objects.user.AccessLevel; @@ -49,11 +47,14 @@ import net.jami.jams.server.core.workflows.RevokeDeviceFlow; import net.jami.jams.server.core.workflows.RevokeUserFlow; import org.apache.commons.codec.binary.Base64; +import org.bouncycastle.cert.X509CRLEntryHolder; +import org.bouncycastle.cert.X509CRLHolder; import org.json.JSONObject; import java.io.IOException; import java.util.HashMap; import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -64,48 +65,37 @@ public class UserServlet extends HttpServlet { @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) @JsonContent protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - StatementList statementList = new StatementList(); - StatementElement st1 = - new StatementElement("username", "=", req.getParameter("username"), ""); - statementList.addStatement(st1); - if (!dataStore.getUserDao().getObjects(statementList).isEmpty()) { - User user = dataStore.getUserDao().getObjects(statementList).get(0); - if (certificateAuthority.getLatestCRL().get() != null) - user.setRevoked( - certificateAuthority - .getLatestCRL() - .get() - .getRevokedCertificate( - user.getCertificate().getSerialNumber()) - != null); - else user.setRevoked(false); - if (!user.getNeedsPasswordReset() && req.getParameter("needPW") != null) { - String pw = - PasswordUtil.hashPassword( - req.getParameter("password"), Base64.decodeBase64(user.getSalt())); - StatementList update = new StatementList(); - StatementElement st0 = new StatementElement("password", "=", pw, ""); - update.addStatement(st0); - StatementList constraint = new StatementList(); - StatementElement st = - new StatementElement("username", "=", req.getParameter("username"), ""); - constraint.addStatement(st); - StatementElement st2 = new StatementElement("needsPasswordReset", "=", "true", ""); - update.addStatement(st2); - // refresh variable - dataStore.getUserDao().updateObject(update, constraint); - user = dataStore.getUserDao().getObjects(statementList).get(0); - } - user.setPassword(""); - user.setSalt(""); - resp.getOutputStream().write(JsonStream.serialize(user).getBytes()); - resp.setStatus(200); - } else { + String username = req.getParameter("username"); + Optional<User> result = dataStore.getUserDao().getByUsername(username); + if (result.isEmpty()) { resp.sendError(404, "Could not obtain user!"); } + + User user = result.get(); + X509CRLHolder crl = certificateAuthority.getLatestCRL().get(); + if (crl != null) { + X509CRLEntryHolder revoked = + crl.getRevokedCertificate(user.getCertificate().getSerialNumber()); + user.setRevoked(revoked != null); + } else { + user.setRevoked(false); + } + + if (!user.getNeedsPasswordReset() && req.getParameter("needPW") != null) { + String pw = req.getParameter("password"); + String password = PasswordUtil.hashPassword(pw, Base64.decodeBase64(user.getSalt())); + dataStore.getUserDao().updateObject(password, username); + + user = dataStore.getUserDao().getByUsername(username).get(); + } + user.setPassword(""); + user.setSalt(""); + resp.getOutputStream().write(JsonStream.serialize(user).getBytes()); + resp.setStatus(200); } - // Create an internal user - this is always technically available, because internal users have - // the right to exist. + + // Create an internal user - this is always technically available, because + // internal users have the right to exist. @Override @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) @JsonContent @@ -116,29 +106,39 @@ public class UserServlet extends HttpServlet { req.getReader() .lines() .collect(Collectors.joining(System.lineSeparator()))); - String pw = obj.getString("password"); - if (!pw.isEmpty()) { - User user = new User(); - user.setUsername(obj.getString("username")); - user.setNeedsPasswordReset(true); - byte[] salt = PasswordUtil.generateSalt(); - pw = PasswordUtil.hashPassword(pw, salt); - user.setPassword(pw); - user.setSalt(Base64.encodeBase64String(salt)); - user.setRealm("LOCAL"); - user.setUserType(AuthenticationSourceType.LOCAL); - if (userAuthenticationModule.createUser( - user.getUserType(), user.getRealm(), nameServer, user)) { - HashMap<String, String> statusInfo = new HashMap<>(); - statusInfo.put("password", pw); - resp.getOutputStream().write(JsonStream.serialize(statusInfo).getBytes()); - resp.setStatus(200); - return; - } + + String password = obj.getString("password"); + + if (password.isEmpty()) { + resp.sendError(400, "Password is empty!"); + return; + } + + byte[] salt = PasswordUtil.generateSalt(); + String hashedPassword = PasswordUtil.hashPassword(password, salt); + + String username = obj.getString("username"); + + User user = new User(); + user.setUsername(username); + user.setNeedsPasswordReset(true); + user.setPassword(hashedPassword); + user.setSalt(Base64.encodeBase64String(salt)); + user.setRealm("LOCAL"); + user.setUserType(AuthenticationSourceType.LOCAL); + + if (userAuthenticationModule.createUser( + user.getUserType(), user.getRealm(), nameServer, user)) { + HashMap<String, String> statusInfo = new HashMap<>(); + statusInfo.put("password", hashedPassword); + resp.getOutputStream().write(JsonStream.serialize(statusInfo).getBytes()); + resp.setStatus(200); + return; } resp.sendError(500, "Could not create a user successfully!"); } + // Update user data. @Override @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) @@ -151,17 +151,17 @@ public class UserServlet extends HttpServlet { String pw = obj.getString("password"); String username = obj.getString("username"); - StatementList statementList = new StatementList(); - StatementElement st0 = new StatementElement("username", "=", username, ""); - statementList.addStatement(st0); - if (dataStore.getUserDao().getObjects(statementList).isEmpty()) { + Optional<User> result = dataStore.getUserDao().getByUsername(username); + + if (result.isEmpty()) { resp.sendError(404, "User was not found!"); return; } - User user = dataStore.getUserDao().getObjects(statementList).get(0); + User user = result.get(); - // Check if he is AD/LDAP - then return a 403, because we can't set such password. + // Check if he is AD/LDAP - then return a 403, because we can't set such + // password. if (user.getUserType() != AuthenticationSourceType.LOCAL) { resp.sendError( 500, "The user is not a local user, therefore we cannot change his data!"); @@ -169,29 +169,22 @@ public class UserServlet extends HttpServlet { } byte[] salt = PasswordUtil.generateSalt(); - StatementList update = new StatementList(); - StatementElement st1 = - new StatementElement("password", "=", PasswordUtil.hashPassword(pw, salt), ""); - update.addStatement(st1); - StatementElement st2 = - new StatementElement("salt", "=", Base64.encodeBase64String(salt), ""); - update.addStatement(st2); - StatementList constraint = new StatementList(); - StatementElement st3 = new StatementElement("username", "=", username, ""); - constraint.addStatement(st3); - if (dataStore.getUserDao().updateObject(update, constraint)) resp.setStatus(200); + String password = PasswordUtil.hashPassword(pw, salt); + String encodedSalt = Base64.encodeBase64String(salt); + if (dataStore.getUserDao().updateObject(password, encodedSalt, username)) + resp.setStatus(200); else resp.sendError(500, "could not update the users's data field!"); } + // Revoke a user. @Override @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN}) protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String username = req.getParameter("username"); AtomicReference<DeviceRevocationResponse> devResponse = - new AtomicReference<>(RevokeUserFlow.revokeUser(req.getParameter("username"))); - StatementList statementList = new StatementList(); - StatementElement st1 = new StatementElement("owner", "=", req.getParameter("username"), ""); - statementList.addStatement(st1); - List<Device> devices = dataStore.getDeviceDao().getObjects(statementList); + new AtomicReference<>(RevokeUserFlow.revokeUser(username)); + List<Device> devices = dataStore.getDeviceDao().getByOwner(username); + if (certificateAuthority.getLatestCRL() != null) { devices.forEach( device -> { @@ -202,8 +195,7 @@ public class UserServlet extends HttpServlet { device.getCertificate().getSerialNumber()) == null) devResponse.set( - RevokeDeviceFlow.revokeDevice( - req.getParameter("username"), device.getDeviceId())); + RevokeDeviceFlow.revokeDevice(username, device.getDeviceId())); }); } if (devResponse.get() != null && devResponse.get().isSuccess()) { diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UsersServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UsersServlet.java index 6ec96c579e07c3100636c8d2bec21ecb76410872..a2f593cb3a575c9977d56f10d48219aa652c44c8 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UsersServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UsersServlet.java @@ -46,8 +46,6 @@ public class UsersServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getOutputStream() - .write( - JsonStream.serialize(dataStore.getUserDao().getObjects(null).get(0)) - .getBytes()); + .write(JsonStream.serialize(dataStore.getUserDao().getAll().get(0)).getBytes()); } } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java index 246332af817f7ad947f6e61e3a02a3aefd32bb3b..1eb9d414f3cf744889f11f38b9e31ff4bc930496 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/contacts/ContactServlet.java @@ -33,8 +33,6 @@ import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.contacts.Contact; import net.jami.jams.common.serialization.tomcat.TomcatCustomErrorHandler; import net.jami.jams.common.utils.ContactMerger; @@ -42,7 +40,6 @@ import net.jami.jams.common.utils.ContactMerger; import org.json.JSONObject; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Scanner; @@ -64,10 +61,8 @@ public class ContactServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - StatementList statementList = new StatementList(); - statementList.addStatement( - new StatementElement("owner", "=", req.getAttribute("username").toString(), "")); - List<Contact> contactList = dataStore.getContactDao().getObjects(statementList); + String username = req.getAttribute("username").toString(); + List<Contact> contactList = dataStore.getContactDao().getByOwner(username); resp.getOutputStream().write(JsonStream.serialize(contactList).getBytes()); } @@ -90,20 +85,21 @@ public class ContactServlet extends HttpServlet { Scanner s = new Scanner(req.getInputStream()).useDelimiter("\\A"); String res = s.hasNext() ? s.next() : ""; final JSONObject obj = new JSONObject(res); - Contact contact = new Contact(); + // TODO: Replace with mergetool. + Contact contact = new Contact(); contact.setDisplayName(obj.get("displayName").toString()); contact.setTimestamp(System.currentTimeMillis() / 1000); contact.setStatus('A'); contact.setOwner(req.getAttribute("username").toString()); contact.setUri(obj.get("uri").toString()); - StatementList statementList = new StatementList(); - statementList.addStatement( - new StatementElement("owner", "=", req.getAttribute("username").toString(), "")); - List<Contact> localList = dataStore.getContactDao().getObjects(statementList); - List<Contact> remoteList = new ArrayList<>(); - remoteList.add(contact); + + String owner = req.getAttribute("username").toString(); + List<Contact> localList = dataStore.getContactDao().getByOwner(owner); + + List<Contact> remoteList = List.of(contact); List<Contact> result = ContactMerger.mergeContacts(localList, remoteList); + if (dataStore.getContactDao().storeContactList(result)) resp.setStatus(200); else TomcatCustomErrorHandler.sendCustomError( @@ -124,22 +120,10 @@ public class ContactServlet extends HttpServlet { @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - StatementList statementList = new StatementList(); - statementList.addStatement( - new StatementElement("owner", "=", req.getAttribute("username").toString(), "AND")); - statementList.addStatement(new StatementElement("uri", "=", req.getParameter("uri"), "")); - /* - * List<Contact> remoteList = - * dataStore.getContactDao().getObjects(statementList); - * remoteList.get(0).setStatus('D'); - * remoteList.get(0).setTimestamp(System.currentTimeMillis()); statementList = - * new StatementList(); statementList.addStatement(new - * StatementElement("owner","=",req.getAttribute("username").toString(),"")); - * List<Contact> localList = - * dataStore.getContactDao().getObjects(statementList); List<Contact> result = - * ContactMerger.mergeContacts(localList,remoteList); - */ - if (dataStore.getContactDao().deleteObject(statementList)) resp.setStatus(200); + String owner = req.getAttribute("username").toString(); + String uri = req.getParameter("uri"); + + if (dataStore.getContactDao().deleteObject(owner, uri)) resp.setStatus(200); else TomcatCustomErrorHandler.sendCustomError( resp, 500, "could not delete a contact due to server-side error"); @@ -162,16 +146,16 @@ public class ContactServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - StatementList statementList = new StatementList(); - statementList.addStatement( - new StatementElement("owner", "=", req.getAttribute("username").toString(), "")); - List<Contact> localList = dataStore.getContactDao().getObjects(statementList); + String owner = req.getAttribute("username").toString(); + List<Contact> localList = dataStore.getContactDao().getByOwner(owner); List<Contact> remoteList = Arrays.asList( JsonIterator.deserialize( req.getInputStream().readAllBytes(), Contact[].class)); - remoteList.forEach(contact -> contact.setOwner(req.getAttribute("username").toString())); + + remoteList.forEach(contact -> contact.setOwner(owner)); List<Contact> result = ContactMerger.mergeContacts(localList, remoteList); + if (!dataStore.getContactDao().storeContactList(result)) TomcatCustomErrorHandler.sendCustomError(resp, 500, "Could not store contacts!"); else resp.getOutputStream().write(JsonStream.serialize(result).getBytes()); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DeviceServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DeviceServlet.java index f812e639344b3f0d05f2bf686384fd4510328c12..aa3031ec1569fba03b83a6eb8933493914e68f5d 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DeviceServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DeviceServlet.java @@ -37,8 +37,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.jami.jams.common.annotations.ScopedServletMethod; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.devices.Device; import net.jami.jams.common.objects.requests.DeviceRegistrationRequest; import net.jami.jams.common.objects.responses.DeviceRegistrationResponse; @@ -76,12 +74,10 @@ public class DeviceServlet extends HttpServlet { throws ServletException, IOException { String username = req.getAttribute("username").toString(); String deviceId = req.getPathInfo().replace("/", ""); - StatementList statementList = new StatementList(); - StatementElement st1 = new StatementElement("owner", "=", username, "AND"); - StatementElement st2 = new StatementElement("deviceId", "=", deviceId, ""); - statementList.addStatement(st1); - statementList.addStatement(st2); - Device device = dataStore.getDeviceDao().getObjects(statementList).get(0); + + Device device = + dataStore.getDeviceDao().getByDeviceIdAndOwner(deviceId, username).orElseThrow(); + if (certificateAuthority.getLatestCRL().get() != null) device.setRevoked( certificateAuthority @@ -123,11 +119,14 @@ public class DeviceServlet extends HttpServlet { @Override @ScopedServletMethod(securityGroups = {AccessLevel.USER}) protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + Gson gson = new Gson(); + String username = req.getAttribute("username").toString(); + DeviceRegistrationRequest request = JsonIterator.deserialize( req.getInputStream().readAllBytes(), DeviceRegistrationRequest.class); DeviceRegistrationResponse devResponse = - RegisterDeviceFlow.registerDevice(req.getAttribute("username").toString(), request); + RegisterDeviceFlow.registerDevice(username, request); if (devResponse == null) { TomcatCustomErrorHandler.sendCustomError( @@ -135,7 +134,6 @@ public class DeviceServlet extends HttpServlet { return; } - Gson gson = new Gson(); String filteredJson = gson.toJson(devResponse); JsonObject obj = gson.fromJson(filteredJson, JsonObject.class); @@ -204,15 +202,9 @@ public class DeviceServlet extends HttpServlet { String username = req.getAttribute("username").toString(); String deviceId = req.getPathInfo().replace("/", ""); String deviceName = req.getParameter("deviceName"); - StatementList update = new StatementList(); - StatementElement st0 = new StatementElement("deviceName", "=", deviceName, ""); - update.addStatement(st0); - StatementList constraint = new StatementList(); - StatementElement st1 = new StatementElement("owner", "=", username, "AND"); - StatementElement st2 = new StatementElement("deviceId", "=", deviceId, ""); - update.addStatement(st1); - update.addStatement(st2); - if (dataStore.getDeviceDao().updateObject(update, constraint)) resp.setStatus(200); + + if (dataStore.getDeviceDao().updateObject(deviceName, username, deviceId)) + resp.setStatus(200); else TomcatCustomErrorHandler.sendCustomError( resp, 500, "could not update device information due to server-side error"); @@ -235,20 +227,20 @@ public class DeviceServlet extends HttpServlet { throws ServletException, IOException { String deviceId = req.getPathInfo().replace("/", ""); // If the device does not belong to the user throw a 403 - StatementList statementList = new StatementList(); - StatementElement statementElement = - new StatementElement("owner", "=", req.getAttribute("username").toString(), ""); - statementList.addStatement(statementElement); - if (dataStore.getDeviceDao().getObjects(statementList).stream() + String owner = req.getAttribute("username").toString(); + + long deviceIdCount = + dataStore.getDeviceDao().getByOwner(owner).stream() .filter(device -> device.getDeviceId().equals(deviceId)) - .count() - == 0) { + .count(); + + if (deviceIdCount == 0) { TomcatCustomErrorHandler.sendCustomError( resp, 403, "You do not have sufficient rights to revoke this device!"); return; } - DeviceRevocationResponse devResponse = - RevokeDeviceFlow.revokeDevice(req.getAttribute("username").toString(), deviceId); + + DeviceRevocationResponse devResponse = RevokeDeviceFlow.revokeDevice(owner, deviceId); if (devResponse != null) resp.getOutputStream().write(JsonStream.serialize(devResponse).getBytes()); else diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DevicesServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DevicesServlet.java index e99fa20378cce9f2bbf15c92f8ca60b87d963056..e8af8c4bd29ada6bc37d8d625e19e69cab528015 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DevicesServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/device/DevicesServlet.java @@ -33,8 +33,6 @@ import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.devices.Device; import java.io.IOException; @@ -64,9 +62,7 @@ public class DevicesServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getAttribute("username").toString(); - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("owner", "=", username, "")); - List<Device> devices = dataStore.getDeviceDao().getObjects(statementList); + List<Device> devices = dataStore.getDeviceDao().getByOwner(username); if (certificateAuthority.getLatestCRL() != null) { devices.forEach( device -> { diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java index 365723c062ed6fa8bdc987150fb7ecb0e6320650..281f0d1c6045d7f52220ce2a58f5aea8e4c40086 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java @@ -32,11 +32,11 @@ import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import lombok.extern.slf4j.Slf4j; + import net.jami.jams.common.authentication.AuthenticationSourceType; import net.jami.jams.common.authmodule.AuthModuleKey; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.User; import net.jami.jams.common.objects.user.UserProfile; @@ -203,11 +203,7 @@ public class DirectoryEntryServlet extends HttpServlet { String jamiId = req.getParameter("jamiId"); if (jamiId != null) { - StatementList statementList = new StatementList(); - StatementElement statementElement = - new StatementElement("jamiId", "=", jamiId, null); - statementList.addStatement(statementElement); - User user = dataStore.getUserDao().getObjects(statementList).get(0); + User user = dataStore.getUserDao().getByJamiId(jamiId).get(0); List<UserProfile> userProfiles = new ArrayList<>(); userAuthenticationModule .getAuthSources() diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java index 4319ce71f1ff86163c307523caec210d534619f8..ce82b41f233ef87b9977027841cd1d0f99145ce0 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java @@ -40,14 +40,10 @@ import net.jami.jams.common.annotations.JsonContent; import net.jami.jams.common.authentication.AuthenticationSource; import net.jami.jams.common.authentication.AuthenticationSourceType; import net.jami.jams.common.authmodule.AuthModuleKey; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; -import net.jami.jams.common.objects.user.Group; import net.jami.jams.common.objects.user.Policy; import net.jami.jams.common.objects.user.PolicyData; import net.jami.jams.common.objects.user.User; -import net.jami.jams.common.objects.user.UserGroupMapping; import net.jami.jams.common.objects.user.UserProfile; import org.json.JSONObject; @@ -71,50 +67,31 @@ public class SearchDirectoryServlet extends HttpServlet { // requires changes on the name server as well. List<UserProfile> userProfiles = new ArrayList<>(); - /** - * - */ @Override @JsonContent protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String pageParam = req.getParameter("page"); Optional<Integer> page; - if (req.getParameter("page") == null) page = Optional.empty(); - else page = Optional.ofNullable(Integer.parseInt(req.getParameter("page"))); + if (pageParam == null) page = Optional.empty(); + else page = Optional.ofNullable(Integer.parseInt(pageParam)); ConcurrentHashMap<AuthModuleKey, AuthenticationSource> authSources = new ConcurrentHashMap<>(userAuthenticationModule.getAuthSources()); // Check if the actual user is allowed to lookup in the directory - Group group = new Group(); - StatementList statementList1 = new StatementList(); - - statementList1.addStatement( - new StatementElement("username", "=", req.getAttribute("username").toString(), "")); - List<UserGroupMapping> mappings = - dataStore.getUserGroupMappingsDao().getObjects(statementList1); - if (mappings != null && !mappings.isEmpty()) { - statementList1 = new StatementList(); - statementList1.addStatement( - new StatementElement("id", "=", mappings.get(0).getGroupId(), "")); - group = dataStore.getGroupDao().getObjects(statementList1).get(0); - } + String username = req.getAttribute("username").toString(); + + try { + Policy policy = dataStore.getPolicyDao().getByUsername(username).orElseThrow(); + PolicyData policyData = + JsonIterator.deserialize(policy.getPolicyData(), PolicyData.class); - if (!group.isEmpty() && group.hasBlueprint()) { - StatementElement st2 = new StatementElement("name", "=", group.getBlueprint(), ""); - StatementList statementList2 = new StatementList(); - statementList2.addStatement((st2)); - try { - Policy policy = dataStore.getPolicyDao().getObjects(statementList2).get(0); - PolicyData policyData = - JsonIterator.deserialize(policy.getPolicyData(), PolicyData.class); - if (!policyData.getAllowLookup()) { - resp.sendError(403, "Operation not allowed!"); - return; - } - } catch (Exception e1) { - log.warn( - "No policy available for user - not adding a policy component to response"); + if (!policyData.getAllowLookup()) { + resp.sendError(403, "Operation not allowed!"); + return; } + } catch (Exception e1) { + log.warn("No policy available for user - not adding a policy component to response"); } if (authSources.size() > 1) { @@ -124,51 +101,42 @@ public class SearchDirectoryServlet extends HttpServlet { }); } + String queryString = req.getParameter("queryString"); + authSources.forEach( (k, v) -> { - if (req.getParameter("queryString").equals("*")) - userProfiles = - v.searchUserProfiles( - req.getParameter("queryString"), "FULL_TEXT_NAME", page); - else { - userProfiles = - v.searchUserProfiles( - req.getParameter("queryString"), "FULL_TEXT_NAME", page); - if (userProfiles.isEmpty() - && userProfiles.addAll( - v.searchUserProfiles( - req.getParameter("queryString"), - "LOGON_NAME", - page))) { - Set<UserProfile> s = - new TreeSet<UserProfile>( - new Comparator<UserProfile>() { - @Override - public int compare(UserProfile o1, UserProfile o2) { - if (o1.getUsername().equals(o2.getUsername())) - return 0; - return 1; - } - }); - s.addAll(userProfiles); - userProfiles = new ArrayList<>(s); - } + if (queryString.equals("*")) { + userProfiles = v.searchUserProfiles(queryString, "FULL_TEXT_NAME", page); + } + userProfiles = v.searchUserProfiles(queryString, "FULL_TEXT_NAME", page); + if (userProfiles.isEmpty() + && userProfiles.addAll( + v.searchUserProfiles(queryString, "LOGON_NAME", page))) { + Set<UserProfile> s = + new TreeSet<UserProfile>( + new Comparator<UserProfile>() { + @Override + public int compare(UserProfile o1, UserProfile o2) { + if (o1.getUsername().equals(o2.getUsername())) + return 0; + return 1; + } + }); + s.addAll(userProfiles); + userProfiles = new ArrayList<>(s); } userProfiles.parallelStream() .forEach( profile -> { - StatementList statementList = new StatementList(); - StatementElement statementElement = - new StatementElement( - "username", "=", profile.getUsername(), ""); - statementList.addStatement(statementElement); List<User> results = new ArrayList<>(); - while (results.size() == 0) { + while (results.isEmpty()) { results = dataStore .getUserDao() - .getObjects(statementList); - if (results.size() == 0) { + .getByUsername(profile.getUsername()) + .map(user -> List.of(user)) + .orElseGet(() -> List.of()); + if (results.isEmpty()) { User user = new User(); user.setUsername(profile.getUsername()); user.setRealm(k.getRealm()); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/policyData/PolicyDataServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/policyData/PolicyDataServlet.java index ff01dd9289e307c648e5705a759037a0aa09c9bf..c23770a95e81f07d15093a7ad9573fd7ea9f2ce1 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/policyData/PolicyDataServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/policyData/PolicyDataServlet.java @@ -25,7 +25,6 @@ import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import net.jami.jams.common.objects.user.Group; import net.jami.jams.common.serialization.tomcat.TomcatCustomErrorHandler; import net.jami.jams.server.core.workflows.RegisterDeviceFlow; import net.jami.jams.server.servlets.api.auth.device.DeviceServlet; @@ -69,8 +68,7 @@ public class PolicyDataServlet extends HttpServlet { throws ServletException, IOException { String username = req.getAttribute("username").toString(); - Group group = RegisterDeviceFlow.getGroupByUsername(username); - String policyData = RegisterDeviceFlow.getPolicyData(group); + String policyData = RegisterDeviceFlow.getPolicyData(username); if (policyData == null) { TomcatCustomErrorHandler.sendCustomError( diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java index 4fb2a126ffd955304798c0bf795272ae655b14fe..c0e76bba33d4b456b1379f078eaa7972a96cc87e 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java @@ -35,12 +35,11 @@ import jakarta.servlet.http.HttpServletResponse; import net.jami.jams.common.annotations.ScopedServletMethod; import net.jami.jams.common.authentication.AuthenticationSourceType; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.User; import java.io.IOException; +import java.util.Optional; @WebServlet("/api/auth/user") public class UserServlet extends HttpServlet { @@ -74,24 +73,24 @@ public class UserServlet extends HttpServlet { @ScopedServletMethod(securityGroups = {AccessLevel.USER}) protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - StatementList statementList = new StatementList(); - StatementElement st = - new StatementElement("username", "=", req.getAttribute("username").toString(), ""); - statementList.addStatement(st); - if (!dataStore.getUserDao().getObjects(statementList).isEmpty()) { - User user = dataStore.getUserDao().getObjects(statementList).get(0); - if (certificateAuthority.getLatestCRL().get() != null) { - user.setRevoked( - certificateAuthority - .getLatestCRL() - .get() - .getRevokedCertificate( - user.getCertificate().getSerialNumber()) - != null); - } else user.setRevoked(false); - resp.setStatus(200); - resp.getOutputStream().write(JsonStream.serialize(user).getBytes()); - } else resp.sendError(404, "User was not found!"); + String username = req.getAttribute("username").toString(); + Optional<User> result = dataStore.getUserDao().getByUsername(username); + if (result.isEmpty()) { + resp.sendError(404, "User was not found!"); + return; + } + + User user = result.get(); + if (certificateAuthority.getLatestCRL().get() != null) { + user.setRevoked( + certificateAuthority + .getLatestCRL() + .get() + .getRevokedCertificate(user.getCertificate().getSerialNumber()) + != null); + } else user.setRevoked(false); + resp.setStatus(200); + resp.getOutputStream().write(JsonStream.serialize(user).getBytes()); } // The user can update 3 fields: password,privatekey,publickey @@ -110,24 +109,18 @@ public class UserServlet extends HttpServlet { @ScopedServletMethod(securityGroups = AccessLevel.USER) protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { String username = req.getAttribute("username").toString(); + // Check if he is AD/LDAP - then return a 403, because we can't set such password. - StatementList select = new StatementList(); - StatementElement st = new StatementElement("username", "=", username, ""); - select.addStatement(st); - if (dataStore.getUserDao().getObjects(select).get(0).getUserType() - != AuthenticationSourceType.LOCAL) { + User user = dataStore.getUserDao().getByUsername(username).orElseThrow(); + if (user.getUserType() != AuthenticationSourceType.LOCAL) { resp.sendError( 403, "The user is not a local user, therefore we cannot change his data!"); return; } - StatementList update = new StatementList(); - StatementElement st0 = - new StatementElement("password", "=", req.getParameter("password"), ""); - update.addStatement(st0); - StatementList constraint = new StatementList(); - StatementElement st1 = new StatementElement("username", "=", username, ""); - constraint.addStatement(st1); - if (dataStore.getUserDao().updateObject(update, constraint)) resp.setStatus(200); + + String password = req.getParameter("password"); + + if (dataStore.getUserDao().updateObject(password, username)) resp.setStatus(200); else resp.sendError(500, "could not update the users's data field!"); } } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java index 72b2cc1135cabdb26328e546ea401349ea60b4c7..0240bb3b33f82a26281ee39ca41066240c3a005c 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java @@ -60,11 +60,12 @@ public class StartInstallServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Here we must decide which page to show - login or sign-up - if (dataStore != null - && dataStore.getUserDao() != null - && !dataStore.getUserDao().getObjects(null).isEmpty()) - resp.setHeader("showLogin", "true"); - else resp.setHeader("showLogin", "false"); + boolean showLogin = + dataStore != null + && dataStore.getUserDao() != null + && !dataStore.getUserDao().getAll().isEmpty(); + + resp.setHeader("showLogin", showLogin ? "true" : "false"); } @Override @@ -89,7 +90,7 @@ public class StartInstallServlet extends HttpServlet { @JsonContent protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - if (dataStore.getUserDao().getObjects(null).size() != 0) { + if (!dataStore.getUserDao().getAll().isEmpty()) { resp.sendError( 500, "We have tried to create an administrative account where one already exists!"); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/DApiFilter.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/DApiFilter.java index 6fc069c75e9c58c29a19df7159e05b48a73c3a0e..d4515409fdac36802bb49d06f1e399aa0c601b39 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/DApiFilter.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/DApiFilter.java @@ -42,7 +42,8 @@ import net.jami.jams.server.Server; import java.io.IOException; /** - * Since we have the @ScopedServletMethod annotation, the admin filter became absolutely useless + * Since we have the @ScopedServletMethod annotation, the admin filter became + * absolutely useless * as we can simply scope things. */ @WebFilter(urlPatterns = {"/api/auth/*", "/api/admin/*"}) @@ -56,23 +57,25 @@ public class DApiFilter implements Filter { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; response.setContentType("application/json;charset=UTF-8"); + if (!Server.isInstalled.get()) { TomcatCustomErrorHandler.sendCustomError( response, 404, "Setup has not yet been completed!"); - } else { - boolean authsuccess = false; - boolean isLogin = false; - boolean isOCSPCheck = false; + return; + } - if (request.getServletPath().contains("login")) isLogin = true; - else if (request.getServletPath().contains("ocsp")) isOCSPCheck = true; - else authsuccess = doAuthCheck(request); - if (authsuccess || isLogin || isOCSPCheck) { - filterChain.doFilter(servletRequest, servletResponse); - } else { - TomcatCustomErrorHandler.sendCustomError( - response, 401, "You are not authenticated!"); - } + boolean authsuccess = false; + boolean isLogin = false; + boolean isOCSPCheck = false; + + if (request.getServletPath().contains("login")) isLogin = true; + else if (request.getServletPath().contains("ocsp")) isOCSPCheck = true; + else authsuccess = doAuthCheck(request); + if (authsuccess || isLogin || isOCSPCheck) { + filterChain.doFilter(servletRequest, servletResponse); + return; } + + TomcatCustomErrorHandler.sendCustomError(response, 401, "You are not authenticated!"); } } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/FilterUtils.java b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/FilterUtils.java index 7bdab5d79f7b8580c4be73d711aadbcb7183c201..5ba99ad955645c0ea97a5cb355130273c04596e8 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/filters/FilterUtils.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/filters/FilterUtils.java @@ -35,8 +35,6 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.AccessLevel; import net.jami.jams.common.objects.user.User; @@ -95,13 +93,12 @@ public class FilterUtils { default: return false; } - StatementList statementList = new StatementList(); - StatementElement statementElement = - new StatementElement("username", "=", token.getJWTClaimsSet().getSubject(), ""); - statementList.addStatement(statementElement); + + String username = token.getJWTClaimsSet().getSubject(); log.info("Getting user from database"); - User user = dataStore.getUserDao().getObjects(statementList).get(0); + User user = dataStore.getUserDao().getByUsername(username).orElseThrow(); log.info("User retrieved from database: {}", user); + if (!user.getAccessLevelName().equals("ADMIN") && certificateAuthority.getLatestCRL().get() != null) { if (certificateAuthority @@ -110,10 +107,12 @@ public class FilterUtils { .getRevokedCertificate(user.getCertificate().getSerialNumber()) != null) return false; } + JWSVerifier jwsVerifier = new RSASSAVerifier(userAuthenticationModule.getAuthModulePubKey()); + if (token.verify(jwsVerifier) && verifyValidity(token)) { - request.setAttribute(USERNAME_ATTR, token.getJWTClaimsSet().getSubject()); + request.setAttribute(USERNAME_ATTR, username); request.setAttribute( ACCESS_LEVEL_ATTR, AccessLevel.valueOf(token.getJWTClaimsSet().getClaim("scope").toString())); diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/x509/OCSPServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/x509/OCSPServlet.java index 165864a3810c6062c2453cb58d404126a4220d65..819d04ac9758f2f84b645ebfd56464f888df5e3c 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/x509/OCSPServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/x509/OCSPServlet.java @@ -30,8 +30,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.jami.jams.ca.JamsCA; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.devices.Device; import net.jami.jams.common.objects.user.User; @@ -63,8 +61,10 @@ public class OCSPServlet extends HttpServlet { String issuerId = req.getPathInfo().replace("/", ""); /* - * If there is no issue id we are dealing with a certificate signed byt the CA root - * Else the certificate is a device certificate signed by a user with and the issuerId is his Jami Id + * If there is no issue id we are dealing with a certificate signed byt the CA + * root + * Else the certificate is a device certificate signed by a user with and the + * issuerId is his Jami Id */ if (issuerId == "") { @@ -79,56 +79,32 @@ public class OCSPServlet extends HttpServlet { byte[] respBytes = response.getEncoded(); resp.getOutputStream().write(respBytes); } else resp.setStatus(404); - } else { - User targetUser = null; - StatementList userStatementsList = new StatementList(); - StatementElement usernameStatement = - new StatementElement("jamiId", "=", issuerId, ""); - userStatementsList.addStatement(usernameStatement); - - try { - targetUser = dataStore.getUserDao().getObjects(userStatementsList).get(0); - StatementList deviceStatementsList = new StatementList(); - StatementElement deviceOwnerStatement = - new StatementElement("owner", "=", targetUser.getUsername(), ""); - deviceStatementsList.addStatement(deviceOwnerStatement); - List<Device> devices = - dataStore.getDeviceDao().getObjects(deviceStatementsList); - - boolean deviceDoesNotExist = true; - for (Device d : devices) { - for (BigInteger id : ids) { - if (d.getCertificate().getSerialNumber().equals(id)) { - deviceDoesNotExist = false; - } - } - } - OCSPResp response = null; - - if (deviceDoesNotExist) { - response = - JamsCA.getOCSPResponse( - ocspReq, - targetUser.getCertificate(), - targetUser.getPrivateKey(), - true); - } else { - response = - JamsCA.getOCSPResponse( - ocspReq, - targetUser.getCertificate(), - targetUser.getPrivateKey(), - false); - } - if (response != null) { - byte[] respBytes = response.getEncoded(); - resp.getOutputStream().write(respBytes); - } else resp.setStatus(404); - } catch (Exception e) { - resp.sendError(404, "Could not find the requested certificate!"); + return; + } + + User targetUser = dataStore.getUserDao().getByJamiId(issuerId).get(0); + List<Device> devices = dataStore.getDeviceDao().getByOwner(targetUser.getUsername()); + + boolean deviceDoesNotExist = true; + for (Device d : devices) { + for (BigInteger id : ids) { + if (d.getCertificate().getSerialNumber().equals(id)) { + deviceDoesNotExist = false; + } } } + OCSPResp response = + JamsCA.getOCSPResponse( + ocspReq, + targetUser.getCertificate(), + targetUser.getPrivateKey(), + deviceDoesNotExist); + + if (response != null) { + byte[] respBytes = response.getEncoded(); + resp.getOutputStream().write(respBytes); + } else resp.setStatus(404); } catch (Exception e) { resp.sendError(404, "Could not find the requested certificate!"); diff --git a/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java b/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java index 465d71617c61ee95251dd8690cef41003c9ad60a..a34d7ed958ea4496b3159a59bab40bc2d84442a0 100644 --- a/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java +++ b/jams-server/src/main/java/net/jami/jams/server/startup/CryptoEngineLoader.java @@ -26,12 +26,10 @@ import lombok.extern.slf4j.Slf4j; import net.jami.datastore.main.DataStore; import net.jami.jams.common.cryptoengineapi.CertificateAuthority; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.system.SystemAccount; import net.jami.jams.common.utils.LibraryLoader; -import java.util.List; +import java.util.Optional; @Slf4j public class CryptoEngineLoader { @@ -42,22 +40,17 @@ public class CryptoEngineLoader { Class<?> cls = LibraryLoader.classLoader.loadClass("net.jami.jams.ca.JamsCA"); CertificateAuthority certificateAuthority = (CertificateAuthority) cls.getConstructor().newInstance(); - StatementList statementList = new StatementList(); - statementList.addStatement(new StatementElement("entity", "=", "CA", "")); - List<SystemAccount> accounts = dataStore.getSystemDao().getObjects(statementList); - if (accounts.size() == 0) { + + Optional<SystemAccount> accounts = dataStore.getSystemDao().getCA(); + + if (accounts.isEmpty()) { log.info( "This is an fresh install, and it has no CA or any system accounts - if there is a config.json" + " file in your directory, this means the install is broken and you should delete and restart!"); } else { - statementList = new StatementList(); - statementList.addStatement(new StatementElement("entity", "=", "CA", "")); - SystemAccount caAccount = dataStore.getSystemDao().getObjects(statementList).get(0); - statementList = new StatementList(); - statementList.addStatement(new StatementElement("entity", "=", "OCSP", "")); - SystemAccount ocspAccount = - dataStore.getSystemDao().getObjects(statementList).get(0); - log.info("Injecting OCSP and CA acocunts..."); + SystemAccount caAccount = accounts.orElseThrow(); + SystemAccount ocspAccount = dataStore.getSystemDao().getOCSP().orElseThrow(); + log.info("Injecting OCSP and CA accounts..."); certificateAuthority.init(config, caAccount, ocspAccount); } log.info( diff --git a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java index 84e023f30a3cb7f5693d3391772c37fe2db7a41e..56c177fa8b5eb24028b8aa12a7b0af6cfd24983b 100644 --- a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java +++ b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/service/UserProfileService.java @@ -27,8 +27,6 @@ import static net.jami.jams.server.Server.dataStore; import lombok.extern.slf4j.Slf4j; import net.jami.datastore.main.DataStore; -import net.jami.jams.common.dao.StatementElement; -import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.user.UserProfile; import net.jami.jams.ldap.connector.LDAPConnector; @@ -91,13 +89,7 @@ public class UserProfileService { .map(UserProfileService::profileFromResponse) .collect(Collectors.toList()); for (UserProfile p : profilesFromResponse) { - StatementList statementList = new StatementList(); - StatementElement st = - new StatementElement("username", "=", p.getUsername(), ""); - statementList.addStatement(st); - - if (dataStore.getUserProfileDao().getObjects(statementList).isEmpty()) - dataStore.getUserProfileDao().storeObject(p); + dataStore.getUserProfileDao().insertIfNotExists(p); } return profilesFromResponse; diff --git a/pom.xml b/pom.xml index f1d899b03cee7bef2a103717c6a2f1b53d6b4797..5aaff754c2b830478fb72fdecd827828e952e3d1 100644 --- a/pom.xml +++ b/pom.xml @@ -149,6 +149,12 @@ </includes> <followSymlinks>false</followSymlinks> </fileset> + <fileset> + <directory>coverage/</directory> + <includes> + <include>**</include> + </includes> + </fileset> </filesets> </configuration> </plugin>