Skip to content

Commit

Permalink
app's admin can create private namespace. & default create namespace …
Browse files Browse the repository at this point in the history
…when create public appnamespace
  • Loading branch information
lepdou committed Feb 28, 2017
1 parent 12a0073 commit cd55a0d
Show file tree
Hide file tree
Showing 28 changed files with 204 additions and 82 deletions.
Expand Up @@ -39,9 +39,9 @@ public ClusterDTO create(@PathVariable("appId") String appId,
}

if (autoCreatePrivateNamespace) {
entity = clusterService.saveWithCreatePrivateNamespace(entity);
entity = clusterService.saveWithInstanceOfAppNamespaces(entity);
} else {
entity = clusterService.saveWithoutCreatePrivateNamespace(entity);
entity = clusterService.saveWithoutInstanceOfAppNamespaces(entity);
}

dto = BeanUtils.transfrom(ClusterDTO.class, entity);
Expand Down
Expand Up @@ -20,6 +20,8 @@ public interface AppNamespaceRepository extends PagingAndSortingRepository<AppNa

List<AppNamespace> findByAppIdAndIsPublic(String appId, boolean isPublic);

List<AppNamespace> findByAppId(String appId);

List<AppNamespace> findFirst500ByIdGreaterThanOrderByIdAsc(long id);

}
Expand Up @@ -30,7 +30,7 @@ public App createNewApp(App app) {

clusterService.createDefaultCluster(appId, createBy);

namespaceService.createPrivateNamespace(appId, ConfigConsts.CLUSTER_NAME_DEFAULT, createBy);
namespaceService.instanceOfAppNamespaces(appId, ConfigConsts.CLUSTER_NAME_DEFAULT, createBy);

return app;
}
Expand Down
Expand Up @@ -8,7 +8,6 @@
import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.repository.AppNamespaceRepository;
import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.exception.ServiceException;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.core.ConfigConsts;
Expand Down Expand Up @@ -47,6 +46,10 @@ public AppNamespace findPublicNamespaceByName(String namespaceName) {
return appNamespaceRepository.findByNameAndIsPublicTrue(namespaceName);
}

public List<AppNamespace> findByAppId(String appId) {
return appNamespaceRepository.findByAppId(appId);
}

