Commit b3e60336 by lepdou

branch restful api add permission validate

parent 7dcb2464
...@@ -30,6 +30,10 @@ public class PermissionValidator { ...@@ -30,6 +30,10 @@ public class PermissionValidator {
} }
public boolean hasOperateNamespacePermission(String appId, String namespaceName){
return hasModifyNamespacePermission(appId, namespaceName) || hasReleaseNamespacePermission(appId, namespaceName);
}
public boolean hasAssignRolePermission(String appId) { public boolean hasAssignRolePermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.ASSIGN_ROLE, PermissionType.ASSIGN_ROLE,
......
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.constants.NamespaceBranchStatus;
import com.ctrip.framework.apollo.common.dto.GrayReleaseRuleDTO; import com.ctrip.framework.apollo.common.dto.GrayReleaseRuleDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.dto.ReleaseDTO; import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.auth.PermissionValidator;
import com.ctrip.framework.apollo.portal.entity.model.NamespaceReleaseModel; import com.ctrip.framework.apollo.portal.entity.model.NamespaceReleaseModel;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceVO; import com.ctrip.framework.apollo.portal.entity.vo.NamespaceVO;
import com.ctrip.framework.apollo.portal.service.NamespaceBranchService; import com.ctrip.framework.apollo.portal.service.NamespaceBranchService;
import com.ctrip.framework.apollo.portal.service.ReleaseService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
...@@ -21,6 +24,10 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -21,6 +24,10 @@ import org.springframework.web.bind.annotation.RestController;
public class NamespaceBranchController { public class NamespaceBranchController {
@Autowired @Autowired
private PermissionValidator permissionValidator;
@Autowired
private ReleaseService releaseService;
@Autowired
private NamespaceBranchService namespaceBranchService; private NamespaceBranchService namespaceBranchService;
@RequestMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches") @RequestMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches")
...@@ -31,6 +38,7 @@ public class NamespaceBranchController { ...@@ -31,6 +38,7 @@ public class NamespaceBranchController {
return namespaceBranchService.findBranch(appId, Env.valueOf(env), clusterName, namespaceName); return namespaceBranchService.findBranch(appId, Env.valueOf(env), clusterName, namespaceName);
} }
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches", method = RequestMethod.POST) @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches", method = RequestMethod.POST)
public NamespaceDTO createBranch(@PathVariable String appId, public NamespaceDTO createBranch(@PathVariable String appId,
@PathVariable String env, @PathVariable String env,
...@@ -46,21 +54,35 @@ public class NamespaceBranchController { ...@@ -46,21 +54,35 @@ public class NamespaceBranchController {
@PathVariable String clusterName, @PathVariable String clusterName,
@PathVariable String namespaceName, @PathVariable String namespaceName,
@PathVariable String branchName) { @PathVariable String branchName) {
boolean canDelete = permissionValidator.hasReleaseNamespacePermission(appId, namespaceName) ||
(permissionValidator.hasModifyNamespacePermission(appId, namespaceName) &&
releaseService.loadLatestRelease(appId, Env.valueOf(env), branchName, namespaceName) == null);
if (!canDelete) {
throw new AccessDeniedException("Forbidden operation. "
+ "Caused by: 1.you don't have release permission "
+ "or 2. you don't have modification permission "
+ "or 3. you have modification permission but branch has been released");
}
namespaceBranchService.deleteBranch(appId, Env.valueOf(env), clusterName, namespaceName, branchName); namespaceBranchService.deleteBranch(appId, Env.valueOf(env), clusterName, namespaceName, branchName);
} }
@PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/merge", method = RequestMethod.POST) @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, public ReleaseDTO merge(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@PathVariable String branchName, @RequestParam(value = "deleteBranch", defaultValue = "true") boolean deleteBranch, @PathVariable String branchName, @RequestParam(value = "deleteBranch", defaultValue = "true") boolean deleteBranch,
@RequestBody NamespaceReleaseModel model) { @RequestBody NamespaceReleaseModel model) {
ReleaseDTO createdRelease = namespaceBranchService.merge(appId, Env.valueOf(env), clusterName, namespaceName, branchName, return namespaceBranchService.merge(appId, Env.valueOf(env), clusterName, namespaceName, branchName,
model.getReleaseTitle(), model.getReleaseComment(), deleteBranch); model.getReleaseTitle(), model.getReleaseComment(), deleteBranch);
return createdRelease;
} }
...@@ -73,6 +95,8 @@ public class NamespaceBranchController { ...@@ -73,6 +95,8 @@ public class NamespaceBranchController {
return namespaceBranchService.findBranchGrayRules(appId, Env.valueOf(env), clusterName, namespaceName, branchName); return namespaceBranchService.findBranchGrayRules(appId, Env.valueOf(env), clusterName, namespaceName, branchName);
} }
@PreAuthorize(value = "@permissionValidator.hasOperateNamespacePermission(#appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/rules", method = RequestMethod.PUT) @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, public void updateBranchRules(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
......
...@@ -76,16 +76,6 @@ public class NamespaceBranchService { ...@@ -76,16 +76,6 @@ public class NamespaceBranchService {
String operator = userInfoHolder.getUser().getUserId(); String operator = userInfoHolder.getUser().getUserId();
//Refusing request if user has not release permission and branch has been released
if (!permissionValidator.hasReleaseNamespacePermission(appId, namespaceName)
&& (!permissionValidator.hasModifyNamespacePermission(appId, namespaceName) ||
releaseService.loadLatestRelease(appId, env, branchName, namespaceName) != null)) {
throw new BadRequestException("Forbidden operation. "
+ "Cause by: you has not release permission "
+ "or you has not modify permission "
+ "or you has modify permission but branch has been released");
}
namespaceBranchAPI.deleteBranch(appId, env, clusterName, namespaceName, branchName, operator); namespaceBranchAPI.deleteBranch(appId, env, clusterName, namespaceName, branchName, operator);
Cat.logEvent(CatEventType.DELETE_GRAY_RELEASE, Cat.logEvent(CatEventType.DELETE_GRAY_RELEASE,
......
...@@ -53,14 +53,18 @@ function itemModalDirective(toastr, AppUtil, EventManager, ConfigService) { ...@@ -53,14 +53,18 @@ function itemModalDirective(toastr, AppUtil, EventManager, ConfigService) {
scope.toOperationNamespace.baseInfo.namespaceName, scope.toOperationNamespace.baseInfo.namespaceName,
scope.item).then( scope.item).then(
function (result) { function (result) {
toastr.success("添加成功,如需生效请发布");
scope.item.addItemBtnDisabled = false;
AppUtil.hideModal('#itemModal');
EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE, EventManager.emit(EventManager.EventType.REFRESH_NAMESPACE,
{ {
namespace: scope.toOperationNamespace namespace: scope.toOperationNamespace
}); });
toastr.success("添加成功,如需生效请发布");
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "添加失败"); toastr.error(AppUtil.errorMsg(result), "添加失败");
scope.item.addItemBtnDisabled = false;
}); });
} else { } else {
if (selectedClusters.length == 0) { if (selectedClusters.length == 0) {
...@@ -75,6 +79,8 @@ function itemModalDirective(toastr, AppUtil, EventManager, ConfigService) { ...@@ -75,6 +79,8 @@ function itemModalDirective(toastr, AppUtil, EventManager, ConfigService) {
scope.toOperationNamespace.baseInfo.namespaceName, scope.toOperationNamespace.baseInfo.namespaceName,
scope.item).then( scope.item).then(
function (result) { function (result) {
scope.item.addItemBtnDisabled = false;
AppUtil.hideModal('#itemModal');
toastr.success(cluster.env + " , " + scope.item.key, "添加成功,如需生效请发布"); toastr.success(cluster.env + " , " + scope.item.key, "添加成功,如需生效请发布");
if (cluster.env == scope.env && if (cluster.env == scope.env &&
cluster.name == scope.cluster) { cluster.name == scope.cluster) {
...@@ -86,12 +92,11 @@ function itemModalDirective(toastr, AppUtil, EventManager, ConfigService) { ...@@ -86,12 +92,11 @@ function itemModalDirective(toastr, AppUtil, EventManager, ConfigService) {
} }
}, function (result) { }, function (result) {
toastr.error(AppUtil.errorMsg(result), "添加失败"); toastr.error(AppUtil.errorMsg(result), "添加失败");
scope.item.addItemBtnDisabled = false;
}); });
}); });
} }
scope.item.addItemBtnDisabled = false;
AppUtil.hideModal('#itemModal');
} else { } else {
......
...@@ -875,6 +875,11 @@ ...@@ -875,6 +875,11 @@
<!--gray rules--> <!--gray rules-->
<div class="rules-manage-view row" ng-show="namespace.branch.viewType == 'rule'"> <div class="rules-manage-view row" ng-show="namespace.branch.viewType == 'rule'">
<div class="alert alert-warning no-radius" ng-show="!namespace.hasModifyPermission && !namespace.hasReleasePermission">
<strong>Tips:</strong>
您没有权限编辑灰度规则, 具有namespace修改权或者发布权的人员才可以编辑灰度规则. 如需要编辑灰度规则,请找项目管理员申请权限.
</div>
<table class="table table-bordered table-hover"> <table class="table table-bordered table-hover">
<thead> <thead>
<tr> <tr>
...@@ -892,9 +897,11 @@ ...@@ -892,9 +897,11 @@
<td class="text-center" width="10%"> <td class="text-center" width="10%">
<img src="img/edit.png" class="i-20 hover" <img src="img/edit.png" class="i-20 hover"
data-tooltip="tooltip" data-placement="bottom" title="修改" data-tooltip="tooltip" data-placement="bottom" title="修改"
ng-show="namespace.hasModifyPermission || namespace.hasReleasePermission"
ng-click="editRuleItem(namespace.branch, ruleItem)"> ng-click="editRuleItem(namespace.branch, ruleItem)">
<img src="img/cancel.png" class="i-20 hover" style="margin-left: 5px;" <img src="img/cancel.png" class="i-20 hover" style="margin-left: 5px;"
data-tooltip="tooltip" data-placement="bottom" title="删除" data-tooltip="tooltip" data-placement="bottom" title="删除"
ng-show="namespace.hasModifyPermission || namespace.hasReleasePermission"
ng-click="deleteRuleItem(namespace.branch, ruleItem)"> ng-click="deleteRuleItem(namespace.branch, ruleItem)">
</td> </td>
</tr> </tr>
...@@ -902,6 +909,7 @@ ...@@ -902,6 +909,7 @@
</tbody> </tbody>
</table> </table>
<button class="btn btn-primary" <button class="btn btn-primary"
ng-if="namespace.hasModifyPermission || namespace.hasReleasePermission"
ng-show="(namespace.isPublic && !namespace.isLinkedNamespace) || ng-show="(namespace.isPublic && !namespace.isLinkedNamespace) ||
((!namespace.isPublic || namespace.isLinkedNamespace) ((!namespace.isPublic || namespace.isLinkedNamespace)
&& (!namespace.branch.rules && (!namespace.branch.rules
...@@ -909,7 +917,11 @@ ...@@ -909,7 +917,11 @@
|| !namespace.branch.rules.ruleItems.length))" || !namespace.branch.rules.ruleItems.length))"
ng-click="addRuleItem(namespace.branch)">新增规则 ng-click="addRuleItem(namespace.branch)">新增规则
</button> </button>
</div> </div>
<!--instances --> <!--instances -->
<div class="panel panel-default" ng-show="namespace.branch.viewType == 'instance'"> <div class="panel panel-default" ng-show="namespace.branch.viewType == 'instance'">
<div class="panel-heading text-right"> <div class="panel-heading text-right">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment