Browse Source

Refactoring Api: identity-resource

Add New New component :PermissionForm
pull/109/head
cKey 5 years ago
parent
commit
48215226f0
  1. 0
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCloneDto.cs
  2. 9
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCorsOriginDto.cs
  3. 5
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientUpdateDto.cs
  4. 2
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/IdentityResources/Dto/IdentityResourceDto.cs
  5. 68
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json
  6. 69
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json
  7. 39
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs
  8. BIN
      aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db
  9. 268
      vueJs/src/api/clients.ts
  10. 166
      vueJs/src/api/identity-resources.ts
  11. 12
      vueJs/src/api/permission.ts
  12. 466
      vueJs/src/components/PermissionForm/index.vue
  13. 5
      vueJs/src/views/admin/claim-type/components/CreateOrUpdateCliamTypeForm.vue
  14. 5
      vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceCreateOrEditForm.vue
  15. 204
      vueJs/src/views/admin/identityServer/client/index.vue
  16. 238
      vueJs/src/views/admin/identityServer/identity-resources/components/IdentityResourceCreateOrEditForm.vue
  17. 120
      vueJs/src/views/admin/identityServer/identity-resources/index.vue
  18. 5
      vueJs/src/views/admin/roles/components/RoleClaimCreateOrUpdateForm.vue
  19. 5
      vueJs/src/views/admin/roles/components/RoleEditForm.vue
  20. 5
      vueJs/src/views/admin/users/components/UserClaimCreateOrUpdateForm.vue

0
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCloneInputDto.cs → aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCloneDto.cs

9
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCorsOriginDto.cs

@ -1,9 +0,0 @@
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Abp.IdentityServer.Clients
{
public class ClientCorsOriginDto : EntityDto
{
public string Origin { get; set; }
}
}

5
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientUpdateDto.cs

@ -114,6 +114,10 @@ namespace LINGYUN.Abp.IdentityServer.Clients
/// 密钥
/// </summary>
public List<SecretCreateOrUpdateDto> Secrets { get; set; }
/// <summary>
/// 声明
/// </summary>
public List<ClientClaimDto> Claims { get; set; }
public ClientUpdateDto()
{
@ -127,6 +131,7 @@ namespace LINGYUN.Abp.IdentityServer.Clients
IdentityProviderRestrictions = new List<string>();
Properties = new Dictionary<string, string>();
Secrets = new List<SecretCreateOrUpdateDto>();
Claims = new List<ClientClaimDto>();
}
}
}

2
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/IdentityResources/Dto/IdentityResourceDto.cs

@ -12,8 +12,6 @@ namespace LINGYUN.Abp.IdentityServer.IdentityResources
public string Description { get; set; }
public string ConcurrencyStamp { get; set; }
public bool Enabled { get; set; }
public bool Required { get; set; }

68
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json

@ -31,7 +31,11 @@
"Resource:Enabled": "Enabled",
"Resource:New": "Add New",
"Resource:Edit": "Edit",
"Resource:Delete": "Delete",
"Resource:WillDelete": "Resource :{0} will be deleted",
"Resource:Name": "Resource - {0}",
"Resource:Api": "Api Resource",
"Resource:Identity": "Identity Resource",
"UserClaim": "User claim",
"NoClaim": "Owned claims",
"ExistsClaim": "Not owned claims",
@ -49,6 +53,68 @@
"Secret:New": "Add New",
"Secret:Type": "Type",
"Secret:HashType": "Hash Type",
"Secret:Value": "Value"
"Secret:Value": "Value",
"Client:Enabled": "Enabled",
"Client:New": "Add New",
"Client:Edit": "Edit",
"Client:Delete": "Delete",
"Client:WillDelete": "Client :{0} will be deleted",
"Client:Name": "Client - {0}",
"Client:Id": "Client Id",
"Client:Clone": "Clone",
"Clone:CopyAllowedGrantType": "Copy the Client allowed GrantType",
"Clone:CopyRedirectUri": "Copy the Client redirect Uri",
"Clone:CopyAllowedScope": "Copy the Client scopes",
"Clone:CopyClaim": "Copy the Client claims",
"Clone:CopyAllowedCorsOrigin": "Copy the Client Cors-Origin Uri",
"Clone:CopyPostLogoutRedirectUri": "Copy the Client Redirect Uri",
"Clone:CopyProperties": "Copy the Client Properties",
"Clone:CopyIdentityProviderRestriction": "Copy the Client Identity Provider Restriction",
"Client:ProtocolType": "Protocol Type",
"Client:RequiredClientSecret": "Require Client Secret",
"Client:RequiredPkce": "Required Pkce",
"Client:AllowedPlainTextPkce": "Allowed Plain Text Pkce",
"Client:AllowedOfflineAccess": "Allowed Offline Access",
"Client:AllowedScopes": "Allowed Scopes",
"Client:RedirectUris": "Redirect Uris",
"Client:AllowedGrantTypes": "Allowed Grant Types",
"Client:AllowedAccessTokensViaBrowser": "Allowed Access Tokens Via Browser",
"Client:IdentityTokenLifetime": "Identity Token Lifetime(s)",
"Client:AccessTokenLifetime": "Access Token Lifetime(s)",
"Client:AuthorizationCodeLifetime": "Authorization Code Lifetime(s)",
"Client:AbsoluteRefreshTokenLifetime": "Absolute Refresh Token Lifetime(s)",
"Client:SlidingRefreshTokenLifetime": "Sliding Refresh Token Lifetime(s)",
"Client:DeviceCodeLifetime": "Device Code Lifetime(s)",
"Client:ClientClaimsPrefix": "Client Claims Prefix",
"Client:FrontChannelLogoutUri": "Front Channel Logout Uri",
"Client:FrontChannelLogoutSessionRequired": "Front Channel Logout Session Required",
"Client:BackChannelLogoutUri": "Back Channel Logout Uri",
"Client:BackChannelLogoutSessionRequired": "Back Channel Logout Session Required",
"Client:EnableLocalLogin": "Enable Local Login",
"Client:PostLogoutRedirectUris": "Post Logout Redirect Uris",
"Client:IdentityProviderRestrictions": "Identity Provider Restrictions",
"Client:UserSsoLifetime": "User Sso Lifetime",
"Client:AccessTokenType": "AccessToken Type",
"Client:RefreshTokenUsage": "Refresh Token Usage",
"Client:RefreshTokenExpiration": "RefreshToken Expiration",
"Client:AllowedCorsOrigins": "Allowed Cors Origins",
"Client:UpdateAccessTokenClaimsOnRefresh": "Update AccessToken Claims On Refresh",
"Client:IncludeJwtId": "Include Jwt Id",
"Client:AlwaysSendClientClaims": "Always Send Client Claims",
"Client:AlwaysIncludeUserClaimsInIdToken": "Always Include User Claims In Id Token",
"Client:PairWiseSubjectSalt": "Pair Wise Subject Salt",
"Client:RequireConsent": "Require Consent",
"Client:AllowRememberConsent": "Allow Remember Consent",
"Client:ClientUri": "Client Uri",
"Client:LogoUri": "Logo Uri",
"Client:UserCodeType": "User Code Type",
"Claims": "Claims",
"Claims:New": "Add New",
"Claims:Type": "Type",
"Claims:Value": "Value",
"Propertites": "Propertites",
"Propertites:New": "Add New",
"Propertites:Value": "Value",
"Permissions": "Permissions"
}
}

69
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json