public List<AppNamespace> findPublicNamespacesByNames(Set<String> namespaceNames) {
if (namespaceNames == null || namespaceNames.isEmpty()) {
return Collections.emptyList();
Expand Down Expand Up @@ -100,14 +103,12 @@ public AppNamespace createAppNamespace(AppNamespace appNamespace) {
appNamespace.setId(0);//protection
appNamespace.setDataChangeCreatedBy(createBy);
appNamespace.setDataChangeLastModifiedBy(createBy);

appNamespace = appNamespaceRepository.save(appNamespace);

if (!appNamespace.isPublic()) {
linkPrivateAppNamespaceInAllCluster(appNamespace.getAppId(), appNamespace.getName(), createBy);
}
instanceOfAppNamespaceInAllCluster(appNamespace.getAppId(), appNamespace.getName(), createBy);

auditService.audit(AppNamespace.class.getSimpleName(), appNamespace.getId(), Audit.OP.INSERT,
createBy);
auditService.audit(AppNamespace.class.getSimpleName(), appNamespace.getId(), Audit.OP.INSERT, createBy);
return appNamespace;
}

Expand All @@ -122,15 +123,17 @@ public AppNamespace update(AppNamespace appNamespace) {
return managedNs;
}

private void linkPrivateAppNamespaceInAllCluster(String appId, String namespaceName, String createBy) {
private void instanceOfAppNamespaceInAllCluster(String appId, String namespaceName, String createBy) {
List<Cluster> clusters = clusterService.findParentClusters(appId);

for (Cluster cluster : clusters) {
Namespace namespace = new Namespace();
namespace.setClusterName(cluster.getName());
namespace.setAppId(appId);
namespace.setNamespaceName(namespaceName);
namespace.setDataChangeCreatedBy(createBy);
namespace.setDataChangeLastModifiedBy(createBy);

namespaceService.save(namespace);
}
}
Expand Down
Expand Up @@ -39,7 +39,7 @@ public Cluster findOne(String appId, String name) {
return clusterRepository.findByAppIdAndName(appId, name);
}

public Cluster findOne(long clusterId){
public Cluster findOne(long clusterId) {
return clusterRepository.findOne(clusterId);
}

Expand All @@ -59,18 +59,18 @@ public List<Cluster> findParentClusters(String appId) {
}

@Transactional
public Cluster saveWithCreatePrivateNamespace(Cluster entity) {
public Cluster saveWithInstanceOfAppNamespaces(Cluster entity) {

Cluster savedCluster = saveWithoutCreatePrivateNamespace(entity);
Cluster savedCluster = saveWithoutInstanceOfAppNamespaces(entity);

namespaceService.createPrivateNamespace(savedCluster.getAppId(), savedCluster.getName(),
savedCluster.getDataChangeCreatedBy());
namespaceService.instanceOfAppNamespaces(savedCluster.getAppId(), savedCluster.getName(),
savedCluster.getDataChangeCreatedBy());

return savedCluster;
}

@Transactional
public Cluster saveWithoutCreatePrivateNamespace(Cluster entity){
public Cluster saveWithoutInstanceOfAppNamespaces(Cluster entity) {
if (!isClusterNameUnique(entity.getAppId(), entity.getName())) {
throw new BadRequestException("cluster not unique");
}
Expand Down Expand Up @@ -108,7 +108,7 @@ public Cluster update(Cluster cluster) {
managedCluster = clusterRepository.save(managedCluster);

auditService.audit(Cluster.class.getSimpleName(), managedCluster.getId(), Audit.OP.UPDATE,
managedCluster.getDataChangeLastModifiedBy());
managedCluster.getDataChangeLastModifiedBy());

return managedCluster;
}
Expand All @@ -128,9 +128,9 @@ public void createDefaultCluster(String appId, String createBy) {
auditService.audit(Cluster.class.getSimpleName(), cluster.getId(), Audit.OP.INSERT, createBy);
}

public List<Cluster> findChildClusters(String appId, String parentClusterName){
public List<Cluster> findChildClusters(String appId, String parentClusterName) {
Cluster parentCluster = findOne(appId, parentClusterName);
if (parentCluster == null){
if (parentCluster == null) {
throw new BadRequestException("parent cluster not exist");
}

Expand Down
Expand Up @@ -52,7 +52,7 @@ public Namespace createBranch(String appId, String parentClusterName, String nam
//create child cluster
Cluster childCluster = createChildCluster(appId, parentCluster, namespaceName, operator);

Cluster createdChildCluster = clusterService.saveWithoutCreatePrivateNamespace(childCluster);
Cluster createdChildCluster = clusterService.saveWithoutInstanceOfAppNamespaces(childCluster);

//create child namespace
childNamespace = createNamespaceBranch(appId, createdChildCluster.getName(),
Expand Down
Expand Up @@ -313,12 +313,11 @@ public Namespace update(Namespace namespace) {
}

@Transactional
public void createPrivateNamespace(String appId, String clusterName, String createBy) {
public void instanceOfAppNamespaces(String appId, String clusterName, String createBy) {

//load all private app namespace
List<AppNamespace> privateAppNamespaces = appNamespaceService.findPrivateAppNamespace(appId);
//create all private namespace
for (AppNamespace appNamespace : privateAppNamespaces) {
List<AppNamespace> appNamespaces = appNamespaceService.findByAppId(appId);

for (AppNamespace appNamespace : appNamespaces) {
Namespace ns = new Namespace();
ns.setAppId(appId);
ns.setClusterName(clusterName);
Expand Down
@@ -1,6 +1,7 @@
package com.ctrip.framework.apollo.portal.component;

import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
import com.ctrip.framework.apollo.portal.constant.PermissionType;
import com.ctrip.framework.apollo.portal.service.RolePermissionService;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;
Expand All @@ -16,53 +17,57 @@ public class PermissionValidator {
private UserInfoHolder userInfoHolder;
@Autowired
private RolePermissionService rolePermissionService;
@Autowired
private PortalConfig portalConfig;

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 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 hasDeleteNamespacePermission(String appId) {
return hasAssignRolePermission(appId) || isSuperAdmin();
}

public boolean hasOperateNamespacePermission(String appId, String namespaceName){
public boolean hasOperateNamespacePermission(String appId, String namespaceName) {
return hasModifyNamespacePermission(appId, namespaceName) || hasReleaseNamespacePermission(appId, namespaceName);
}

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);
}


public boolean hasCreateClusterPermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.CREATE_CLUSTER,
appId);
PermissionType.CREATE_NAMESPACE,
appId);
}

public boolean hasCreateAppNamespacePermission(String appId, AppNamespace appNamespace) {

boolean isPublicAppNamespace = appNamespace.isPublic();
if (isPublicAppNamespace) {

if (portalConfig.canAppAdminCreatePrivateNamespace() || isPublicAppNamespace) {
return hasCreateNamespacePermission(appId);
} else {
return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId());
}

return isSuperAdmin();
}

public boolean hasCreateClusterPermission(String appId) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.CREATE_CLUSTER,
appId);
}

public boolean isAppAdmin(String appId) {
Expand Down
Expand Up @@ -153,6 +153,14 @@ public String emailGrayRulesModuleTemplate() {
return getValue("email.template.release.module.rules", "");
}

public String wikiAddress() {
return getValue("wiki.address", "https://github.com/ctripcorp/apollo/wiki");
}

public boolean canAppAdminCreatePrivateNamespace() {
return getBooleanProperty("admin.createPrivateNamespace.switch", true);
}

/***
* The following configurations are used in ctrip profile
**/
Expand Down
Expand Up @@ -11,6 +11,7 @@
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
import com.ctrip.framework.apollo.portal.constant.RoleType;
import com.ctrip.framework.apollo.portal.entity.model.NamespaceCreationModel;
import com.ctrip.framework.apollo.portal.entity.bo.NamespaceBO;
Expand Down Expand Up @@ -62,6 +63,9 @@ public class NamespaceController {
private RoleInitializationService roleInitializationService;
@Autowired
private RolePermissionService rolePermissionService;
@Autowired
private PortalConfig portalConfig;


@RequestMapping(value = "/appnamespaces/public", method = RequestMethod.GET)
public List<AppNamespace> findPublicAppNamespaces() {
Expand Down Expand Up @@ -119,14 +123,7 @@ public ResponseEntity<Void> createNamespace(@PathVariable String appId,
}
}

//default assign modify、release namespace role to namespace creator
String loginUser = userInfoHolder.getUser().getUserId();
rolePermissionService
.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.MODIFY_NAMESPACE),
Sets.newHashSet(loginUser), loginUser);
rolePermissionService
.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.RELEASE_NAMESPACE),
Sets.newHashSet(loginUser), loginUser);
assignNamespaceRoleToOperator(appId, namespaceName);

return ResponseEntity.ok().build();
}
Expand Down Expand Up @@ -169,6 +166,10 @@ public AppNamespace createAppNamespace(@PathVariable String appId, @RequestBody
appNamespace.setDataChangeLastModifiedBy(operator);
AppNamespace createdAppNamespace = appNamespaceService.createAppNamespaceInLocal(appNamespace);

if (portalConfig.canAppAdminCreatePrivateNamespace() || createdAppNamespace.isPublic()) {
assignNamespaceRoleToOperator(appId, appNamespace.getName());
}

publisher.publishEvent(new AppNamespaceCreationEvent(createdAppNamespace));

return createdAppNamespace;
Expand Down Expand Up @@ -196,4 +197,15 @@ public List<NamespaceDTO> getPublicAppNamespaceAllNamespaces(@PathVariable Strin

}

private void assignNamespaceRoleToOperator(String appId, String namespaceName) {
//default assign modify、release namespace role to namespace creator
String operator = userInfoHolder.getUser().getUserId();

rolePermissionService
.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.MODIFY_NAMESPACE),
Sets.newHashSet(operator), operator);
rolePermissionService
.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, RoleType.RELEASE_NAMESPACE),
Sets.newHashSet(operator), operator);
}
}
@@ -0,0 +1,27 @@
package com.ctrip.framework.apollo.portal.controller;

import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
import com.ctrip.framework.apollo.portal.entity.vo.PageSetting;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PageSettingController {

@Autowired
private PortalConfig portalConfig;

@RequestMapping(value = "/page-settings", method = RequestMethod.GET)
public PageSetting getPageSetting() {
PageSetting setting = new PageSetting();

setting.setWikiAddress(portalConfig.wikiAddress());
setting.setCanAppAdminCreatePrivateNamespace(portalConfig.canAppAdminCreatePrivateNamespace());

return setting;
}

}
@@ -0,0 +1,24 @@
package com.ctrip.framework.apollo.portal.entity.vo;

public class PageSetting {

private String wikiAddress;

private boolean canAppAdminCreatePrivateNamespace;

public String getWikiAddress() {
return wikiAddress;
}

public void setWikiAddress(String wikiAddress) {
this.wikiAddress = wikiAddress;
}

public boolean isCanAppAdminCreatePrivateNamespace() {
return canAppAdminCreatePrivateNamespace;
}

public void setCanAppAdminCreatePrivateNamespace(boolean canAppAdminCreatePrivateNamespace) {
this.canAppAdminCreatePrivateNamespace = canAppAdminCreatePrivateNamespace;
}
}
Expand Up @@ -77,10 +77,7 @@ public AppNamespace createAppNamespaceInLocal(AppNamespace appNamespace) {

AppNamespace createdAppNamespace = appNamespaceRepository.save(appNamespace);

//如果是私有的app namespace 要默认初始化权限,如果是公共的,则在关联此namespace的时候初始化权限
if (!createdAppNamespace.isPublic()) {
roleInitializationService.initNamespaceRoles(appNamespace.getAppId(), appNamespace.getName());
}
roleInitializationService.initNamespaceRoles(appNamespace.getAppId(), appNamespace.getName());

return createdAppNamespace;
}
Expand Down
1 change: 1 addition & 0 deletions apollo-portal/src/main/resources/static/app.html
Expand Up @@ -118,6 +118,7 @@
<script type="application/javascript" src="scripts/services/AppService.js"></script>
<script type="application/javascript" src="scripts/services/EnvService.js"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script>
<script type="application/javascript" src="scripts/services/CommonService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
<script type="application/javascript" src="scripts/services/OrganizationService.js"></script>
<script type="application/javascript" src="scripts/directive/directive.js"></script>
Expand Down

0 comments on commit cd55a0d

Please sign in to comment.