/
setwind
/
olympiad
Обзор
Документация
Войти
/
setwind
/
olympiad
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/main/java/com/cfuv/olympus/web/security/FileAccessManager.java
94 строки
4 KB
setwind
test and groups view
05 май 2025, 15:35
05 май 2025, 15:35
8e680ac
Код
Авторство
О чём код?
package com.cfuv.olympus.web.security; import com.cfuv.olympus.entity.domain.user.Role; import com.cfuv.olympus.entity.dto.file.FileContent; import com.cfuv.olympus.entity.dto.file.FilePath; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.web.access.intercept.RequestAuthorizationContext; import org.springframework.stereotype.Component; import java.util.Collection; import java.util.Optional; import java.util.function.Supplier; @Slf4j @Component public class FileAccessManager implements AuthorizationManager<RequestAuthorizationContext> { @Override public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext object) { HttpServletRequest request = object.getRequest(); if (authentication.get().getPrincipal() instanceof UserSession user) { Optional<FilePath> parsed = parsePath(request); return parsed .filter(path -> (hasAdmin(user.getAuthorities()) || checkRolesAndAuthority(user, path))) .map(path -> new AuthorizationDecision(true)) .orElse(new AuthorizationDecision(false)); } return new AuthorizationDecision(false); } private boolean checkRolesAndAuthority(UserSession user, FilePath path) { final Collection<? extends GrantedAuthority> authorities = user.getAuthorities(); if (path.content().equals(FileContent.TEST)) return false; return isCurrentContest(user, path) && ((isNotUserTask(path)) || (hasJudge(authorities)) || (userIsAuthor(user, path))); } private boolean isNotUserTask(FilePath path) { return !path.content().equals(FileContent.USER_TASK); } private boolean userIsAuthor(UserSession user, FilePath path) { return user.getId().equals(path.taskNumber()); } private boolean hasJudge(Collection<? extends GrantedAuthority> authorities) { return hasRole(authorities, Role.ROLE_JUDGE); } private static boolean isCurrentContest(UserSession user, FilePath path) { return path.contestId().equals(user.getContestId()); } private Optional<FilePath> parsePath(HttpServletRequest request) { try { String[] uri = request.getRequestURI().replace("/api/v1/content/", "").split("/"); if (uri.length < 4) return Optional.empty(); FileContent content = FileContent.valueOf(uri[0]); Long contestId = Long.valueOf(uri[1]); Long taskNumber = Long.valueOf(uri[2]); Long idInContest = null; if (content.equals(FileContent.USER_TASK)) idInContest = Long.valueOf(uri[3]); return Optional.of(new FilePath(content, contestId, taskNumber, idInContest)); } catch (IllegalArgumentException e) { return Optional.empty(); } } private boolean hasAdmin(Collection<? extends GrantedAuthority> authorities) { return hasRole(authorities, Role.ROLE_ADMIN); } private static boolean hasRole(Collection<? extends GrantedAuthority> authorities, Role role) { return authorities.stream().map(GrantedAuthority::getAuthority).anyMatch(s -> s.equals(role.name())); } }