@ -32,7 +32,10 @@
"Resource:New": "添加新资源",
"Resource:Edit": "编辑资源",
"Resource:Delete": "删除资源",
"Resource:WillDelete": "资源:{0} 将被删除",
"Resource:Name": "资源 - {0}",
"Resource:Api": "Api 资源",
"Resource:Identity": "身份资源",
"UserClaim": "用户声明",
"NoClaim": "未拥有声明",
"ExistsClaim": "已拥有声明",
@ -43,13 +46,75 @@
"Description": "描述",
"Required": "必要",
"Emphasize": "强调",
"ShowInDiscoveryDocument": "强调",
"ShowInDiscoveryDocument": "在发现文档中显示",
"Expiration": "过期",
"Scope:New": "添加新作用域",
"Scope:Delete": "删除作用域",
"Secret:New": "添加新密钥",
"Secret:Type": "密钥类型",
"Secret:HashType": "哈希类型",
"Secret:Value": "值"
"Secret:Value": "值",
"Client:Enabled": "启用客户端",
"Client:New": "添加新客户端",
"Client:Edit": "编辑客户端",
"Client:Delete": "删除客户端",
"Client:WillDelete": "客户端:{0} 将被删除",
"Client:Name": "客户端 - {0}",
"Client:Id": "客户端标识",
"Client:Clone": "克隆客户端",
"Clone:CopyAllowedGrantType": "复制客户端授权类型",
"Clone:CopyRedirectUri": "复制客户端重定向 Uri",
"Clone:CopyAllowedScope": "复制客户端作用域",
"Clone:CopyClaim": "复制客户端声明",
"Clone:CopyAllowedCorsOrigin": "复制客户端跨域来源",
"Clone:CopyPostLogoutRedirectUri": "复制客户端注销重定向 Uri",
"Clone:CopyProperties": "复制客户端属性",
"Clone:CopyIdentityProviderRestriction": "复制身份提供程序限制",
"Client:ProtocolType": "协议类型",
"Client:RequireClientSecret": "需要客户端密钥",
"Client:RequirePkce": "需要 Pkce",
"Client:AllowedPlainTextPkce": "允许纯文本 Pkce",
"Client:AllowedOfflineAccess": "允许离线访问",
"Client:AllowedScopes": "允许的作用域",
"Client:RedirectUris": "重定向 Uri",
"Client:AllowedGrantTypes": "允许的授权类型",
"Client:AllowedAccessTokensViaBrowser": "允许通过浏览器访问令牌",
"Client:IdentityTokenLifetime": "身份令牌有效期(s)",
"Client:AccessTokenLifetime": "访问令牌有效期(s)",
"Client:AuthorizationCodeLifetime": "授权码有效期(s)",
"Client:AbsoluteRefreshTokenLifetime": "绝对刷新令牌有效期(s)",
"Client:SlidingRefreshTokenLifetime": "滚动刷新令牌有效期(s)",
"Client:DeviceCodeLifetime": "设备授权码有效期(s)",
"Client:ClientClaimsPrefix": "客户端声明前缀",
"Client:FrontChannelLogoutUri": "前端通道注销 Uri",
"Client:FrontChannelLogoutSessionRequired": "需要前端通道注销会话",
"Client:BackChannelLogoutUri": "后端通道退出 Uri",
"Client:BackChannelLogoutSessionRequired": "需要后端通道注销会话",
"Client:EnableLocalLogin": "启用本地登录",
"Client:PostLogoutRedirectUris": "注销重定向 Uri",
"Client:IdentityProviderRestrictions": "身份提供程序限制",
"Client:UserSsoLifetime": "用户 SSO 生命周期",
"Client:AccessTokenType": "访问令牌类型",
"Client:RefreshTokenUsage": "刷新令牌使用情况",
"Client:RefreshTokenExpiration": "刷新令牌过期方式",
"Client:AllowedCorsOrigins": "允许跨域来源",
"Client:UpdateAccessTokenClaimsOnRefresh": "刷新时更新访问令牌声明",
"Client:IncludeJwtId": "包括 Jwt 标识",
"Client:AlwaysSendClientClaims": "始终发送客户端声明",
"Client:AlwaysIncludeUserClaimsInIdToken": "始终在标识令牌中包含用户声明",
"Client:PairWiseSubjectSalt": "配对主体盐",
"Client:RequireConsent": "需要同意",
"Client:AllowRememberConsent": "允许记住同意",
"Client:ClientUri": "客户端 Uri",
"Client:LogoUri": "徽标 Uri",
"Client:UserCodeType": "用户代码类型",
"Claims": "声明",
"Claims:New": "添加新声明",
"Claims:Type": "声明类型",
"Claims:Value": "值",
"Propertites": "属性",
"Propertites:New": "添加新属性",
"Propertites:Value": "值",
"Permissions": "权限"
}
}

39
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs

@ -40,7 +40,7 @@ namespace LINGYUN.Abp.IdentityServer.Clients
client.AddGrantType(grantType);
}
client = await ClientRepository.InsertAsync(client, true);
client = await ClientRepository.InsertAsync(client);
await CurrentUnitOfWork.SaveChangesAsync();
@ -50,7 +50,8 @@ namespace LINGYUN.Abp.IdentityServer.Clients
[Authorize(AbpIdentityServerPermissions.Clients.Delete)]
public virtual async Task DeleteAsync(Guid id)
{
await ClientRepository.DeleteAsync(id);
var client = await ClientRepository.GetAsync(id);
await ClientRepository.DeleteAsync(client);
await CurrentUnitOfWork.SaveChangesAsync();
}
@ -64,10 +65,9 @@ namespace LINGYUN.Abp.IdentityServer.Clients
public virtual async Task<PagedResultDto<ClientDto>> GetListAsync(ClientGetByPagedDto input)
{
// Abp官方IdentityServer项目不支持Filter过滤...
var clients = await ClientRepository.GetListAsync(input.Sorting,
input.SkipCount, input.MaxResultCount,
input.Filter, true);
input.Filter);
var clientCount = await ClientRepository.GetCountAsync();
@ -245,6 +245,8 @@ namespace LINGYUN.Abp.IdentityServer.Clients
#region Secrets
// 移除已经不存在的客户端密钥
client.ClientSecrets.RemoveAll(secret => !input.Secrets.Any(inputSecret => secret.Value == inputSecret.Value && secret.Type == inputSecret.Type));
var currentSecrets = new List<ClientSecretDto>();
foreach (var inputSecret in input.Secrets)
{
@ -271,23 +273,8 @@ namespace LINGYUN.Abp.IdentityServer.Clients
if (clientSecret == null)
{
client.AddSecret(inputSecretValue, inputSecret.Expiration, inputSecret.Type, inputSecret.Description);
currentSecrets.Add(new ClientSecretDto
{
Value = inputSecretValue,
Type = inputSecret.Type
});
}
else
{
currentSecrets.Add(new ClientSecretDto
{
Value = clientSecret.Value,
Type = clientSecret.Type
});
}
}
// 移除已经不存在的客户端密钥
client.ClientSecrets.RemoveAll(secret => !currentSecrets.Any(allowSecret => secret.Value == allowSecret.Value && secret.Type == allowSecret.Type));
#endregion
@ -305,6 +292,20 @@ namespace LINGYUN.Abp.IdentityServer.Clients
#endregion
#region Claims
// 移除已经不存在的客户端声明
client.ClientSecrets.RemoveAll(secret => !input.Claims.Any(inputClaim => secret.Value == inputClaim.Value && secret.Type == inputClaim.Type));
foreach (var inputClaim in input.Claims)
{
if (client.FindClaim(inputClaim.Value, inputClaim.Type) == null)
{
client.AddClaim(inputClaim.Value, inputClaim.Type);
}
}
#endregion
client = await ClientRepository.UpdateAsync(client);
await CurrentUnitOfWork.SaveChangesAsync();

BIN
aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db

Binary file not shown.

268
vueJs/src/api/clients.ts

