/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package controllers.tenant;
import com.emc.storageos.db.client.model.AuthnProvider;
import com.emc.storageos.model.auth.AuthnProviderRestRep;
import com.emc.storageos.model.auth.AuthnUpdateParam;
import com.emc.storageos.model.auth.RoleAssignmentEntry;
import com.emc.storageos.model.keystone.OSTenantRestRep;
import com.emc.storageos.model.keystone.OSTenantListRestRep;
import com.emc.storageos.model.quota.QuotaInfo;
import com.emc.storageos.model.tenant.*;
import com.emc.vipr.client.core.util.ResourceUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import controllers.Common;
import controllers.deadbolt.Restrict;
import controllers.deadbolt.Restrictions;
import controllers.security.Security;
import controllers.util.Models;
import controllers.util.ViprResourceController;
import controllers.util.FlashException;
import models.RoleAssignmentType;
import models.Roles;
import models.TenantSource;
import models.TenantsSynchronizationOptions;
import models.datatable.OpenStackTenantsDataTable;
import models.datatable.TenantRoleAssignmentDataTable;
import models.datatable.TenantsDataTable;
import models.security.UserInfo;
import org.apache.commons.lang.StringUtils;
import play.data.binding.As;
import play.data.validation.MaxSize;
import play.data.validation.MinSize;
import play.data.validation.Required;
import play.data.validation.Validation;
import play.i18n.Messages;
import play.mvc.Util;
import play.mvc.With;
import play.Logger;
import play.exceptions.ActionNotFoundException;
import play.mvc.Controller;
import util.*;
import util.datatable.DataTablesSupport;
import java.util.*;
import static com.emc.vipr.client.core.util.ResourceUtils.uri;
import static util.BourneUtil.getViprClient;
import static util.RoleAssignmentUtils.createRoleAssignmentEntry;
import static util.RoleAssignmentUtils.getTenantRoleAssignment;
import static util.RoleAssignmentUtils.getTenantRoleAssignments;
import static util.RoleAssignmentUtils.deleteTenantRoleAssignment;
import static util.RoleAssignmentUtils.putTenantRoleAssignmentChanges;
@With(Common.class)
@Restrictions({ @Restrict("ROOT_TENANT_ADMIN"), @Restrict("HOME_TENANT_ADMIN"), @Restrict("TENANT_ADMIN"), @Restrict("SECURITY_ADMIN") })
public class Tenants extends ViprResourceController {
protected static final String UNKNOWN = "tenants.unknown";
protected static final String UPDATED = "keystoneProvider.updated";
protected static final String SAVED = "LDAPsources.saved";
protected static final String INTERVAL_ERROR = "ldapSources.synchronizationInterval.integerRequired";
private static String authnProviderName = "";
// Minimum interval in seconds.
public static final int MIN_INTERVAL_DELAY = 10;
public static void list() {
TenantsDataTable dataTable = new TenantsDataTable();
renderArgs.put("sources", TenantSource.options(TenantSource.TENANTS_SOURCE_ALL, TenantSource.TENANTS_SOURCE_LOCAL, TenantSource.TENANTS_SOURCE_OS));
renderArgs.put("currentSource", Models.currentSource());
if (isKeystoneAuthnProviderCreated()) {
AuthnProviderRestRep authnProvider = AuthnProviderUtils.getKeystoneAuthProvider();
authnProviderName = authnProvider.getName();
TenantsSyncOptionsForm keystoneProvider = new TenantsSyncOptionsForm();
keystoneProvider.readFrom(authnProvider);
renderArgs.put("tenantsOptions",
TenantsSynchronizationOptions.options(TenantsSynchronizationOptions.ADDITION, TenantsSynchronizationOptions.DELETION));
renderArgs.put("interval", getInterval(authnProvider));
renderArgs.put("osTenantsToAdd", new KeystoneSynchronizationTenantsDataTable());
renderArgs.put("osTenantsToRemove", new KeystoneSynchronizationTenantsDataTable());
render(dataTable, keystoneProvider);
}
render(dataTable);
}
public static void selectSource(String source, String url) {
Models.setSource(source);
if (url != null) {
try {
redirect(Common.toSafeRedirectURL(url));
} catch (ActionNotFoundException noAction) {
Logger.error(noAction, "Action not found for %s", url);
badRequest();
}
}
}
public static void listJson() {
List<TenantsDataTable.Tenant> tenants = Lists.newArrayList();
List<TenantOrgRestRep> subtenants;
UserInfo user = Security.getUserInfo();
String source = Models.currentSource();
if (Security.isRootTenantAdmin() || Security.isSecurityAdmin()) {
TenantOrgRestRep rootTenant = TenantUtils.findRootTenant();
if (source.equals(TenantSource.getTenantSource(rootTenant.getUserMappings())) ||
source.equals(TenantSource.TENANTS_SOURCE_ALL)) {
tenants.add(new TenantsDataTable.Tenant(rootTenant, ((Security.isRootTenantAdmin() || Security.isSecurityAdmin()))));
}
subtenants = TenantUtils.getSubTenants(rootTenant.getId());
} else if (Security.isHomeTenantAdmin()) {
TenantOrgRestRep userTenant = TenantUtils.getUserTenant();
if (source.equals(TenantSource.getTenantSource(userTenant.getUserMappings())) ||
source.equals(TenantSource.TENANTS_SOURCE_ALL)) {
tenants.add(new TenantsDataTable.Tenant(userTenant, true));
}
subtenants = getViprClient().tenants().getByIds(user.getSubTenants());
} else {
subtenants = getViprClient().tenants().getByIds(user.getSubTenants());
}
for (TenantOrgRestRep tenant : subtenants) {
boolean admin = Security.isRootTenantAdmin() || user.hasSubTenantRole(tenant.getId().toString(), Security.TENANT_ADMIN)
|| Security.isSecurityAdmin();
if (admin && (source.equals(TenantSource.getTenantSource(tenant.getUserMappings())) ||
source.equals(TenantSource.TENANTS_SOURCE_ALL))) {
tenants.add(new TenantsDataTable.Tenant(tenant, admin));
}
}
renderJSON(DataTablesSupport.createJSON(tenants, params));
}
public static void synchronizeOSTenants(@As(",") String[] ids) {
List<OSTenantRestRep> tenants = OpenStackTenantsUtils.getOpenStackTenantsFromDataBase();
if (ids != null) {
List<String> idList = Arrays.asList(ids);
if(!idList.get(0).isEmpty()) {
for (OSTenantRestRep tenant : tenants) {
if (idList.contains(tenant.getId().toString())) {
if (tenant.getExcluded()) {
tenant.setExcluded(false);
} else {
tenant.setExcluded(true);
}
}
}
OSTenantListRestRep params = new OSTenantListRestRep();
params.setOSTenantsRestRep(tenants);
OpenStackTenantsUtils.updateOpenStackTenants(params);
}
}
flash.success(MessagesUtils.get(UPDATED));
list();
}
/**
* Gets the list of OpenStack tenants.
*/
public static void tenantsListToAddJson() {
OpenStackTenantsUtils.synchronizeOpenStackTenants();
List<OpenStackTenantsDataTable.OpenStackTenant> tenants = Lists.newArrayList();
for (OSTenantRestRep tenant : OpenStackTenantsUtils.getOpenStackTenantsFromDataBase()) {
if(tenant.getExcluded()) {
tenants.add(new OpenStackTenantsDataTable.OpenStackTenant(tenant));
}
}
renderJSON(DataTablesSupport.createJSON(tenants, params));
}
public static void tenantsListToRemoveJson() {
OpenStackTenantsUtils.synchronizeOpenStackTenants();
List<OpenStackTenantsDataTable.OpenStackTenant> tenants = Lists.newArrayList();
for (OSTenantRestRep tenant : OpenStackTenantsUtils.getOpenStackTenantsFromDataBase()) {
if(!tenant.getExcluded()) {
tenants.add(new OpenStackTenantsDataTable.OpenStackTenant(tenant));
}
}
renderJSON(DataTablesSupport.createJSON(tenants, params));
}
public static boolean isKeystoneAuthnProviderCreated() {
AuthnProviderRestRep authnProvider = AuthnProviderUtils.getKeystoneAuthProvider();
if (authnProvider != null && authnProvider.getAutoRegCoprHDNImportOSProjects()) {
return true;
}
return false;
}
public static String getInterval(AuthnProviderRestRep authnProvider) {
String interval = "";
for (String option : authnProvider.getTenantsSynchronizationOptions()) {
// There is only ADDITION, DELETION and interval in this StringSet.
if (!AuthnProvider.TenantsSynchronizationOptions.ADDITION.toString().equals(option) &&
!AuthnProvider.TenantsSynchronizationOptions.DELETION.toString().equals(option)) {
interval = option;
}
}
return interval;
}
public static class KeystoneSynchronizationTenantsDataTable extends OpenStackTenantsDataTable {
public KeystoneSynchronizationTenantsDataTable() {
alterColumn("name").setRenderFunction(null);
}
}
@FlashException("edit")
public static void syncOptions(TenantsSyncOptionsForm keystoneProvider) {
String interval = keystoneProvider.synchronizationInterval;
if (!StringUtils.isNumeric(interval) || (StringUtils.isNumeric(interval) && (Integer.parseInt(interval) < MIN_INTERVAL_DELAY))) {
flash.error(MessagesUtils.get(INTERVAL_ERROR, keystoneProvider.synchronizationInterval));
} else {
keystoneProvider.update();
flash.success(MessagesUtils.get(SAVED, authnProviderName));
}
list();
}
@FlashException("list")
public static void edit(String id) {
TenantOrgRestRep viprTenant = TenantUtils.getTenant(id);
if (viprTenant == null) {
flash.error(MessagesUtils.get(UNKNOWN, id));
list();
}
QuotaInfo quota = TenantUtils.getQuota(id);
if (viprTenant != null) {
TenantForm tenant = new TenantForm().from(viprTenant, quota);
tenant.usermapping = UserMappingForm.loadUserMappingForms(viprTenant.getUserMappings());
addRenderArgs(tenant);
//namespace entries
List<StringOption> allNamespace = TenantUtils.getUnmappedNamespace();
allNamespace.add(new StringOption(viprTenant.getNamespace(), viprTenant.getNamespace()));
renderArgs.put("namespaceOptions", allNamespace);
render(tenant);
}
else {
flash.error(MessagesUtils.get("tenants.unknown", id));
list();
}
}
@FlashException(keep = true, referrer = { "create", "edit" })
public static void save(TenantForm tenant) {
tenant.validate("tenant");
if (Validation.hasErrors()) {
Common.handleError();
}
if (tenant.isNew()) {
List<UserMappingParam> tempMappings = UserMappingForm.getAddedMappings(Collections.<UserMappingParam> emptyList(),
tenant.usermapping);
TenantCreateParam createParam = new TenantCreateParam(tenant.name, tempMappings);
createParam.setDescription(tenant.description);
if(tenant.enableNamespace){
createParam.setNamespace(tenant.namespace);
}
tenant.id = stringId(TenantUtils.create(createParam));
saveTenantQuota(tenant);
}
else {
TenantOrgRestRep currentTenant = TenantUtils.getTenant(tenant.id);
if (currentTenant != null) {
UserMappingChanges mappingChanges = null;
if (Security.isSecurityAdmin()) {
mappingChanges = new UserMappingChanges(UserMappingForm.getAddedMappings(currentTenant.getUserMappings(),
tenant.usermapping),
UserMappingForm.getRemovedMappings(currentTenant.getUserMappings(), tenant.usermapping));
}
TenantUpdateParam updateParam = new TenantUpdateParam(tenant.name, mappingChanges);
updateParam.setDescription(tenant.description);
if (tenant.enableNamespace) {
updateParam.setNamespace(tenant.namespace);
} else if (currentTenant.getNamespace() != null) {
updateParam.setDetachNamespace(true);
}
TenantUtils.update(tenant.id, updateParam);
// only SecurityAdmin and SystemAdmin has the permission to update Quota
if (Security.isSecurityAdmin() || Security.isSystemAdmin()) {
saveTenantQuota(tenant);
}
}
}
Security.clearUserInfo();
flash.success(MessagesUtils.get("tenants.saved", tenant.name));
list();
}
@Restrictions({ @Restrict("SECURITY_ADMIN") })
public static void create() {
TenantForm tenant = new TenantForm();
addRenderArgs(tenant);
render("@edit", tenant);
}
@FlashException("list")
@Restrictions({ @Restrict("SECURITY_ADMIN") })
public static void delete(@As(",") String[] ids) {
if (ids != null && ids.length > 0) {
boolean deleteExecuted = false;
for (String id : ids) {
if (TenantUtils.isRootTenant(uri(id))) {
flash.error(MessagesUtils.get("tenants.delete.root"));
}
else {
if (TenantUtils.deactivate(uri(id))) {
deleteExecuted = true;
}
}
}
if (deleteExecuted == true) {
Security.clearUserInfo();
flash.success(MessagesUtils.get("tenants.deleted"));
}
}
list();
}
@Util
private static void addRenderArgs(TenantForm tenant) {
List<String> domains = Lists.newArrayList();
for (AuthnProviderRestRep authProvider : AuthnProviderUtils.getAuthnProviders()) {
if (!authProvider.getDisable()) {
domains.addAll(authProvider.getDomains());
}
}
Gson g = new Gson();
renderArgs.put("domainsJson", g.toJson(domains));
List<StringOption> allNamespace = TenantUtils.getUnmappedNamespace();
renderArgs.put("namespaceOptions", allNamespace);
}
@Util
private static void saveTenantQuota(TenantForm tenant) {
if (tenant.enableQuota) {
TenantUtils.enableQuota(tenant.id, tenant.quota);
}
else {
TenantUtils.disableQuota(tenant.id);
}
}
@Restrictions({ @Restrict("SECURITY_ADMIN"), @Restrict("TENANT_ADMIN") })
public static void listRoles(String id) {
TenantRoleAssignmentDataTable dataTable = new TenantRoleAssignmentDataTable(uri(id));
TenantOrgRestRep tenant = TenantUtils.getTenant(id);
render("@listRoles", dataTable, tenant);
}
@Restrictions({ @Restrict("SECURITY_ADMIN"), @Restrict("TENANT_ADMIN") })
public static void listRolesJson(String id) {
List<RoleAssignmentEntry> viprRoleAssignments = getTenantRoleAssignments(id);
List<TenantRoleAssignmentDataTable.RoleInfo> roles = Lists.newArrayList();
for (RoleAssignmentEntry viprRoleAssignment : viprRoleAssignments) {
roles.add(new TenantRoleAssignmentDataTable.RoleInfo(viprRoleAssignment, id));
}
renderJSON(DataTablesSupport.createJSON(roles, params));
}
@Restrictions({ @Restrict("SECURITY_ADMIN"), @Restrict("TENANT_ADMIN") })
public static void editRole(@Required String id) {
// Extract info from id
String name = TenantRoleAssignmentForm.extractNameFromId(id);
RoleAssignmentType type = TenantRoleAssignmentForm.extractTypeFromId(id);
String tId = TenantRoleAssignmentForm.extractTenantFromId(id);
String tenantId = params.get("tenantId");
RoleAssignmentEntry roleAssignmentEntry = getTenantRoleAssignment(name, type, ResourceUtils.uri(tId));
if (roleAssignmentEntry != null) {
addTenantAndRolesToRenderArgs(tenantId);
Boolean isRootUser = RoleAssignmentUtils.isRootUser(roleAssignmentEntry);
TenantRoleAssignmentForm roleAssignment = new TenantRoleAssignmentForm();
roleAssignment.id = id;
roleAssignment.tenantId = tenantId;
roleAssignment.readFrom(roleAssignmentEntry);
render(roleAssignment, isRootUser);
}
else {
flash.error(MessagesUtils.get("roleAssignments.unknown", name));
listRoles(tenantId);
}
}
@FlashException(keep = true, referrer = { "createRole", "editRole" })
@Restrictions({ @Restrict("SECURITY_ADMIN"), @Restrict("TENANT_ADMIN") })
public static void saveRole(TenantRoleAssignmentForm roleAssignment) {
String tenantId = params.get("tenantId");
roleAssignment.validate(tenantId, "roleAssignment");
if (Validation.hasErrors()) {
Common.handleError();
}
roleAssignment.save(tenantId);
flash.success(MessagesUtils.get("roleAssignments.saved", roleAssignment.name));
if (RoleAssignmentType.USER.equals(roleAssignment.type)
&& Security.getUserInfo().getIdentifier().equalsIgnoreCase(roleAssignment.name)) {
Security.clearUserInfo();
}
listRoles(tenantId);
}
@Restrictions({ @Restrict("SECURITY_ADMIN"), @Restrict("TENANT_ADMIN") })
public static void createRole(@Required String tenantId) {
addTenantAndRolesToRenderArgs(tenantId);
TenantRoleAssignmentForm roleAssignment = new TenantRoleAssignmentForm();
render("@editRole", roleAssignment);
}
@Util
private static void addTenantAndRolesToRenderArgs(String tenantId) {
renderArgs.put("tenantId", tenantId);
renderArgs.put("currentTenantName", TenantUtils.getTenant(tenantId).getName());
renderArgs.put("roles", Roles.options(Roles.TENANT_ROLES));
}
/**
* Removes a number of role assignments from the given tenant, and redisplays the role assignment page.
*
* @param tenantId
* the tenant ID.
* @param ids
* the IDs of the roles to remove.
*/
@Restrictions({ @Restrict("SECURITY_ADMIN"), @Restrict("TENANT_ADMIN") })
public static void removeRoleAssignments(String tenantId, @As(",") String[] ids) {
if ((ids == null) || (ids.length == 0)) {
listRoles(tenantId);
}
deleteRoleAssignments(ids);
listRoles(tenantId);
}
@Util
private static void deleteRoleAssignments(String[] ids) {
if (ids != null && ids.length > 0) {
boolean deletedRoleAssignment = false;
for (String id : ids) {
String name = TenantRoleAssignmentForm.extractNameFromId(id);
RoleAssignmentType type = TenantRoleAssignmentForm.extractTypeFromId(id);
String tenantId = TenantRoleAssignmentForm.extractTenantFromId(id);
if (RoleAssignmentUtils.isRootUser(type, name)) {
flash.put("warningMessage", MessagesUtils.get("roleAssignments.rootNotDeleted"));
}
else {
deleteTenantRoleAssignment(tenantId, type, name);
deletedRoleAssignment = true;
}
}
if (deletedRoleAssignment) {
flash.success(MessagesUtils.get("roleAssignments.deleted"));
}
}
}
public static class TenantsSyncOptionsForm {
public String id;
public String name;
public List<String> tenantsSynchronizationOptions;
public String synchronizationInterval;
public void readFrom(AuthnProviderRestRep keystoneProvider) {
this.id = stringId(keystoneProvider);
this.name = keystoneProvider.getName();
this.tenantsSynchronizationOptions = Lists.newArrayList(keystoneProvider.getTenantsSynchronizationOptions());
}
private void update() {
AuthnUpdateParam param = new AuthnUpdateParam();
AuthnProviderRestRep provider = AuthnProviderUtils.getKeystoneAuthProvider();
AuthnUpdateParam.TenantsSynchronizationOptionsChanges tenantsSynchronizationOptionsChanges = getTenantsSynchronizationOptionsChanges(
provider);
if (!(tenantsSynchronizationOptionsChanges.getAdd().isEmpty() && tenantsSynchronizationOptionsChanges.getRemove().isEmpty())) {
param.setTenantsSynchronizationOptionsChanges(tenantsSynchronizationOptionsChanges);
param.setLabel(this.name);
param.setMode(provider.getMode());
AuthnProviderUtils.update(provider.getId().toString(), param);
}
}
private AuthnUpdateParam.TenantsSynchronizationOptionsChanges
getTenantsSynchronizationOptionsChanges(AuthnProviderRestRep provider) {
Set<String> newValues;
if (this.tenantsSynchronizationOptions != null) {
newValues = Sets.newHashSet(tenantsSynchronizationOptions);
newValues.add(synchronizationInterval);
} else {
newValues = Sets.newHashSet(synchronizationInterval);
}
Set<String> oldValues = provider.getTenantsSynchronizationOptions();
AuthnUpdateParam.TenantsSynchronizationOptionsChanges changes = new AuthnUpdateParam.TenantsSynchronizationOptionsChanges();
changes.getAdd().addAll(newValues);
changes.getAdd().removeAll(oldValues);
changes.getRemove().addAll(oldValues);
changes.getRemove().removeAll(newValues);
return changes;
}
}
public static class TenantForm {
public String id;
@Required
@MaxSize(128)
@MinSize(2)
public String name;
@MaxSize(128)
@MinSize(2)
public String description;
public List<UserMappingForm> usermapping = Lists.newArrayList();
public Boolean enableQuota = Boolean.FALSE;
public Long quota;
public Boolean enableNamespace = Boolean.FALSE;
public String namespace;
public TenantForm from(TenantOrgRestRep from, QuotaInfo quota) {
this.id = from.getId().toString();
this.name = from.getName();
this.description = from.getDescription();
this.namespace = from.getNamespace();
if (null != from.getNamespace()) {
this.enableNamespace = Boolean.TRUE;
}
this.enableQuota = quota.getEnabled();
this.quota = quota.getQuotaInGb();
return this;
}
public boolean isNew() {
return StringUtils.isBlank(id);
}
public void validate(String formName) {
Validation.valid(formName, this);
// if the user is not security admin, skip validation for user-mapping and quota below
// as the fields are disabled in UI, and should be no change for them.
if (!Security.isSecurityAdmin()) {
return;
}
// Root Tenant is special in that it doesn't need UserMappings
if (!TenantUtils.isRootTenant(uri(id))) {
if (usermapping.isEmpty()) {
Validation.addError(formName + ".usermapping", Messages.get("tenant.userMappingRequired"));
}
}
for (UserMappingForm userMappingForm : usermapping) {
try {
if (userMappingForm != null) {
userMappingForm.validate();
}
} catch (Exception e) {
Validation.addError(formName + ".usermapping", e.getMessage());
}
}
if (enableQuota) {
if (this.quota == null) {
Validation.addError(formName + ".quota", MessagesUtils.get("tenant.quota.error.required"));
}
else {
String quotaParamName = formName + ".quota";
String quotaParamString = params.get(quotaParamName);
try {
int quota = Integer.parseInt(quotaParamString);
if (quota <= 0) {
Validation.addError(quotaParamName, MessagesUtils.get("tenant.quota.error.mustBeBigger"));
}
} catch (NumberFormatException e) {
Validation.addError(quotaParamName, MessagesUtils.get("tenant.quota.error.invalid"));
}
}
}
}
}
public static class TenantRoleAssignmentForm {
private static final String ID_DELIMITER = "~~~~";
public String id;
@Required
@MaxSize(128)
@MinSize(2)
public String name;
@Required
public RoleAssignmentType type = RoleAssignmentType.GROUP;
public String tenantId;
public Boolean tenantAdmin = Boolean.FALSE;
public Boolean projectAdmin = Boolean.FALSE;
public Boolean tenantApprover = Boolean.FALSE;
public static String createId(String tenantId, String name, RoleAssignmentType type) {
return tenantId + ID_DELIMITER + name + ID_DELIMITER + type.name();
}
public static String extractNameFromId(String id) {
if (StringUtils.isNotBlank(id)) {
String[] parts = id.split(ID_DELIMITER);
if (parts.length == 3) {
return parts[1];
}
else {
return id;
}
}
return null;
}
public static String extractTenantFromId(String id) {
if (StringUtils.isNotBlank(id)) {
String[] parts = id.split(ID_DELIMITER);
if (parts.length == 3) {
return parts[0];
}
}
return null;
}
public static RoleAssignmentType extractTypeFromId(String id) {
if (StringUtils.isNotBlank(id)) {
String[] parts = id.split(ID_DELIMITER);
if (parts.length == 3) {
return RoleAssignmentType.valueOf(parts[2]);
}
}
return null;
}
public boolean isNew() {
return StringUtils.isBlank(id);
}
public void validate(String tenantId, String formName) {
Validation.valid(formName, this);
if (isNew()) {
// Ensure we aren't overwriting an existing role assignment with this new one
RoleAssignmentEntry roleAssignmentEntry = getTenantRoleAssignment(name, type, ResourceUtils.uri(tenantId));
if (roleAssignmentEntry != null) {
Validation.addError(formName + ".name", Messages.get("roleAssignments." + type + ".alreadyExists"));
}
boolean atLeastOneChecked = tenantAdmin || projectAdmin || tenantApprover;
if (atLeastOneChecked == false) {
flash.error(Messages.get("roleAssignments.atLeastOneChecked"));
Validation.addError(formName, Messages.get("roleAssignments.atLeastOneChecked")); // here to fail validation
}
}
}
public void save(String tenantId) {
RoleAssignmentEntry roleAssignmentEntry = getTenantRoleAssignment(name, type, ResourceUtils.uri(tenantId));
if (Security.isSecurityAdmin() || Security.isTenantAdmin()) {
List<RoleAssignmentEntry> tenantRolesToAdd = Lists.newArrayList();
List<RoleAssignmentEntry> tenantRolesToRemove = Lists.newArrayList();
writeTenantRoleChangesTo(roleAssignmentEntry, tenantRolesToAdd, tenantRolesToRemove);
if (!tenantRolesToAdd.isEmpty() || !tenantRolesToRemove.isEmpty()) {
putTenantRoleAssignmentChanges(tenantId, tenantRolesToAdd, tenantRolesToRemove);
}
}
}
public void readFrom(RoleAssignmentEntry bourneRoleAssignment) {
if (StringUtils.isNotBlank(bourneRoleAssignment.getSubjectId())) {
name = bourneRoleAssignment.getSubjectId();
type = RoleAssignmentType.USER;
}
else {
name = bourneRoleAssignment.getGroup();
type = RoleAssignmentType.GROUP;
}
id = createId(tenantId, name, type);
tenantAdmin = isRoleAssigned(bourneRoleAssignment, Security.TENANT_ADMIN);
projectAdmin = isRoleAssigned(bourneRoleAssignment, Security.PROJECT_ADMIN);
tenantApprover = isRoleAssigned(bourneRoleAssignment, Security.TENANT_APPROVER);
}
private boolean isRoleAssigned(RoleAssignmentEntry roleAssignParamEntry, String findRole) {
if (roleAssignParamEntry.getRoles() != null && findRole != null) {
return roleAssignParamEntry.getRoles().contains(findRole);
}
return false;
}
private boolean hasRoleChanged(RoleAssignmentEntry roleAssignParamEntry, String findRole) {
if (roleAssignParamEntry != null) {
boolean value = isRoleAssigned(roleAssignParamEntry, findRole);
if (Roles.isTenantAdmin(findRole)) {
return tenantAdmin != value;
}
else if (Roles.isProjectAdmin(findRole)) {
return projectAdmin != value;
}
else if (Roles.isTenantApprover(findRole)) {
return tenantApprover != value;
}
}
return true;
}
public void writeTenantRoleChangesTo(RoleAssignmentEntry roleAssignmentEntry, List<RoleAssignmentEntry> add,
List<RoleAssignmentEntry> remove) {
RoleAssignmentEntry rae = createRoleAssignmentEntry(type, name, Security.TENANT_ADMIN);
if (hasRoleChanged(roleAssignmentEntry, Security.TENANT_ADMIN)) {
if (tenantAdmin != null && tenantAdmin == true) {
add.add(rae);
}
else {
remove.add(rae);
}
}
rae = createRoleAssignmentEntry(type, name, Security.PROJECT_ADMIN);
if (hasRoleChanged(roleAssignmentEntry, Security.PROJECT_ADMIN)) {
if (projectAdmin != null && projectAdmin == true) {
add.add(rae);
}
else {
remove.add(rae);
}
}
rae = createRoleAssignmentEntry(type, name, Security.TENANT_APPROVER);
if (hasRoleChanged(roleAssignmentEntry, Security.TENANT_APPROVER)) {
if (tenantApprover != null && tenantApprover == true) {
add.add(rae);
}
else {
remove.add(rae);
}
}
}
}
}