package org.ovirt.engine.api.restapi.resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.Response;
import org.ovirt.engine.api.common.security.auth.Principal;
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.PermissionResource;
import org.ovirt.engine.api.resource.AssignedPermissionsResource;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.PermissionsOperationsParametes;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.businessentities.DbUser;
import org.ovirt.engine.core.common.businessentities.ad_groups;
import org.ovirt.engine.core.common.businessentities.permissions;
import org.ovirt.engine.core.common.interfaces.SearchType;
import org.ovirt.engine.core.common.queries.MultilevelAdministrationByPermissionIdParameters;
import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.common.users.VdcUser;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.StringHelper;
public class BackendAssignedPermissionsResource
extends AbstractBackendCollectionResource<Permission, permissions>
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, permissions.class);
this.targetId = targetId;
this.queryType = queryType;
this.queryParams = queryParams;
this.suggestedParentType = suggestedParentType;
this.objectType = objectType;
}
@Override
public Permissions list() {
return mapCollection(getBackendCollection(queryType, queryParams));
}
@Override
public Response add(Permission permission) {
validateParameters(permission,
isPrincipalSubCollection()
? new String[] {"role.id", "dataCenter|cluster|host|storageDomain|vm|vmpool|template.id"}
: new String[] {"role.id", "user|group.id"});
permissions entity = map(permission, getPermissionsTemplate(permission));
return performCreation(VdcActionType.AddPermission,
getPrincipal(entity, permission),
new QueryIdResolver(VdcQueryType.GetPermissionById,
MultilevelAdministrationByPermissionIdParameters.class));
}
@Override
public Response performRemove(String id) {
return performAction(VdcActionType.RemovePermission, new PermissionsOperationsParametes(getPermissions(id)));
}
@Override
@SingleEntityResource
public PermissionResource getPermissionSubResource(String id) {
return inject(new BackendPermissionResource(id, this, suggestedParentType));
}
protected Permissions mapCollection(List<permissions> entities) {
Permissions collection = new Permissions();
Map<Guid, DbUser> users = getUsers();
for (permissions entity : entities) {
if (entity.getObjectType() != VdcObjectType.System) {
Permission permission = map(entity, users.containsKey(entity.getad_element_id()) ? users.get(entity.getad_element_id()) : null);
collection.getPermissions().add(addLinks(permission, permission.getUser() != null ? suggestedParentType : Group.class));
}
}
return collection;
}
public Map<Guid, DbUser> getUsers() {
HashMap<Guid, DbUser> users = new HashMap<Guid, DbUser>();
for (DbUser user : asCollection(DbUser.class, getEntity(List.class, SearchType.DBUser, "users:"))) {
users.put(user.getuser_id(), user);
}
return users;
}
/**
* injects user/group base on permission owner type
* @param entity the permission to map
* @param user the permission owner
* @return permission
*/
public Permission map(permissions entity, DbUser user) {
Permission template = new Permission();
if (entity.getad_element_id() != null && user != null) {
if (isUser(user)) {
template.setUser(new User());
template.getUser().setId(entity.getad_element_id().toString());
} else if (entity.getad_element_id() != null) {
template.setGroup(new Group());
template.getGroup().setId(entity.getad_element_id().toString());
}
}
return map(entity, template);
}
//REVISIT: fix once BE can distinguish between the user and group
private boolean isUser(DbUser user) {
return StringHelper.isNullOrEmpty(user.getusername()) ? false : true;
}
/**
* @pre completeness of "user|group.id" already validated if not
* user sub-collection
*/
protected PermissionsOperationsParametes getPrincipal(permissions entity, Permission permission) {
PermissionsOperationsParametes ret = null;
if (isUserSubCollection() || permission.isSetUser()) {
VdcUser user = new VdcUser();
user.setUserId(isUserSubCollection()
? targetId
: asGuid(permission.getUser().getId()));
user.setDomainControler(getCurrent().get(Principal.class).getDomain());
ret = new PermissionsOperationsParametes(entity, user);
} else if (isGroupSubCollection() || permission.isSetGroup()) {
ad_groups group = new ad_groups();
group.setid(isGroupSubCollection()
? targetId
: asGuid(permission.getGroup().getId()));
group.setdomain(getCurrent().get(Principal.class).getDomain());
ret = new PermissionsOperationsParametes(entity, group);
}
return ret;
}
@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 permissions getPermissionsTemplate(Permission perm) {
permissions permission = new permissions();
// allow the target Id to be implicit in the client-provided
// representation
if (isPrincipalSubCollection()) {
permission.setad_element_id(targetId);
permission.setObjectId(getMapper(Permission.class, Guid.class).map(perm, null));
} else {
if (perm.getUser()!=null) {
permission.setad_element_id(asGuid(perm.getUser().getId()));
} else { //if user is null, group is not null; this was validated before
permission.setad_element_id(asGuid(perm.getGroup().getId()));
}
permission.setObjectId(targetId);
permission.setObjectType(objectType);
}
return permission;
}
protected boolean isPrincipalSubCollection() {
return isUserSubCollection() || isGroupSubCollection();
}
protected boolean isUserSubCollection() {
return User.class.equals(suggestedParentType);
}
protected boolean isGroupSubCollection() {
return Group.class.equals(suggestedParentType);
}
protected permissions getPermissions(String id) {
return getEntity(permissions.class,
VdcQueryType.GetPermissionById,
new MultilevelAdministrationByPermissionIdParameters(new Guid(id)),
id);
}
}