@ -1,18 +1,17 @@
import ApiService from './serviceBase'
import { FullAuditedEntityDto, PagedAndSortedResultRequestDto, PagedResultDto } from './types'
import { FullAuditedEntityDto, PagedAndSortedResultRequestDto, PagedResultDto, SecretBase, Claim } from './types'
const sourceUrl = '/api/identity-server/clients'
const serviceUrl = process.env.VUE_APP_BASE_API
export default class ClientService {
public static getClientById(id: string) {
let _url = '/api/IdentityServer/Clients/'
_url += id
const _url = sourceUrl + '/' + id
return ApiService.Get<Client>(_url, serviceUrl)
}
public static getClients(payload: ClientGetByPaged) {
let _url = '/api/IdentityServer/Clients'
_url += '?filter=' + payload.filter
let _url = sourceUrl + '?filter=' + payload.filter
_url += '&sorting=' + payload.sorting
_url += '&skipCount=' + payload.skipCount
_url += '&maxResultCount=' + payload.maxResultCount
@ -20,144 +19,39 @@ export default class ClientService {
}
public static createClient(payload: ClientCreate) {
const _url = '/api/IdentityServer/Clients'
return ApiService.Post<Client>(_url, payload, serviceUrl)
return ApiService.Post<Client>(sourceUrl, payload, serviceUrl)
}
public static cloneClient(payload: ClientClone) {
const _url = '/api/IdentityServer/Clients/Clone'
public static cloneClient(id: string, payload: ClientClone) {
const _url = sourceUrl + '/' + id + '/clone'
return ApiService.Post<Client>(_url, payload, serviceUrl)
}
public static updateClient(payload: ClientUpdate) {
const _url = '/api/IdentityServer/Clients'
public static updateClient(id: string, payload: ClientUpdate) {
const _url = sourceUrl + '/' + id
return ApiService.Put<Client>(_url, payload, serviceUrl)
}
public static deleteClient(id: string) {
const _url = '/api/IdentityServer/Clients/' + id
return ApiService.Delete(_url, serviceUrl)
}
public static addClientSecret(payload: ClientSecretCreate) {
const _url = '/api/IdentityServer/Clients/Secrets'
return ApiService.Post<ClientSecret>(_url, payload, serviceUrl)
}
public static deleteClientSecret(clientId: string, type: string, value: string) {
let _url = '/api/IdentityServer/Clients/Secrets'
_url += '?clientId=' + clientId
_url += '&type=' + type
_url += '&value=' + value
return ApiService.Delete(_url, serviceUrl)
}
public static addClientProperty(payload: ClientPropertyCreate) {
const _url = '/api/IdentityServer/Clients/Properties'
return ApiService.Post<ClientProperty>(_url, payload, serviceUrl)
}
public static deleteClientProperty(clientId: string, key: string, value: string) {
let _url = '/api/IdentityServer/Clients/Properties'
_url += '?clientId=' + clientId
_url += '&key=' + key
_url += '&value=' + value
return ApiService.Delete(_url, serviceUrl)
}
public static addClientClaim(payload: ClientClaimCreate) {
const _url = '/api/IdentityServer/Clients/Claims'
return ApiService.Post<ClientClaim>(_url, payload, serviceUrl)
}
public static deleteClientClaim(clientId: string, type: string, value: string) {
let _url = '/api/IdentityServer/Clients/Claims'
_url += '?clientId=' + clientId
_url += '&type=' + type
_url += '&value=' + value
const _url = sourceUrl + '/' + id
return ApiService.Delete(_url, serviceUrl)
}
}
export class ClientGetByPaged extends PagedAndSortedResultRequestDto {
filter = ''
}
export enum HashType {
Sha256,
Sha512
Sha256 = 0,
Sha512 = 1
}
export class ClientSecret {
type = ''
value = ''
export class SecretCreateOrUpdate extends SecretBase {
hashType = HashType.Sha256
description? = ''
expiration? = undefined
}
export class ClientRedirectUri {
redirectUri = ''
}
export class ClientClaim {
type = ''
value = ''
}
export class ClientCorsOrigin {
origin = ''
}
export class ClientGrantType {
grantType = ''
}
export class ClientIdPRestriction {
provider = ''
}
export class ClientPostLogoutRedirectUri {
postLogoutRedirectUri = ''
}
export class ClientProperty {
key = ''
value = ''
}
export class ClientScope {
scope = ''
}
export class ClientSecretCreate extends ClientSecret {
clientId!: string
constructor() {
super()
this.type = 'SharedSecret'
this.hashType = HashType.Sha256
}
}
export class ClientClaimCreate extends ClientClaim {
clientId!: string
}
export class ClientPropertyCreate extends ClientProperty {
clientId!: string
export class ClientGetByPaged extends PagedAndSortedResultRequestDto {
filter = ''
}
export class ClientCreate {
clientId = ''
clientName = ''
description? = ''
allowedGrantTypes?: ClientGrantType[]
constructor() {
this.allowedGrantTypes = new Array<ClientGrantType>()
}
}
export class ClientClaim extends Claim {}
export class ClientClone {
sourceClientId = ''
@ -218,39 +112,27 @@ export class Client extends FullAuditedEntityDto {
userSsoLifetime!: number
userCodeType?: string
deviceCodeLifetime!: number
allowedScopes!: ClientScope[]
clientSecrets!: ClientSecret[]
allowedGrantTypes!: ClientGrantType[]
allowedCorsOrigins!: ClientCorsOrigin[]
redirectUris!: ClientRedirectUri[]
postLogoutRedirectUris!: ClientPostLogoutRedirectUri[]
identityProviderRestrictions!: ClientIdPRestriction[]
claims!: ClientClaim[]
properties!: ClientProperty[]
constructor() {
super()
this.allowedScopes = new Array<ClientScope>()
this.clientSecrets = new Array<ClientSecret>()
this.allowedGrantTypes = new Array<ClientGrantType>()
this.allowedCorsOrigins = new Array<ClientCorsOrigin>()
this.redirectUris = new Array<ClientRedirectUri>()
this.postLogoutRedirectUris = new Array<ClientPostLogoutRedirectUri>()
this.identityProviderRestrictions = new Array<ClientIdPRestriction>()
this.claims = new Array<ClientClaim>()
this.properties = new Array<ClientProperty>()
}
public static empty() {
return new Client()
}
}
export class ClientUpdateData {
concurrencyStamp!: string
allowedScopes = new Array<string>()
clientSecrets = new Array<string>()
allowedGrantTypes = new Array<string>()
allowedCorsOrigins = new Array<string>()
redirectUris = new Array<string>()
postLogoutRedirectUris = new Array<string>()
identityProviderRestrictions = new Array<string>()
claims = new Array<string>()
properties = new Array<string>()
}
export class ClientCreateOrUpdate {
clientId = ''
clientName = ''
description? = ''
allowedGrantTypes = new Array<string>()
}
export class ClientCreate extends ClientCreateOrUpdate {}
export class ClientUpdate extends ClientCreateOrUpdate {
clientUri? = ''
logoUri? = ''
enabled = true
@ -266,7 +148,7 @@ export class ClientUpdateData {
frontChannelLogoutSessionRequired = true
backChannelLogoutUri? = ''
backChannelLogoutSessionRequired = true
allowOfflineAccess = false
allowOfflineAccess = true
identityTokenLifetime = 300
accessTokenLifetime = 3600
authorizationCodeLifetime = 300
@ -285,75 +167,13 @@ export class ClientUpdateData {
userSsoLifetime!: number
userCodeType? = ''
deviceCodeLifetime = 300
allowedScopes!: ClientScope[]
allowedGrantTypes!: ClientGrantType[]
allowedCorsOrigins!: ClientCorsOrigin[]
redirectUris!: ClientRedirectUri[]
postLogoutRedirectUris!: ClientPostLogoutRedirectUri[]
identityProviderRestrictions!: ClientIdPRestriction[]
constructor() {
this.allowedScopes = new Array<ClientScope>()
this.allowedGrantTypes = new Array<ClientGrantType>()
this.allowedCorsOrigins = new Array<ClientCorsOrigin>()
this.redirectUris = new Array<ClientRedirectUri>()
this.postLogoutRedirectUris = new Array<ClientPostLogoutRedirectUri>()
this.identityProviderRestrictions = new Array<ClientIdPRestriction>()
}
public setClient(client: Client) {
this.absoluteRefreshTokenLifetime = client.absoluteRefreshTokenLifetime
this.accessTokenLifetime = client.accessTokenLifetime
this.accessTokenType = client.accessTokenType
this.allowAccessTokensViaBrowser = client.allowAccessTokensViaBrowser
this.allowOfflineAccess = client.allowOfflineAccess
this.allowPlainTextPkce = client.allowPlainTextPkce
this.allowRememberConsent = client.allowRememberConsent
this.allowedCorsOrigins = client.allowedCorsOrigins
this.allowedGrantTypes = client.allowedGrantTypes
this.allowedScopes = client.allowedScopes
this.alwaysIncludeUserClaimsInIdToken = client.alwaysIncludeUserClaimsInIdToken
this.alwaysSendClientClaims = client.alwaysSendClientClaims
this.authorizationCodeLifetime = client.authorizationCodeLifetime
this.backChannelLogoutSessionRequired = client.backChannelLogoutSessionRequired
this.backChannelLogoutUri = client.backChannelLogoutUri
this.clientClaimsPrefix = client.clientClaimsPrefix
this.clientId = client.clientId
this.clientName = client.clientName
this.clientUri = client.clientUri
this.concurrencyStamp = client.concurrencyStamp
this.consentLifetime = client.consentLifetime
this.description = client.description
this.deviceCodeLifetime = client.deviceCodeLifetime
this.enableLocalLogin = client.enableLocalLogin
this.enabled = client.enabled
this.frontChannelLogoutSessionRequired = client.frontChannelLogoutSessionRequired
this.frontChannelLogoutUri = client.frontChannelLogoutUri
this.identityProviderRestrictions = client.identityProviderRestrictions
this.identityTokenLifetime = client.identityTokenLifetime
this.includeJwtId = client.includeJwtId
this.logoUri = client.logoUri
this.pairWiseSubjectSalt = client.pairWiseSubjectSalt
this.postLogoutRedirectUris = client.postLogoutRedirectUris
this.protocolType = client.protocolType
this.redirectUris = client.redirectUris
this.refreshTokenExpiration = client.refreshTokenExpiration
this.refreshTokenUsage = client.refreshTokenUsage
this.requireClientSecret = client.requireClientSecret
this.requireConsent = client.requireConsent
this.requirePkce = client.requirePkce
this.slidingRefreshTokenLifetime = client.slidingRefreshTokenLifetime
this.updateAccessTokenClaimsOnRefresh = client.updateAccessTokenClaimsOnRefresh
this.userCodeType = client.userCodeType
this.userSsoLifetime = client.userSsoLifetime
}
}
export class ClientUpdate {
id!: string
client!: ClientUpdateData
constructor() {
this.client = new ClientUpdateData()
}
apiResources = new Array<string>()
identityResources = new Array<string>()
allowedCorsOrigins = new Array<string>()
redirectUris = new Array<string>()
postLogoutRedirectUris = new Array<string>()
identityProviderRestrictions = new Array<string>()
properties: {[key: string]: string} = {}
secrets = new Array<SecretCreateOrUpdate>()
claims = new Array<ClientClaim>()
}

166
vueJs/src/api/identity-resources.ts

@ -35,7 +35,7 @@ export default class IdentityResourceService {
* @param payload IdentityResourceCreate
* @returns IdentityResource
*/
public static createIdentityResource(payload: IdentityResourceCreate) {
public static createIdentityResource(payload: IdentityResourceCreateOrUpdate) {
return ApiService.Post<IdentityResource>(sourceUrl, payload, serviceUrl)
}
@ -44,7 +44,7 @@ export default class IdentityResourceService {
* @param payload IdentityResourceUpdate
* @returns IdentityResource
*/
public static updateIdentityResource(id: string, payload: IdentityResourceUpdate) {
public static updateIdentityResource(id: string, payload: IdentityResourceCreateOrUpdate) {
const _url = sourceUrl + '/' + id
return ApiService.Put<IdentityResource>(_url, payload, serviceUrl)
}
@ -59,161 +59,31 @@ export default class IdentityResourceService {
}
}
/** 身份资源用户声明 */
export class IdentityClaim {
/** 用户声明 */
type = ''
}
/** 身份资源属性 */
export class IdentityProperty {
/** 键 */
key = ''
/** 值 */
value = ''
}
/** 身份资源属性创建对象 */
export class IdentityPropertyCreate {
/** 身份资源标识 */
identityResourceId = ''
/** 键 */
key = ''
/** 值 */
value = ''
/** 并发令牌 */
concurrencyStamp = ''
/** 返回一个空对象 */
public static empty() {
return new IdentityPropertyCreate()
}
}
/** 身份资源分页查询对象 */
export class IdentityResourceGetByPaged extends PagedAndSortedResultRequestDto {
/** 过滤参数 */
filter = ''
/** 返回一个空对象 */
public static empty() {
return new IdentityResourceGetByPaged()
}
}
/** 身份资源创建对象 */
export class IdentityResourceCreate {
/** 名称 */
export class IdentityResource extends FullAuditedEntityDto {
id!: string
name = ''
/** 显示名称 */
displayName? = ''
/** 说明 */
description? = ''
/** 启用 */
displayName?: string = ''
description?: string = ''
enabled = true
/** 必须 */
required = false
/** 强调 */
emphasize = false
/** 在发现文档显示 */
showInDiscoveryDocument = false
/** 用户声明 */
userClaims = new Array<IdentityClaim>()
/** 返回一个空对象 */
public static empty() {
return new IdentityResourceCreate()
}
showInDiscoveryDocument = true
userClaims = new Array<string>()
properties: {[key: string]: string} = {}
}
/** 创建身份资源 */
public static create(identityResource: IdentityResource) {
const resource = new IdentityResourceCreate()
resource.description = identityResource.description
resource.displayName = identityResource.displayName
resource.emphasize = identityResource.emphasize
resource.enabled = identityResource.enabled
resource.name = identityResource.name
resource.required = identityResource.required
resource.showInDiscoveryDocument = identityResource.showInDiscoveryDocument
resource.userClaims = identityResource.userClaims
return resource
}
export class IdentityResourceGetByPaged extends PagedAndSortedResultRequestDto {
filter = ''
}
/** 身份资源变更对象 */
export class IdentityResourceUpdate {
/** 身份资源标识 */
id = ''
/** 名称 */
export class IdentityResourceCreateOrUpdate {
name = ''
/** 显示名称 */
displayName? = ''
/** 说明 */
description? = ''
/** 启用 */
displayName?: string = ''
description?: string = ''
enabled = true
/** 必须 */
required = false
/** 强调 */
emphasize = false
/** 在发现文档显示 */
showInDiscoveryDocument = false
/** 并发令牌 */
concurrencyStamp = ''
/** 用户声明 */
userClaims = new Array<IdentityClaim>()
/** 返回一个空对象 */
public static empty() {
return new IdentityResourceUpdate()
}
/** 创建身份资源 */
public static create(identityResource: IdentityResource) {
const resource = new IdentityResourceUpdate()
resource.concurrencyStamp = identityResource.concurrencyStamp
resource.description = identityResource.description
resource.displayName = identityResource.displayName
resource.emphasize = identityResource.emphasize
resource.enabled = identityResource.enabled
resource.id = identityResource.id
resource.name = identityResource.name
resource.required = identityResource.required
resource.showInDiscoveryDocument = identityResource.showInDiscoveryDocument
resource.userClaims = identityResource.userClaims
return resource
}
}
/** 身份资源对象 */
export class IdentityResource extends FullAuditedEntityDto {
/** 身份资源标识 */
id!: string
/** 名称 */
name!: string
/** 显示名称 */
displayName?: string
/** 说明 */
description?: string
/** 并发令牌 */
concurrencyStamp!: string
/** 启用 */
enabled!: boolean
/** 必须 */
required!: boolean
/** 强调 */
emphasize!: boolean
/** 在发现文档显示 */
showInDiscoveryDocument!: boolean
/** 用户声明 */
userClaims!: IdentityClaim[]
/** 属性 */
properties!: IdentityProperty[]
/** 返回一个空对象 */
public static empty() {
const resource = new IdentityResource()
resource.enabled = true
return resource
}
showInDiscoveryDocument = true
userClaims = new Array<string>()
properties: {[key: string]: string} = {}
}

12
vueJs/src/api/permission.ts

@ -36,11 +36,23 @@ export class UpdatePermissionsDto {
constructor() {
this.permissions = new Array<UpdatePermissionDto>()
}
public addPermission(name: string, isGranted: boolean) {
this.permissions.push(new UpdatePermissionDto(name, isGranted))
}
}
export class UpdatePermissionDto implements IPermission {
name!: string
isGranted!: boolean
constructor(
name: string,
isGranted: boolean
) {
this.name = name
this.isGranted = isGranted
}
}
export class PermissionProvider {

466
vueJs/src/components/PermissionForm/index.vue

@ -0,0 +1,466 @@
<template>
<el-dialog
v-el-draggable-dialog
width="800px"
:visible="showDialog"
:title="$t('AbpPermissionManagement.Permissions') + '-' + entityDisplayName"
custom-class="modal-form"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
@close="onFormClosed"
>
<el-form>
<el-checkbox
:disabled="readonly"
:value="grantAllCheckBoxCheckAll"
:indeterminate="grantAllCheckBoxForward"
@change="onGrantAllClicked"
>
{{ $t('AbpPermissionManagement.SelectAllInAllTabs') }}
</el-checkbox>
<el-divider />
<el-tabs
tab-position="left"
type="card"
>
<el-tab-pane
v-for="group in permissionGroups"
:key="group.name"
:label="group.displayName + ' (' + grantedCount(group) + ')'"
:name="group.name"
>
<el-card shadow="never">
<div
slot="header"
class="clearfix"
>
<h3>{{ group.displayName }}</h3>
</div>
<el-checkbox
:disabled="readonly"
:value="scopeCheckBoxCheckAll(group)"
:indeterminate="scopeCheckBoxForward(group)"
@change="(checked) => onCheckScopeAllClicked(checked, group, 'permissionTree-' + group.name)"
>
{{ $t('AbpPermissionManagement.SelectAllInThisTab') }}
</el-checkbox>
<el-divider />
<el-tree
:ref="'permissionTree-' + group.name"
show-checkbox
:check-strictly="true"
node-key="id"
:data="group.permissions"
:default-checked-keys="grantedPermissionKeys(group)"
@check-change="(permission, checked) => onPermissionTreeNodeCheckChanged(permission, checked, group, 'permissionTree-' + group.name)"
/>
</el-card>
</el-tab-pane>
</el-tabs>
<el-divider />
<el-form-item>
<el-button
class="cancel"
type="info"
style="width:100px"
@click="onFormClosed"
>
{{ $t('AbpPermissionManagement.Cancel') }}
</el-button>
<el-button
:disabled="readonly"
class="confirm"
type="primary"
style="width:100px"
icon="el-icon-check"
:loading="confirmButtonBusy"
@click="onSave"
>
{{ confirmButtonTitle }}
</el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
import PermissionApiService, { Permission, UpdatePermissionsDto } from '@/api/permission'
import { Tree } from 'element-ui'
/** element权限树 */
export class PermissionItem {
/** 权限标识 */
id = ''
/** 显示名称 */
label = ''
/** 是否授权 */
isGrant = false
/** 是否禁用 */
disabled = false
/** 子节点 */
children = new Array<PermissionItem>()
/** 父节点 */
parent?: PermissionItem
constructor(
id: string,
label: string,
isGrant: boolean
) {
this.id = id
this.label = label
this.isGrant = isGrant
}
public createChildren(permission: PermissionItem) {
permission.parent = this
this.children.push(permission)
}
public setGrant(grant: boolean) {
this.isGrant = grant
if (this.parent) {
this.parent.setGrant(grant)
}
}
public static setPermissionGrant(grant: boolean, permission: PermissionItem) {
permission.setGrant(grant)
if (!grant) {
permission.children.map(p => {
PermissionItem.setPermissionGrant(false, p)
})
}
}
public static setAllPermissionGrant(grant: boolean, permission: PermissionItem) {
permission.setGrant(grant)
permission.children.map(p => {
PermissionItem.setAllPermissionGrant(grant, p)
})
}
}
export class PermissionGroup {
name = ''
displayName = ''
permissions = new Array<PermissionItem>()
constructor(
name: string,
displayName: string
) {
this.name = name
this.displayName = displayName
}
public permissionCount() {
let count = 0
count += this.deepPermissionCount(this.permissions)
return count
}
public addPermission(permission: PermissionItem) {
this.permissions.push(permission)
}
public setAllGrant(grant: boolean) {
this.permissions.map(p => {
PermissionItem.setAllPermissionGrant(grant, p)
})
}
public grantedPermissionKeys() {
const keys = new Array<string>()
this.deepGrantedPermissionKeys(keys, this.permissions)
return keys
}
public grantedCount() {
let count = 0
count += this.deepGrantedCount(this.permissions)
return count
}
private deepGrantedCount(permissions: PermissionItem[]) {
let count = 0
count += permissions.filter(p => p.isGrant).length
permissions.forEach(p => {
count += this.deepGrantedCount(p.children)
})
return count
}
private deepGrantedPermissionKeys(keys: string[], permissions: PermissionItem[]) {
permissions.forEach(p => {
if (p.isGrant) {
keys.push(p.id)
}
this.deepGrantedPermissionKeys(keys, p.children)
})
}
private deepPermissionCount(permissions: PermissionItem[]) {
let count = 0
count += permissions.length
permissions.forEach(p => {
count += this.deepPermissionCount(p.children)
})
return count
}
}
/**
* 权限编辑组件
* 大量的计算属性与事件响应,还能再优化
*/
@Component({
name: 'PermissionForm'
})
export default class PermissionForm extends Vue {
/** 权限提供者名称 */
@Prop({ default: '' })
private providerName!: string
/** 权限提供者标识 */
@Prop({ default: '' })
private providerKey!: string
/** 是否展示权限编辑组件 */
@Prop({ default: false })
private showDialog!: boolean
/** 权限节点是否只读 */
@Prop({ default: false })
private readonly!: boolean
/** 确认按钮忙碌状态 */
private confirmButtonBusy = false
/** 当前编辑权限实体名称 */
private entityDisplayName = ''
/** 得到的权限组集合 */
private permissionGroups = new Array<PermissionGroup>()
/**
* 用于显示已授权数量
*/
get grantedCount() {
return (group: PermissionGroup) => {
return group.grantedCount()
}
}
/**
* 所有已授权数量
*/
get grantAllCount() {
let count = 0
this.permissionGroups.forEach(group => {
count += group.grantedCount()
})
return count
}
/**
* 用于勾选TreeNode
*/
get grantedPermissionKeys() {
return (group: PermissionGroup) => {
return group.grantedPermissionKeys()
}
}
/**
* 某个权限组权限数量
* 用于设定单个Tree的全选CheckBox状态
*/
get permissionCount() {
return (group: PermissionGroup) => {
return group.permissionCount()
}
}
/**
* 所有权限数量
*/
get permissionAllCount() {
let count = 0
this.permissionGroups.forEach(group => {
count += group.permissionCount()
})
return count
}
/**
* 单个Tree的全选CheckBox是否为选中状态
*/
get scopeCheckBoxCheckAll() {
return (group: PermissionGroup) => {
const grantCount = group.grantedCount()
return grantCount === group.permissionCount()
}
}
/**
* 单个Tree的全选CheckBox状态是否为预选状态
*/
get scopeCheckBoxForward() {
return (group: PermissionGroup) => {
const grantCount = group.grantedCount()
return grantCount > 0 && grantCount < group.permissionCount()
}
}
/**
* 授权所有CheckBox是否为选中状态
*/
get grantAllCheckBoxCheckAll() {
return this.grantAllCount === this.permissionAllCount
}
/**
* 授权所有CheckBox状态是否为预选状态
*/
get grantAllCheckBoxForward() {
const grantCount = this.grantAllCount
return grantCount > 0 && grantCount < this.permissionAllCount
}
/**
* 确认按钮标题
*/
get confirmButtonTitle() {
if (this.confirmButtonBusy) {
return this.$t('AbpPermissionManagement.SavingWithThreeDot')
}
return this.$t('AbpPermissionManagement.Save')
}
/**
* 响应组件可视事件
*/
@Watch('showDialog', { immediate: true })
private onShowDialogChanged() {
this.handleGetPermissions()
}
/**
* 获取权限集合
*/
private handleGetPermissions() {
this.permissionGroups.length = 0
if (this.showDialog && this.providerName) {
PermissionApiService.getPermissionsByKey(this.providerName, this.providerKey).then(res => {
this.entityDisplayName = res.entityDisplayName
res.groups.map(g => {
const group = new PermissionGroup(g.name, g.displayName)
const parents = g.permissions.filter(p => p.parentName === null)
parents.forEach(parent => {
const permission = new PermissionItem(parent.name, parent.displayName, parent.isGranted)
permission.disabled = this.readonly
const subPermissions = g.permissions.filter(p => p.parentName?.startsWith(parent.name))
this.generatePermission(permission, subPermissions)
group.addPermission(permission)
})
this.permissionGroups.push(group)
})
})
}
}
/**
* @param permissionTree 二级权限树
* @param permissions 权限列表
*/
private generatePermission(permission: PermissionItem, permissions: Permission[]) {
const subPermissions = permissions.filter(p => p.parentName !== permission.id)
permissions = permissions.filter(p => p.parentName === permission.id)
permissions.forEach(p => {
const children = new PermissionItem(p.name, p.displayName, p.isGranted)
children.disabled = this.readonly
const itemSubPermissions = subPermissions.filter(sp => sp.parentName === p.name)
if (itemSubPermissions.length > 0) {
this.generatePermission(children, itemSubPermissions)
}
permission.createChildren(children)
})
}
/**
* 保存权限
*/
private onSave() {
const updatePermission = new UpdatePermissionsDto()
this.permissionGroups.forEach(group => {
this.updatePermissionByInput(updatePermission, group.permissions)
})
this.confirmButtonBusy = true
PermissionApiService
.setPermissionsByKey(this.providerName, this.providerKey, updatePermission)
.then(() => {
this.$message.success(this.$t('global.successful').toString())
})
.finally(() => {
this.confirmButtonBusy = false
})
}
private updatePermissionByInput(permissions: UpdatePermissionsDto, items: PermissionItem[]) {
items.forEach(p => {
permissions.addPermission(p.id, p.isGrant)
this.updatePermissionByInput(permissions, p.children)
})
}
/**
* 窗口关闭事件
*/
private onFormClosed() {
this.$emit('closed')
}
/**
* 授予所有权限 按钮事件
*/
private onGrantAllClicked(checked: boolean) {
this.permissionGroups.forEach(group => {
group.setAllGrant(checked)
const trees = this.$refs['permissionTree-' + group.name] as Tree[]
trees[0].setCheckedKeys(this.grantedPermissionKeys(group))
})
}
/**
* Permission Tree 全选按钮事件
*/
private onCheckScopeAllClicked(checked: boolean, group: PermissionGroup, treeRef: any) {
group.setAllGrant(checked)
const trees = this.$refs[treeRef] as Tree[]
trees[0].setCheckedKeys(this.grantedPermissionKeys(group))
}
/**
* Permission TreeNode 变更事件
*/
private onPermissionTreeNodeCheckChanged(permission: PermissionItem, checked: boolean, group: PermissionGroup, treeRef: any) {
PermissionItem.setPermissionGrant(checked, permission)
if (permission.children.length > 0) {
const trees = this.$refs[treeRef] as Tree[]
trees[0].setCheckedKeys(this.grantedPermissionKeys(group))
}
}
}
</script>
<style lang="scss" scoped>
.confirm {
position: absolute;
right: 10px;
}
.cancel {
position: absolute;
right: 120px;
}
</style>

5
vueJs/src/views/admin/claim-type/components/CreateOrUpdateCliamTypeForm.vue

@ -153,11 +153,6 @@ export default class CreateOrUpdateCliamTypeForm extends Vue {
return false
}
@Watch('claimTypeId')
private onClaimTypeIdChanged() {
this.handleGetClaimType()
}
@Watch('showDialog', { immediate: true })
private onShowDialogChanged() {
this.handleGetClaimType()

5
vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceCreateOrEditForm.vue

@ -187,11 +187,6 @@ export default class extends Vue {
return false
}
@Watch('apiResourceId')
private onApiResourceIdChanged() {
this.handleGetApiResource()
}
@Watch('showDialog', { immediate: true })
private onShowDialogChanged() {
this.handleGetApiResource()

204
vueJs/src/views/admin/identityServer/client/index.vue

@ -25,7 +25,7 @@
:disabled="!checkPermission(['IdentityServer.Clients.Create'])"
@click="handleShowCreateClientForm()"
>
{{ $t('identityServer.createClient') }}
{{ $t('AbpIdentityServer.Client:New') }}
</el-button>
</div>
@ -40,7 +40,7 @@
@sort-change="handleSortChange"
>
<el-table-column
:label="$t('identityServer.clientId')"
:label="$t('AbpIdentityServer.Client:Id')"
prop="clientId"
sortable
width="150px"
@ -51,7 +51,7 @@
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.clientName')"
:label="$t('AbpIdentityServer.Name')"
prop="clientName"
sortable
width="200px"
@ -62,20 +62,43 @@
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.clientStatus')"
:label="$t('AbpIdentityServer.Description')"
prop="description"
sortable
width="200px"
align="center"
>
<template slot-scope="{row}">
<span>{{ row.description }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('AbpIdentityServer.Client:Enabled')"
prop="enabled"
sortable
width="140px"
align="center"
>
<template slot-scope="{row}">
<el-tag :type="row.enabled | statusFilter">
{{ formatStatusText(row.enabled) }}
</el-tag>
<el-switch
v-model="row.enabled"
disabled
/>
</template>
</el-table-column>
<el-table-column
:label="$t('AbpIdentityServer.Client:ProtocolType')"
prop="protocolType"
sortable
width="120px"
align="center"
>
<template slot-scope="{row}">
<span>{{ row.protocolType }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.identityTokenLifetime')"
:label="$t('AbpIdentityServer.Client:IdentityTokenLifetime')"
prop="identityTokenLifetime"
width="170px"
align="center"
@ -85,7 +108,7 @@
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.accessTokenLifetime')"
:label="$t('AbpIdentityServer.Client:AccessTokenLifetime')"
prop="accessTokenLifetime"
width="170px"
align="center"
@ -95,7 +118,7 @@
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.authorizationCodeLifetime')"
:label="$t('AbpIdentityServer.Client:AuthorizationCodeLifetime')"
prop="authorizationCodeLifetime"
width="170px"
align="center"
@ -105,7 +128,7 @@
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.deviceCodeLifetime')"
:label="$t('AbpIdentityServer.Client:DeviceCodeLifetime')"
prop="deviceCodeLifetime"
width="170px"
align="center"
@ -115,7 +138,7 @@
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.absoluteRefreshTokenLifetime')"
:label="$t('AbpIdentityServer.Client:AbsoluteRefreshTokenLifetime')"
prop="absoluteRefreshTokenLifetime"
width="180px"
align="center"
@ -125,7 +148,7 @@
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.slidingRefreshTokenLifetime')"
:label="$t('AbpIdentityServer.Client:SlidingRefreshTokenLifetime')"
prop="slidingRefreshTokenLifetime"
width="180px"
align="center"
@ -135,7 +158,7 @@
</template>
</el-table-column>
<el-table-column
:label="$t('identityServer.clientClaimsPrefix')"
:label="$t('AbpIdentityServer.Client:ClientClaimsPrefix')"
prop="clientClaimsPrefix"
width="120px"
align="center"
@ -157,7 +180,7 @@
type="primary"
@click="handleShowEditClientForm(row)"
>
{{ $t('identityServer.updateClient') }}
{{ $t('AbpIdentityServer.Client:Edit') }}
</el-button>
<el-dropdown
class="options"
@ -168,46 +191,27 @@
size="mini"
type="info"
>
{{ $t('identityServer.otherOpera') }}<i class="el-icon-arrow-down el-icon--right" />
{{ $t('global.operaActions') }}<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
:command="{key: 'clone', row}"
:disabled="!checkPermission(['IdentityServer.Clients.Clone'])"
>
{{ $t('identityServer.cloneClint') }}
</el-dropdown-item>
<el-dropdown-item
divided
:command="{key: 'claim', row}"
:disabled="!checkPermission(['IdentityServer.Clients.Claims'])"
>
{{ $t('identityServer.clientClaim') }}
</el-dropdown-item>
<el-dropdown-item
:command="{key: 'property', row}"
:disabled="!checkPermission(['IdentityServer.Clients.Properties'])"
>
{{ $t('identityServer.clientProperty') }}
</el-dropdown-item>
<el-dropdown-item
:command="{key: 'secret', row}"
:disabled="!checkPermission(['IdentityServer.Clients.Secrets'])"
:command="{key: 'permissions', row}"
:disabled="!checkPermission(['IdentityServer.Clients.ManagePermissions'])"
>
{{ $t('identityServer.clientSecret') }}
{{ $t('AbpIdentityServer.Permissions') }}
</el-dropdown-item>
<el-dropdown-item
:command="{key: 'permissions', row}"
:disabled="!checkPermission(['IdentityServer.Clients.ManagePermissions'])"
:command="{key: 'clone', row}"
:disabled="!checkPermission(['IdentityServer.Clients.Clone'])"
>
{{ $t('identityServer.clientPermission') }}
{{ $t('AbpIdentityServer.Client:Clone') }}
</el-dropdown-item>
<el-dropdown-item
divided
:command="{key: 'delete', row}"
:disabled="!checkPermission(['IdentityServer.Clients.Delete'])"
>
{{ $t('identityServer.deleteClient') }}
{{ $t('AbpIdentityServer.Client:Delete') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@ -215,7 +219,7 @@
</el-table-column>
</el-table>
<Pagination
<pagination
v-show="dataTotal>0"
:total="dataTotal"
:page.sync="currentPage"
@ -224,50 +228,11 @@
@sort-change="handleSortChange"
/>
<client-create-form
:show-dialog="showCreateClientDialog"
@closed="handleClientCreateFormClosed"
/>
<client-clone-form
:show-dialog="showCloneClientDialog"
:client-id="editClient.id"
@closed="handleClientCloneFormClosed"
/>
<client-edit-form
:show-dialog="showEditClientDialog"
:client-id="editClient.id"
@closed="handleClientEditFormClosed"
/>
<client-secret-edit-form
:show-dialog="showEditClientSecretDialog"
:client-id="editClient.id"
:client-secrets="editClient.clientSecrets"
@closed="handleClientSecretEditFormClosed"
@clientClaimChanged="refreshPagedData"
/>
<client-claim-edit-form
:show-dialog="showEditClientClaimDialog"
:client-id="editClient.id"
:client-claims="editClient.claims"
@closed="handleClientClaimEditFormClosed"
@clientClaimChanged="refreshPagedData"
/>
<client-property-edit-form
:show-dialog="showEditClientPropertyDialog"
:client-id="editClient.id"
:client-properties="editClient.properties"
@clientPropertyChanged="refreshPagedData"
@closed="handleClientPropertyEditFormClosed"
/>
<client-permission-edit-form
<permission-form
provider-name="C"
:provider-key="editClientId"
:show-dialog="showEditClientPermissionDialog"
:client-id="editClient.clientId"
:readonly="!checkPermission(['IdentityServer.Clients.ManagePermissions'])"
@closed="handleClientPermissionEditFormClosed"
/>
</div>
@ -279,26 +244,15 @@ import { checkPermission } from '@/utils/permission'
import DataListMiXin from '@/mixins/DataListMiXin'
import Component, { mixins } from 'vue-class-component'
import Pagination from '@/components/Pagination/index.vue'
import ClientEditForm from './components/ClientEditForm.vue'
import ClientCloneForm from './components/ClientCloneForm.vue'
import ClientCreateForm from './components/ClientCreateForm.vue'
import ClientSecretEditForm from './components/ClientSecretEditForm.vue'
import ClientClaimEditForm from './components/ClientClaimEditForm.vue'
import ClientPropertyEditForm from './components/ClientPropertyEditForm.vue'
import ClientPermissionEditForm from './components/ClientPermissionEditForm.vue'
import ClientService, { Client, ClientGetByPaged } from '@/api/clients'
import PermissionForm from '@/components/PermissionForm/index.vue'
@Component({
name: 'IdentityServerClient',
components: {
Pagination,
ClientEditForm,
ClientCloneForm,
ClientCreateForm,
ClientClaimEditForm,
ClientSecretEditForm,
ClientPropertyEditForm,
ClientPermissionEditForm
PermissionForm
},
methods: {
checkPermission,
@ -316,15 +270,12 @@ import ClientService, { Client, ClientGetByPaged } from '@/api/clients'
}
})
export default class extends mixins(DataListMiXin) {
private editClient = Client.empty()
private editClientId = ''
private editClientTitle = ''
private showEditClientDialog = false
private showCloneClientDialog = false
private showCreateClientDialog = false
private showEditClientSecretDialog = false
private showEditClientClaimDialog = false
private showEditClientPropertyDialog = false
private showEditClientPermissionDialog = false
public dataFilter = new ClientGetByPaged()
@ -342,14 +293,12 @@ export default class extends mixins(DataListMiXin) {
}
private handleShowCreateClientForm() {
this.editClient = Client.empty()
this.editClientTitle = this.l('identityServer.createClient')
this.editClientTitle = this.l('AbpIdentityServer.Client:New')
this.showCreateClientDialog = true
}
private handleShowEditClientForm(client: Client) {
this.editClient = client
this.editClientTitle = this.l('identityServer.updateClientByName', { name: this.editClient.clientName })
this.editClientId = client.clientId
this.showEditClientDialog = true
}
@ -374,29 +323,17 @@ export default class extends mixins(DataListMiXin) {
}
}
private handleClientSecretEditFormClosed() {
this.showEditClientSecretDialog = false
}
private handleClientClaimEditFormClosed() {
this.showEditClientClaimDialog = false
}
private handleClientPropertyEditFormClosed() {
this.showEditClientPropertyDialog = false
}
private handleClientPermissionEditFormClosed() {
this.showEditClientPermissionDialog = false
}
private handleDeleteClient(id: string, clientId: string) {
this.$confirm(this.l('identityServer.deleteClientById', { id: clientId }),
this.l('identityServer.deleteClient'), {
this.$confirm(this.l('AbpIdentityServer.Client:WillDelete', { 0: clientId }),
this.l('AbpUi.AreYouSure'), {
callback: (action) => {
if (action === 'confirm') {
ClientService.deleteClient(id).then(() => {
this.$message.success(this.l('identityServer.deleteClientSuccess', { id: clientId }))
this.$message.success(this.l('global.successful'))
this.refreshPagedData()
})
}
@ -405,20 +342,11 @@ export default class extends mixins(DataListMiXin) {
}
private handleCommand(command: {key: string, row: Client}) {
this.editClient = command.row
this.editClientId = command.row.clientId
switch (command.key) {
case 'clone' :
this.showCloneClientDialog = true
break
case 'secret' :
this.showEditClientSecretDialog = true
break
case 'claim' :
this.showEditClientClaimDialog = true
break
case 'property':
this.showEditClientPropertyDialog = true
break
case 'permissions':
this.showEditClientPermissionDialog = true
break
@ -428,16 +356,6 @@ export default class extends mixins(DataListMiXin) {
default: break
}
}
private formatStatusText(status: boolean) {
let statusText = ''
if (status) {
statusText = this.l('enabled')
} else {
statusText = this.l('disbled')
}
return statusText
}
}
</script>

238
vueJs/src/views/admin/identityServer/identity-resources/components/IdentityResourceCreateOrEditForm.vue

@ -13,92 +13,99 @@
<div class="app-container">
<el-form
ref="formIdentityResource"
label-width="120px"
label-width="130px"
:model="identityResource"
:rules="identityResourceRules"
>
<el-form-item
prop="enabled"
:label="$t('identityServer.enabledResource')"
<el-tabs
v-model="activeTable"
type="border-card"
>
<el-switch
v-model="identityResource.enabled"
/>
</el-form-item>
<el-form-item
prop="name"
:label="$t('identityServer.resourceName')"
>
<el-input
v-model="identityResource.name"
:disabled="isEdit"
:placeholder="$t('pleaseInputBy', {key: $t('identityServer.resourceName')})"
/>
</el-form-item>
<el-form-item
prop="displayName"
:label="$t('identityServer.resourceDisplayName')"
>
<el-input
v-model="identityResource.displayName"
/>
</el-form-item>
<el-form-item
prop="description"
:label="$t('identityServer.resourceDescription')"
>
<el-input
v-model="identityResource.description"
/>
</el-form-item>
<el-form-item
prop="required"
:label="$t('identityServer.identityResourceRequired')"
>
<el-switch
v-model="identityResource.required"
/>
</el-form-item>
<el-form-item
prop="emphasize"
:label="$t('identityServer.identityResourceEmphasize')"
>
<el-switch
v-model="identityResource.emphasize"
/>
</el-form-item>
<el-form-item
prop="showInDiscoveryDocument"
:label="$t('identityServer.identityResourceShowInDiscoveryDocument')"
>
<el-switch
v-model="identityResource.showInDiscoveryDocument"
/>
</el-form-item>
<el-form-item
prop="userClaims"
:label="$t('identityServer.resourceUserClaims')"
>
<el-select
v-model="identityResource.userClaims"
multiple
style="width: 100%;"
value-key="type"
<el-tab-pane
name="information"
:label="$t('AbpIdentityServer.Information')"
>
<el-form-item
prop="enabled"
:label="$t('AbpIdentityServer.Resource:Enabled')"
>
<el-switch
v-model="identityResource.enabled"
/>
</el-form-item>
<el-form-item
prop="name"
:label="$t('AbpIdentityServer.Name')"
>
<el-input
v-model="identityResource.name"
:disabled="isEdit"
:placeholder="$t('pleaseInputBy', {key: $t('AbpIdentityServer.Name')})"
/>
</el-form-item>
<el-form-item
prop="displayName"
:label="$t('AbpIdentityServer.DisplayName')"
>
<el-input
v-model="identityResource.displayName"
/>
</el-form-item>
<el-form-item
prop="description"
:label="$t('AbpIdentityServer.Description')"
>
<el-input
v-model="identityResource.description"
/>
</el-form-item>
<el-form-item
prop="required"
:label="$t('AbpIdentityServer.Required')"
>
<el-switch
v-model="identityResource.required"
/>
</el-form-item>
<el-form-item
prop="emphasize"
:label="$t('AbpIdentityServer.Emphasize')"
>
<el-switch
v-model="identityResource.emphasize"
/>
</el-form-item>
<el-form-item
prop="showInDiscoveryDocument"
:label="$t('AbpIdentityServer.ShowInDiscoveryDocument')"
>
<el-switch
v-model="identityResource.showInDiscoveryDocument"
/>
</el-form-item>
</el-tab-pane>
<el-tab-pane
name="claims"
:label="$t('AbpIdentityServer.UserClaim')"
>
<el-option
v-for="claim in identityClaims"
:key="claim.type"
:label="claim.type"
:value="claim"
<el-transfer
v-model="identityResource.userClaims"
class="transfer-scope"
:data="identityClaims"
:props="{
key: 'type',
label: 'value'
}"
:titles="[$t('AbpIdentityServer.NoClaim'), $t('AbpIdentityServer.ExistsClaim')]"
/>
</el-select>
</el-form-item>
</el-tab-pane>
</el-tabs>
<el-form-item>
<el-button
class="cancel"
style="width:100px"
@click="onCancel"
@click="onFormClosed(false)"
>
{{ $t('global.cancel') }}
</el-button>
@ -106,7 +113,7 @@
class="confirm"
type="primary"
style="width:100px"
@click="onSaveIdentityResource"
@click="onSave"
>
{{ $t('global.confirm') }}
</el-button>
@ -117,10 +124,12 @@
</template>
<script lang="ts">
import IdentityResourceService, { IdentityResourceCreate, IdentityResourceUpdate, IdentityResource, IdentityClaim } from '@/api/identityresources'
import ClaimTypeApiService from '@/api/cliam-type'
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import { Form } from 'element-ui'
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import { Claim } from '@/api/types'
import ClaimTypeApiService from '@/api/cliam-type'
import IdentityResourceService, { IdentityResource, IdentityResourceCreateOrUpdate } from '@/api/identity-resources'
@Component({
name: 'IdentityResourceCreateOrEditForm'
@ -135,8 +144,9 @@ export default class extends Vue {
@Prop({ default: '' })
private identityResourceId!: string
private identityClaims = new Array<IdentityClaim>()
private identityResource: IdentityResource
private activeTable = 'information'
private identityClaims = new Array<Claim>()
private identityResource = new IdentityResource()
private identityResourceRules = {
name: [
{ required: true, message: this.l('pleaseInputBy', { key: this.l('identityServer.resourceName') }), trigger: 'blur' }
@ -150,20 +160,9 @@ export default class extends Vue {
return false
}
constructor() {
super()
this.identityResource = IdentityResource.empty()
}
@Watch('identityResourceId', { immediate: true })
private onIdentityResourceIdChanged() {
if (this.identityResourceId) {
IdentityResourceService.getIdentityResourceById(this.identityResourceId).then(resource => {
this.identityResource = resource
})
} else {
this.identityResource = IdentityResource.empty()
}
@Watch('showDialog', { immediate: true })
private onShowDialogChanged() {
this.handleGetIdentityResource()
}
mounted() {
@ -173,30 +172,40 @@ export default class extends Vue {
private handleGetClaimTypes() {
ClaimTypeApiService.getActivedClaimTypes().then(res => {
res.items.map(claim => {
const identityClaim = new IdentityClaim()
identityClaim.type = claim.name
const identityClaim = new Claim(claim.name, claim.name)
this.identityClaims.push(identityClaim)
})
})
}
private onSaveIdentityResource() {
private handleGetIdentityResource() {
this.activeTable = 'information'
if (this.showDialog && this.identityResourceId) {
IdentityResourceService.getIdentityResourceById(this.identityResourceId).then(resource => {
this.identityResource = resource
})
} else {
this.identityResource = new IdentityResource()
}
}
private onSave() {
const frmIdentityResource = this.$refs.formIdentityResource as any
frmIdentityResource.validate((valid: boolean) => {
if (valid) {
const editIdentityResource = new IdentityResourceCreateOrUpdate()
this.updateIdentityResourceByInput(editIdentityResource)
if (this.isEdit) {
const updateIdentityResource = IdentityResourceUpdate.create(this.identityResource)
IdentityResourceService.updateIdentityResource(updateIdentityResource).then(resource => {
IdentityResourceService.updateIdentityResource(this.identityResourceId, editIdentityResource).then(resource => {
this.identityResource = resource
const successMessage = this.l('identityServer.updateIdentityResourceSuccess', { name: resource.name })
const successMessage = this.l('global.successful')
this.$message.success(successMessage)
this.onFormClosed(true)
})
} else {
const createIdentityResource = IdentityResourceCreate.create(this.identityResource)
IdentityResourceService.createIdentityResource(createIdentityResource).then(resource => {
IdentityResourceService.createIdentityResource(editIdentityResource).then(resource => {
this.identityResource = resource
const successMessage = this.l('identityServer.createIdentityResourceSuccess', { name: resource.name })
const successMessage = this.l('global.successful')
this.$message.success(successMessage)
this.onFormClosed(true)
})
@ -205,15 +214,23 @@ export default class extends Vue {
})
}
private updateIdentityResourceByInput(identityResource: IdentityResourceCreateOrUpdate) {
identityResource.name = this.identityResource.name
identityResource.displayName = this.identityResource.displayName
identityResource.description = this.identityResource.description
identityResource.enabled = this.identityResource.enabled
identityResource.required = this.identityResource.required
identityResource.emphasize = this.identityResource.emphasize
identityResource.showInDiscoveryDocument = this.identityResource.showInDiscoveryDocument
identityResource.userClaims = this.identityResource.userClaims
identityResource.properties = this.identityResource.properties
}
private onFormClosed(changed: boolean) {
this.resetFields()
this.$emit('closed', changed)
}
private onCancel() {
this.onFormClosed(false)
}
private resetFields() {
const frmIdentityResource = this.$refs.formIdentityResource as Form
frmIdentityResource.resetFields()
@ -229,9 +246,14 @@ export default class extends Vue {
.confirm {
position: absolute;
right: 10px;
top: 20px;
}
.cancel {
position: absolute;
right: 120px;
top: 20px;
}
.transfer-scope ::v-deep .el-transfer-panel{
width: 250px;
}
</style>

120
vueJs/src/views/admin/identityServer/identity-resources/index.vue

@ -25,7 +25,7 @@
:disabled="!checkPermission(['IdentityServer.IdentityResources.Create'])"
@click="handleShowEditIdentityResourceForm"
>
{{ $t('identityServer.createIdentityResource') }}
{{ $t('AbpIdentityServer.Resource:New') }}
</el-button>
</div>
@ -40,7 +40,7 @@
@sort-change="handleSortChange"
>
<el-table-column
:label="$t('global.name')"
:label="$t('AbpIdentityServer.Name')"
prop="name"
sortable
width="150px"
@ -51,7 +51,7 @@
</template>
</el-table-column>
<el-table-column
:label="$t('global.displayName')"
:label="$t('AbpIdentityServer.DisplayName')"
prop="displayName"
sortable
width="200px"
@ -62,20 +62,21 @@
</template>
</el-table-column>
<el-table-column
:label="$t('global.status')"
:label="$t('AbpIdentityServer.Resource:Enabled')"
prop="enabled"
sortable
width="140px"
align="center"
>
<template slot-scope="{row}">
<el-tag :type="row.enabled | statusFilter">
{{ formatStatusText(row.enabled) }}
</el-tag>
<el-switch
v-model="row.enabled"
disabled
/>
</template>
</el-table-column>
<el-table-column
:label="$t('global.description')"
:label="$t('AbpIdentityServer.Description')"
prop="description"
sortable
width="200px"
@ -125,35 +126,16 @@
type="primary"
@click="handleShowEditIdentityResourceForm(row)"
>
{{ $t('identityServer.updateIdentityResource') }}
{{ $t('AbpIdentityServer.Resource:Edit') }}
</el-button>
<el-dropdown
class="options"
@command="handleCommand"
<el-button
:disabled="!checkPermission(['IdentityServer.IdentityResources.Delete'])"
size="mini"
type="danger"
@click="handleDeleteIdentityResource(row)"
>
<el-button
v-permission="['IdentityServer.IdentityResources']"
size="mini"
type="info"
>
{{ $t('global.otherOpera') }}<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
:command="{key: 'property', row}"
:disabled="!checkPermission(['IdentityServer.IdentityResources.Properties'])"
>
{{ $t('identityServer.identityResourceProperties') }}
</el-dropdown-item>
<el-dropdown-item
divided
:command="{key: 'delete', row}"
:disabled="!checkPermission(['IdentityServer.IdentityResources.Delete'])"
>
{{ $t('identityServer.deleteIdentityResource') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
{{ $t('AbpIdentityServer.Resource:Delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
@ -166,6 +148,13 @@
@pagination="refreshPagedData"
@sort-change="handleSortChange"
/>
<identity-resource-create-or-edit-form
:identity-resource-id="editIdentityResourceId"
:title="editIdentityResourceTitle"
:show-dialog="showEditIdentityResourceDialog"
@closed="onIdentityResourceEditFormClosed"
/>
</div>
</template>
@ -177,10 +166,13 @@ import Component, { mixins } from 'vue-class-component'
import Pagination from '@/components/Pagination/index.vue'
import IdentityResourceService, { IdentityResource, IdentityResourceGetByPaged } from '@/api/identity-resources'
import IdentityResourceCreateOrEditForm from './components/IdentityResourceCreateOrEditForm.vue'
@Component({
name: 'IdentityServerIdentityResource',
components: {
Pagination
Pagination,
IdentityResourceCreateOrEditForm
},
methods: {
checkPermission
@ -199,10 +191,9 @@ import IdentityResourceService, { IdentityResource, IdentityResourceGetByPaged }
}
})
export default class extends mixins(DataListMiXin) {
private editIdentityResource = IdentityResource.empty()
private editIdentityResourceId = ''
private editIdentityResourceTitle = ''
private showEditIdentityPropertyDialog = false
private showEditIdentityResourceDialog = false
public dataFilter = new IdentityResourceGetByPaged()
@ -220,31 +211,22 @@ export default class extends mixins(DataListMiXin) {
}
private handleShowEditIdentityResourceForm(resource: IdentityResource) {
this.editIdentityResource = IdentityResource.empty()
if (resource) {
this.editIdentityResource = resource
this.editIdentityResourceTitle = this.l('identityServer.updateIdentityResourceByName', { name: this.editIdentityResource.name })
this.editIdentityResourceId = resource.id
this.editIdentityResourceTitle = this.l('AbpIdentityServer.Resource:Name', { 0: resource.name })
} else {
this.editIdentityResourceTitle = this.l('identityServer.createIdentityResource')
this.editIdentityResourceTitle = this.l('AbpIdentityServer.Resource:New')
}
this.showEditIdentityResourceDialog = true
}
private handleIdentityResourceEditFormClosed(changed: boolean) {
this.reset(changed)
}
private handleIdentityPropertyEditFormClosed(changed: boolean) {
this.reset(changed)
}
private handleDeleteIdentityResource(id: string, name: string) {
this.$confirm(this.l('identityServer.deleteIdentityResourceByName', { name: name }),
this.l('identityServer.deleteIdentityResource'), {
private handleDeleteIdentityResource(resource: IdentityResource) {
this.$confirm(this.l('AbpIdentityServer.Resource:WillDelete', { 0: resource.name }),
this.l('AbpUi.AreYouSure'), {
callback: (action) => {
if (action === 'confirm') {
IdentityResourceService.deleteIdentityResource(id).then(() => {
this.$message.success(this.l('identityServer.deleteIdentityResourceSuccess', { name: name }))
IdentityResourceService.deleteIdentityResource(resource.id).then(() => {
this.$message.success(this.l('global.successful'))
this.refreshPagedData()
})
}
@ -252,34 +234,8 @@ export default class extends mixins(DataListMiXin) {
})
}
private handleCommand(command: {key: string, row: IdentityResource}) {
switch (command.key) {
case 'property' :
this.editIdentityResource = command.row
this.showEditIdentityPropertyDialog = true
break
case 'delete' :
this.handleDeleteIdentityResource(command.row.id, command.row.name)
break
default: break
}
}
private formatStatusText(status: boolean) {
let statusText = ''
if (status) {
statusText = this.l('enabled')
} else {
statusText = this.l('disbled')
}
return statusText
}
private reset(changed: boolean) {
this.editIdentityResourceTitle = ''
this.editIdentityResource = IdentityResource.empty()
private onIdentityResourceEditFormClosed(changed: boolean) {
this.showEditIdentityResourceDialog = false
this.showEditIdentityPropertyDialog = false
if (changed) {
this.refreshPagedData()
}

5
vueJs/src/views/admin/roles/components/RoleClaimCreateOrUpdateForm.vue

@ -197,11 +197,6 @@ export default class UserClaimCreateOrUpdateForm extends Vue {
}
}
@Watch('roleId')
private onUserIdChanged() {
this.handleGetRoleClaims()
}
@Watch('showDialog', { immediate: true })
private onShowDialogChanged() {
this.handleGetRoleClaims()

5
vueJs/src/views/admin/roles/components/RoleEditForm.vue

@ -125,11 +125,6 @@ export default class extends Vue {
]
}
@Watch('roleId')
private onRoleIdChanged() {
this.handleGetRole()
}
@Watch('showDialog', { immediate: true })
private onShowDialogChanged() {
this.handleGetRole()

5
vueJs/src/views/admin/users/components/UserClaimCreateOrUpdateForm.vue

@ -197,11 +197,6 @@ export default class UserClaimCreateOrUpdateForm extends Vue {
}
}
@Watch('userId')
private onUserIdChanged() {
this.handleGetUserClaims()
}
@Watch('showDialog', { immediate: true })
private onShowDialogChanged() {
this.handleGetUserClaims()

Loading…
Cancel
Save