Skip to content

Commit

Permalink
Optimize the UI experience of open platform authorization management (
Browse files Browse the repository at this point in the history
…#4436)

* add tech-support-qq-4.png

* Update README.md

* Enhance the user experience in the scenario of submitting duplicate keys

* Modify the key-value conflict exception prompt, adjust the code style

* Optimize the UI experience of open platform authorization management

* doc(CHANGES.md): update CHANGES.md

* Fixed use of document title sequence numbers

* Update apollo-portal/src/main/resources/static/i18n/en.json

Co-authored-by: Jason Song <[email protected]>

* Update apollo-portal/src/main/resources/static/i18n/en.json

Co-authored-by: Jason Song <[email protected]>

* Optimize the display of create consumer button

* Fix the problem of deleting consumer permissions

* Optimize the UI experience of open platform authorization management

* doc(CHANGES.md): update CHANGES.md

* Fixed use of document title sequence numbers

* Update apollo-portal/src/main/resources/static/i18n/en.json

Co-authored-by: Jason Song <[email protected]>

* Update apollo-portal/src/main/resources/static/i18n/en.json

Co-authored-by: Jason Song <[email protected]>

* Optimize the display of create consumer button

* Fix the problem of deleting consumer permissions

* Optimize ConsumerController related interface declaration

* Update apollo-portal/src/main/resources/static/i18n/en.json

Co-authored-by: Jason Song <[email protected]>
  • Loading branch information
klboke and nobodyiam authored Jul 6, 2022
1 parent 804ffae commit 5ab705d
Show file tree
Hide file tree
Showing 18 changed files with 984 additions and 158 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Apollo 2.1.0
* [Upgrade mysql-connector-java version to fix possible transaction rollback failure issue](https://github.com/apolloconfig/apollo/pull/4425)
* [Remove database migration tool Flyway](https://github.com/apolloconfig/apollo/pull/4361)
* [Optimize Spring-Security Firewall Deny Request Response 400](https://github.com/apolloconfig/apollo/pull/4428)
* [Optimize the UI experience of open platform authorization management](https://github.com/apolloconfig/apollo/pull/4436)
* [Allow users to associate multiple public namespaces at a time](https://github.com/apolloconfig/apollo/pull/4437)

------------------
All issues and pull requests are [here](https://github.com/apolloconfig/apollo/milestone/11?closed=1)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.ctrip.framework.apollo.openapi.service;

import com.ctrip.framework.apollo.common.dto.PageDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.openapi.entity.Consumer;
import com.ctrip.framework.apollo.openapi.entity.ConsumerAudit;
Expand All @@ -38,7 +39,9 @@
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.hash.Hashing;
import java.util.Objects;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -291,4 +294,27 @@ private Set<String> findAppIdsByRoleIds(List<Long> roleIds) {

return appIds;
}

public List<Consumer> findAllConsumer(Pageable page){
return this.consumerRepository.findAll(page).getContent();
}

@Transactional
public void deleteConsumer(String appId){
Consumer consumer = consumerRepository.findByAppId(appId);
if (consumer == null) {
throw new BadRequestException("ConsumerApp not exist");
}
long consumerId = consumer.getId();
List<ConsumerRole> consumerRoleList = consumerRoleRepository.findByConsumerId(consumerId);
ConsumerToken consumerToken = consumerTokenRepository.findByConsumerId(consumerId);

consumerRoleRepository.deleteAll(consumerRoleList);
consumerRepository.delete(consumer);

if (Objects.nonNull(consumerToken)) {
consumerTokenRepository.delete(consumerToken);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.ctrip.framework.apollo.portal.environment.Env;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -71,7 +72,7 @@ public ConsumerToken createConsumer(@RequestBody Consumer consumer,
}

@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@GetMapping(value = "/consumers/by-appId")
@GetMapping(value = "/consumer-tokens/by-appId")
public ConsumerToken getConsumerTokenByAppId(@RequestParam String appId) {
return consumerService.getConsumerTokenByAppId(appId);
}
Expand Down Expand Up @@ -119,6 +120,16 @@ public List<ConsumerRole> assignNamespaceRoleToConsumer(@PathVariable String tok
return consumerService.assignNamespaceRoleToConsumer(token, appId, namespaceName);
}

@GetMapping("/consumers")
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
public List<Consumer> getConsumerList(Pageable page){
return consumerService.findAllConsumer(page);
}

@DeleteMapping(value = "/consumers/by-appId")
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
public void deleteConsumers(@RequestParam String appId) {
consumerService.deleteConsumer(appId);
}

}
7 changes: 7 additions & 0 deletions apollo-portal/src/main/resources/static/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
"Common.PleaseChooseDepartment": "Please select department",
"Common.PleaseChooseOwner": "Please select app owner",
"Common.LoginExpiredTips": "Your login is expired. Please refresh the page and try again.",
"Common.Operation": "Operation",
"Common.Delete": "Delete",
"Component.DeleteNamespace.Title": "Delete Namespace",
"Component.DeleteNamespace.PublicContent": "Deleting namespace will cause the instances unable to get the configuration of this namespace. Are you sure to delete it?",
"Component.DeleteNamespace.PrivateContent": "Deleting a private Namespace will cause the instances unable to get the configuration of this namespace, and the page will prompt 'missing namespace' (unless the AppNamespace is deleted by admin tool). Are you sure to delete it?",
Expand Down Expand Up @@ -591,6 +593,11 @@
"Open.Manage.AppNotCreated": "App('{{appId}}') does not exist, please create it first",
"Open.Manage.GrantSuccessfully": "Authorize Successfully",
"Open.Manage.GrantFailed": "Failed to authorize",
"Open.Manage.ViewAndGrantPermission": "Grant Permission",
"Open.Manage.DeleteConsumer.Confirm": "You are deleting a third-party app with <b>AppId={{toOperationConsumer.appId}},AppName={{toOperationConsumer.name}}</b>,<br>Are you sure you want to delete?",
"Open.Manage.DeleteConsumer.Success": "Third-party app deleted successfully",
"Open.Manage.DeleteConsumer.Error": "Third-party app deletion failed",
"Open.Manage.CreateConsumer.Button": "Create Third-Party App",
"Namespace.Role.Title": "Permission Management",
"Namespace.Role.GrantModifyTo": "Permission to edit",
"Namespace.Role.GrantModifyTo2": "(Can edit the configuration)",
Expand Down
7 changes: 7 additions & 0 deletions apollo-portal/src/main/resources/static/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
"Common.PleaseChooseDepartment": "请选择部门",
"Common.PleaseChooseOwner": "请选择应用负责人",
"Common.LoginExpiredTips": "您的登录信息已过期,请刷新页面后重试",
"Common.Operation": "操作",
"Common.Delete": "删除",
"Component.DeleteNamespace.Title": "删除 Namespace",
"Component.DeleteNamespace.PublicContent": "删除 Namespace 将导致实例获取不到此 Namespace 的配置,确定要删除吗?",
"Component.DeleteNamespace.PrivateContent": "删除私有 Namespace 将导致实例获取不到此 Namespace 的配置,且页面会提示缺失 Namespace(除非使用管理员工具删除 AppNamespace),确定要删除吗?",
Expand Down Expand Up @@ -591,6 +593,11 @@
"Open.Manage.AppNotCreated": "App('{{appId}}')未创建,请先创建",
"Open.Manage.GrantSuccessfully": "赋权成功",
"Open.Manage.GrantFailed": "赋权失败",
"Open.Manage.ViewAndGrantPermission": "查看Token并赋权",
"Open.Manage.DeleteConsumer.Confirm": "您正在删除 <b>AppId='{{toOperationConsumer.appId}}',应用名称='{{toOperationConsumer.name}}'</b> 的第三方应用,<br>确定要删除吗?",
"Open.Manage.DeleteConsumer.Success": "第三方应用删除成功",
"Open.Manage.DeleteConsumer.Error": "第三方应用删除失败",
"Open.Manage.CreateConsumer.Button": "创建第三方应用",
"Namespace.Role.Title": "权限管理",
"Namespace.Role.GrantModifyTo": "修改权",
"Namespace.Role.GrantModifyTo2": "(可以修改配置)",
Expand Down
241 changes: 241 additions & 0 deletions apollo-portal/src/main/resources/static/open/add-consumer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
<!--
~ Copyright 2022 Apollo Authors
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
-->
<!doctype html>
<html ng-app="open_manage">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="../img/config.png">
<!-- styles -->
<link rel="stylesheet" type="text/css" href="../vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../vendor/angular/angular-toastr-1.4.1.min.css">
<link rel="stylesheet" type="text/css" media='all' href="../vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="../styles/common-style.css">
<link rel="stylesheet" type="text/css" href="../vendor/select2/select2.min.css">
<title>{{'Open.Manage.Title' | translate }}</title>
</head>

<body>

<apollonav></apollonav>


<div class="container-fluid" ng-controller="OpenManageController">
<div class="col-md-10 col-md-offset-1 panel">

<section class="panel-body" ng-show="isRootUser">
<!--project admin-->
<section class="row">
<h5>{{'Open.Manage.CreateThirdApp' | translate }}
<small>
{{'Open.Manage.CreateThirdAppTips' | translate }}
</small>
</h5>
<hr>
<form class="form-horizontal">
<div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield>
{{'Open.Manage.ThirdAppId' | translate }}
</label>
<div class="col-sm-3">
<input type="text" class="form-control" ng-model="consumer.appId">
<small>{{'Open.Manage.ThirdAppIdTips' | translate }}</small>
</div>
<div class="col-sm-1">
<button class="btn btn-info" ng-click="getTokenByAppId()">{{'Common.Search' | translate }}</button>
</div>
<div class="col-sm-6">
<h4 style="color: red" ng-show="consumerToken"
ng-bind="'Token: ' + consumerToken.token"></h4>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield>
{{'Common.Department' | translate }}
</label>
<div class="col-sm-3">
<select id="organization">
<option></option>
</select>
</div>
</div>
<div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield>
{{'Open.Manage.ThirdAppName' | translate }}
</label>
<div class="col-sm-3">
<input type="text" class="form-control" ng-model="consumer.name">
<small>{{'Open.Manage.ThirdAppNameTips' | translate }}</small>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield>
{{'Open.Manage.ProjectOwner' | translate }}
</label>
<div class="col-sm-6 J_ownerSelectorPanel">
<apollouserselector apollo-id="'ownerSelector'"></apollouserselector>
</div>
</div>

<div class="form-group">
<div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" ng-disabled="submitBtnDisabled"
ng-click="createConsumer()">
{{'Open.Manage.Create' | translate }}
</button>
</div>
</div>
</form>
</section>

<section class="row">
<h5>{{'Open.Manage.GrantPermission' | translate }}
<small>
{{'Open.Manage.GrantPermissionTips' | translate }}
</small>
</h5>
<hr>
<form class="form-horizontal" ng-submit="assignRoleToConsumer()">

<div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield>
{{'Open.Manage.Token' | translate }}
</label>
<div class="col-sm-5">
<input type="text" class="form-control" ng-model="consumerRole.token" required>
</div>
</div>
<div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label">
<apollorequiredfield></apollorequiredfield>
{{'Open.Manage.ManagedAppId' | translate }}
</label>
<div class="col-sm-3">
<input type="text" class="form-control" ng-model="consumerRole.appId" required>
</div>
</div>
<div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label">
{{'Open.Manage.ManagedNamespace' | translate }}</label>
<div class="col-sm-3">
<input type="text" class="form-control" ng-model="consumerRole.namespaceName">
<small>{{'Open.Manage.ManagedNamespaceTips' | translate }}</small>
</div>
</div>
<div class="form-group" valdr-form-group>
<label class="col-sm-2 control-label">
{{'Open.Manage.GrantType' | translate }}
</label>
<div class="col-sm-3">
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" ng-value="'NamespaceRole'"
ng-model="consumerRole.type">
{{'Open.Manage.GrantType.Namespace' | translate }}
</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" ng-value="'AppRole'"
ng-model="consumerRole.type">
{{'Open.Manage.GrantType.App' | translate }}
</label>
</div>
</div>
<div class="form-group" valdr-form-group ng-show="consumerRole.type=='NamespaceRole'">
<label class="col-sm-2 control-label">
{{'Open.Manage.GrantEnv' | translate }}
</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>{{'Open.Manage.GrantEnvTips' | translate }}</small>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-9">
<button type="submit" class="btn btn-primary" ng-disabled="submitBtnDisabled">
{{'Common.Submit' | translate }}
</button>
</div>
</div>
</form>

</section>

</section>

<section class="panel-body text-center" ng-if="!isRootUser">
<h4>{{'Common.IsRootUser' | translate }}</h4>
</section>

</div>
</div>

<div ng-include="'../views/common/footer.html'"></div>

<!-- jquery.js -->
<script src="../vendor/jquery.min.js" type="text/javascript"></script>

<!--angular-->
<script src="../vendor/angular/angular.min.js"></script>
<script src="../vendor/angular/angular-route.min.js"></script>
<script src="../vendor/angular/angular-resource.min.js"></script>
<script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="../vendor/angular/loading-bar.min.js"></script>
<script src="../vendor/angular/angular-cookies.min.js"></script>

<script src="../vendor/angular/angular-translate.2.18.1/angular-translate.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-loader-static-files.min.js"></script>
<script src="../vendor/angular/angular-translate.2.18.1/angular-translate-storage-cookie.min.js"></script>
<!--valdr-->
<script src="../vendor/valdr/valdr.min.js" type="text/javascript"></script>
<script src="../vendor/valdr/valdr-message.min.js" type="text/javascript"></script>

<!-- bootstrap.js -->
<script src="../vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>

<script src="../vendor/lodash.min.js"></script>

<script src="../vendor/select2/select2.min.js" type="text/javascript"></script>
<!--biz-->
<!--must import-->
<script type="application/javascript" src="../scripts/app.js"></script>
<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/services/PermissionService.js"></script>
<script type="application/javascript" src="../scripts/services/OrganizationService.js"></script>
<script type="application/javascript" src="../scripts/services/ConsumerService.js"></script>

<script type="application/javascript" src="../scripts/AppUtils.js"></script>

<script type="application/javascript" src="../scripts/PageCommon.js"></script>
<script type="application/javascript" src="../scripts/directive/directive.js"></script>
<script type="application/javascript" src="../scripts/valdr.js"></script>

<script type="application/javascript" src="../scripts/controller/open/OpenManageController.js"></script>
</body>

</html>
Loading

0 comments on commit 5ab705d

Please sign in to comment.