Skip to content

Commit

Permalink
RANGER-4607: Ranger REST API improvements
Browse files Browse the repository at this point in the history
RANGER-4545: DELETE /assets/resources/{resource_id} API should return proper status code for non admin users
RANGER-4546: /assets/ugsyncAudits/{sync_source} API is accessible by user without permission on audit module
RANGER-4548: Return proper error message in the response for /tags/tags, /tags/resources and /tags/types API for non admin users
RANGER-4547: The reponse metrics (pagination values) for the /assets/ugsyncAudits/{sync_source} API is not proper
RANGER-4549: Non admin users cannot access /public/v2/api/roles/names and /public/v2/api/roles/name/{name} API, but can access /public/v2/api/roles API
RANGER-4551: No response returned for /assets/policyList/{service_name} API
RANGER-4550: API request to /assets/resource/{id} returns no response
RANGER-4552: Response metrics for /assets/report is not proper, and pagination does not work
RANGER-4553: Response metrics for /xaudit/trx_log not proper
RANGER-4554: Response metrics for /assets/resources not proper
RANGER-4555: Response metrics for /assets/assets API not proper
RANGER-4573: /xaudit/trx_log API not accessible by keyadmin user
RANGER-4578: /xuser/groupgroups and /xuser/groupusers APIs allow creation of entities even without groupId / userId fields in the request
RANGER-4574: /public/v2/api/service/{service_name}/policy/{policy_name} API returns policies for users without access to the policy
RANGER-4575: /plugins/policy/{policy_id}/version/{version_number} API returns policies for users without access to the policy
RANGER-4576: User without access to policy is able to fetch policy details using /plugins/policies/{service_type}/for-resource API endpoint
RANGER-4577: UI and API behaviour for fetching users not consistent for keyadmin users
RANGER-4589: keyadmin user can update the user password via UI but cannot update the user password using /users/{user_id}/passwordchange API
RANGER-4588: /xaudit/trx_log/{trx_log_id} is not accessible by keyadmin user
RANGER-4591: keyadmin user can access non kms related admin audits using /assets/report/{transaction_id} API
RANGER-4594: keyadmin user can mark ROLE_USER users as disabled by setting status to 0 using /users API
RANGER-4595: keyadmin user able to view the user permission objects via /users API
RANGER-4596: keyadmin can fetch the details of admin and auditor users through /users API endpoint
RANGER-4598: ROLE_USER cannot acccess /xusers/groups API but can access /xusers/groups/groupName/{group_name} API
RANGER-4586: XUserREST and UserREST API improvement for keyadmin users
Change-Id: I1fa52a99049d81e58c40d071211d62b278ff8ef1
  • Loading branch information
pradeepagrawal8184 committed Sep 13, 2024
1 parent 854a113 commit 3d04d9a
Show file tree
Hide file tree
Showing 23 changed files with 595 additions and 769 deletions.
54 changes: 3 additions & 51 deletions security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

package org.apache.ranger.biz;

import java.io.File;
import java.io.IOException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
Expand Down Expand Up @@ -68,8 +66,6 @@
import org.apache.ranger.view.*;
import org.apache.ranger.view.VXTrxLogV2.AttributeChangeInfo;
import org.apache.ranger.view.VXTrxLogV2.ObjectChangeInfo;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -165,53 +161,6 @@ public void init() {
logger.info("<== AssetMgr.init()");
}

public File getXResourceFile(Long id, String fileType) {
VXResource xResource = xResourceService.readResource(id);
if (xResource == null) {
throw this.restErrorUtil.createRESTException(
"serverMsg.datasourceIdEmpty" + "id " + id,
MessageEnums.DATA_NOT_FOUND, id, "dataSourceId",
"DataSource not found with " + "id " + id);
}

return getXResourceFile(xResource, fileType);
}

