/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package controllers.auth; import com.emc.storageos.api.service.impl.resource.UserGroupService; import com.emc.storageos.model.auth.AuthnProviderRestRep; import com.emc.storageos.model.usergroup.*; import com.emc.storageos.model.usergroup.UserGroupUpdateParam; import com.emc.storageos.model.usergroup.UserGroupCreateParam; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import controllers.Common; import controllers.deadbolt.Restrict; import controllers.deadbolt.Restrictions; import controllers.security.Security; import controllers.util.FlashException; import controllers.util.ViprResourceController; import models.datatable.UserGroupDataTable; import models.datatable.UserGroupDataTable.UserGroupInfo; import org.apache.commons.lang.StringUtils; import org.springframework.util.CollectionUtils; 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.mvc.With; import util.AuthnProviderUtils; import util.MessagesUtils; import util.StringOption; import util.UserGroupUtils; import java.net.URI; import java.util.HashSet; import java.util.List; import java.util.Set; import static com.emc.vipr.client.core.util.ResourceUtils.uris; /** * Controller for User Group widget. */ @With(Common.class) @Restrictions({ @Restrict("SECURITY_ADMIN"), @Restrict("TENANT_ADMIN") }) public class UserGroup extends ViprResourceController { protected static final String SAVED = "userGroup.saved"; protected static final String DELETED = "userGroup.deleted"; protected static final String FAILED = "userGroup.failed"; protected static final String UNKNOWN = "userGroup.unknown"; protected static final String MODEL_NAME = "userGroup"; public static final String EXPECTED_GEO_VERSION = UserGroupService.getExpectedGeoVDCVersion(); // // Add reference data so that they can be reference in html template // private static void addReferenceData() { List<StringOption> domains = Lists.newArrayList(); for (AuthnProviderRestRep authProvider : AuthnProviderUtils.getAuthnProviders()) { if (!authProvider.getDisable()) { for (String domain : authProvider.getDomains()) { StringOption domainOption = new StringOption(domain, StringOption.getDisplayValue(domain, "Domains")); domains.add(domainOption); } } } renderArgs.put("domainsJson", domains); } /** * if it was not redirect from another page, clean flash * */ public static void list() { renderArgs.put("dataTable", new UserGroupDataTable()); render(); } public static void listJson() { performListJson(UserGroupUtils.getUserGroups(), new JsonItemOperation()); } @Restrictions({ @Restrict("SECURITY_ADMIN") }) public static void create() { UserGroupForm userGroup = new UserGroupForm(); // put all "initial create only" defaults here rather than field initializers edit(userGroup); } @Restrictions({ @Restrict("SECURITY_ADMIN") }) private static void edit(UserGroupForm userGroup) { addReferenceData(); render("@edit", userGroup); } @FlashException("list") @Restrictions({ @Restrict("SECURITY_ADMIN") }) public static void edit(String id) { UserGroupRestRep userGroup = UserGroupUtils.getUserGroup(id); if (userGroup == null) { flash.error(MessagesUtils.get(UNKNOWN, id)); list(); } edit(new UserGroupForm(userGroup)); } @FlashException(keep = true) public static void save(UserGroupForm userGroup) { userGroup.validate("userGroup"); if (Validation.hasErrors()) { Common.handleError(); } userGroup.save(); flash.success(MessagesUtils.get(SAVED, userGroup.name)); list(); } public static void delete(@As(",") String[] ids) { delete(uris(ids)); } private static void delete(List<URI> ids) { performSuccessFail(ids, new DeleteOperation(), DELETED, FAILED); list(); } public static class UserGroupForm { private static String LINE_BREAK = "\r\n"; public String id; @Required @MaxSize(128) @MinSize(2) public String name; @Required public String domain; public List<AttributeMapping> attributes = Lists.newArrayList(); public UserGroupForm() { } public UserGroupForm(UserGroupRestRep userGroupRep) { readFrom(userGroupRep); } public boolean isNew() { return StringUtils.isBlank(id); } public void readFrom(UserGroupRestRep userGroupRep) { this.id = stringId(userGroupRep); this.name = userGroupRep.getName(); this.domain = userGroupRep.getDomain(); if (!CollectionUtils.isEmpty(userGroupRep.getAttributes())) { for (UserAttributeParam userAttributeMapping : userGroupRep.getAttributes()) { if (userAttributeMapping != null) { AttributeMapping mapping = new AttributeMapping(); mapping.key = userAttributeMapping.getKey(); mapping.values = StringUtils.join(userAttributeMapping.getValues(), "\n"); this.attributes.add(mapping); } } } } public UserGroupRestRep save() { if (isNew()) { return create(); } else { return update(); } } private UserGroupRestRep create() { UserGroupCreateParam param = new UserGroupCreateParam(); param.setLabel(this.name); param.setDomain(this.domain); for (AttributeMapping mapping : this.attributes) { if (mapping != null) { param.getAttributes().add(mapping.createUserAttributeParam()); } } return UserGroupUtils.create(param); } private UserGroupRestRep update() { UserGroupUpdateParam param = new UserGroupUpdateParam(); UserGroupRestRep userGroupRestRep = UserGroupUtils.getUserGroup(this.id); param.setLabel(userGroupRestRep.getName()); param.setDomain(this.domain); Set<UserAttributeParam> oldAttributes = userGroupRestRep.getAttributes(); Set<UserAttributeParam> newAttributes = new HashSet<UserAttributeParam>(); for (AttributeMapping mapping : this.attributes) { if (mapping != null) { newAttributes.add(mapping.createUserAttributeParam()); } } param.getAddAttributes().addAll(newAttributes); param.getAddAttributes().removeAll(oldAttributes); for (UserAttributeParam oldAttribute : oldAttributes) { param.getRemoveAttributes().add(oldAttribute.getKey()); } for (UserAttributeParam newAttribute : newAttributes) { param.getRemoveAttributes().remove(newAttribute.getKey()); } return UserGroupUtils.update(this.id, param); } public void validate(String fieldName) { Validation.valid(fieldName, this); Validation.required(fieldName + ".name", this.name); Validation.required(fieldName + ".domain", this.domain); if (this.name.contains("@")) { Validation.addError(fieldName + ".name", "userGroup.name.invalid"); } validateAttributeEntries(fieldName); } public void validateAttributeEntries(String fieldName) { int attributeIndex = 0; for (AttributeMapping mapping : this.attributes) { if (mapping != null) { if (StringUtils.isBlank(mapping.key)) { Validation.addError(fieldName + ".attributes[" + attributeIndex + "].key", "userGroup.attributes.key.required"); } if (StringUtils.isBlank(mapping.values)) { Validation.addError(fieldName + ".attributes[" + attributeIndex + "].values", "userGroup.attributes.values.required"); } } attributeIndex++; } } public static class AttributeMapping { public String key; public String values; public UserAttributeParam createUserAttributeParam() { UserAttributeParam attributeParam = new UserAttributeParam(); attributeParam.setKey(key); Set<String> valueList = Sets.newHashSet(); if (!StringUtils.isBlank(this.values)) { String[] values = this.values.split(LINE_BREAK); for (String val : values) { if (!StringUtils.isBlank(val.trim())) { valueList.add(val.trim()); } } } attributeParam.setValues(valueList); return attributeParam; } } } protected static class JsonItemOperation implements ResourceValueOperation<UserGroupInfo, UserGroupRestRep> { @Override public UserGroupInfo performOperation(UserGroupRestRep userGroupRestRep) throws Exception { return new UserGroupInfo(userGroupRestRep, Security.isSecurityAdmin()); } } protected static class DeleteOperation implements ResourceIdOperation<Void> { @Override public Void performOperation(URI id) throws Exception { UserGroupUtils.delete(id); return null; } } }