Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 3751 Allow to grant permissions to group #3752

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
37 changes: 27 additions & 10 deletions api/src/main/java/com/epam/pipeline/acl/user/RoleApiService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2020 EPAM Systems, Inc. (https://www.epam.com/)
* Copyright 2017-2024 EPAM Systems, Inc. (https://www.epam.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,58 +19,75 @@
import com.epam.pipeline.controller.vo.user.RoleVO;
import com.epam.pipeline.entity.user.ExtendedRole;
import com.epam.pipeline.entity.user.Role;
import com.epam.pipeline.manager.security.acl.AclMask;
import com.epam.pipeline.manager.security.acl.AclMaskList;
import com.epam.pipeline.manager.user.RoleManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;

import static com.epam.pipeline.security.acl.AclExpressions.ADMIN_ONLY;
import static com.epam.pipeline.security.acl.AclExpressions.OR;
import static com.epam.pipeline.security.acl.AclExpressions.OR_USER_READER;

@Service
public class RoleApiService {

public static final String ROLE_READ_FILTER = ADMIN_ONLY + OR_USER_READER + OR +
"hasPermission(filterObject.id, 'com.epam.pipeline.entity.user.Role', 'READ')";

public static final String ROLE_READ_ACCESS = ADMIN_ONLY + OR_USER_READER + OR +
"hasPermission(returnObject.id, 'com.epam.pipeline.entity.user.Role', 'READ')";

@Autowired
private RoleManager roleManager;

@PreAuthorize(ADMIN_ONLY + OR_USER_READER)
public Collection<Role> loadRolesWithUsers() {
@PostFilter(ROLE_READ_FILTER)
@AclMaskList
public List<Role> loadRolesWithUsers() {
return roleManager.loadAllRoles(true);
}

public Collection<Role> loadRoles() {
@AclMaskList
public List<Role> loadRoles() {
return roleManager.loadAllRoles(false);
}

@PreAuthorize(ADMIN_ONLY + OR_USER_READER)
@PostAuthorize(ROLE_READ_ACCESS)
@AclMask
public Role loadRole(final Long id) {
return roleManager.loadRoleWithUsers(id);
}

@PreAuthorize(ADMIN_ONLY + OR_USER_READER)
@PostAuthorize(ROLE_READ_ACCESS)
@AclMask
public Role loadRoleByName(final String name) {
return roleManager.loadRoleByNameWithUsers(name);
}

@PreAuthorize(ADMIN_ONLY)
@AclMask
public Role createRole(String name, boolean userDefault, Long storageId) {
return roleManager.createRole(name, false, userDefault, storageId);
return roleManager.create(name, false, userDefault, storageId);
}

@PreAuthorize(ADMIN_ONLY)
@PreAuthorize(ADMIN_ONLY + OR + "hasPermission(#roleId, 'com.epam.pipeline.entity.user.Role', 'WRITE')")
@AclMask
public Role updateRole(final Long roleId, final RoleVO roleVO) {
return roleManager.update(roleId, roleVO);
}

@PreAuthorize(ADMIN_ONLY)
public Role deleteRole(Long id) {
return roleManager.deleteRole(id);
return roleManager.delete(id);
}

@PreAuthorize(ADMIN_ONLY)
@AclMask
public ExtendedRole assignRole(Long roleId, List<Long> userIds) {
return roleManager.assignRole(roleId, userIds);
}
Expand Down
51 changes: 28 additions & 23 deletions api/src/main/java/com/epam/pipeline/dao/user/RoleDao.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 EPAM Systems, Inc. (https://www.epam.com/)
* Copyright 2017-2014 EPAM Systems, Inc. (https://www.epam.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -62,33 +62,35 @@ public class RoleDao extends NamedParameterJdbcDaoSupport {
private DaoHelper daoHelper;

@Transactional(propagation = Propagation.MANDATORY)
public Role createRole(String name) {
return createRole(name, false, false, null);
public Role createRole(final String name, final String owner) {
return createRole(name, false, false, null, owner);
}

@Transactional(propagation = Propagation.MANDATORY)
public Role createRole(String name, boolean predefined, boolean userDefault, Long storageId) {
Role role = new Role();
public Role createRole(final String name, final boolean predefined, final boolean userDefault,
final Long storageId, final String owner) {
final Role role = new Role();
role.setName(name);
role.setId(daoHelper.createId(roleSequence));
role.setUserDefault(userDefault);
role.setPredefined(predefined);
role.setDefaultStorageId(storageId);
role.setOwner(owner);
getNamedParameterJdbcTemplate().update(createRoleQuery, RoleParameters.getParameters(role));
return role;
}

@Transactional(propagation = Propagation.MANDATORY)
public void updateRole(Role role) {
public void updateRole(final Role role) {
getNamedParameterJdbcTemplate().update(updateRoleQuery, RoleParameters.getParameters(role));
}

@Transactional(propagation = Propagation.MANDATORY)
public void deleteRole(Long id) {
public void deleteRole(final Long id) {
getJdbcTemplate().update(deleteRoleQuery, id);
}

public Collection<Role> loadAllRoles(boolean loadUsers) {
public List<Role> loadAllRoles(final boolean loadUsers) {
return loadUsers ?
new ArrayList<>(getJdbcTemplate().query(loadRolesWithUsersQuery,
RoleParameters.getExtendedRowExtractor(true))) :
Expand All @@ -99,37 +101,37 @@ public List<Role> loadUserDefaultRoles() {
return getJdbcTemplate().query(loadUserDefaultRolesQuery, RoleParameters.getRowMapper(false));
}

public List<Role> loadRolesByStorageId(Long storageId) {
public List<Role> loadRolesByStorageId(final Long storageId) {
return getJdbcTemplate().query(loadRolesByStorageIdQuery, RoleParameters.getRowMapper(false), storageId);
}

public ExtendedRole loadExtendedRole(Long roleId) {
public ExtendedRole loadExtendedRole(final Long roleId) {
Collection<ExtendedRole> roles = getJdbcTemplate()
.query(loadRoleWithUsersQuery, RoleParameters.getExtendedRowExtractor(true), roleId);
return CollectionUtils.isEmpty(roles) ? null : roles.stream().findFirst().orElse(null);
}

public Optional<Role> loadRole(Long id) {
public Optional<Role> loadRole(final Long id) {
return loadRoleByParameter(id, loadRoleQuery);
}

public Optional<Role> loadRoleByName(String name) {
public Optional<Role> loadRoleByName(final String name) {
return loadRoleByParameter(name, loadRoleByNameQuery);
}

private Optional<Role> loadRoleByParameter(Object parameter, String loadRoleQuery) {
List<Role> result =
private Optional<Role> loadRoleByParameter(final Object parameter, final String loadRoleQuery) {
final List<Role> result =
getJdbcTemplate().query(loadRoleQuery, RoleParameters.getRowMapper(false), parameter);
return result.stream().findFirst();
}

public List<Role> loadRolesList(List<Long> ids) {
public List<Role> loadRolesList(final List<Long> ids) {
return getNamedParameterJdbcTemplate().query(loadRoleListQuery,
RoleParameters.getIdListParameters(ids), RoleParameters.getRowMapper(false));
}

@Transactional(propagation = Propagation.MANDATORY)
public void deleteRoleReferences(Long id) {
public void deleteRoleReferences(final Long id) {
getJdbcTemplate().update(deleteRolesReferencesQuery, id);
}

Expand All @@ -141,20 +143,22 @@ enum RoleParameters {
IDS,
ROLE_DEFAULT_STORAGE_ID,
ROLE_DEFAULT_PROFILE_ID,
GROUP_BLOCKED;
GROUP_BLOCKED,
ROLE_OWNER;

private static MapSqlParameterSource getParameters(Role role) {
private static MapSqlParameterSource getParameters(final Role role) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue(ROLE_ID.name(), role.getId());
params.addValue(ROLE_NAME.name(), role.getName());
params.addValue(ROLE_PREDEFINED.name(), role.isPredefined());
params.addValue(ROLE_USER_DEFAULT.name(), role.isUserDefault());
params.addValue(ROLE_DEFAULT_STORAGE_ID.name(), role.getDefaultStorageId());
params.addValue(ROLE_OWNER.name(), role.getOwner());
return params;
}

public static MapSqlParameterSource getIdListParameters(List<Long> ids) {
MapSqlParameterSource params = new MapSqlParameterSource();
public static MapSqlParameterSource getIdListParameters(final List<Long> ids) {
final MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue(IDS.name(), ids);
return params;
}
Expand All @@ -166,23 +170,24 @@ private static RowMapper<Role> getRowMapper(final boolean getGroupStatus) {
};
}

static Role parseRole(ResultSet rs, Role role, boolean getGroupStatus) throws SQLException {
static Role parseRole(final ResultSet rs, final Role role, final boolean getGroupStatus) throws SQLException {
role.setId(rs.getLong(ROLE_ID.name()));
role.setName(rs.getString(ROLE_NAME.name()));
role.setPredefined(rs.getBoolean(ROLE_PREDEFINED.name()));
role.setUserDefault(rs.getBoolean(ROLE_USER_DEFAULT.name()));
long defaultStorageId = rs.getLong(ROLE_DEFAULT_STORAGE_ID.name());
final long defaultStorageId = rs.getLong(ROLE_DEFAULT_STORAGE_ID.name());
if (!rs.wasNull()) {
role.setDefaultStorageId(defaultStorageId);
}
long defaultProfileId = rs.getLong(ROLE_DEFAULT_PROFILE_ID.name());
final long defaultProfileId = rs.getLong(ROLE_DEFAULT_PROFILE_ID.name());
if (!rs.wasNull()) {
role.setDefaultProfileId(defaultProfileId);
}
if (getGroupStatus) {
final boolean groupStatus = rs.getBoolean(GROUP_BLOCKED.name());
role.setBlocked(!rs.wasNull() && groupStatus);
}
role.setOwner(rs.getString(ROLE_OWNER.name()));
return role;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@
import java.util.stream.Collectors;

import com.fasterxml.jackson.core.type.TypeReference;
import lombok.RequiredArgsConstructor;

Check failure on line 40 in api/src/main/java/com/epam/pipeline/manager/contextual/ContextualPreferenceManager.java

View workflow job for this annotation

GitHub Actions / Checkstyle Report

com.puppycrawl.tools.checkstyle.checks.imports.UnusedImportsCheck

Unused import - lombok.RequiredArgsConstructor.

Check notice on line 40 in api/src/main/java/com/epam/pipeline/manager/contextual/ContextualPreferenceManager.java

View workflow job for this annotation

GitHub Actions / PMD Report

Import Statements UnusedImports

Avoid unused imports such as 'lombok.RequiredArgsConstructor'
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

@Service
@RequiredArgsConstructor
public class ContextualPreferenceManager {

private final ContextualPreferenceDao contextualPreferenceDao;
Expand All @@ -54,6 +54,18 @@
private final UserManager userManager;
private final MessageHelper messageHelper;

public ContextualPreferenceManager(final ContextualPreferenceDao contextualPreferenceDao,
final ContextualPreferenceHandler contextualPreferenceHandler,
final AuthManager authManager,
@Lazy final UserManager userManager,
final MessageHelper messageHelper) {
this.contextualPreferenceDao = contextualPreferenceDao;
this.contextualPreferenceHandler = contextualPreferenceHandler;
this.authManager = authManager;
this.userManager = userManager;
this.messageHelper = messageHelper;
}

/**
* Loads all independent contextual preferences.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2020 EPAM Systems, Inc. (https://www.epam.com/)
* Copyright 2017-2024 EPAM Systems, Inc. (https://www.epam.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -39,7 +39,6 @@
import com.epam.pipeline.manager.preference.PreferenceManager;
import com.epam.pipeline.manager.preference.SystemPreferences;
import com.epam.pipeline.manager.security.AuthManager;
import com.epam.pipeline.manager.user.RoleManager;
import com.epam.pipeline.manager.utils.MetadataParsingUtils;
import com.epam.pipeline.mapper.MetadataEntryMapper;
import com.epam.pipeline.utils.CommonUtils;
Expand Down Expand Up @@ -90,9 +89,6 @@ public class MetadataManager {
@Autowired
private FolderManager folderManager;

@Autowired
private RoleManager roleManager;

@Autowired
private MetadataEntryMapper metadataEntryMapper;

Expand Down Expand Up @@ -223,11 +219,7 @@ public MetadataEntry findMetadataEntryByNameOrId(String identifier, AclClass ent
}

private Long loadEntityId(String identifier, AclClass entityClass) {
if (entityClass.equals(AclClass.ROLE)) {
return roleManager.loadRoleByNameOrId(identifier).getId();
} else {
return entityManager.loadByNameOrId(entityClass, identifier).getId();
}
return entityManager.loadByNameOrId(entityClass, identifier).getId();
}

@Transactional(propagation = Propagation.REQUIRED)
Expand Down Expand Up @@ -405,13 +397,7 @@ private void checkEntityExistsAndCanBeModified(final Long entityId, final AclCla
}

private Object loadEntity(final Long entityId, final AclClass entityClass) {
Object entity;
if (entityClass.equals(AclClass.ROLE)) {
entity = roleManager.loadRole(entityId);
} else {
entity = entityManager.load(entityClass, entityId);
}
return entity;
return entityManager.load(entityClass, entityId);
}

private void checkEntityExists(final Object entity, final Long entityId, final AclClass entityClass) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ private Map<String, Date> findOwnersByUser(final String userIdentifier, final St

private Map<String, Date> findOwnersByRole(final String roleIdentifier, final String metadataKey,
final Integer specifiedDays) {
final Role role = roleManager.loadRoleByNameOrId(roleIdentifier);
final Role role = roleManager.loadByNameOrId(roleIdentifier);
final int days = Objects.nonNull(specifiedDays)
? specifiedDays
: findDaysInMetadata(role.getId(), AclClass.ROLE, metadataKey);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 EPAM Systems, Inc. (https://www.epam.com/)
* Copyright 2017-2024 EPAM Systems, Inc. (https://www.epam.com/)
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
Expand Down Expand Up @@ -64,9 +64,6 @@ public boolean metadataPermission(final Long entityId, final AclClass entityClas
if (permissionHelper.isAdmin()) {
return true;
}
if (entityClass.equals(AclClass.ROLE)) {
return false;
}
if (entityClass.equals(AclClass.PIPELINE_USER) && isSameUser(entityId)) {
return true;
}
Expand Down
Loading
Loading