public File getXResourceFile(VXResource xResource, String fileType) {
File file = null;
try {
if (fileType != null) {
if ("json".equalsIgnoreCase(fileType)) {
file = jsonUtil.writeJsonToFile(xResource,
xResource.getName());
} else {
throw restErrorUtil.createRESTException(
"Please send the supported filetype.",
MessageEnums.INVALID_INPUT_DATA);
}
} else {
throw restErrorUtil
.createRESTException(
"Please send the file format in which you want to export.",
MessageEnums.DATA_NOT_FOUND);
}
} catch (JsonGenerationException e) {
throw this.restErrorUtil.createRESTException(
"serverMsg.jsonGeneration" + " : " + e.getMessage(),
MessageEnums.ERROR_SYSTEM);
} catch (JsonMappingException e) {
throw this.restErrorUtil.createRESTException(
"serverMsg.jsonMapping" + " : " + e.getMessage(),
MessageEnums.ERROR_SYSTEM);
} catch (IOException e) {
throw this.restErrorUtil.createRESTException(
"serverMsg.ioException" + " : " + e.getMessage(),
MessageEnums.ERROR_SYSTEM);
}

return file;
}

public String getLatestRepoPolicy(VXAsset xAsset, List<VXResource> xResourceList, Long updatedTime,
X509Certificate[] certchain, boolean httpEnabled, String epoch,
String ipAddress, boolean isSecure, String count, String agentId) {
Expand Down Expand Up @@ -1396,6 +1345,9 @@ public VXUgsyncAuditInfoList getUgsyncAudits(SearchCriteria searchCriteria) {
}

public VXUgsyncAuditInfoList getUgsyncAuditsBySyncSource(String syncSource) {
if (!msBizUtil.hasModuleAccess(RangerConstants.MODULE_AUDIT)) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User is not having permissions on the "+RangerConstants.MODULE_AUDIT+" module.", true);
}
if(syncSource!=null && !syncSource.trim().isEmpty()){
return xUgsyncAuditInfoService.searchXUgsyncAuditInfoBySyncSource(syncSource);
}else{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5067,9 +5067,11 @@ public int compare(RangerPolicy c1, RangerPolicy c2) {

// fetch policies maintained for the roles and groups belonging to the group
String groupName = searchFilter.getParam("group");
if (StringUtils.isBlank(groupName)) {
groupName = RangerConstants.GROUP_PUBLIC;
}
if (!StringUtils.isEmpty(groupName)) {
Set<String> groupNames = daoMgr.getXXGroupGroup().findGroupNamesByGroupName(groupName);
groupNames.add(RangerConstants.GROUP_PUBLIC);
groupNames.add(groupName);
Set<Long> processedSvcIdsForGroup = new HashSet<>();
Set<String> processedGroupsName = new HashSet<>();
Expand Down
162 changes: 66 additions & 96 deletions security-admin/src/main/java/org/apache/ranger/biz/UserMgr.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ public XXPortalUser updateUser(VXPortalUser userProfile) {
userProfile.setPublicScreenName(gjUser.getLoginId());
}

if (rangerBizUtil.isKeyAdmin() && userProfile.getStatus() != gjUser.getStatus()) {
throw restErrorUtil.createRESTException("Status update is not permitted to logged in user.", MessageEnums.INVALID_INPUT_DATA);
}

// userRoleList
updateRoles(userProfile.getId(), userProfile.getUserRoleList());

Expand Down Expand Up @@ -338,17 +342,10 @@ public void setUserRoles(Long userId, List<VXString> vStringRolesList) {

/**
* @param pwdChange
* @return
*/
public VXResponse changePassword(VXPasswordChange pwdChange) {

VXResponse ret = new VXResponse();

// First let's get the XXPortalUser for the current logged in user
String currentUserLoginId = ContextUtil.getCurrentUserLoginId();
XXPortalUser gjUserCurrent = daoManager.getXXPortalUser().findByLoginId(currentUserLoginId);
checkAccessForUpdate(gjUserCurrent);

* @return
*/
public VXResponse changePassword(VXPasswordChange pwdChange) {
VXResponse ret = new VXResponse();
// Get the user of whom we want to change the password
XXPortalUser gjUser = daoManager.getXXPortalUser().findByLoginId(pwdChange.getLoginId());
if (gjUser == null) {
Expand All @@ -362,8 +359,8 @@ public VXResponse changePassword(VXPasswordChange pwdChange) {
vXResponse.setMsgDesc("SECURITY:changePassword().Ranger External Users cannot change password. LoginId=" + pwdChange.getLoginId());
throw restErrorUtil.generateRESTException(vXResponse);
}
String currentPassword = gjUser.getPassword();
checkAccess(gjUser);
String currentPassword = gjUser.getPassword();
//check current password and provided old password is same or not
if (this.isFipsEnabled) {
if (!isPasswordValid(pwdChange.getLoginId(), currentPassword, pwdChange.getOldPassword())) {
Expand Down Expand Up @@ -436,8 +433,7 @@ private void updateOldPasswords(XXPortalUser gjUser, List<String> oldPasswords)
* @return
*/
public VXPortalUser changeEmailAddress(XXPortalUser gjUser, VXPasswordChange changeEmail) {
checkAccessForUpdate(gjUser);
rangerBizUtil.blockAuditorRoleUser();
checkAccess(gjUser);
if (StringUtils.isEmpty(changeEmail.getEmailAddress())) {
changeEmail.setEmailAddress(null);
}
Expand Down Expand Up @@ -625,33 +621,24 @@ protected void gjUserToUserProfile(XXPortalUser user, VXPortalUser userProfile)
}

userProfile.setId(user.getId());
List<XXUserPermission> xUserPermissions = daoManager
.getXXUserPermission().findByUserPermissionIdAndIsAllowed(
userProfile.getId());
List<XXGroupPermission> xxGroupPermissions = daoManager
.getXXGroupPermission().findbyVXPortalUserId(
userProfile.getId());

List<VXGroupPermission> groupPermissions = new ArrayList<VXGroupPermission>();
List<VXUserPermission> vxUserPermissions = new ArrayList<VXUserPermission>();
for (XXGroupPermission xxGroupPermission : xxGroupPermissions) {
VXGroupPermission groupPermission = xGroupPermissionService
.populateViewBean(xxGroupPermission);
groupPermission.setModuleName(daoManager.getXXModuleDef()
.findByModuleId(groupPermission.getModuleId())
.getModule());
groupPermissions.add(groupPermission);
}
for (XXUserPermission xUserPermission : xUserPermissions) {
VXUserPermission vXUserPermission = xUserPermissionService
.populateViewBean(xUserPermission);
vXUserPermission.setModuleName(daoManager.getXXModuleDef()
.findByModuleId(vXUserPermission.getModuleId())
.getModule());
vxUserPermissions.add(vXUserPermission);
if (sess.isUserAdmin() || sess.getXXPortalUser().getId().equals(user.getId())) {
List<XXUserPermission> xUserPermissions = daoManager.getXXUserPermission().findByUserPermissionIdAndIsAllowed(userProfile.getId());
List<XXGroupPermission> xxGroupPermissions = daoManager.getXXGroupPermission().findbyVXPortalUserId(userProfile.getId());
List<VXGroupPermission> groupPermissions = new ArrayList<VXGroupPermission>();
List<VXUserPermission> vxUserPermissions = new ArrayList<VXUserPermission>();
for (XXGroupPermission xxGroupPermission : xxGroupPermissions) {
VXGroupPermission groupPermission = xGroupPermissionService.populateViewBean(xxGroupPermission);
groupPermission.setModuleName(daoManager.getXXModuleDef().findByModuleId(groupPermission.getModuleId()).getModule());
groupPermissions.add(groupPermission);
}
for (XXUserPermission xUserPermission : xUserPermissions) {
VXUserPermission vXUserPermission = xUserPermissionService.populateViewBean(xUserPermission);
vXUserPermission.setModuleName(daoManager.getXXModuleDef().findByModuleId(vXUserPermission.getModuleId()).getModule());
vxUserPermissions.add(vXUserPermission);
}
userProfile.setGroupPermissions(groupPermissions);
userProfile.setUserPermList(vxUserPermissions);
}
userProfile.setGroupPermissions(groupPermissions);
userProfile.setUserPermList(vxUserPermissions);
userProfile.setFirstName(user.getFirstName());
userProfile.setLastName(user.getLastName());
userProfile.setPublicScreenName(user.getPublicScreenName());
Expand Down Expand Up @@ -765,14 +752,20 @@ public VXPortalUserList searchUsers(SearchCriteria searchCriteria) {
@SuppressWarnings("rawtypes")
List resultList = query.getResultList();
// Iterate over the result list and create the return list
int adminCount = 0;
for (Object object : resultList) {
XXPortalUser gjUser = (XXPortalUser) object;
VXPortalUser userProfile = new VXPortalUser();
gjUserToUserProfile(gjUser, userProfile);
objectList.add(userProfile);
if (rangerBizUtil.isKeyAdmin() && (userProfile.getUserRoleList().contains(RangerConstants.ROLE_SYS_ADMIN) || userProfile.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR))) {
adminCount++;
continue;
} else {
objectList.add(userProfile);
}
}

returnList.setResultSize(resultSize);
returnList.setResultSize(resultSize-adminCount);
returnList.setPageSize(query.getMaxResults());
returnList.setSortBy(sortBy);
returnList.setSortType(querySortType);
Expand Down Expand Up @@ -1007,9 +1000,7 @@ public XXPortalUserRole addUserRole(Long userId, String userRole) {
public void checkAccess(Long userId) {
XXPortalUser gjUser = daoManager.getXXPortalUser().getById(userId);
if (gjUser == null) {
throw restErrorUtil
.create403RESTException("serverMsg.userMgrWrongUser: "
+ userId);
throw restErrorUtil.create403RESTException("serverMsg.userMgrWrongUser: " + userId);
}

checkAccess(gjUser);
Expand All @@ -1021,58 +1012,14 @@ public void checkAccess(Long userId) {
*/
public void checkAccess(XXPortalUser gjUser) {
if (gjUser == null) {
throw restErrorUtil
.create403RESTException("serverMsg.userMgrWrongUser");
throw restErrorUtil.create403RESTException("serverMsg.userMgrWrongUser");
}
UserSessionBase sess = ContextUtil.getCurrentUserSession();
if (sess != null) {

// Admin
if (sess.isUserAdmin() || sess.isKeyAdmin()) {
return;
}

// Self
if (sess.getXXPortalUser().getId().equals(gjUser.getId())) {
return;
}

}
throw restErrorUtil.create403RESTException("User "
+ " access denied. loggedInUser="
+ (sess != null ? sess.getXXPortalUser().getId()
: "Not Logged In") + ", accessing user="
+ gjUser.getId());

}

public void checkAccessForUpdate(XXPortalUser gjUser) {
if (gjUser == null) {
throw restErrorUtil
.create403RESTException("serverMsg.userMgrWrongUser");
}
UserSessionBase sess = ContextUtil.getCurrentUserSession();
if (sess != null) {

// Admin
if (sess.isUserAdmin()) {
return;
}

// Self
if (sess.getXXPortalUser().getId().equals(gjUser.getId())) {
return;
}

VXPortalUser requestedVXUser = getUserProfileByLoginId(gjUser.getLoginId());
if (requestedVXUser !=null && CollectionUtils.isNotEmpty(requestedVXUser.getUserRoleList()) && hasAccessToGetUserInfo(requestedVXUser)) {
return;
}
VXResponse vXResponse = new VXResponse();
vXResponse.setStatusCode(HttpServletResponse.SC_FORBIDDEN);
vXResponse.setMsgDesc("User "
+ " access denied. loggedInUser="
+ (sess != null ? sess.getXXPortalUser().getId()
: "Not Logged In") + ", accessing user="
+ gjUser.getId());
throw restErrorUtil.generateRESTException(vXResponse);
logger.info("Logged-In user is not allowed to access requested user data.");
throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "Logged-In user is not allowed to access requested user data", true);

}

Expand Down Expand Up @@ -1460,4 +1407,27 @@ private String encodeString(String text, String salt, String algorithm) {
throw restErrorUtil.createRESTException("algorithm `" + algorithm + "' not supported");
}
}

private boolean hasAccessToGetUserInfo(VXPortalUser requestedVXUser) {
UserSessionBase userSession = ContextUtil.getCurrentUserSession();
if (userSession != null && userSession.getLoginId() != null) {
VXPortalUser loggedInVXUser = getUserProfileByLoginId(userSession.getLoginId());
if (loggedInVXUser != null && loggedInVXUser.getUserRoleList().size() == 1) {
if (loggedInVXUser.getUserRoleList().contains(RangerConstants.ROLE_USER)) {
return requestedVXUser.getId().equals(loggedInVXUser.getId()) ? true : false;
} else if (loggedInVXUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN) || loggedInVXUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)) {
if (requestedVXUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN) || requestedVXUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR) || requestedVXUser.getUserRoleList().contains(RangerConstants.ROLE_USER)) {
return true;
}
} else if (loggedInVXUser.getUserRoleList().contains(RangerConstants.ROLE_SYS_ADMIN) || loggedInVXUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR)) {
if (loggedInVXUser.getUserRoleList().contains(RangerConstants.ROLE_SYS_ADMIN) && "rangerusersync".equalsIgnoreCase(userSession.getLoginId())) {
return true;
} else if (requestedVXUser.getUserRoleList().contains(RangerConstants.ROLE_SYS_ADMIN) || requestedVXUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || requestedVXUser.getUserRoleList().contains(RangerConstants.ROLE_USER)) {
return true;
}
}
}
}
return false;
}
}
22 changes: 16 additions & 6 deletions security-admin/src/main/java/org/apache/ranger/biz/XAuditMgr.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ public class XAuditMgr extends XAuditMgrBase {
RangerBizUtil rangerBizUtil;

public VXTrxLog getXTrxLog(Long id) {
checkAdminAccess();
return super.getXTrxLog(id);
if (rangerBizUtil.isAdmin() || rangerBizUtil.isKeyAdmin() || rangerBizUtil.isAuditAdmin() || rangerBizUtil.isAuditKeyAdmin()) {
return super.getXTrxLog(id);
} else {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User don't have permission to perform this action", true);
}
}

public VXTrxLog createXTrxLog(VXTrxLog vXTrxLog) {
Expand All @@ -75,13 +78,20 @@ public void deleteXTrxLog(Long id, boolean force) {
}

public VXTrxLogList searchXTrxLogs(SearchCriteria searchCriteria) {
checkAdminAccess();
return super.searchXTrxLogs(searchCriteria);
if (rangerBizUtil.isAdmin() || rangerBizUtil.isKeyAdmin() || rangerBizUtil.isAuditAdmin() || rangerBizUtil.isAuditKeyAdmin()) {
return super.searchXTrxLogs(searchCriteria);
} else {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User don't have permission to perform this action", true);
}

}

public VXLong getXTrxLogSearchCount(SearchCriteria searchCriteria) {
checkAdminAccess();
return super.getXTrxLogSearchCount(searchCriteria);
if (rangerBizUtil.isAdmin() || rangerBizUtil.isKeyAdmin() || rangerBizUtil.isAuditAdmin() || rangerBizUtil.isAuditKeyAdmin()) {
return super.getXTrxLogSearchCount(searchCriteria);
} else {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User don't have permission to perform this action", true);
}
}

public VXAccessAudit createXAccessAudit(VXAccessAudit vXAccessAudit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@

package org.apache.ranger.biz;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.ranger.common.MessageEnums;
import org.apache.ranger.common.RESTErrorUtil;
import org.apache.ranger.common.SearchCriteria;
import org.apache.ranger.plugin.store.PList;
import org.apache.ranger.service.XAccessAuditService;
import org.apache.ranger.service.RangerTrxLogV2Service;
import org.apache.ranger.service.XAccessAuditService;
import org.apache.ranger.view.VXAccessAudit;
import org.apache.ranger.view.VXAccessAuditList;
import org.apache.ranger.view.VXLong;
Expand All @@ -33,9 +36,6 @@
import org.apache.ranger.view.VXTrxLogV2;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.stream.Collectors;

public class XAuditMgrBase {

@Autowired
Expand Down
Loading

0 comments on commit 3d04d9a

Please sign in to comment.