未验证 提交 0bc91cc1 编写于 作者: J Jason Song 提交者: GitHub

Merge pull request #1282 from nobodyiam/branch_env_permission

Support role permissions per environment
......@@ -19,26 +19,25 @@ public class ConsumerPermissionValidator {
private ConsumerAuthUtil consumerAuthUtil;
public boolean hasModifyNamespacePermission(HttpServletRequest request, String appId, String
namespaceName) {
public boolean hasModifyNamespacePermission(HttpServletRequest request, String appId, String namespaceName,
String env) {
if (hasCreateNamespacePermission(request, appId)) {
return true;
}
return permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request),
PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
RoleUtils.buildNamespaceTargetId(appId, namespaceName, env));
}
public boolean hasReleaseNamespacePermission(HttpServletRequest request, String appId, String
namespaceName) {
public boolean hasReleaseNamespacePermission(HttpServletRequest request, String appId, String namespaceName,
String env) {
if (hasCreateNamespacePermission(request, appId)) {
return true;
}
return permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request),
PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
RoleUtils.buildNamespaceTargetId(appId, namespaceName, env));
}
......
......@@ -112,17 +112,21 @@ public class ConsumerService {
return consumerRepository.findOne(consumerId);
}
@Transactional
public List<ConsumerRole> assignNamespaceRoleToConsumer(String token, String appId, String namespaceName) {
return assignNamespaceRoleToConsumer(token, appId, namespaceName, null);
}
@Transactional
public List<ConsumerRole> assignNamespaceRoleToConsumer(String token, String appId, String namespaceName, String env) {
Long consumerId = getConsumerIdByToken(token);
if (consumerId == null) {
throw new BadRequestException("Token is Illegal");
}
Role namespaceModifyRole =
rolePermissionService.findRoleByRoleName(RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName));
rolePermissionService.findRoleByRoleName(RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName, env));
Role namespaceReleaseRole =
rolePermissionService.findRoleByRoleName(RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName));
rolePermissionService.findRoleByRoleName(RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName, env));
if (namespaceModifyRole == null || namespaceReleaseRole == null) {
throw new BadRequestException("Namespace's role does not exist. Please check whether namespace has created.");
......
......@@ -32,7 +32,7 @@ public class ItemController {
private UserService userService;
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName)")
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.POST)
public OpenItemDTO createItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......@@ -60,7 +60,7 @@ public class ItemController {
return OpenApiBeanUtils.transformFromItemDTO(createdItem);
}
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName)")
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{key:.+}", method = RequestMethod.PUT)
public void updateItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......@@ -91,7 +91,7 @@ public class ItemController {
}
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName)")
@PreAuthorize(value = "@consumerPermissionValidator.hasModifyNamespacePermission(#request, #appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{key:.+}", method = RequestMethod.DELETE)
public void deleteItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......
......@@ -33,7 +33,7 @@ public class ReleaseController {
@Autowired
private UserService userService;
@PreAuthorize(value = "@consumerPermissionValidator.hasReleaseNamespacePermission(#request, #appId, #namespaceName)")
@PreAuthorize(value = "@consumerPermissionValidator.hasReleaseNamespacePermission(#request, #appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases", method = RequestMethod.POST)
public OpenReleaseDTO createRelease(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName,
......
......@@ -6,7 +6,6 @@ import com.ctrip.framework.apollo.portal.constant.PermissionType;
import com.ctrip.framework.apollo.portal.service.RolePermissionService;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;
import com.ctrip.framework.apollo.portal.util.RoleUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
......@@ -22,14 +21,26 @@ public class PermissionValidator {
public boolean hasModifyNamespacePermission(String appId, String namespaceName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
}
public boolean hasModifyNamespacePermission(String appId, String namespaceName, String env) {
return hasModifyNamespacePermission(appId, namespaceName) ||
rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.MODIFY_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName, env));
}
public boolean hasReleaseNamespacePermission(String appId, String namespaceName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
}
public boolean hasReleaseNamespacePermission(String appId, String namespaceName, String env) {
return hasReleaseNamespacePermission(appId, namespaceName) ||
rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.RELEASE_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName, env));
}
public boolean hasDeleteNamespacePermission(String appId) {
......@@ -40,17 +51,23 @@ public class PermissionValidator {
return hasModifyNamespacePermission(appId, namespaceName) || hasReleaseNamespacePermission(appId, namespaceName);
}
public boolean hasOperateNamespacePermission(String appId, String namespaceName, String env) {
return hasOperateNamespacePermission(appId, namespaceName) ||
hasModifyNamespacePermission(appId, namespaceName, env) ||
hasReleaseNamespacePermission(appId, namespaceName, env);
}
public boolean hasAssignRolePermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.ASSIGN_ROLE,
appId);
PermissionType.ASSIGN_ROLE,
appId);
}
public boolean hasCreateNamespacePermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.CREATE_NAMESPACE,
appId);
PermissionType.CREATE_NAMESPACE,
appId);
}
public boolean hasCreateAppNamespacePermission(String appId, AppNamespace appNamespace) {
......@@ -66,8 +83,8 @@ public class PermissionValidator {
public boolean hasCreateClusterPermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.CREATE_CLUSTER,
appId);
PermissionType.CREATE_CLUSTER,
appId);
}
public boolean isAppAdmin(String appId) {
......
......@@ -104,7 +104,7 @@ public abstract class ConfigPublishEmailBuilder {
email.setSubject(subject());
email.setSenderEmailAddress(portalConfig.emailSender());
email.setRecipients(recipients(releaseHistory.getAppId(), releaseHistory.getNamespaceName()));
email.setRecipients(recipients(releaseHistory.getAppId(), releaseHistory.getNamespaceName(), env.toString()));
String emailBody = emailContent(env, releaseHistory);
//clear not used module
......@@ -208,13 +208,19 @@ public abstract class ConfigPublishEmailBuilder {
return releaseService.compare(env, releaseHistory.getPreviousReleaseId(), releaseHistory.getReleaseId());
}
private List<String> recipients(String appId, String namespaceName) {
private List<String> recipients(String appId, String namespaceName, String env) {
Set<UserInfo> modifyRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.MODIFY_NAMESPACE));
Set<UserInfo> envModifyRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.MODIFY_NAMESPACE, env));
Set<UserInfo> releaseRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.RELEASE_NAMESPACE));
Set<UserInfo> envReleaseRoleUsers =
rolePermissionService
.queryUsersWithRole(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.RELEASE_NAMESPACE, env));
Set<UserInfo> owners = rolePermissionService.queryUsersWithRole(RoleUtils.buildAppMasterRoleName(appId));
Set<String> userIds = new HashSet<>(modifyRoleUsers.size() + releaseRoleUsers.size() + owners.size());
......@@ -223,10 +229,18 @@ public abstract class ConfigPublishEmailBuilder {
userIds.add(userInfo.getUserId());
}
for (UserInfo userInfo : envModifyRoleUsers) {
userIds.add(userInfo.getUserId());
}
for (UserInfo userInfo : releaseRoleUsers) {
userIds.add(userInfo.getUserId());
}
for (UserInfo userInfo : envReleaseRoleUsers) {
userIds.add(userInfo.getUserId());
}
for (UserInfo userInfo : owners) {
userIds.add(userInfo.getUserId());
}
......
package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.portal.service.RoleInitializationService;
import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.http.MultiResponseEntity;
......@@ -53,6 +56,8 @@ public class AppController {
private ApplicationEventPublisher publisher;
@Autowired
private RolePermissionService rolePermissionService;
@Autowired
private RoleInitializationService roleInitializationService;
@RequestMapping(value = "", method = RequestMethod.GET)
public List<App> findApps(@RequestParam(value = "appIds", required = false) String appIds) {
......@@ -132,6 +137,8 @@ public class AppController {
appService.createAppInRemote(Env.valueOf(env), app);
roleInitializationService.initNamespaceSpecificEnvRoles(app.getAppId(), ConfigConsts.NAMESPACE_APPLICATION, env, userInfoHolder.getUser().getUserId());
return ResponseEntity.ok().build();
}
......
......@@ -2,12 +2,15 @@ package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.core.enums.EnvUtils;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.openapi.entity.Consumer;
import com.ctrip.framework.apollo.openapi.entity.ConsumerRole;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import com.ctrip.framework.apollo.openapi.service.ConsumerService;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
......@@ -19,12 +22,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Objects;
import java.util.*;
/**
* @author Jason Song(song_s@ctrip.com)
......@@ -69,6 +67,7 @@ public class ConsumerController {
@RequestMapping(value = "/consumers/{token}/assign-role", method = RequestMethod.POST)
public List<ConsumerRole> assignNamespaceRoleToConsumer(@PathVariable String token,
@RequestParam String type,
@RequestParam(required = false) String envs,
@RequestBody NamespaceDTO namespace) {
String appId = namespace.getAppId();
......@@ -77,13 +76,33 @@ public class ConsumerController {
if (StringUtils.isEmpty(appId)) {
throw new BadRequestException("Params(AppId) can not be empty.");
}
if (Objects.equals("AppRole", type)) {
return Collections.singletonList(consumerService.assignAppRoleToConsumer(token, appId));
} else {
if (StringUtils.isEmpty(namespaceName)) {
throw new BadRequestException("Params(NamespaceName) can not be empty.");
}
if (null != envs){
String[] envArray = envs.split(",");
List<String> envList = Lists.newArrayList();
// validate env parameter
for (String env : envArray) {
if (Strings.isNullOrEmpty(env)) {
continue;
}
if (null == EnvUtils.transformEnv(env)) {
throw new BadRequestException(String.format("env: %s is illegal", env));
}
envList.add(env);
}
List<ConsumerRole> consumeRoles = new ArrayList<>();
for (String env : envList) {
consumeRoles.addAll(consumerService.assignNamespaceRoleToConsumer(token, appId, namespaceName, env));
}
return consumeRoles;
}
return consumerService.assignNamespaceRoleToConsumer(token, appId, namespaceName);
}
}
......
......@@ -4,15 +4,18 @@ import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.component.PermissionValidator;
import com.ctrip.framework.apollo.portal.entity.model.NamespaceSyncModel;
import com.ctrip.framework.apollo.portal.entity.model.NamespaceTextModel;
import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifier;
import com.ctrip.framework.apollo.portal.service.ItemService;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
......@@ -34,8 +37,10 @@ public class ItemController {
private ItemService configService;
@Autowired
private UserInfoHolder userInfoHolder;
@Autowired
private PermissionValidator permissionValidator;
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = {
"application/json"})
public void modifyItemsByText(@PathVariable String appId, @PathVariable String env,
......@@ -52,7 +57,7 @@ public class ItemController {
configService.updateConfigItemByText(model);
}
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.POST)
public ItemDTO createItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......@@ -71,7 +76,7 @@ public class ItemController {
return configService.createItem(appId, Env.valueOf(env), clusterName, namespaceName, item);
}
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.PUT)
public void updateItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......@@ -85,7 +90,7 @@ public class ItemController {
}
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env) ")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}", method = RequestMethod.DELETE)
public void deleteItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......@@ -134,15 +139,32 @@ public class ItemController {
return configService.compare(model.getSyncToNamespaces(), model.getSyncItems());
}
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = {
"application/json"})
public ResponseEntity<Void> update(@PathVariable String appId, @PathVariable String namespaceName,
@RequestBody NamespaceSyncModel model) {
checkModel(Objects.nonNull(model) && !model.isInvalid());
configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems());
return ResponseEntity.status(HttpStatus.OK).build();
boolean hasPermission = permissionValidator.hasModifyNamespacePermission(appId, namespaceName);
Env envNoPermission = null;
// if uses has ModifyNamespace permission then he has permission
if (!hasPermission) {
// else check if user has every env's ModifyNamespace permission
hasPermission = true;
for (NamespaceIdentifier namespaceIdentifier : model.getSyncToNamespaces()) {
// once user has not one of the env's ModifyNamespace permission, then break the loop
hasPermission &= permissionValidator.hasModifyNamespacePermission(namespaceIdentifier.getAppId(), namespaceIdentifier.getNamespaceName(), namespaceIdentifier.getEnv().toString());
if (!hasPermission) {
envNoPermission = namespaceIdentifier.getEnv();
break;
}
}
}
if (hasPermission) {
configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems());
return ResponseEntity.status(HttpStatus.OK).build();
}
else
throw new AccessDeniedException(String.format("您没有修改环境%s的权限", envNoPermission));
}
private boolean isValidItem(ItemDTO item) {
......
......@@ -46,7 +46,7 @@ public class NamespaceBranchController {
return namespaceBranchService.findBranch(appId, Env.valueOf(env), clusterName, namespaceName);
}
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches", method = RequestMethod.POST)
public NamespaceDTO createBranch(@PathVariable String appId,
@PathVariable String env,
......@@ -63,9 +63,9 @@ public class NamespaceBranchController {
@PathVariable String namespaceName,
@PathVariable String branchName) {
boolean canDelete = permissionValidator.hasReleaseNamespacePermission(appId, namespaceName) ||
(permissionValidator.hasModifyNamespacePermission(appId, namespaceName) &&
releaseService.loadLatestRelease(appId, Env.valueOf(env), branchName, namespaceName) == null);
boolean canDelete = permissionValidator.hasReleaseNamespacePermission(appId, namespaceName, env) ||
(permissionValidator.hasModifyNamespacePermission(appId, namespaceName, env) &&
releaseService.loadLatestRelease(appId, Env.valueOf(env), branchName, namespaceName) == null);
if (!canDelete) {
......@@ -81,7 +81,7 @@ public class NamespaceBranchController {
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/merge", method = RequestMethod.POST)
public ReleaseDTO merge(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......@@ -120,7 +120,7 @@ public class NamespaceBranchController {
}
@PreAuthorize(value = "@permissionValidator.hasOperateNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasOperateNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/rules", method = RequestMethod.PUT)
public void updateBranchRules(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
......
......@@ -104,6 +104,7 @@ public class NamespaceController {
String operator = userInfoHolder.getUser().getUserId();
roleInitializationService.initNamespaceRoles(appId, namespaceName, operator);
roleInitializationService.initNamespaceEnvRoles(appId, namespaceName, operator);
for (NamespaceCreationModel model : models) {
NamespaceDTO namespace = model.getNamespace();
......
package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.enums.EnvUtils;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceEnvRolesAssignedUsers;
import com.ctrip.framework.apollo.portal.service.RoleInitializationService;
import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
......@@ -37,6 +41,14 @@ public class PermissionController {
private RolePermissionService rolePermissionService;
@Autowired
private UserService userService;
@Autowired
private RoleInitializationService roleInitializationService;
@RequestMapping(value = "/apps/{appId}/initPermission", method = RequestMethod.POST)
public ResponseEntity<Void> initAppPermission(@PathVariable String appId, @RequestBody String namespaceName) {
roleInitializationService.initNamespaceEnvRoles(appId, namespaceName, userInfoHolder.getUser().getUserId());
return ResponseEntity.ok().build();
}
@RequestMapping(value = "/apps/{appId}/permissions/{permissionType}", method = RequestMethod.GET)
public ResponseEntity<PermissionCondition> hasPermission(@PathVariable String appId, @PathVariable String permissionType) {
......@@ -60,6 +72,18 @@ public class PermissionController {
return ResponseEntity.ok().body(permissionCondition);
}
@RequestMapping(value = "/apps/{appId}/envs/{env}/namespaces/{namespaceName}/permissions/{permissionType}", method = RequestMethod.GET)
public ResponseEntity<PermissionCondition> hasPermission(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName,
@PathVariable String permissionType) {
PermissionCondition permissionCondition = new PermissionCondition();
permissionCondition.setHasPermission(
rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), permissionType,
RoleUtils.buildNamespaceTargetId(appId, namespaceName, env)));
return ResponseEntity.ok().body(permissionCondition);
}
@RequestMapping(value = "/permissions/root", method = RequestMethod.GET)
public ResponseEntity<PermissionCondition> hasRootPermission() {
PermissionCondition permissionCondition = new PermissionCondition();
......@@ -70,6 +94,72 @@ public class PermissionController {
}
@RequestMapping(value = "/apps/{appId}/envs/{env}/namespaces/{namespaceName}/role_users", method = RequestMethod.GET)
public NamespaceEnvRolesAssignedUsers getNamespaceEnvRoles(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName) {
// validate env parameter
if (null == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal");
}
NamespaceEnvRolesAssignedUsers assignedUsers = new NamespaceEnvRolesAssignedUsers();
assignedUsers.setNamespaceName(namespaceName);
assignedUsers.setAppId(appId);
assignedUsers.setEnv(Env.fromString(env));
Set<UserInfo> releaseNamespaceUsers =
rolePermissionService.queryUsersWithRole(RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName, env));
assignedUsers.setReleaseRoleUsers(releaseNamespaceUsers);
Set<UserInfo> modifyNamespaceUsers =
rolePermissionService.queryUsersWithRole(RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName, env));
assignedUsers.setModifyRoleUsers(modifyNamespaceUsers);
return assignedUsers;
}
@PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/namespaces/{namespaceName}/roles/{roleType}", method = RequestMethod.POST)
public ResponseEntity<Void> assignNamespaceEnvRoleToUser(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName,
@PathVariable String roleType, @RequestBody String user) {
checkUserExists(user);
RequestPrecondition.checkArgumentsNotEmpty(user);
if (!RoleType.isValidRoleType(roleType)) {
throw new BadRequestException("role type is illegal");
}
// validate env parameter
if (null == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal");
}
Set<String> assignedUser = rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType, env),
Sets.newHashSet(user), userInfoHolder.getUser().getUserId());
if (CollectionUtils.isEmpty(assignedUser)) {
throw new BadRequestException(user + "已授权");
}
return ResponseEntity.ok().build();
}
@PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/namespaces/{namespaceName}/roles/{roleType}", method = RequestMethod.DELETE)
public ResponseEntity<Void> removeNamespaceEnvRoleFromUser(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName,
@PathVariable String roleType, @RequestParam String user) {
RequestPrecondition.checkArgumentsNotEmpty(user);
if (!RoleType.isValidRoleType(roleType)) {
throw new BadRequestException("role type is illegal");
}
// validate env parameter
if (null == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal");
}
rolePermissionService.removeRoleFromUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType, env),
Sets.newHashSet(user), userInfoHolder.getUser().getUserId());
return ResponseEntity.ok().build();
}
@RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/role_users", method = RequestMethod.GET)
public NamespaceRolesAssignedUsers getNamespaceRoles(@PathVariable String appId, @PathVariable String namespaceName) {
......
......@@ -36,7 +36,7 @@ public class ReleaseController {
@Autowired
private PortalConfig portalConfig;
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/releases", method = RequestMethod.POST)
public ReleaseDTO createRelease(@PathVariable String appId,
@PathVariable String env, @PathVariable String clusterName,
......@@ -67,7 +67,7 @@ public class ReleaseController {
return createdRelease;
}
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName)")
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/releases",
method = RequestMethod.POST)
public ReleaseDTO createGrayRelease(@PathVariable String appId,
......@@ -138,6 +138,7 @@ public class ReleaseController {
}
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)")
@RequestMapping(path = "/envs/{env}/releases/{releaseId}/rollback", method = RequestMethod.PUT)
public void rollback(@PathVariable String env,
@PathVariable long releaseId) {
......
package com.ctrip.framework.apollo.portal.entity.vo;
import com.ctrip.framework.apollo.core.enums.Env;
public class NamespaceEnvRolesAssignedUsers extends NamespaceRolesAssignedUsers {
private Env env;
public Env getEnv() {
return env;
}
public void setEnv(Env env) {
this.env = env;
}
}
......@@ -116,6 +116,7 @@ public class AppNamespaceService {
AppNamespace createdAppNamespace = appNamespaceRepository.save(appNamespace);
roleInitializationService.initNamespaceRoles(appNamespace.getAppId(), appNamespace.getName(), operator);
roleInitializationService.initNamespaceEnvRoles(appNamespace.getAppId(), appNamespace.getName(), operator);
return createdAppNamespace;
}
......
......@@ -8,4 +8,8 @@ public interface RoleInitializationService {
public void initNamespaceRoles(String appId, String namespaceName, String operator);
public void initNamespaceEnvRoles(String appId, String namespaceName, String operator);
public void initNamespaceSpecificEnvRoles(String appId, String namespaceName, String env, String operator);
}
package com.ctrip.framework.apollo.portal.spi.defaultimpl;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
......@@ -18,7 +20,7 @@ import com.ctrip.framework.apollo.portal.util.RoleUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.Set;
import java.util.*;
/**
* Created by timothy on 2017/4/26.
......@@ -29,6 +31,8 @@ public class DefaultRoleInitializationService implements RoleInitializationServi
private UserInfoHolder userInfoHolder;
@Autowired
private RolePermissionService rolePermissionService;
@Autowired
private PortalConfig portalConfig;
@Transactional
public void initAppRoles(App app) {
......@@ -47,9 +51,10 @@ public class DefaultRoleInitializationService implements RoleInitializationServi
//assign master role to user
rolePermissionService
.assignRoleToUsers(RoleUtils.buildAppMasterRoleName(appId), Sets.newHashSet(app.getOwnerName()),
operator);
operator);
initNamespaceRoles(appId, ConfigConsts.NAMESPACE_APPLICATION, operator);
initNamespaceEnvRoles(appId, ConfigConsts.NAMESPACE_APPLICATION, operator);
//assign modify、release namespace role to user
rolePermissionService.assignRoleToUsers(
......@@ -67,13 +72,37 @@ public class DefaultRoleInitializationService implements RoleInitializationServi
String modifyNamespaceRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName);
if (rolePermissionService.findRoleByRoleName(modifyNamespaceRoleName) == null) {
createNamespaceRole(appId, namespaceName, PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName), operator);
modifyNamespaceRoleName, operator);
}
String releaseNamespaceRoleName = RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName);
if (rolePermissionService.findRoleByRoleName(releaseNamespaceRoleName) == null) {
createNamespaceRole(appId, namespaceName, PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName), operator);
releaseNamespaceRoleName, operator);
}
}
@Transactional
public void initNamespaceEnvRoles(String appId, String namespaceName, String operator) {
List<Env> portalEnvs = portalConfig.portalSupportedEnvs();
for (Env env : portalEnvs) {
initNamespaceSpecificEnvRoles(appId, namespaceName, env.toString(), operator);
}
}
@Transactional
public void initNamespaceSpecificEnvRoles(String appId, String namespaceName, String env, String operator) {
String modifyNamespaceEnvRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName, env);
if (rolePermissionService.findRoleByRoleName(modifyNamespaceEnvRoleName) == null) {
createNamespaceEnvRole(appId, namespaceName, PermissionType.MODIFY_NAMESPACE, env,
modifyNamespaceEnvRoleName, operator);
}
String releaseNamespaceEnvRoleName = RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName, env);
if (rolePermissionService.findRoleByRoleName(releaseNamespaceEnvRoleName) == null) {
createNamespaceEnvRole(appId, namespaceName, PermissionType.RELEASE_NAMESPACE, env,
releaseNamespaceEnvRoleName, operator);
}
}
......@@ -121,4 +150,15 @@ public class DefaultRoleInitializationService implements RoleInitializationServi
rolePermissionService
.createRoleWithPermissions(role, Sets.newHashSet(createdPermission.getId()));
}
private void createNamespaceEnvRole(String appId, String namespaceName, String permissionType, String env,
String roleName, String operator) {
Permission permission =
createPermission(RoleUtils.buildNamespaceTargetId(appId, namespaceName, env), permissionType, operator);
Permission createdPermission = rolePermissionService.createPermission(permission);
Role role = createRole(roleName, operator);
rolePermissionService
.createRoleWithPermissions(role, Sets.newHashSet(createdPermission.getId()));
}
}
......@@ -7,7 +7,7 @@ import com.ctrip.framework.apollo.portal.constant.RoleType;
public class RoleUtils {
private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR);
private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).skipNulls();
public static String buildAppMasterRoleName(String appId) {
return STRING_JOINER.join(RoleType.MASTER, appId);
......@@ -18,7 +18,11 @@ public class RoleUtils {
}
public static String buildModifyNamespaceRoleName(String appId, String namespaceName) {
return STRING_JOINER.join(RoleType.MODIFY_NAMESPACE, appId, namespaceName);
return buildModifyNamespaceRoleName(appId, namespaceName, null);
}
public static String buildModifyNamespaceRoleName(String appId, String namespaceName, String env) {
return STRING_JOINER.join(RoleType.MODIFY_NAMESPACE, appId, namespaceName, env);
}
public static String buildModifyDefaultNamespaceRoleName(String appId) {
......@@ -26,11 +30,19 @@ public class RoleUtils {
}
public static String buildReleaseNamespaceRoleName(String appId, String namespaceName) {
return STRING_JOINER.join(RoleType.RELEASE_NAMESPACE, appId, namespaceName);
return buildReleaseNamespaceRoleName(appId, namespaceName, null);
}
public static String buildReleaseNamespaceRoleName(String appId, String namespaceName, String env) {
return STRING_JOINER.join(RoleType.RELEASE_NAMESPACE, appId, namespaceName, env);
}
public static String buildNamespaceRoleName(String appId, String namespaceName, String roleType) {
return STRING_JOINER.join(roleType, appId, namespaceName);
return buildNamespaceRoleName(appId, namespaceName, roleType, null);
}
public static String buildNamespaceRoleName(String appId, String namespaceName, String roleType, String env) {
return STRING_JOINER.join(roleType, appId, namespaceName, env);
}
public static String buildReleaseDefaultNamespaceRoleName(String appId) {
......@@ -38,7 +50,11 @@ public class RoleUtils {
}
public static String buildNamespaceTargetId(String appId, String namespaceName) {
return STRING_JOINER.join(appId, namespaceName);
return buildNamespaceTargetId(appId, namespaceName, null);
}
public static String buildNamespaceTargetId(String appId, String namespaceName, String env) {
return STRING_JOINER.join(appId, namespaceName, env);
}
public static String buildDefaultNamespaceTargetId(String appId) {
......
......@@ -40,16 +40,30 @@
<form class="form-inline" ng-submit="assignRoleToUser('ModifyNamespace')">
<div class="form-group">
<apollouserselector apollo-id="modifyRoleWidgetId"></apollouserselector>
<select class="form-control input-sm" ng-model="modifyRoleSelectedEnv">
<option value="">所有环境</option>
<option ng-repeat="env in envs" ng-value="env">{{env}}</option>
</select>
</div>
<button type="submit" class="btn btn-default" style="margin-left: 20px;" ng-disabled="modifyRoleSubmitBtnDisabled">添加</button>
</form>
<!-- Split button -->
<div class="item-container">
<h5>所有环境</h5>
<div class="btn-group item-info" ng-repeat="user in rolesAssignedUsers.modifyRoleUsers">
<button type="button" class="btn btn-default" ng-bind="user.userId"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ModifyNamespace', user.userId)">
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ModifyNamespace', user.userId, null)">
<span class="glyphicon glyphicon-remove"></span>
</button>
</div>
</div>
<div class="item-container" ng-repeat="env in envs">
<h5>{{env}}</h5>
<div class="btn-group item-info" ng-repeat="user in envRolesAssignedUsers[env].modifyRoleUsers">
<button type="button" class="btn btn-default" ng-bind="user.userId"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ModifyNamespace', user.userId, env)">
<span class="glyphicon glyphicon-remove"></span>
</button>
</div>
......@@ -69,21 +83,35 @@
<form class="form-inline" ng-submit="assignRoleToUser('ReleaseNamespace')">
<div class="form-group">
<apollouserselector apollo-id="releaseRoleWidgetId"></apollouserselector>
<select class="form-control input-sm" ng-model="releaseRoleSelectedEnv">
<option value="">所有环境</option>
<option ng-repeat="env in envs" ng-value="env">{{env}}</option>
</select>
</div>
<button type="submit" class="btn btn-default" style="margin-left: 20px;" ng-disabled="ReleaseRoleSubmitBtnDisabled">添加</button>
</form>
<!-- Split button -->
<div class="item-container">
<h5>所有环境</h5>
<div class="btn-group item-info" ng-repeat="user in rolesAssignedUsers.releaseRoleUsers">
<button type="button" class="btn btn-default" ng-bind="user.userId"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ReleaseNamespace', user.userId)">
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ReleaseNamespace', user.userId, null)">
<span class="glyphicon glyphicon-remove"></span>
</button>
</div>
</div>
<div class="item-container" ng-repeat="env in envs">
<h5>{{env}}</h5>
<div class="btn-group item-info" ng-repeat="user in envRolesAssignedUsers[env].releaseRoleUsers">
<button type="button" class="btn btn-default" ng-bind="user.userId"></button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" ng-click="removeUserRole('ReleaseNamespace', user.userId, env)">
<span class="glyphicon glyphicon-remove"></span>
</button>
</div>
</div>
</div>
</div>
......
......@@ -135,6 +135,20 @@
</label>
</div>
</div>
<div class="form-group" valdr-form-group ng-show="consumerRole.type=='NamespaceRole'">
<label class="col-sm-2 control-label">
环境
</label>
<div class="col-sm-10">
<div>
<label class="checkbox-inline" ng-repeat="env in envs">
<input type="checkbox" ng-checked="env.checked" ng-click="switchSelect(env)" />
{{env.env}}
</label>
</div>
<small>(不选择则所有环境都有权限,如果提示Namespace's role does not exist,请先打开该Namespace的授权页面触发一下权限的初始化动作)</small>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary"
......
open_manage_module.controller('OpenManageController',
['$scope', 'toastr', 'AppUtil', 'OrganizationService', 'ConsumerService', 'PermissionService',
['$scope', 'toastr', 'AppUtil', 'OrganizationService', 'ConsumerService', 'PermissionService','EnvService',
OpenManageController]);
function OpenManageController($scope, toastr, AppUtil, OrganizationService, ConsumerService, PermissionService) {
function OpenManageController($scope, toastr, AppUtil, OrganizationService, ConsumerService, PermissionService, EnvService) {
var $orgWidget = $('#organization');
......@@ -18,12 +18,10 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
$scope.createConsumer = createConsumer;
$scope.assignRoleToConsumer = assignRoleToConsumer;
init();
function init() {
initOrganization();
initPermission();
initEnv();
}
function initOrganization() {
......@@ -50,7 +48,29 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
PermissionService.has_root_permission()
.then(function (result) {
$scope.isRootUser = result.hasPermission;
})
});
}
function initEnv() {
EnvService.find_all_envs()
.then(function (result){
$scope.envs = new Array();
for (var iLoop = 0; iLoop < result.length; iLoop++) {
$scope.envs.push({ checked : false, env : result[iLoop] });
$scope.envsChecked = new Array();
}
$scope.switchSelect = function (item) {
item.checked = !item.checked;
$scope.envsChecked = new Array();
for (var iLoop = 0; iLoop < $scope.envs.length; iLoop++) {
var env = $scope.envs[iLoop];
if (env.checked) {
$scope.envsChecked.push(env.env);
}
}
};
});
}
function getTokenByAppId() {
......@@ -68,7 +88,7 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
} else {
$scope.consumerToken = {token: 'App(' + $scope.consumer.appId + ')未创建,请先创建'};
}
})
});
}
function createConsumer() {
......@@ -114,12 +134,14 @@ function OpenManageController($scope, toastr, AppUtil, OrganizationService, Cons
ConsumerService.assignRoleToConsumer($scope.consumerRole.token,
$scope.consumerRole.type,
$scope.consumerRole.appId,
$scope.consumerRole.namespaceName)
$scope.consumerRole.namespaceName,
$scope.envsChecked)
.then(function (consumerRoles) {
toastr.success("赋权成功");
}, function (response) {
AppUtil.showErrorMsg(response, "赋权失败");
})
}
init();
}
role_module.controller('NamespaceRoleController',
['$scope', '$location', '$window', 'toastr', 'AppService', 'UserService', 'AppUtil',
'PermissionService',
function ($scope, $location, $window, toastr, AppService, UserService, AppUtil,
PermissionService) {
['$scope', '$location', '$window', 'toastr', 'AppService', 'UserService', 'AppUtil', 'EnvService',
'PermissionService',
function ($scope, $location, $window, toastr, AppService, UserService, AppUtil, EnvService,
PermissionService) {
var params = AppUtil.parseParams($location.$$url);
$scope.pageContext = {
appId: params.appid,
namespaceName: params.namespaceName
};
var params = AppUtil.parseParams($location.$$url);
$scope.pageContext = {
appId: params.appid,
namespaceName: params.namespaceName
};
$scope.modifyRoleSubmitBtnDisabled = false;
$scope.modifyRoleSubmitBtnDisabled = false;
$scope.ReleaseRoleSubmitBtnDisabled = false;
$scope.releaseRoleWidgetId = 'releaseRoleWidgetId';
$scope.modifyRoleWidgetId = 'modifyRoleWidgetId';
$scope.modifyRoleSelectedEnv = "";
$scope.releaseRoleSelectedEnv = "";
PermissionService.init_app_namespace_permission($scope.pageContext.appId, $scope.pageContext.namespaceName)
.then(function (result) {
}, function(result) {
toastr.warn(AppUtil.errorMsg(result), "初始化授权出错");
});
PermissionService.has_assign_user_permission($scope.pageContext.appId)
.then(function (result) {
$scope.hasAssignUserPermission = result.hasPermission;
}, function (reslt) {
});
EnvService.find_all_envs()
.then(function (result){
$scope.envs = result;
$scope.envRolesAssignedUsers = {};
for (var iLoop = 0; iLoop < result.length; iLoop++) {
var env = result[iLoop];
PermissionService.get_namespace_env_role_users($scope.pageContext.appId, env, $scope.pageContext.namespaceName)
.then(function (result) {
$scope.envRolesAssignedUsers[result.env] = result;
}, function(result) {
toastr.error(AppUtil.errorMsg(result), "加载" + env + "授权用户出错");
});
}
});
PermissionService.get_namespace_role_users($scope.pageContext.appId,
$scope.pageContext.namespaceName)
.then(function (result) {
$scope.rolesAssignedUsers = result;
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载授权用户出错");
});
$scope.assignRoleToUser = function (roleType) {
if ("ReleaseNamespace" === roleType) {
var user = $('.' + $scope.releaseRoleWidgetId).select2('data')[0];
if (!user) {
toastr.warning("请选择用户");
return;
}
$scope.ReleaseRoleSubmitBtnDisabled = true;
var toAssignReleaseNamespaceRoleUser = user.id;
var assignReleaseNamespaceRoleFunc = $scope.releaseRoleSelectedEnv === "" ?
PermissionService.assign_release_namespace_role :
function (appId, namespaceName, user) {
return PermissionService.assign_release_namespace_env_role(appId, $scope.releaseRoleSelectedEnv, namespaceName, user);
};
assignReleaseNamespaceRoleFunc($scope.pageContext.appId,
$scope.pageContext.namespaceName,
toAssignReleaseNamespaceRoleUser)
.then(function (result) {
toastr.success("添加成功");
$scope.ReleaseRoleSubmitBtnDisabled = false;
if ($scope.releaseRoleSelectedEnv === "") {
$scope.rolesAssignedUsers.releaseRoleUsers.push(
{userId: toAssignReleaseNamespaceRoleUser});
} else {
$scope.envRolesAssignedUsers[$scope.releaseRoleSelectedEnv].releaseRoleUsers.push(
{userId: toAssignReleaseNamespaceRoleUser});
}
$('.' + $scope.releaseRoleWidgetId).select2("val", "");
$scope.releaseRoleSelectedEnv = "";
}, function (result) {
$scope.ReleaseRoleSubmitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "添加失败");
});
} else {
var user = $('.' + $scope.modifyRoleWidgetId).select2('data')[0];
if (!user) {
toastr.warning("请选择用户");
return;
}
$scope.modifyRoleSubmitBtnDisabled = true;
var toAssignModifyNamespaceRoleUser = user.id;
$scope.releaseRoleWidgetId = 'releaseRoleWidgetId';
$scope.modifyRoleWidgetId = 'modifyRoleWidgetId';
PermissionService.has_assign_user_permission($scope.pageContext.appId)
.then(function (result) {
$scope.hasAssignUserPermission = result.hasPermission;
}, function (reslt) {
});
PermissionService.get_namespace_role_users($scope.pageContext.appId,
$scope.pageContext.namespaceName)
.then(function (result) {
$scope.rolesAssignedUsers = result;
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载授权用户出错");
});
$scope.assignRoleToUser = function (roleType) {
if ('ReleaseNamespace' == roleType) {
var user = $('.' + $scope.releaseRoleWidgetId).select2('data')[0];
if (!user) {
toastr.warning("请选择用户");
return;
}
$scope.ReleaseRoleSubmitBtnDisabled = true;
var toAssignReleaseNamespaceRoleUser = user.id;
PermissionService.assign_release_namespace_role($scope.pageContext.appId,
$scope.pageContext.namespaceName,
toAssignReleaseNamespaceRoleUser)
.then(function (result) {
toastr.success("添加成功");
$scope.ReleaseRoleSubmitBtnDisabled = false;
$scope.rolesAssignedUsers.releaseRoleUsers.push(
{userId: toAssignReleaseNamespaceRoleUser});
$('.' + $scope.releaseRoleWidgetId).select2("val", "");
}, function (result) {
$scope.ReleaseRoleSubmitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "添加失败");
});
} else {
var user = $('.' + $scope.modifyRoleWidgetId).select2('data')[0];
if (!user) {
toastr.warning("请选择用户");
return;
}
$scope.modifyRoleSubmitBtnDisabled = true;
var toAssignModifyNamespaceRoleUser = user.id;
PermissionService.assign_modify_namespace_role($scope.pageContext.appId,
$scope.pageContext.namespaceName,
toAssignModifyNamespaceRoleUser)
.then(function (result) {
toastr.success("添加成功");
$scope.modifyRoleSubmitBtnDisabled = false;
$scope.rolesAssignedUsers.modifyRoleUsers.push(
{userId: toAssignModifyNamespaceRoleUser});
$('.' + $scope.modifyRoleWidgetId).select2("val", "");
}, function (result) {
$scope.modifyRoleSubmitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "添加失败");
});
}
};
$scope.removeUserRole = function (roleType, user) {
if ('ReleaseNamespace' == roleType) {
PermissionService.remove_release_namespace_role($scope.pageContext.appId,
$scope.pageContext.namespaceName,
user)
.then(function (result) {
toastr.success("删除成功");
removeUserFromList($scope.rolesAssignedUsers.releaseRoleUsers, user);
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败");
});
} else {
PermissionService.remove_modify_namespace_role($scope.pageContext.appId,
$scope.pageContext.namespaceName,
user)
.then(function (result) {
toastr.success("删除成功");
removeUserFromList($scope.rolesAssignedUsers.modifyRoleUsers, user);
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败");
});
}
};
function removeUserFromList(list, user) {
var index = 0;
for (var i = 0; i < list.length; i++) {
if (list[i].userId == user) {
index = i;
break;
}
}
list.splice(index, 1);
var assignModifyNamespaceRoleFunc = $scope.modifyRoleSelectedEnv === "" ?
PermissionService.assign_modify_namespace_role :
function (appId, namespaceName, user) {
return PermissionService.assign_modify_namespace_env_role(appId, $scope.modifyRoleSelectedEnv, namespaceName, user);
};
assignModifyNamespaceRoleFunc($scope.pageContext.appId,
$scope.pageContext.namespaceName,
toAssignModifyNamespaceRoleUser)
.then(function (result) {
toastr.success("添加成功");
$scope.modifyRoleSubmitBtnDisabled = false;
if ($scope.modifyRoleSelectedEnv === "") {
$scope.rolesAssignedUsers.modifyRoleUsers.push(
{userId: toAssignModifyNamespaceRoleUser});
} else {
$scope.envRolesAssignedUsers[$scope.modifyRoleSelectedEnv].modifyRoleUsers.push(
{userId: toAssignModifyNamespaceRoleUser});
}
$('.' + $scope.modifyRoleWidgetId).select2("val", "");
$scope.modifyRoleSelectedEnv = "";
}, function (result) {
$scope.modifyRoleSubmitBtnDisabled = false;
toastr.error(AppUtil.errorMsg(result), "添加失败");
});
}
};
$scope.removeUserRole = function (roleType, user, env) {
if ("ReleaseNamespace" === roleType) {
var removeReleaseNamespaceRoleFunc = !env ?
PermissionService.remove_release_namespace_role :
function (appId, namespaceName, user) {
return PermissionService.remove_release_namespace_env_role(appId, env, namespaceName, user);
};
removeReleaseNamespaceRoleFunc($scope.pageContext.appId,
$scope.pageContext.namespaceName,
user)
.then(function (result) {
toastr.success("删除成功");
if (!env) {
removeUserFromList($scope.rolesAssignedUsers.releaseRoleUsers, user);
} else {
removeUserFromList($scope.envRolesAssignedUsers[env].releaseRoleUsers, user);
}
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败");
});
} else {
var removeModifyNamespaceRoleFunc = !env ?
PermissionService.remove_modify_namespace_role :
function (appId, namespaceName, user) {
return PermissionService.remove_modify_namespace_env_role(appId, env, namespaceName, user);
};
removeModifyNamespaceRoleFunc($scope.pageContext.appId,
$scope.pageContext.namespaceName,
user)
.then(function (result) {
toastr.success("删除成功");
if (!env) {
removeUserFromList($scope.rolesAssignedUsers.modifyRoleUsers, user);
} else {
removeUserFromList($scope.envRolesAssignedUsers[env].modifyRoleUsers, user);
}
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "删除失败");
});
}
};
function removeUserFromList(list, user) {
var index = 0;
for (var i = 0; i < list.length; i++) {
if (list[i].userId === user) {
index = i;
break;
}
}
list.splice(index, 1);
}
}]);
}]);
......@@ -217,10 +217,26 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
scope.appId,
namespace.baseInfo.namespaceName)
.then(function (result) {
if (!result.hasPermission) {
PermissionService.has_modify_namespace_env_permission(
scope.appId,
scope.env,
namespace.baseInfo.namespaceName
)
.then(function (result) {
//branch has same permission
namespace.hasModifyPermission = result.hasPermission;
if (namespace.branch) {
namespace.branch.hasModifyPermission = result.hasPermission;
}
});
}
else {
//branch has same permission
namespace.hasModifyPermission = result.hasPermission;
if (namespace.branch) {
namespace.branch.hasModifyPermission = result.hasPermission;
if (namespace.branch) {
namespace.branch.hasModifyPermission = result.hasPermission;
}
}
});
......@@ -228,10 +244,26 @@ function directive($window, toastr, AppUtil, EventManager, PermissionService, Na
scope.appId,
namespace.baseInfo.namespaceName)
.then(function (result) {
//branch has same permission
namespace.hasReleasePermission = result.hasPermission;
if (namespace.branch) {
namespace.branch.hasReleasePermission = result.hasPermission;
if (!result.hasPermission) {
PermissionService.has_release_namespace_env_permission(
scope.appId,
scope.env,
namespace.baseInfo.namespaceName
)
.then(function (result) {
//branch has same permission
namespace.hasReleasePermission = result.hasPermission;
if (namespace.branch) {
namespace.branch.hasReleasePermission = result.hasPermission;
}
});
}
else {
//branch has same permission
namespace.hasReleasePermission = result.hasPermission;
if (namespace.branch) {
namespace.branch.hasReleasePermission = result.hasPermission;
}
}
});
}
......
......@@ -29,11 +29,12 @@ appService.service('ConsumerService', ['$resource', '$q', 'AppUtil',
appId: appId
});
},
assignRoleToConsumer: function (token, type, appId, namespaceName) {
assignRoleToConsumer: function (token, type, appId, namespaceName, envs) {
return AppUtil.ajax(resource.assign_role_to_consumer,
{
token: token,
type: type
type: type,
envs: envs
},
{
appId: appId,
......
appService.service('PermissionService', ['$resource', '$q', function ($resource, $q) {
var permission_resource = $resource('', {}, {
init_app_namespace_permission: {
method: 'POST',
url: '/apps/:appId/initPermission?namespace=:namespace'
},
has_app_permission: {
method: 'GET',
url: '/apps/:appId/permissions/:permissionType'
......@@ -8,6 +12,10 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
method: 'GET',
url: '/apps/:appId/namespaces/:namespaceName/permissions/:permissionType'
},
has_namespace_env_permission: {
method: 'GET',
url: '/apps/:appId/envs/:env/namespaces/:namespaceName/permissions/:permissionType'
},
has_root_permission:{
method: 'GET',
url: '/permissions/root'
......@@ -16,14 +24,26 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
method: 'GET',
url: '/apps/:appId/namespaces/:namespaceName/role_users'
},
get_namespace_env_role_users: {
method: 'GET',
url: '/apps/:appId/envs/:env/namespaces/:namespaceName/role_users'
},
assign_namespace_role_to_user: {
method: 'POST',
url: '/apps/:appId/namespaces/:namespaceName/roles/:roleType'
},
assign_namespace_env_role_to_user: {
method: 'POST',
url: '/apps/:appId/envs/:env/namespaces/:namespaceName/roles/:roleType'
},
remove_namespace_role_from_user: {
method: 'DELETE',
url: '/apps/:appId/namespaces/:namespaceName/roles/:roleType?user=:user'
},
remove_namespace_env_role_from_user: {
method: 'DELETE',
url: '/apps/:appId/envs/:env/namespaces/:namespaceName/roles/:roleType?user=:user'
},
get_app_role_users: {
method: 'GET',
url: '/apps/:appId/role_users'
......@@ -38,6 +58,20 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
}
});
function initAppNamespacePermission(appId, namespace) {
var d = $q.defer();
permission_resource.init_app_namespace_permission({
appId: appId,
namespace: namespace
}, namespace,
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
function hasAppPermission(appId, permissionType) {
var d = $q.defer();
permission_resource.has_app_permission({
......@@ -67,6 +101,22 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
return d.promise;
}
function hasNamespaceEnvPermission(appId, env, namespaceName, permissionType) {
var d = $q.defer();
permission_resource.has_namespace_env_permission({
appId: appId,
namespaceName: namespaceName,
permissionType: permissionType,
env: env
},
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
function assignNamespaceRoleToUser(appId, namespaceName, roleType, user) {
var d = $q.defer();
permission_resource.assign_namespace_role_to_user({
......@@ -82,7 +132,23 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
return d.promise;
}
function removeRoleFromUser(appId, namespaceName, roleType, user) {
function assignNamespaceEnvRoleToUser(appId, env, namespaceName, roleType, user) {
var d = $q.defer();
permission_resource.assign_namespace_env_role_to_user({
appId: appId,
namespaceName: namespaceName,
roleType: roleType,
env: env
}, user,
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
function removeNamespaceRoleFromUser(appId, namespaceName, roleType, user) {
var d = $q.defer();
permission_resource.remove_namespace_role_from_user({
appId: appId,
......@@ -98,7 +164,27 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
return d.promise;
}
function removeNamespaceEnvRoleFromUser(appId, env, namespaceName, roleType, user) {
var d = $q.defer();
permission_resource.remove_namespace_env_role_from_user({
appId: appId,
namespaceName: namespaceName,
roleType: roleType,
user: user,
env: env
},
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
return {
init_app_namespace_permission: function (appId, namespace) {
return initAppNamespacePermission(appId, namespace);
},
has_create_namespace_permission: function (appId) {
return hasAppPermission(appId, 'CreateNamespace');
},
......@@ -111,9 +197,15 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
has_modify_namespace_permission: function (appId, namespaceName) {
return hasNamespacePermission(appId, namespaceName, 'ModifyNamespace');
},
has_modify_namespace_env_permission: function (appId, env, namespaceName) {
return hasNamespaceEnvPermission(appId, env, namespaceName, 'ModifyNamespace');
},
has_release_namespace_permission: function (appId, namespaceName) {
return hasNamespacePermission(appId, namespaceName, 'ReleaseNamespace');
},
has_release_namespace_env_permission: function (appId, env, namespaceName) {
return hasNamespaceEnvPermission(appId, env, namespaceName, 'ReleaseNamespace');
},
has_root_permission: function () {
var d = $q.defer();
permission_resource.has_root_permission({ },
......@@ -128,14 +220,26 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
assign_modify_namespace_role: function (appId, namespaceName, user) {
return assignNamespaceRoleToUser(appId, namespaceName, 'ModifyNamespace', user);
},
assign_modify_namespace_env_role: function (appId, env, namespaceName, user) {
return assignNamespaceEnvRoleToUser(appId, env, namespaceName, 'ModifyNamespace', user);
},
assign_release_namespace_role: function (appId, namespaceName, user) {
return assignNamespaceRoleToUser(appId, namespaceName, 'ReleaseNamespace', user);
},
assign_release_namespace_env_role: function (appId, env, namespaceName, user) {
return assignNamespaceEnvRoleToUser(appId, env, namespaceName, 'ReleaseNamespace', user);
},
remove_modify_namespace_role: function (appId, namespaceName, user) {
return removeRoleFromUser(appId, namespaceName, 'ModifyNamespace', user);
return removeNamespaceRoleFromUser(appId, namespaceName, 'ModifyNamespace', user);
},
remove_modify_namespace_env_role: function (appId, env, namespaceName, user) {
return removeNamespaceEnvRoleFromUser(appId, env, namespaceName, 'ModifyNamespace', user);
},
remove_release_namespace_role: function (appId, namespaceName, user) {
return removeRoleFromUser(appId, namespaceName, 'ReleaseNamespace', user);
return removeNamespaceRoleFromUser(appId, namespaceName, 'ReleaseNamespace', user);
},
remove_release_namespace_env_role: function (appId, env, namespaceName, user) {
return removeNamespaceEnvRoleFromUser(appId, env, namespaceName, 'ReleaseNamespace', user);
},
get_namespace_role_users: function (appId, namespaceName) {
var d = $q.defer();
......@@ -150,6 +254,20 @@ appService.service('PermissionService', ['$resource', '$q', function ($resource,
});
return d.promise;
},
get_namespace_env_role_users: function (appId, env, namespaceName) {
var d = $q.defer();
permission_resource.get_namespace_env_role_users({
appId: appId,
namespaceName: namespaceName,
env: env
},
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
get_app_role_users: function (appId) {
var d = $q.defer();
permission_resource.get_app_role_users({
......
package com.ctrip.framework.apollo.openapi.service;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.openapi.entity.Consumer;
import com.ctrip.framework.apollo.openapi.entity.ConsumerRole;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
......@@ -178,12 +179,20 @@ public class ConsumerServiceTest extends AbstractUnitTest {
String testNamespace = "namespace";
String modifyRoleName = RoleUtils.buildModifyNamespaceRoleName(testAppId, testNamespace);
String releaseRoleName = RoleUtils.buildReleaseNamespaceRoleName(testAppId, testNamespace);
String envModifyRoleName = RoleUtils.buildModifyNamespaceRoleName(testAppId, testNamespace, Env.DEV.toString());
String envReleaseRoleName = RoleUtils.buildReleaseNamespaceRoleName(testAppId, testNamespace, Env.DEV.toString());
long modifyRoleId = 1;
long releaseRoleId = 2;
long envModifyRoleId = 3;
long envReleaseRoleId = 4;
Role modifyRole = createRole(modifyRoleId, modifyRoleName);
Role releaseRole = createRole(releaseRoleId, releaseRoleName);
Role envModifyRole = createRole(envModifyRoleId, modifyRoleName);
Role envReleaseRole = createRole(envReleaseRoleId, releaseRoleName);
when(rolePermissionService.findRoleByRoleName(modifyRoleName)).thenReturn(modifyRole);
when(rolePermissionService.findRoleByRoleName(releaseRoleName)).thenReturn(releaseRole);
when(rolePermissionService.findRoleByRoleName(envModifyRoleName)).thenReturn(envModifyRole);
when(rolePermissionService.findRoleByRoleName(envReleaseRoleName)).thenReturn(envReleaseRole);
when(consumerRoleRepository.findByConsumerIdAndRoleId(consumerId, modifyRoleId)).thenReturn(null);
......@@ -191,14 +200,21 @@ public class ConsumerServiceTest extends AbstractUnitTest {
when(userInfoHolder.getUser()).thenReturn(owner);
ConsumerRole namespaceModifyConsumerRole = createConsumerRole(consumerId, modifyRoleId);
ConsumerRole namespaceEnvModifyConsumerRole = createConsumerRole(consumerId, envModifyRoleId);
ConsumerRole namespaceReleaseConsumerRole = createConsumerRole(consumerId, releaseRoleId);
ConsumerRole namespaceEnvReleaseConsumerRole = createConsumerRole(consumerId, envReleaseRoleId);
doReturn(namespaceModifyConsumerRole).when(consumerService).createConsumerRole(consumerId, modifyRoleId, testOwner);
doReturn(namespaceEnvModifyConsumerRole).when(consumerService).createConsumerRole(consumerId, envModifyRoleId, testOwner);
doReturn(namespaceReleaseConsumerRole).when(consumerService).createConsumerRole(consumerId, releaseRoleId, testOwner);
doReturn(namespaceEnvReleaseConsumerRole).when(consumerService).createConsumerRole(consumerId, envReleaseRoleId, testOwner);
consumerService.assignNamespaceRoleToConsumer(token, testAppId, testNamespace);
consumerService.assignNamespaceRoleToConsumer(token, testAppId, testNamespace, Env.DEV.toString());
verify(consumerRoleRepository).save(namespaceModifyConsumerRole);
verify(consumerRoleRepository).save(namespaceEnvModifyConsumerRole);
verify(consumerRoleRepository).save(namespaceReleaseConsumerRole);
verify(consumerRoleRepository).save(namespaceEnvReleaseConsumerRole);
}
......
package com.ctrip.framework.apollo.portal.spi.defaultImpl;
import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.AbstractUnitTest;
import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
import com.ctrip.framework.apollo.portal.constant.PermissionType;
import com.ctrip.framework.apollo.portal.entity.bo.UserInfo;
import com.ctrip.framework.apollo.portal.entity.po.Permission;
......@@ -15,6 +17,9 @@ import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anySetOf;
import static org.mockito.Matchers.anyString;
......@@ -32,6 +37,8 @@ public class RoleInitializationServiceTest extends AbstractUnitTest {
private RolePermissionService rolePermissionService;
@Mock
private UserInfoHolder userInfoHolder;
@Mock
private PortalConfig portalConfig;
@InjectMocks
private DefaultRoleInitializationService roleInitializationService;
......@@ -53,14 +60,15 @@ public class RoleInitializationServiceTest extends AbstractUnitTest {
when(rolePermissionService.findRoleByRoleName(anyString())).thenReturn(null);
when(userInfoHolder.getUser()).thenReturn(mockUser());
when(rolePermissionService.createPermission(any())).thenReturn(mockPermission());
when(portalConfig.portalSupportedEnvs()).thenReturn(mockPortalSupportedEnvs());
roleInitializationService.initAppRoles(mockApp());
verify(rolePermissionService, times(3)).findRoleByRoleName(anyString());
verify(rolePermissionService, times(7)).findRoleByRoleName(anyString());
verify(rolePermissionService, times(1)).assignRoleToUsers(
RoleUtils.buildAppMasterRoleName(APP_ID), Sets.newHashSet(CURRENT_USER), CURRENT_USER);
verify(rolePermissionService, times(2)).createPermission(any());
verify(rolePermissionService, times(3)).createRoleWithPermissions(any(), anySetOf(Long.class));
verify(rolePermissionService, times(6)).createPermission(any());
verify(rolePermissionService, times(7)).createRoleWithPermissions(any(), anySetOf(Long.class));
}
@Test
......@@ -153,5 +161,11 @@ public class RoleInitializationServiceTest extends AbstractUnitTest {
return permission;
}
private List<Env> mockPortalSupportedEnvs(){
List<Env> envArray = new ArrayList<>();
envArray.add(Env.DEV);
envArray.add(Env.FAT);
return envArray;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册