package it.inaf.ia2.gms.persistence; import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.persistence.model.PermissionEntity; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; @Component public class PermissionsDAO { private static final String PERMISSION_COLUMNS = "group_id, user_id, permission, group_path, update_time, set_by"; private final JdbcTemplate jdbcTemplate; @Autowired public PermissionsDAO(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); } public PermissionEntity createOrUpdatePermission(PermissionEntity userPermission) { String sql = "INSERT INTO gms_permission(group_id, user_id, permission, group_path, set_by) VALUES(?, ?, ?, ?, ?)\n" + "ON CONFLICT (group_id, user_id) DO UPDATE\n" + "SET permission = EXCLUDED.permission, set_by = EXCLUDED.set_by, update_time = NOW()"; jdbcTemplate.update(conn -> { int i = 0; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(++i, userPermission.getGroupId()); ps.setString(++i, userPermission.getUserId()); ps.setObject(++i, userPermission.getPermission().toString(), Types.OTHER); ps.setObject(++i, userPermission.getGroupPath(), Types.OTHER); ps.setString(++i, userPermission.getSetBy()); return ps; }); return userPermission; } public PermissionEntity updatePermission(PermissionEntity userPermission) { String sql = "UPDATE gms_permission SET permission = ?, set_by = ?, update_time = NOW() " + " WHERE group_id = ? AND user_id = ? AND group_path = ?"; jdbcTemplate.update(conn -> { int i = 0; PreparedStatement ps = conn.prepareStatement(sql); ps.setObject(++i, userPermission.getPermission().toString(), Types.OTHER); ps.setString(++i, userPermission.getSetBy()); ps.setString(++i, userPermission.getGroupId()); ps.setString(++i, userPermission.getUserId()); ps.setObject(++i, userPermission.getGroupPath(), Types.OTHER); return ps; }); return userPermission; } public List findUserPermissions(String userId) { String sql = "SELECT " + PERMISSION_COLUMNS + " FROM gms_permission WHERE user_id = ?"; return jdbcTemplate.query(conn -> { PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, userId); return ps; }, resultSet -> { return getPermissionsFromResultSet(resultSet); }); } /** * Finds all direct user permissions for a given parent path (returns also * all sub-groups permissions). */ public List findUserPermissions(String userId, String path) { String sql = "SELECT " + PERMISSION_COLUMNS + " FROM gms_permission WHERE user_id = ?\n" + "AND (group_path <@ ? OR group_path @> ?)"; return jdbcTemplate.query(conn -> { PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, userId); ps.setObject(2, path, Types.OTHER); ps.setObject(3, path, Types.OTHER); return ps; }, resultSet -> { return getPermissionsFromResultSet(resultSet); }); } public Optional findPermissionEntity(String groupId, String userId) { String sql = "SELECT " + PERMISSION_COLUMNS + " FROM gms_permission WHERE group_id = ? AND user_id = ?"; return jdbcTemplate.query(conn -> { PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, groupId); ps.setString(2, userId); return ps; }, resultSet -> { if (resultSet.next()) { return Optional.of(getPermissionEntityFromResultSet(resultSet)); } return Optional.empty(); }); } public List getGroupsPermissions(String groupId) { String sql = "SELECT " + PERMISSION_COLUMNS + " FROM gms_permission WHERE group_id = ?"; return jdbcTemplate.query(conn -> { PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, groupId); return ps; }, resultSet -> { return getPermissionsFromResultSet(resultSet); }); } private List getPermissionsFromResultSet(ResultSet resultSet) throws SQLException { List permissions = new ArrayList<>(); while (resultSet.next()) { permissions.add(getPermissionEntityFromResultSet(resultSet)); } return permissions; } private PermissionEntity getPermissionEntityFromResultSet(ResultSet resultSet) throws SQLException { PermissionEntity permission = new PermissionEntity(); permission.setGroupId(resultSet.getString("group_id")); permission.setUserId(resultSet.getString("user_id")); permission.setPermission(Permission.valueOf(resultSet.getString("permission"))); permission.setGroupPath(resultSet.getString("group_path")); permission.setSetBy(resultSet.getString("set_by")); permission.setUpdateTime(new Date(resultSet.getDate("update_time").getTime())); return permission; } public void deletePermission(String groupId, String userId) { String sql = "DELETE FROM gms_permission WHERE group_id = ? AND user_id = ?"; jdbcTemplate.update(conn -> { PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, groupId); ps.setString(2, userId); return ps; }); } public void deleteAllGroupsPermissions(List groupIds) { if (groupIds.isEmpty()) { return; } String sql = "DELETE FROM gms_permission WHERE group_id IN (" + String.join(",", groupIds.stream().map(g -> "?").collect(Collectors.toList())) + ")"; jdbcTemplate.update(conn -> { PreparedStatement ps = conn.prepareStatement(sql); int i = 0; for (String groupId : groupIds) { ps.setString(++i, groupId); } return ps; }); } }