diff --git a/src/main/java/net/geant/nmaas/portal/api/auth/OIDCAuthController.java b/src/main/java/net/geant/nmaas/portal/api/auth/OIDCAuthController.java index df0071568b9ec3cac5f4b67f0b067124021d5ea1..526d2faad742b5ef8f4e711534c54aa2daf9adde 100644 --- a/src/main/java/net/geant/nmaas/portal/api/auth/OIDCAuthController.java +++ b/src/main/java/net/geant/nmaas/portal/api/auth/OIDCAuthController.java @@ -71,7 +71,7 @@ public class OIDCAuthController { ); throw new AuthenticationException(ae.getMessage()); } - checkUserApprovals(user); +// checkUserApprovals(user); if (configurationManager.getConfiguration().isMaintenance() && user.getRoles().stream().noneMatch(value -> value.getRole().equals(Role.ROLE_SYSTEM_ADMIN))) { diff --git a/src/main/java/net/geant/nmaas/portal/api/security/JWTTokenService.java b/src/main/java/net/geant/nmaas/portal/api/security/JWTTokenService.java index c63d712c4ca30753f48562f4a11deac2f9a44aa9..813a0fb209d63796ca882cac4eba8bfaa446c888 100644 --- a/src/main/java/net/geant/nmaas/portal/api/security/JWTTokenService.java +++ b/src/main/java/net/geant/nmaas/portal/api/security/JWTTokenService.java @@ -26,12 +26,11 @@ import java.util.stream.Collectors; @Slf4j public class JWTTokenService { - private JWTSettings jwtSettings; - private static final String SCOPES = "scopes"; - private static final String LANGUAGE = "language"; + private JWTSettings jwtSettings; + @Value("${domain.global:GLOBAL}") String globalDomain; @@ -47,16 +46,16 @@ public class JWTTokenService { if (user == null || StringUtils.isEmpty(user.getUsername())) { throw new IllegalArgumentException("User or username is not set"); } - if(user.getFirstname() != null && !user.getFirstname().isEmpty()) { + if (user.getFirstname() != null && !user.getFirstname().isEmpty()) { preferredUsername = user.getFirstname(); - }else{ + } else { preferredUsername = user.getUsername(); } - log.error("Get request for a token"); - log.error("user = {} {} {}", user.getId(), user.getUsername(), user.getSelectedLanguage()); - log.error("jwtSigningKey= {}", jwtSettings.getSigningKey()); + log.trace("Get request for a token"); + log.trace("user = {} {} {}", user.getId(), user.getUsername(), user.getSelectedLanguage()); + log.trace("jwtSigningKey= {}", jwtSettings.getSigningKey()); user.getRoles().forEach(role -> { - log.error("Role = {} {} {} {}", role.getRole().toString(), role.getAuthority(), role.getDomain().getCodename(), role.getUser().getId()); + log.trace("Role = {} {} {} {}", role.getRole().toString(), role.getAuthority(), role.getDomain().getCodename(), role.getUser().getId()); }); String result = Jwts.builder() .setSubject(user.getUsername()) @@ -88,7 +87,7 @@ public class JWTTokenService { .claim(LANGUAGE, user.getSelectedLanguage()) .signWith(getSignInKey(jwtSettings.getSigningKey()), SignatureAlgorithm.HS512) .compact(); - log.error(result); + log.trace(result); return result; } diff --git a/src/main/java/net/geant/nmaas/portal/service/impl/ApplicationBaseServiceImpl.java b/src/main/java/net/geant/nmaas/portal/service/impl/ApplicationBaseServiceImpl.java index 409f04ab8af15bb694daf34610bd592b65b18e71..0231ea424db52d97c5655dbd9a8e316598c9b0e3 100644 --- a/src/main/java/net/geant/nmaas/portal/service/impl/ApplicationBaseServiceImpl.java +++ b/src/main/java/net/geant/nmaas/portal/service/impl/ApplicationBaseServiceImpl.java @@ -74,7 +74,7 @@ public class ApplicationBaseServiceImpl implements ApplicationBaseService { private void handleTags(ApplicationBase base) { List<Tag> tags = base.getTags().stream() .map(tag -> tagRepository.findByName(tag.getName()).orElse(new Tag(tag.getName()))) - .collect(Collectors.toList()); + .toList(); base.setTags(new HashSet<>(tags)); } @@ -139,16 +139,16 @@ public class ApplicationBaseServiceImpl implements ApplicationBaseService { @Override public List<ApplicationBaseViewS> findAllActiveAppsSmall() { - log.debug("Loading information about all applications"); + log.trace("Loading information about all applications"); LocalDateTime beginning = LocalDateTime.now(); List<ApplicationBaseS> allSmall = appBaseRepository.findAllSmall(); LocalDateTime end = LocalDateTime.now(); - log.debug("Loaded base data from db in {}ms", end.toInstant(ZoneOffset.UTC).toEpochMilli() - beginning.toInstant(ZoneOffset.UTC).toEpochMilli()); + log.trace("Loaded base data from db in {}ms", end.toInstant(ZoneOffset.UTC).toEpochMilli() - beginning.toInstant(ZoneOffset.UTC).toEpochMilli()); List<ApplicationBaseViewS> result = allSmall.stream() .map(app -> modelMapper.map(app, ApplicationBaseViewS.class)) .collect(Collectors.toList()); LocalDateTime finish = LocalDateTime.now(); - log.debug("Complete data is ready after next {}ms", finish.toInstant(ZoneOffset.UTC).toEpochMilli() - end.toInstant(ZoneOffset.UTC).toEpochMilli()); + log.trace("Complete data is ready after next {}ms", finish.toInstant(ZoneOffset.UTC).toEpochMilli() - end.toInstant(ZoneOffset.UTC).toEpochMilli()); return result; } diff --git a/src/main/java/net/geant/nmaas/portal/service/impl/DomainServiceImpl.java b/src/main/java/net/geant/nmaas/portal/service/impl/DomainServiceImpl.java index 9062b6ed820c8217d3fa7611c1983a7d0eb4bd96..83d7f5652960618b49c181aacc23ba4566c05c98 100644 --- a/src/main/java/net/geant/nmaas/portal/service/impl/DomainServiceImpl.java +++ b/src/main/java/net/geant/nmaas/portal/service/impl/DomainServiceImpl.java @@ -52,6 +52,8 @@ import java.util.Set; import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkArgument; +import static net.geant.nmaas.portal.persistent.entity.Role.ROLE_GROUP_DOMAIN_ADMIN; +import static net.geant.nmaas.portal.persistent.entity.Role.ROLE_GROUP_MANAGER; import static net.geant.nmaas.portal.persistent.entity.Role.ROLE_GUEST; @Service @@ -369,6 +371,19 @@ public class DomainServiceImpl implements DomainService { public void removeMemberRole(Long domainId, Long userId, Role role) { checkParams(domainId, userId); checkParams(role); + //if deleting group_manager role delete also group_domain_admin + if(role.equals(ROLE_GROUP_MANAGER)) { + Optional<User> user = userService.findById(userId); + if(user.isPresent()) { + List<UserRole> roles = user.get().getRoles().stream().filter(r -> r.getRole().equals(ROLE_GROUP_DOMAIN_ADMIN)).toList(); + roles.forEach(r -> { + userRoleRepository.deleteBy(userId, r.getDomain().getId(), r.getRole()); + log.info("Deleting role {} from domain {} for user {} as part of ROLE_GROUP_MANAGER removal", r.getRole(), r.getDomain().getCodename(), userId); + }); + domainGroupService.deleteUserFromAllDomainsGroups(user.get()); + log.info("Delete user {} from all domain groups", user.get().getId()); + } + } userRoleRepository.deleteBy(userId, domainId, role); } diff --git a/src/main/java/net/geant/nmaas/portal/service/impl/OidcUserServiceImpl.java b/src/main/java/net/geant/nmaas/portal/service/impl/OidcUserServiceImpl.java index 85b513fec339c7f61e545664ecde9b8190d91515..4e3ad3a2d9fbfbef011d00afb86eff08870e1496 100644 --- a/src/main/java/net/geant/nmaas/portal/service/impl/OidcUserServiceImpl.java +++ b/src/main/java/net/geant/nmaas/portal/service/impl/OidcUserServiceImpl.java @@ -2,6 +2,7 @@ package net.geant.nmaas.portal.service.impl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import net.geant.nmaas.portal.api.exception.ExternalUserMatchException; import net.geant.nmaas.portal.api.exception.MissingElementException; import net.geant.nmaas.portal.api.exception.SignupException; import net.geant.nmaas.portal.exceptions.ObjectAlreadyExistsException; @@ -43,18 +44,25 @@ public class OidcUserServiceImpl implements OidcUserService { boolean existUserBySamlToken = userService .existsBySamlToken(oidcUserSub); - if (existUserBySamlToken) { + if (existUserBySamlToken) { //exist by saml_token and everything is correct return userService .findBySamlToken(oidcUserSub) .orElseThrow(); } - if (userService.existsByEmail(oidcUserEmail)) { + + if (userService.existsByEmail(oidcUserEmail)) {//exist by email needs work with this account User user = userService.findByEmail(oidcUserEmail); + //check if user with given email have older SamlToken as Email or Username if (user.getSamlToken().equals(oidcUserEmail) || user.getSamlToken().equals(oidcUserPreferredUsername)) { user.setSamlToken(oidcUserSub); userService.update(user); return user; + }else{ + throw new ExternalUserMatchException("External user " + + oidcUserSub + + " does not match internal user with SamlToken " + + user.getSamlToken()); } } return registerNewUser(oidcUser); diff --git a/src/main/resources/changelog.json b/src/main/resources/changelog.json index ed50a597c6e79c34dcec4db0986d4ae24dfee13b..0c9424123e22cf4acb205a85f20eb18eb5c18e0c 100644 --- a/src/main/resources/changelog.json +++ b/src/main/resources/changelog.json @@ -2,12 +2,17 @@ "versions" : [ { "verNo" : "1.7.1", - "date" : "(2025/04/10)", + "date" : "(2025/04/15)", "topic" : [ { - "title" : "Authentication and user access improvements", + "title" : "Authentication and user access enhancements", "tags" : "[Enhancement]", - "description" : "JWT size reduction and account linking mechanism" + "description" : "JWT size reduction and improved account linking mechanism" + }, + { + "title" : "User role management improvements", + "tags" : "[Enhancement]", + "description" : "Properly handing role removal action and removed obsolete calls to the backend API" } ] },