package org.ovirt.engine.api.restapi.resource; import java.io.Serializable; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.ws.rs.core.Response; import org.ovirt.engine.api.model.BaseResource; import org.ovirt.engine.api.model.Group; import org.ovirt.engine.api.model.Permission; import org.ovirt.engine.api.model.Permissions; import org.ovirt.engine.api.model.User; import org.ovirt.engine.api.resource.AssignedPermissionsResource; import org.ovirt.engine.api.resource.PermissionResource; import org.ovirt.engine.api.restapi.types.GroupMapper; import org.ovirt.engine.api.restapi.types.UserMapper; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.PermissionsOperationsParameters; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.aaa.DbGroup; import org.ovirt.engine.core.common.businessentities.aaa.DbUser; import org.ovirt.engine.core.common.queries.GetPermissionsForObjectParameters; import org.ovirt.engine.core.common.queries.IdQueryParameters; import org.ovirt.engine.core.common.queries.VdcQueryParametersBase; import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.compat.Guid; public class BackendAssignedPermissionsResource extends AbstractBackendCollectionResource<Permission, org.ovirt.engine.core.common.businessentities.Permission> implements AssignedPermissionsResource { private Guid targetId; private VdcQueryType queryType; private VdcQueryParametersBase queryParams; private Class<? extends BaseResource> suggestedParentType; private VdcObjectType objectType; public BackendAssignedPermissionsResource(Guid targetId, VdcQueryType queryType, VdcQueryParametersBase queryParams, Class<? extends BaseResource> suggestedParentType) { this(targetId, queryType, queryParams, suggestedParentType, null); } public BackendAssignedPermissionsResource(Guid targetId, VdcQueryType queryType, VdcQueryParametersBase queryParams, Class<? extends BaseResource> suggestedParentType, VdcObjectType objectType) { super(Permission.class, org.ovirt.engine.core.common.businessentities.Permission.class); this.targetId = targetId; this.queryType = queryType; this.queryParams = queryParams; this.suggestedParentType = suggestedParentType; this.objectType = objectType; } @Override public Permissions list() { Set<org.ovirt.engine.core.common.businessentities.Permission> permissions = new TreeSet<>(new PermissionsComparator()); List<org.ovirt.engine.core.common.businessentities.Permission> directPermissions = getBackendCollection(queryType, queryParams); permissions.addAll(directPermissions); if (queryType.equals(VdcQueryType.GetPermissionsForObject)) { permissions.addAll(getInheritedPermissions()); } return mapCollection(permissions); } private List<org.ovirt.engine.core.common.businessentities.Permission> getInheritedPermissions() { ((GetPermissionsForObjectParameters)queryParams).setVdcObjectType(objectType); ((GetPermissionsForObjectParameters)queryParams).setDirectOnly(false); List<org.ovirt.engine.core.common.businessentities.Permission> inheritedPermissions = getBackendCollection(queryType, queryParams); for (org.ovirt.engine.core.common.businessentities.Permission entity : inheritedPermissions) { if (objectType != null) { entity.setObjectType(objectType); entity.setObjectId(targetId); } } return inheritedPermissions; } static class PermissionsComparator implements Comparator<org.ovirt.engine.core.common.businessentities.Permission>, Serializable { @Override public int compare( org.ovirt.engine.core.common.businessentities.Permission o1, org.ovirt.engine.core.common.businessentities.Permission o2) { String id1 = o1.getId().toString(); String id2 = o2.getId().toString(); return id1.compareTo(id2); } } @Override public Response add(Permission permission) { validateParameters(permission, isPrincipalSubCollection() ? new String[] {"role.id|name", "dataCenter|cluster|host|storageDomain|vm|vmPool|template.id"} : new String[] {"role.id|name", "user|group.id"}); PermissionsOperationsParameters parameters = getParameters(permission); QueryIdResolver<Guid> resolver = new QueryIdResolver<>(VdcQueryType.GetPermissionById, IdQueryParameters.class); return performCreate(VdcActionType.AddPermission, parameters, resolver); } @Override public PermissionResource getPermissionResource(String id) { return inject(new BackendPermissionResource(id, targetId, this, suggestedParentType)); } protected Permissions mapCollection(Set<org.ovirt.engine.core.common.businessentities.Permission> entities) { Permissions collection = new Permissions(); for (org.ovirt.engine.core.common.businessentities.Permission entity : entities) { castEveryonePermissionsToUser(entity); Permission permission = map(entity, getUserById(entity.getAdElementId())); collection.getPermissions().add(addLinks(permission, permission.getUser() != null ? suggestedParentType : Group.class)); } return collection; } private void castEveryonePermissionsToUser(org.ovirt.engine.core.common.businessentities.Permission entity) { if (entity.getAdElementId() != null && entity.getAdElementId().equals(Guid.EVERYONE) && queryType.equals(VdcQueryType.GetPermissionsByAdElementId)) { entity.setAdElementId(this.targetId); } } public DbUser getUserById(Guid userId) { IdQueryParameters queryParameters = new IdQueryParameters(userId); VdcQueryReturnValue userQueryResponse = runQuery(VdcQueryType.GetDbUserByUserId, queryParameters); DbUser returnValue = null; if (userQueryResponse != null && userQueryResponse.getSucceeded()) { returnValue = userQueryResponse.getReturnValue(); } return returnValue; } public Map<Guid, DbUser> getUsers() { HashMap<Guid, DbUser> users = new HashMap<>(); for (DbUser user : lookupUsers()) { users.put(user.getId(), user); } return users; } private List<DbUser> lookupUsers() { VdcQueryParametersBase queryParams = new VdcQueryParametersBase(); queryParams.setFiltered(isFiltered()); return getBackendCollection(DbUser.class, VdcQueryType.GetAllDbUsers, queryParams); } /** * injects user/group base on permission owner type * @param entity the permission to map * @param user the permission owner * @return permission */ public Permission map(org.ovirt.engine.core.common.businessentities.Permission entity, DbUser user) { Permission template = new Permission(); if (entity.getAdElementId() != null) { if (isUser(user)) { template.setUser(new User()); template.getUser().setId(entity.getAdElementId().toString()); } else { template.setGroup(new Group()); template.getGroup().setId(entity.getAdElementId().toString()); } } return map(entity, template); } //REVISIT: fix once BE can distinguish between the user and group private static boolean isUser(DbUser user) { return user != null && !user.isGroup(); } /** * Find the user or group that the permissions applies to. * * @param permission the incoming permission model * @return the user or group that the permission applies to */ private Object getPrincipal(Permission permission) { if (isUserSubCollection()) { DbUser dbUser = new DbUser(); dbUser.setId(targetId); return dbUser; } if (isGroupSubCollection()) { DbGroup dbGroup = new DbGroup(); dbGroup.setId(targetId); return dbGroup; } if (permission.isSetUser()) { User user = permission.getUser(); DbUser dbUser = UserMapper.map(user, null); if (dbUser.getDomain() == null) { dbUser.setDomain(getCurrent().getUser().getDomain()); } return dbUser; } if (permission.isSetGroup()) { Group group = permission.getGroup(); DbGroup dbGroup = GroupMapper.map(group, null); if (dbGroup.getDomain() == null) { dbGroup.setDomain(getCurrent().getUser().getDomain()); } return dbGroup; } return null; } /** * Create the parameters for the permissions operation. * * @param model the incoming permission * @return the parameters for the operation */ private PermissionsOperationsParameters getParameters(Permission model) { org.ovirt.engine.core.common.businessentities.Permission entity = map(model, null); if (!isPrincipalSubCollection()) { entity.setObjectId(targetId); entity.setObjectType(objectType); } PermissionsOperationsParameters parameters = new PermissionsOperationsParameters(); parameters.setPermission(entity); Object principal = getPrincipal(model); if (principal instanceof DbUser) { DbUser user = (DbUser) principal; entity.setAdElementId(user.getId()); parameters.setUser(user); } if (principal instanceof DbGroup) { DbGroup group = (DbGroup) principal; entity.setAdElementId(group.getId()); parameters.setGroup(group); } return parameters; } @Override public Permission addParents(Permission permission) { // REVISIT for entity-level permissions we need an isUser // flag on the permissions entity in order to distinguish // between the user and group cases if (isGroupSubCollection() && permission.isSetUser() && permission.getUser().isSetId()) { permission.setGroup(new Group()); permission.getGroup().setId(permission.getUser().getId()); permission.setUser(null); } return permission; } protected boolean isPrincipalSubCollection() { return isUserSubCollection() || isGroupSubCollection(); } protected boolean isUserSubCollection() { return User.class.equals(suggestedParentType); } protected boolean isGroupSubCollection() { return Group.class.equals(suggestedParentType); } }