/
kolivim
/
obmen
Обзор
Документация
Войти
/
kolivim
/
obmen
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
FULL___RoleService.java
128 строк
6 KB
kolivim
Create: FULL___RoleService.java
02 июл 2026, 21:24
Верифицирован
02 июл 2026, 21:24
a2d5afb
Код
Авторство
О чём код?
package com.example.admin.service; import com.example.admin.dto.RoleAssignmentRequest; import com.example.admin.model.RoleAssignment; import com.example.admin.repository.RoleAssignmentRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; import java.sql.*; import java.util.LinkedHashSet; import java.util.Set; @Service @RequiredArgsConstructor @Slf4j public class RoleService { private final RoleAssignmentRepository repository; private final DataSource dataSource; @Value("${admin.username}") private String validAdminUsername; @Value("${admin.password}") private String validAdminPassword; @Transactional public RoleAssignment assignRole(RoleAssignmentRequest request) { // 1. Проверка учётных данных администратора if (!validAdminUsername.equals(request.getAdminUsername())) { throw new IllegalArgumentException("Неверное имя администратора"); } if (!validAdminPassword.equals(request.getAdminPassword())) { throw new IllegalArgumentException("Неверный пароль администратора"); } // 2. Нормализация имён (Oracle чувствителен к регистру, обычно всё в верхнем) String roleName = request.getRoleName().trim().toUpperCase(); String targetUsername = request.getTargetUsername().trim().toUpperCase(); // 3. Проверка, что роль ещё не была назначена (по таблице аудита) if (repository.existsByRoleNameAndTargetUsername(roleName, targetUsername)) { throw new IllegalArgumentException( String.format("У пользователя '%s' уже есть роль '%s'", targetUsername, roleName)); } // 4. Работа с Oracle try (Connection connection = dataSource.getConnection()) { // 4.1 Выдача роли (с возможным WITH ADMIN OPTION) String grantSql; if (request.isAdminOption()) { grantSql = String.format("GRANT %s TO %s WITH ADMIN OPTION", roleName, targetUsername); } else { grantSql = String.format("GRANT %s TO %s", roleName, targetUsername); } try (Statement stmt = connection.createStatement()) { stmt.execute(grantSql); log.info("Выполнен GRANT: {}", grantSql); } // 4.2 Настройка DEFAULT ROLE, если требуется if (request.isDefaultRole()) { // Получаем текущие дефолтные роли пользователя Set<String> currentDefaults = getCurrentDefaultRoles(connection, targetUsername); log.info("Текущие дефолтные роли пользователя {}: {}", targetUsername, currentDefaults); // Добавляем новую роль к списку currentDefaults.add(roleName); // Формируем команду ALTER USER ... DEFAULT ROLE список_ролей String rolesList = String.join(", ", currentDefaults); String alterSql = String.format("ALTER USER %s DEFAULT ROLE %s", targetUsername, rolesList); try (Statement stmt = connection.createStatement()) { stmt.execute(alterSql); log.info("Обновлены дефолтные роли: {}", alterSql); } } else { log.info("Роль {} НЕ добавляется в дефолтные для {}", roleName, targetUsername); } } catch (SQLException e) { log.error("Ошибка выполнения операций в Oracle: {}", e.getMessage()); throw new RuntimeException("Ошибка базы данных: " + e.getMessage(), e); } // 5. Сохранение аудита RoleAssignment assignment = RoleAssignment.builder() .roleName(roleName) .targetUsername(targetUsername) .adminUsername(request.getAdminUsername().trim()) .defaultRole(request.isDefaultRole()) .adminOption(request.isAdminOption()) .build(); RoleAssignment saved = repository.save(assignment); log.info("Аудит: роль '{}' выдана пользователю '{}', default={}, adminOption={}", saved.getRoleName(), saved.getTargetUsername(), saved.isDefaultRole(), saved.isAdminOption()); return saved; } /** * Возвращает множество ролей, которые являются дефолтными для указанного пользователя. */ private Set<String> getCurrentDefaultRoles(Connection connection, String username) throws SQLException { Set<String> roles = new LinkedHashSet<>(); String query = "SELECT granted_role FROM dba_role_privs WHERE grantee = ? AND default_role = 'YES'"; try (PreparedStatement ps = connection.prepareStatement(query)) { ps.setString(1, username); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { roles.add(rs.getString("granted_role")); } } } return roles; } }