Commit 1794d3d2 authored by nobodyiam's avatar nobodyiam

apollo-portal to support displaying configs only to team members, users could...

apollo-portal to support displaying configs only to team members, users could control this behavior by configuring configView.memberOnly.envs in ApolloPortalDB.ServerConfig.
parent b3fb3fac
...@@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.portal.component; ...@@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.portal.component;
import com.ctrip.framework.apollo.common.entity.AppNamespace; import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.portal.component.config.PortalConfig; import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
import com.ctrip.framework.apollo.portal.constant.PermissionType; import com.ctrip.framework.apollo.portal.constant.PermissionType;
import com.ctrip.framework.apollo.portal.service.AppNamespaceService;
import com.ctrip.framework.apollo.portal.service.RolePermissionService; import com.ctrip.framework.apollo.portal.service.RolePermissionService;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;
import com.ctrip.framework.apollo.portal.util.RoleUtils; import com.ctrip.framework.apollo.portal.util.RoleUtils;
...@@ -18,6 +19,8 @@ public class PermissionValidator { ...@@ -18,6 +19,8 @@ public class PermissionValidator {
private RolePermissionService rolePermissionService; private RolePermissionService rolePermissionService;
@Autowired @Autowired
private PortalConfig portalConfig; private PortalConfig portalConfig;
@Autowired
private AppNamespaceService appNamespaceService;
public boolean hasModifyNamespacePermission(String appId, String namespaceName) { public boolean hasModifyNamespacePermission(String appId, String namespaceName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
...@@ -94,4 +97,20 @@ public class PermissionValidator { ...@@ -94,4 +97,20 @@ public class PermissionValidator {
public boolean isSuperAdmin() { public boolean isSuperAdmin() {
return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId()); return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId());
} }
public boolean shouldHideConfigToCurrentUser(String appId, String env, String namespaceName) {
// 1. check whether the current environment enables member only function
if (!portalConfig.isConfigViewMemberOnly(env)) {
return false;
}
// 2. public namespace is open to every one
AppNamespace appNamespace = appNamespaceService.findByAppIdAndName(appId, namespaceName);
if (appNamespace != null && appNamespace.isPublic()) {
return false;
}
// 3. check app admin and operate permissions
return !isAppAdmin(appId) && !hasOperateNamespacePermission(appId, namespaceName, env);
}
} }
...@@ -74,6 +74,18 @@ public class PortalConfig extends RefreshableConfig { ...@@ -74,6 +74,18 @@ public class PortalConfig extends RefreshableConfig {
return result; return result;
} }
public boolean isConfigViewMemberOnly(String env) {
String[] configViewMemberOnlyEnvs = getArrayProperty("configView.memberOnly.envs", new String[0]);
for (String memberOnlyEnv : configViewMemberOnlyEnvs) {
if (memberOnlyEnv.equalsIgnoreCase(env)) {
return true;
}
}
return false;
}
/*** /***
* Level: normal * Level: normal
**/ **/
......
...@@ -3,8 +3,10 @@ package com.ctrip.framework.apollo.portal.controller; ...@@ -3,8 +3,10 @@ package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.dto.CommitDTO; import com.ctrip.framework.apollo.common.dto.CommitDTO;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition; import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.component.PermissionValidator;
import com.ctrip.framework.apollo.portal.service.CommitService; import com.ctrip.framework.apollo.portal.service.CommitService;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
...@@ -21,10 +23,16 @@ public class CommitController { ...@@ -21,10 +23,16 @@ public class CommitController {
@Autowired @Autowired
private CommitService commitService; private CommitService commitService;
@Autowired
private PermissionValidator permissionValidator;
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/commits", method = RequestMethod.GET) @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/commits", method = RequestMethod.GET)
public List<CommitDTO> find(@PathVariable String appId, @PathVariable String env, public List<CommitDTO> find(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
return Collections.emptyList();
}
RequestPrecondition.checkNumberPositive(size); RequestPrecondition.checkNumberPositive(size);
RequestPrecondition.checkNumberNotNegative(page); RequestPrecondition.checkNumberNotNegative(page);
......
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.dto.ItemChangeSets;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
...@@ -107,6 +108,10 @@ public class ItemController { ...@@ -107,6 +108,10 @@ public class ItemController {
@PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable String clusterName, @PathVariable String namespaceName,
@RequestParam(defaultValue = "lineNum") String orderBy) { @RequestParam(defaultValue = "lineNum") String orderBy) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
return Collections.emptyList();
}
List<ItemDTO> items = configService.findItems(appId, Env.valueOf(env), clusterName, namespaceName); List<ItemDTO> items = configService.findItems(appId, Env.valueOf(env), clusterName, namespaceName);
if ("lastModifiedTime".equals(orderBy)) { if ("lastModifiedTime".equals(orderBy)) {
Collections.sort(items, (o1, o2) -> { Collections.sort(items, (o1, o2) -> {
...@@ -136,7 +141,22 @@ public class ItemController { ...@@ -136,7 +141,22 @@ public class ItemController {
public List<ItemDiffs> diff(@RequestBody NamespaceSyncModel model) { public List<ItemDiffs> diff(@RequestBody NamespaceSyncModel model) {
checkModel(Objects.nonNull(model) && !model.isInvalid()); checkModel(Objects.nonNull(model) && !model.isInvalid());
return configService.compare(model.getSyncToNamespaces(), model.getSyncItems()); List<ItemDiffs> itemDiffs = configService.compare(model.getSyncToNamespaces(), model.getSyncItems());
for (ItemDiffs diff : itemDiffs) {
NamespaceIdentifier namespace = diff.getNamespace();
if (namespace == null) {
continue;
}
if (permissionValidator
.shouldHideConfigToCurrentUser(namespace.getAppId(), namespace.getEnv().name(), namespace.getNamespaceName())) {
diff.setDiffs(new ItemChangeSets());
diff.setExtInfo("您不是该项目的管理员,也没有该Namespace在 " + namespace.getEnv() + " 环境的编辑或发布权限");
}
}
return itemDiffs;
} }
@RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = { @RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = {
......
...@@ -43,7 +43,13 @@ public class NamespaceBranchController { ...@@ -43,7 +43,13 @@ public class NamespaceBranchController {
@PathVariable String env, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String clusterName,
@PathVariable String namespaceName) { @PathVariable String namespaceName) {
return namespaceBranchService.findBranch(appId, Env.valueOf(env), clusterName, namespaceName); NamespaceBO namespaceBO = namespaceBranchService.findBranch(appId, Env.valueOf(env), clusterName, namespaceName);
if (namespaceBO != null && permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
namespaceBO.hideItems();
}
return namespaceBO;
} }
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)")
......
...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.portal.controller; ...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.dto.AppNamespaceDTO; import com.ctrip.framework.apollo.common.dto.AppNamespaceDTO;
import com.ctrip.framework.apollo.common.utils.BeanUtils; import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.portal.component.PermissionValidator;
import com.ctrip.framework.apollo.portal.listener.AppNamespaceDeletionEvent; import com.ctrip.framework.apollo.portal.listener.AppNamespaceDeletionEvent;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
...@@ -62,6 +63,8 @@ public class NamespaceController { ...@@ -62,6 +63,8 @@ public class NamespaceController {
private RolePermissionService rolePermissionService; private RolePermissionService rolePermissionService;
@Autowired @Autowired
private PortalConfig portalConfig; private PortalConfig portalConfig;
@Autowired
private PermissionValidator permissionValidator;
@RequestMapping(value = "/appnamespaces/public", method = RequestMethod.GET) @RequestMapping(value = "/appnamespaces/public", method = RequestMethod.GET)
...@@ -73,14 +76,28 @@ public class NamespaceController { ...@@ -73,14 +76,28 @@ public class NamespaceController {
public List<NamespaceBO> findNamespaces(@PathVariable String appId, @PathVariable String env, public List<NamespaceBO> findNamespaces(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName) { @PathVariable String clusterName) {
return namespaceService.findNamespaceBOs(appId, Env.valueOf(env), clusterName); List<NamespaceBO> namespaceBOs = namespaceService.findNamespaceBOs(appId, Env.valueOf(env), clusterName);
for (NamespaceBO namespaceBO : namespaceBOs) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceBO.getBaseInfo().getNamespaceName())) {
namespaceBO.hideItems();
}
}
return namespaceBOs;
} }
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName:.+}", method = RequestMethod.GET) @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName:.+}", method = RequestMethod.GET)
public NamespaceBO findNamespace(@PathVariable String appId, @PathVariable String env, public NamespaceBO findNamespace(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName) { @PathVariable String clusterName, @PathVariable String namespaceName) {
return namespaceService.loadNamespaceBO(appId, Env.valueOf(env), clusterName, namespaceName); NamespaceBO namespaceBO = namespaceService.loadNamespaceBO(appId, Env.valueOf(env), clusterName, namespaceName);
if (namespaceBO != null && permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
namespaceBO.hideItems();
}
return namespaceBO;
} }
@RequestMapping(value = "/envs/{env}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/associated-public-namespace", @RequestMapping(value = "/envs/{env}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/associated-public-namespace",
......
...@@ -13,6 +13,7 @@ import com.ctrip.framework.apollo.portal.entity.bo.ReleaseBO; ...@@ -13,6 +13,7 @@ import com.ctrip.framework.apollo.portal.entity.bo.ReleaseBO;
import com.ctrip.framework.apollo.portal.listener.ConfigPublishEvent; import com.ctrip.framework.apollo.portal.listener.ConfigPublishEvent;
import com.ctrip.framework.apollo.portal.service.ReleaseService; import com.ctrip.framework.apollo.portal.service.ReleaseService;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
...@@ -113,6 +114,9 @@ public class ReleaseController { ...@@ -113,6 +114,9 @@ public class ReleaseController {
@PathVariable String namespaceName, @PathVariable String namespaceName,
@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "5") int size) { @RequestParam(defaultValue = "5") int size) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
return Collections.emptyList();
}
RequestPrecondition.checkNumberPositive(size); RequestPrecondition.checkNumberPositive(size);
RequestPrecondition.checkNumberNotNegative(page); RequestPrecondition.checkNumberNotNegative(page);
...@@ -128,6 +132,10 @@ public class ReleaseController { ...@@ -128,6 +132,10 @@ public class ReleaseController {
@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "5") int size) { @RequestParam(defaultValue = "5") int size) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
return Collections.emptyList();
}
RequestPrecondition.checkNumberPositive(size); RequestPrecondition.checkNumberPositive(size);
RequestPrecondition.checkNumberNotNegative(page); RequestPrecondition.checkNumberNotNegative(page);
......
...@@ -2,9 +2,11 @@ package com.ctrip.framework.apollo.portal.controller; ...@@ -2,9 +2,11 @@ package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.component.PermissionValidator;
import com.ctrip.framework.apollo.portal.entity.bo.ReleaseHistoryBO; import com.ctrip.framework.apollo.portal.entity.bo.ReleaseHistoryBO;
import com.ctrip.framework.apollo.portal.service.ReleaseHistoryService; import com.ctrip.framework.apollo.portal.service.ReleaseHistoryService;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
...@@ -19,6 +21,8 @@ public class ReleaseHistoryController { ...@@ -19,6 +21,8 @@ public class ReleaseHistoryController {
@Autowired @Autowired
private ReleaseHistoryService releaseHistoryService; private ReleaseHistoryService releaseHistoryService;
@Autowired
private PermissionValidator permissionValidator;
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/releases/histories", @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/releases/histories",
method = RequestMethod.GET) method = RequestMethod.GET)
...@@ -29,6 +33,10 @@ public class ReleaseHistoryController { ...@@ -29,6 +33,10 @@ public class ReleaseHistoryController {
@RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "size", defaultValue = "10") int size) { @RequestParam(value = "size", defaultValue = "10") int size) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
return Collections.emptyList();
}
return releaseHistoryService.findNamespaceReleaseHistory(appId, Env.valueOf(env), clusterName ,namespaceName, page, size); return releaseHistoryService.findNamespaceReleaseHistory(appId, Env.valueOf(env), clusterName ,namespaceName, page, size);
} }
......
...@@ -12,7 +12,8 @@ public class NamespaceBO { ...@@ -12,7 +12,8 @@ public class NamespaceBO {
private boolean isPublic; private boolean isPublic;
private String parentAppId; private String parentAppId;
private String comment; private String comment;
// is the configs hidden to current user?
private boolean isConfigHidden;
public NamespaceDTO getBaseInfo() { public NamespaceDTO getBaseInfo() {
return baseInfo; return baseInfo;
...@@ -70,4 +71,17 @@ public class NamespaceBO { ...@@ -70,4 +71,17 @@ public class NamespaceBO {
this.comment = comment; this.comment = comment;
} }
public boolean isConfigHidden() {
return isConfigHidden;
}
public void setConfigHidden(boolean hidden) {
isConfigHidden = hidden;
}
public void hideItems() {
setConfigHidden(true);
items.clear();
setItemModifiedCnt(0);
}
} }
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
</div> </div>
<div class="release-history-container panel-body row" ng-show="releaseHistories && releaseHistories.length > 0"> <div class="release-history-container panel-body row" ng-show="!isConfigHidden && releaseHistories && releaseHistories.length > 0">
<div class="release-history-list col-md-3"> <div class="release-history-list col-md-3">
<div class="media hover" ng-class="{'active': releaseHistory.id == selectedReleaseHistory}" <div class="media hover" ng-class="{'active': releaseHistory.id == selectedReleaseHistory}"
...@@ -232,8 +232,9 @@ ...@@ -232,8 +232,9 @@
</div> </div>
<div class="panel-body" ng-show="!releaseHistories || releaseHistories.length == 0"> <div class="panel-body" ng-show="isConfigHidden || !releaseHistories || releaseHistories.length == 0">
<h4 class="text-center empty-container">无发布历史信息</h4> <h4 class="text-center empty-container" ng-show="isConfigHidden">您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看发布历史</h4>
<h4 class="text-center empty-container" ng-show="!isConfigHidden">无发布历史信息</h4>
</div> </div>
</section> </section>
......
...@@ -26,6 +26,8 @@ function releaseHistoryController($scope, $location, AppUtil, ...@@ -26,6 +26,8 @@ function releaseHistoryController($scope, $location, AppUtil,
$scope.hasLoadAll = false; $scope.hasLoadAll = false;
$scope.selectedReleaseHistory = 0; $scope.selectedReleaseHistory = 0;
$scope.isTextNamespace = false; $scope.isTextNamespace = false;
// whether current user can view config
$scope.isConfigHidden = false;
$scope.showReleaseHistoryDetail = showReleaseHistoryDetail; $scope.showReleaseHistoryDetail = showReleaseHistoryDetail;
$scope.switchConfigViewType = switchConfigViewType; $scope.switchConfigViewType = switchConfigViewType;
...@@ -99,6 +101,7 @@ function releaseHistoryController($scope, $location, AppUtil, ...@@ -99,6 +101,7 @@ function releaseHistoryController($scope, $location, AppUtil,
if ($scope.isTextNamespace) { if ($scope.isTextNamespace) {
fixTextNamespaceViewType(); fixTextNamespaceViewType();
} }
$scope.isConfigHidden = result.isConfigHidden;
}) })
} }
......
...@@ -53,8 +53,13 @@ ...@@ -53,8 +53,13 @@
</header> </header>
<div id="BODY{{namespace.branch.id}}" class="collapse in"> <div id="BODY{{namespace.branch.id}}" class="collapse in">
<div class="J_namespace-release-tip well well-sm no-radius text-center"
ng-show="namespace.isConfigHidden">
<span style="color: red">您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看配置信息。</span>
</div>
<!--second header--> <!--second header-->
<header class="panel-heading second-panel-heading"> <header class="panel-heading second-panel-heading" ng-show="!namespace.isConfigHidden">
<div class="row"> <div class="row">
<div class="col-md-12 pull-left"> <div class="col-md-12 pull-left">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
...@@ -92,7 +97,7 @@ ...@@ -92,7 +97,7 @@
</div> </div>
</header> </header>
<!--namespace body--> <!--namespace body-->
<section> <section ng-show="!namespace.isConfigHidden">
<!--items--> <!--items-->
<div class="namespace-view-table" ng-show="namespace.branch.viewType == 'table'"> <div class="namespace-view-table" ng-show="namespace.branch.viewType == 'table'">
......
...@@ -92,9 +92,16 @@ ...@@ -92,9 +92,16 @@
</div> </div>
</header> </header>
<div id="BODY{{namespace.id}}" class="collapse in"> <div id="BODY{{namespace.id}}" class="collapse in">
<div class="J_namespace-release-tip well well-sm no-radius text-center"
ng-show="namespace.isConfigHidden">
<span style="color: red">您不是该项目的管理员,也没有该Namespace的编辑或发布权限,无法查看配置信息。</span>
</div>
<!--second header--> <!--second header-->
<header class="panel-heading second-panel-heading"> <header class="panel-heading second-panel-heading" ng-show="!namespace.isConfigHidden">
<div class="row"> <div class="row">
<div class="col-md-6 col-sm-6 pull-left"> <div class="col-md-6 col-sm-6 pull-left">
<!--master branch nav tabs--> <!--master branch nav tabs-->
...@@ -182,7 +189,7 @@ ...@@ -182,7 +189,7 @@
</header> </header>
<!--namespace body--> <!--namespace body-->
<section> <section ng-show="!namespace.isConfigHidden">
<!--table view--> <!--table view-->
<div class="namespace-view-table" ng-show="namespace.viewType == 'table'"> <div class="namespace-view-table" ng-show="namespace.viewType == 'table'">
......
...@@ -312,7 +312,8 @@ VALUES ...@@ -312,7 +312,8 @@ VALUES
('superAdmin', 'apollo', 'Portal超级管理员'), ('superAdmin', 'apollo', 'Portal超级管理员'),
('api.readTimeout', '10000', 'http接口read timeout'), ('api.readTimeout', '10000', 'http接口read timeout'),
('consumer.token.salt', 'someSalt', 'consumer token salt'), ('consumer.token.salt', 'someSalt', 'consumer token salt'),
('admin.createPrivateNamespace.switch', 'true', '是否允许项目管理员创建私有namespace'); ('admin.createPrivateNamespace.switch', 'true', '是否允许项目管理员创建私有namespace'),
('configView.memberOnly.envs', 'pro', '只对项目成员显示配置信息的环境列表,多个env以英文逗号分隔');
INSERT INTO `Users` (`Username`, `Password`, `Email`, `Enabled`) INSERT INTO `Users` (`Username`, `Password`, `Email`, `Enabled`)
VALUES VALUES
......
...@@ -312,7 +312,9 @@ VALUES ...@@ -312,7 +312,9 @@ VALUES
('superAdmin', 'apollo', 'Portal超级管理员'), ('superAdmin', 'apollo', 'Portal超级管理员'),
('api.readTimeout', '10000', 'http接口read timeout'), ('api.readTimeout', '10000', 'http接口read timeout'),
('consumer.token.salt', 'someSalt', 'consumer token salt'), ('consumer.token.salt', 'someSalt', 'consumer token salt'),
('admin.createPrivateNamespace.switch', 'true', '是否允许项目管理员创建私有namespace'); ('admin.createPrivateNamespace.switch', 'true', '是否允许项目管理员创建私有namespace'),
('configView.memberOnly.envs', 'pro', '只对项目成员显示配置信息的环境列表,多个env以英文逗号分隔');
INSERT INTO `Users` (`Username`, `Password`, `Email`, `Enabled`) INSERT INTO `Users` (`Username`, `Password`, `Email`, `Enabled`)
VALUES VALUES
......
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