49 changed files with 2268 additions and 93 deletions
@ -0,0 +1,7 @@ |
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiResourceClaimDto |
|||
{ |
|||
public string Type { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.ApiResources; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiResourceCreateDto |
|||
{ |
|||
[Required] |
|||
[StringLength(ApiResourceConsts.NameMaxLength)] |
|||
public string Name { get; set; } |
|||
|
|||
[StringLength(ApiResourceConsts.DisplayNameMaxLength)] |
|||
public string DisplayName { get; set; } |
|||
|
|||
[StringLength(ApiResourceConsts.DescriptionMaxLength)] |
|||
public string Description { get; set; } |
|||
|
|||
public bool Enabled { get; set; } |
|||
|
|||
public List<ApiResourceClaimDto> UserClaims { get; set; } |
|||
public ApiResourceCreateDto() |
|||
{ |
|||
Enabled = true; |
|||
UserClaims = new List<ApiResourceClaimDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiResourceDto : FullAuditedEntityDto<Guid> |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public bool Enabled { get; set; } |
|||
|
|||
public List<ApiSecretDto> Secrets { get; set; } |
|||
|
|||
public List<ApiScopeDto> Scopes { get; set; } |
|||
|
|||
public List<ApiResourceClaimDto> UserClaims { get; set; } |
|||
|
|||
public ApiResourceDto() |
|||
{ |
|||
Scopes = new List<ApiScopeDto>(); |
|||
Secrets = new List<ApiSecretDto>(); |
|||
UserClaims = new List<ApiResourceClaimDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiResourceGetByIdInputDto : EntityDto<Guid> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiResourceGetByPagedInputDto : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Text; |
|||
using Volo.Abp.IdentityServer.ApiResources; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiResourceUpdateDto |
|||
{ |
|||
[Required] |
|||
public Guid Id { get; set; } |
|||
|
|||
[StringLength(ApiResourceConsts.DisplayNameMaxLength)] |
|||
public string DisplayName { get; set; } |
|||
|
|||
[StringLength(ApiResourceConsts.DescriptionMaxLength)] |
|||
public string Description { get; set; } |
|||
|
|||
public bool Enabled { get; set; } |
|||
|
|||
public List<ApiResourceClaimDto> UserClaims { get; set; } |
|||
|
|||
public ApiResourceUpdateDto() |
|||
{ |
|||
UserClaims = new List<ApiResourceClaimDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiScopeClaimDto |
|||
{ |
|||
public string Type { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.ApiResources; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiScopeCreateDto |
|||
{ |
|||
[Required] |
|||
public Guid ApiResourceId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ApiScopeConsts.NameMaxLength)] |
|||
public string Name { get; set; } |
|||
|
|||
[StringLength(ApiScopeConsts.DisplayNameMaxLength)] |
|||
public string DisplayName { get; set; } |
|||
|
|||
[StringLength(ApiScopeConsts.DescriptionMaxLength)] |
|||
public string Description { get; set; } |
|||
|
|||
public bool Required { get; set; } |
|||
|
|||
public bool Emphasize { get; set; } |
|||
|
|||
public bool ShowInDiscoveryDocument { get; set; } |
|||
|
|||
public List<ApiScopeClaimDto> UserClaims { get; set; } |
|||
|
|||
public ApiScopeCreateDto() |
|||
{ |
|||
UserClaims = new List<ApiScopeClaimDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiScopeDto |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public bool Required { get; set; } |
|||
|
|||
public bool Emphasize { get; set; } |
|||
|
|||
public bool ShowInDiscoveryDocument { get; set; } |
|||
|
|||
public List<ApiScopeClaimDto> UserClaims { get; set; } |
|||
|
|||
public ApiScopeDto() |
|||
{ |
|||
UserClaims = new List<ApiScopeClaimDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.ApiResources; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiScopeGetByNameInputDto |
|||
{ |
|||
[Required] |
|||
public Guid ApiResourceId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ApiScopeConsts.NameMaxLength)] |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiSecretCreateDto |
|||
{ |
|||
[Required] |
|||
public Guid ApiResourceId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.TypeMaxLength)] |
|||
public string Type { get; set; } |
|||
|
|||
public HashType HashType { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.ValueMaxLength)] |
|||
public string Value { get; set; } |
|||
|
|||
[StringLength(SecretConsts.DescriptionMaxLength)] |
|||
public string Description { get; set; } |
|||
|
|||
public DateTime? Expiration { get; set; } |
|||
|
|||
public ApiSecretCreateDto() |
|||
{ |
|||
HashType = 0; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiSecretDto : SecretBaseDto |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public class ApiSecretGetByTypeInputDto |
|||
{ |
|||
[Required] |
|||
public Guid ApiResourceId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.TypeMaxLength)] |
|||
public string Type { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.ValueMaxLength)] |
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
public interface IApiResourceAppService : IApplicationService |
|||
{ |
|||
Task<ApiResourceDto> GetAsync(ApiResourceGetByIdInputDto apiResourceGetById); |
|||
|
|||
Task<PagedResultDto<ApiResourceDto>> GetAsync(ApiResourceGetByPagedInputDto apiResourceGetByPaged); |
|||
|
|||
Task<ApiResourceDto> CreateAsync(ApiResourceCreateDto apiResourceCreate); |
|||
|
|||
Task<ApiResourceDto> UpdateAsync(ApiResourceUpdateDto apiResourceUpdate); |
|||
|
|||
Task DeleteAsync(ApiResourceGetByIdInputDto apiResourceGetById); |
|||
|
|||
Task<ApiSecretDto> AddSecretAsync(ApiSecretCreateDto apiSecretCreate); |
|||
|
|||
Task DeleteSecretAsync(ApiSecretGetByTypeInputDto apiSecretGetByType); |
|||
|
|||
Task<ApiScopeDto> AddScopeAsync(ApiScopeCreateDto apiScopeCreate); |
|||
|
|||
Task DeleteScopeAsync(ApiScopeGetByNameInputDto apiScopeGetByName); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
public enum HashType |
|||
{ |
|||
Sha256, |
|||
Sha512 |
|||
} |
|||
} |
|||
@ -0,0 +1,132 @@ |
|||
using IdentityServer4; |
|||
using IdentityServer4.Models; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.IdentityServer.ApiResources; |
|||
using ApiResource = Volo.Abp.IdentityServer.ApiResources.ApiResource; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
[Authorize(AbpIdentityServerPermissions.ApiResources.Default)] |
|||
public class ApiResourceAppService : AbpIdentityServerAppServiceBase, IApiResourceAppService |
|||
{ |
|||
protected IApiResourceRepository ApiResourceRepository { get; } |
|||
|
|||
public ApiResourceAppService( |
|||
IApiResourceRepository apiResourceRepository) |
|||
{ |
|||
ApiResourceRepository = apiResourceRepository; |
|||
} |
|||
|
|||
public virtual async Task<ApiResourceDto> GetAsync(ApiResourceGetByIdInputDto apiResourceGetById) |
|||
{ |
|||
var apiResource = await ApiResourceRepository.GetAsync(apiResourceGetById.Id); |
|||
|
|||
return ObjectMapper.Map<ApiResource, ApiResourceDto>(apiResource); |
|||
} |
|||
|
|||
public virtual async Task<PagedResultDto<ApiResourceDto>> GetAsync(ApiResourceGetByPagedInputDto apiResourceGetByPaged) |
|||
{ |
|||
var apiResources = await ApiResourceRepository.GetListAsync(apiResourceGetByPaged.Sorting, |
|||
apiResourceGetByPaged.SkipCount, apiResourceGetByPaged.MaxResultCount); |
|||
var apiResourceCount = await ApiResourceRepository.GetCountAsync(); |
|||
|
|||
return new PagedResultDto<ApiResourceDto>(apiResourceCount, |
|||
ObjectMapper.Map<List<ApiResource>, List<ApiResourceDto>>(apiResources)); |
|||
} |
|||
|
|||
[Authorize(AbpIdentityServerPermissions.ApiResources.Create)] |
|||
public virtual async Task<ApiResourceDto> CreateAsync(ApiResourceCreateDto apiResourceCreate) |
|||
{ |
|||
var apiResource = new ApiResource(GuidGenerator.Create(), apiResourceCreate.Name, |
|||
apiResourceCreate.DisplayName, apiResourceCreate.Description); |
|||
apiResource.Enabled = apiResourceCreate.Enabled; |
|||
foreach(var userClaim in apiResourceCreate.UserClaims) |
|||
{ |
|||
apiResource.AddUserClaim(userClaim.Type); |
|||
} |
|||
apiResource = await ApiResourceRepository.InsertAsync(apiResource); |
|||
return ObjectMapper.Map<ApiResource, ApiResourceDto>(apiResource); |
|||
} |
|||
|
|||
[Authorize(AbpIdentityServerPermissions.ApiResources.Update)] |
|||
public virtual async Task<ApiResourceDto> UpdateAsync(ApiResourceUpdateDto apiResourceUpdate) |
|||
{ |
|||
var apiResource = await ApiResourceRepository.GetAsync(apiResourceUpdate.Id); |
|||
apiResource.DisplayName = apiResourceUpdate.DisplayName ?? apiResource.DisplayName; |
|||
apiResource.Description = apiResourceUpdate.Description ?? apiResource.Description; |
|||
apiResource.Enabled = apiResourceUpdate.Enabled; |
|||
|
|||
apiResource.RemoveAllUserClaims(); |
|||
foreach (var userClaim in apiResourceUpdate.UserClaims) |
|||
{ |
|||
apiResource.AddUserClaim(userClaim.Type); |
|||
} |
|||
apiResource = await ApiResourceRepository.UpdateAsync(apiResource); |
|||
return ObjectMapper.Map<ApiResource, ApiResourceDto>(apiResource); |
|||
} |
|||
|
|||
[Authorize(AbpIdentityServerPermissions.ApiResources.Delete)] |
|||
public virtual async Task DeleteAsync(ApiResourceGetByIdInputDto apiResourceGetById) |
|||
{ |
|||
var apiResource = await ApiResourceRepository.GetAsync(apiResourceGetById.Id); |
|||
await ApiResourceRepository.DeleteAsync(apiResource); |
|||
} |
|||
|
|||
[Authorize(AbpIdentityServerPermissions.ApiResources.Secrets.Create)] |
|||
public virtual async Task<ApiSecretDto> AddSecretAsync(ApiSecretCreateDto apiSecretCreate) |
|||
{ |
|||
var apiResource = await ApiResourceRepository.GetAsync(apiSecretCreate.ApiResourceId); |
|||
var apiSecretValue = apiSecretCreate.Value; |
|||
var apiResourceSecret = apiResource.FindSecret(apiSecretValue, apiSecretCreate.Type); |
|||
if(apiResourceSecret == null) |
|||
{ |
|||
if (IdentityServerConstants.SecretTypes.SharedSecret.Equals(apiSecretCreate.Type)) |
|||
{ |
|||
if (apiSecretCreate.HashType == HashType.Sha256) |
|||
{ |
|||
apiSecretValue = apiSecretCreate.Value.Sha256(); |
|||
} |
|||
else if (apiSecretCreate.HashType == HashType.Sha512) |
|||
{ |
|||
apiSecretValue = apiSecretCreate.Value.Sha512(); |
|||
} |
|||
} |
|||
apiResource.AddSecret(apiSecretValue, apiSecretCreate.Expiration, apiSecretCreate.Type, apiSecretCreate.Description); |
|||
apiResourceSecret = apiResource.FindSecret(apiSecretValue, apiSecretCreate.Type); |
|||
} |
|||
|
|||
return ObjectMapper.Map<ApiSecret, ApiSecretDto>(apiResourceSecret); |
|||
} |
|||
|
|||
[Authorize(AbpIdentityServerPermissions.ApiResources.Secrets.Delete)] |
|||
public virtual async Task DeleteSecretAsync(ApiSecretGetByTypeInputDto apiSecretGetByType) |
|||
{ |
|||
var apiResource = await ApiResourceRepository.GetAsync(apiSecretGetByType.ApiResourceId); |
|||
apiResource.RemoveSecret(apiSecretGetByType.Value, apiSecretGetByType.Type); |
|||
} |
|||
|
|||
[Authorize(AbpIdentityServerPermissions.ApiResources.Scope.Create)] |
|||
public virtual async Task<ApiScopeDto> AddScopeAsync(ApiScopeCreateDto apiScopeCreate) |
|||
{ |
|||
var apiResource = await ApiResourceRepository.GetAsync(apiScopeCreate.ApiResourceId); |
|||
var apiResourceScope = apiResource.FindScope(apiScopeCreate.Name); |
|||
if (apiResourceScope == null) |
|||
{ |
|||
apiResource.AddScope(apiScopeCreate.Name, apiScopeCreate.DisplayName, apiScopeCreate.Description, |
|||
apiScopeCreate.Required, apiScopeCreate.Emphasize, apiScopeCreate.ShowInDiscoveryDocument); |
|||
apiResourceScope = apiResource.FindScope(apiScopeCreate.Name); |
|||
} |
|||
return ObjectMapper.Map<ApiScope, ApiScopeDto>(apiResourceScope); |
|||
} |
|||
|
|||
[Authorize(AbpIdentityServerPermissions.ApiResources.Scope.Delete)] |
|||
public virtual async Task DeleteScopeAsync(ApiScopeGetByNameInputDto apiScopeGetByName) |
|||
{ |
|||
var apiResource = await ApiResourceRepository.GetAsync(apiScopeGetByName.ApiResourceId); |
|||
apiResource.RemoveScope(apiScopeGetByName.Name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.ApiResources |
|||
{ |
|||
[RemoteService(Name = AbpIdentityServerConsts.RemoteServiceName)] |
|||
[Area("IdentityServer")] |
|||
[Route("api/IdentityServer/ApiResources")] |
|||
public class ApiResourceController : AbpController, IApiResourceAppService |
|||
{ |
|||
protected IApiResourceAppService ApiResourceAppService { get; } |
|||
public ApiResourceController( |
|||
IApiResourceAppService apiResourceAppService) |
|||
{ |
|||
ApiResourceAppService = apiResourceAppService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{Id}")] |
|||
public virtual async Task<ApiResourceDto> GetAsync(ApiResourceGetByIdInputDto apiResourceGetById) |
|||
{ |
|||
return await ApiResourceAppService.GetAsync(apiResourceGetById); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public virtual async Task<PagedResultDto<ApiResourceDto>> GetAsync(ApiResourceGetByPagedInputDto apiResourceGetByPaged) |
|||
{ |
|||
return await ApiResourceAppService.GetAsync(apiResourceGetByPaged); |
|||
} |
|||
|
|||
[HttpPost] |
|||
public virtual async Task<ApiResourceDto> CreateAsync(ApiResourceCreateDto apiResourceCreate) |
|||
{ |
|||
return await ApiResourceAppService.CreateAsync(apiResourceCreate); |
|||
} |
|||
|
|||
[HttpPut] |
|||
public virtual async Task<ApiResourceDto> UpdateAsync(ApiResourceUpdateDto apiResourceUpdate) |
|||
{ |
|||
return await ApiResourceAppService.UpdateAsync(apiResourceUpdate); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{Id}")] |
|||
public virtual async Task DeleteAsync(ApiResourceGetByIdInputDto apiResourceGetById) |
|||
{ |
|||
await ApiResourceAppService.DeleteAsync(apiResourceGetById); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("Secrets")] |
|||
public virtual async Task<ApiSecretDto> AddSecretAsync(ApiSecretCreateDto apiSecretCreate) |
|||
{ |
|||
return await ApiResourceAppService.AddSecretAsync(apiSecretCreate); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("Secrets")] |
|||
public virtual async Task DeleteSecretAsync(ApiSecretGetByTypeInputDto apiSecretGetByType) |
|||
{ |
|||
await ApiResourceAppService.DeleteSecretAsync(apiSecretGetByType); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("Scopes")] |
|||
public virtual async Task<ApiScopeDto> AddScopeAsync(ApiScopeCreateDto apiScopeCreate) |
|||
{ |
|||
return await ApiResourceAppService.AddScopeAsync(apiScopeCreate); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("Scopes")] |
|||
public virtual async Task DeleteScopeAsync(ApiScopeGetByNameInputDto apiScopeGetByName) |
|||
{ |
|||
await ApiResourceAppService.DeleteScopeAsync(apiScopeGetByName); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,280 @@ |
|||
import ApiService from './serviceBase' |
|||
import { pagerFormat } from '@/utils/index' |
|||
import { FullAuditedEntityDto, PagedAndSortedResultRequestDto, PagedResultDto } from './types' |
|||
|
|||
const serviceUrl = process.env.VUE_APP_BASE_API |
|||
|
|||
export default class ApiResourceService { |
|||
/** |
|||
* 获取Api资源 |
|||
* @param id Api资源标识 |
|||
*/ |
|||
public static getApiResourceById(id: string) { |
|||
let _url = '/api/IdentityServer/ApiResources/' |
|||
_url += id |
|||
return ApiService.Get<ApiResource>(_url, serviceUrl) |
|||
} |
|||
|
|||
/** |
|||
* 获取Api资源列表 |
|||
* @param payload 查询参数 |
|||
*/ |
|||
public static getApiResources(payload: ApiResourceGetByPaged) { |
|||
let _url = '/api/IdentityServer/ApiResources' |
|||
_url += '?filter=' + payload.filter |
|||
_url += '&sorting=' + payload.sorting |
|||
_url += '&skipCount=' + pagerFormat(payload.skipCount) |
|||
_url += '&maxResultCount=' + payload.maxResultCount |
|||
return ApiService.Get<PagedResultDto<ApiResource>>(_url, serviceUrl) |
|||
} |
|||
|
|||
/** |
|||
* 创建Api资源 |
|||
* @param payload api资源参数 |
|||
*/ |
|||
public static createApiResource(payload: ApiResourceCreate) { |
|||
const _url = '/api/IdentityServer/ApiResources' |
|||
return ApiService.Post<ApiResource>(_url, payload, serviceUrl) |
|||
} |
|||
|
|||
/** |
|||
* 变更Api资源 |
|||
* @param payload api资源参数 |
|||
*/ |
|||
public static updateApiResource(payload: ApiResourceUpdate) { |
|||
const _url = '/api/IdentityServer/ApiResources' |
|||
return ApiService.Put<ApiResource>(_url, payload, serviceUrl) |
|||
} |
|||
|
|||
/** |
|||
* 删除Api资源 |
|||
* @param id Api资源标识 |
|||
*/ |
|||
public static deleteApiResource(id: string) { |
|||
let _url = '/api/IdentityServer/ApiResources/' |
|||
_url += id |
|||
return ApiService.Delete(_url, serviceUrl) |
|||
} |
|||
|
|||
/** |
|||
* 增加Api密钥 |
|||
* @param payload Api密钥参数 |
|||
*/ |
|||
public static addApiSecret(payload: ApiSecretCreate) { |
|||
const _url = '/api/IdentityServer/ApiResources/Secrets' |
|||
return ApiService.Post<ApiSecret>(_url, payload, serviceUrl) |
|||
} |
|||
|
|||
/** |
|||
* 删除Api密钥 |
|||
* @param apiResourceId 资源标识 |
|||
* @param type 密钥类型 |
|||
* @param value 密钥值 |
|||
*/ |
|||
public static deleteApiSecret(apiResourceId: string, type: string, value: string) { |
|||
let _url = '/api/IdentityServer/ApiResources/Secrets/' |
|||
_url += '?apiResourceId=' + apiResourceId |
|||
_url += '&type=' + type |
|||
_url += '&value=' + value |
|||
return ApiService.Delete(_url, serviceUrl) |
|||
} |
|||
|
|||
/** |
|||
* 增加Api授权范围 |
|||
* @param payload api授权范围参数 |
|||
*/ |
|||
public static addApiScope(payload: ApiScopeCreate) { |
|||
const _url = '/api/IdentityServer/ApiResources/Scopes' |
|||
return ApiService.Post<ApiScope>(_url, payload, serviceUrl) |
|||
} |
|||
|
|||
/** |
|||
* 删除Api授权范围 |
|||
* @param apiResourceId api资源标识 |
|||
* @param name 授权范围名称 |
|||
*/ |
|||
public static deleteApiScope(apiResourceId: string, name: string) { |
|||
let _url = '/api/IdentityServer/ApiResources/Scopes' |
|||
_url += '?apiResourceId=' + apiResourceId |
|||
_url += '&name=' + name |
|||
return ApiService.Delete(_url, serviceUrl) |
|||
} |
|||
} |
|||
|
|||
export enum HashType { |
|||
Sha256, |
|||
Sha512 |
|||
} |
|||
|
|||
export class ApiSecret { |
|||
type!: string |
|||
value!: string |
|||
hashType?: HashType |
|||
description?: string |
|||
expiration?: Date |
|||
} |
|||
|
|||
export class ApiScopeClaim { |
|||
type!: string |
|||
} |
|||
|
|||
export class ApiResourceClaim { |
|||
type!: string |
|||
} |
|||
|
|||
export class ApiScope { |
|||
name!: string |
|||
displayName?: string |
|||
description?: string |
|||
required!: boolean |
|||
emphasize!: boolean |
|||
showInDiscoveryDocument!: boolean |
|||
userClaims : ApiScopeClaim[] |
|||
|
|||
constructor() { |
|||
this.userClaims = new Array<ApiScopeClaim>() |
|||
} |
|||
} |
|||
|
|||
export class ApiScopeCreate { |
|||
apiResourceId!: string |
|||
name!: string |
|||
displayName?: string |
|||
description?: string |
|||
required!: boolean |
|||
emphasize!: boolean |
|||
showInDiscoveryDocument!: boolean |
|||
userClaims : ApiScopeClaim[] |
|||
|
|||
constructor() { |
|||
this.apiResourceId = '' |
|||
this.name = '' |
|||
this.displayName = '' |
|||
this.description = '' |
|||
this.required = false |
|||
this.emphasize = false |
|||
this.showInDiscoveryDocument = false |
|||
this.userClaims = new Array<ApiScopeClaim>() |
|||
} |
|||
|
|||
public static empty() { |
|||
return new ApiScopeCreate() |
|||
} |
|||
} |
|||
|
|||
export class ApiSecretCreate { |
|||
apiResourceId!: string |
|||
type!: string |
|||
value!: string |
|||
hashType?: HashType |
|||
description?: string |
|||
expiration?: Date |
|||
|
|||
constructor() { |
|||
this.type = 'SharedSecret' |
|||
this.value = '' |
|||
this.hashType = HashType.Sha256 |
|||
this.description = '' |
|||
this.expiration = undefined |
|||
} |
|||
|
|||
public static empty() { |
|||
return new ApiSecretCreate() |
|||
} |
|||
} |
|||
|
|||
export class ApiResourceCreate { |
|||
name!: string |
|||
displayName?: string |
|||
description?: string |
|||
enabled!: boolean |
|||
userClaims!: ApiResourceClaim[] |
|||
|
|||
constructor() { |
|||
this.name = '' |
|||
this.displayName = '' |
|||
this.description = '' |
|||
this.enabled = true |
|||
this.userClaims = new Array<ApiResourceClaim>() |
|||
} |
|||
|
|||
public static empty() { |
|||
return new ApiResourceCreate() |
|||
} |
|||
|
|||
public static create(apiResource: ApiResource) { |
|||
const resource = ApiResourceCreate.empty() |
|||
resource.name = apiResource.name |
|||
resource.displayName = apiResource.displayName |
|||
resource.description = apiResource.description |
|||
resource.enabled = apiResource.enabled |
|||
resource.userClaims = apiResource.userClaims |
|||
return resource |
|||
} |
|||
} |
|||
|
|||
export class ApiResourceUpdate { |
|||
id!: string |
|||
displayName?: string |
|||
description?: string |
|||
enabled!: boolean |
|||
userClaims!: ApiResourceClaim[] |
|||
|
|||
constructor() { |
|||
this.id = '' |
|||
this.displayName = '' |
|||
this.description = '' |
|||
this.enabled = true |
|||
this.userClaims = new Array<ApiResourceClaim>() |
|||
} |
|||
|
|||
public static empty() { |
|||
return new ApiResourceUpdate() |
|||
} |
|||
|
|||
public static create(apiResource: ApiResource) { |
|||
const resource = ApiResourceUpdate.empty() |
|||
resource.id = apiResource.id |
|||
resource.displayName = apiResource.displayName |
|||
resource.description = apiResource.description |
|||
resource.enabled = apiResource.enabled |
|||
resource.userClaims = apiResource.userClaims |
|||
return resource |
|||
} |
|||
} |
|||
|
|||
export class ApiResource extends FullAuditedEntityDto { |
|||
id!: string |
|||
name!: string |
|||
displayName?: string |
|||
description?: string |
|||
enabled!: boolean |
|||
secrets!: ApiSecret[] |
|||
scopes!: ApiScope[] |
|||
userClaims!: ApiResourceClaim[] |
|||
|
|||
constructor() { |
|||
super() |
|||
this.id = '' |
|||
this.name = '' |
|||
this.displayName = '' |
|||
this.description = '' |
|||
this.enabled = true |
|||
this.scopes = new Array<ApiScope>() |
|||
this.secrets = new Array<ApiSecret>() |
|||
this.userClaims = new Array<ApiResourceClaim>() |
|||
} |
|||
|
|||
public static empty() { |
|||
return new ApiResource() |
|||
} |
|||
} |
|||
|
|||
export class ApiResourceGetByPaged extends PagedAndSortedResultRequestDto { |
|||
filter!: string |
|||
|
|||
constructor() { |
|||
super() |
|||
this.filter = '' |
|||
} |
|||
} |
|||
@ -0,0 +1,171 @@ |
|||
<template> |
|||
<div class="app-container"> |
|||
<div class="filter-container"> |
|||
<el-form |
|||
ref="formApiResource" |
|||
label-width="100px" |
|||
:model="apiResource" |
|||
:rules="apiResourceRules" |
|||
> |
|||
<el-form-item |
|||
prop="enabled" |
|||
:label="$t('identityServer.enabledApiResource')" |
|||
> |
|||
<el-switch |
|||
v-model="apiResource.enabled" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="name" |
|||
:label="$t('identityServer.apiResourceName')" |
|||
> |
|||
<el-input |
|||
v-model="apiResource.name" |
|||
:readonly="isEdit" |
|||
:placeholder="$t('pleaseInputBy', {key: $t('identityServer.apiResourceName')})" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="displayName" |
|||
:label="$t('identityServer.apiResourceDisplayName')" |
|||
> |
|||
<el-input |
|||
v-model="apiResource.displayName" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="description" |
|||
:label="$t('identityServer.apiResourceDescription')" |
|||
> |
|||
<el-input |
|||
v-model="apiResource.description" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="userClaims" |
|||
:label="$t('identityServer.apiResourceUserClaims')" |
|||
> |
|||
<el-input-tag-ex |
|||
v-model="apiResource.userClaims" |
|||
label="type" |
|||
/> |
|||
</el-form-item> |
|||
|
|||
<el-form-item> |
|||
<el-button |
|||
class="cancel" |
|||
style="width:100px" |
|||
@click="onCancel" |
|||
> |
|||
{{ $t('table.cancel') }} |
|||
</el-button> |
|||
<el-button |
|||
class="confirm" |
|||
type="primary" |
|||
style="width:100px" |
|||
@click="onSaveApiResource" |
|||
> |
|||
{{ $t('table.confirm') }} |
|||
</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import ApiResourceService, { ApiResourceCreate, ApiResourceUpdate, ApiResource } from '@/api/apiresources' |
|||
import { Component, Prop, Vue, Watch } from 'vue-property-decorator' |
|||
import ElInputTagEx from '@/components/InputTagEx/index.vue' |
|||
|
|||
@Component({ |
|||
name: 'ApiResourceCreateOrEditForm', |
|||
components: { |
|||
ElInputTagEx |
|||
} |
|||
}) |
|||
export default class extends Vue { |
|||
@Prop({ default: '' }) |
|||
private apiResourceId!: string |
|||
|
|||
private apiResource: ApiResource |
|||
private apiResourceRules = { |
|||
name: [ |
|||
{ required: true, message: this.l('pleaseInputBy', { key: this.l('identityServer.apiResourceName') }), trigger: 'blur' } |
|||
] |
|||
} |
|||
|
|||
get isEdit() { |
|||
if (this.apiResource.id) { |
|||
return true |
|||
} |
|||
return false |
|||
} |
|||
|
|||
constructor() { |
|||
super() |
|||
this.apiResource = ApiResource.empty() |
|||
} |
|||
|
|||
@Watch('apiResourceId', { immediate: true }) |
|||
private onApiResourceIdChanged() { |
|||
if (this.apiResourceId) { |
|||
ApiResourceService.getApiResourceById(this.apiResourceId).then(resource => { |
|||
this.apiResource = resource |
|||
}) |
|||
} |
|||
} |
|||
|
|||
private onSaveApiResource() { |
|||
const frmApiResource = this.$refs.formApiResource as any |
|||
frmApiResource.validate((valid: boolean) => { |
|||
if (valid) { |
|||
if (this.isEdit) { |
|||
const updateApiResource = ApiResourceUpdate.create(this.apiResource) |
|||
ApiResourceService.updateApiResource(updateApiResource).then(resource => { |
|||
this.apiResource = resource |
|||
const successMessage = this.l('identityServer.updateApiResourceSuccess', { name: resource.name }) |
|||
this.$message.success(successMessage) |
|||
frmApiResource.resetFields() |
|||
this.$emit('closed', true) |
|||
}) |
|||
} else { |
|||
const createApiResource = ApiResourceCreate.create(this.apiResource) |
|||
ApiResourceService.createApiResource(createApiResource).then(resource => { |
|||
this.apiResource = resource |
|||
const successMessage = this.l('identityServer.createApiResourceSuccess', { name: resource.name }) |
|||
this.$message.success(successMessage) |
|||
frmApiResource.resetFields() |
|||
this.$emit('closed', true) |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
private onCancel() { |
|||
this.resetFields() |
|||
this.$emit('closed', false) |
|||
} |
|||
|
|||
public resetFields() { |
|||
const frmApiResource = this.$refs.formApiResource as any |
|||
frmApiResource.resetFields() |
|||
} |
|||
|
|||
private l(name: string, values?: any[] | { [key: string]: any }) { |
|||
return this.$t(name, values).toString() |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.confirm { |
|||
position: absolute; |
|||
right: 10px; |
|||
} |
|||
.cancel { |
|||
position: absolute; |
|||
right: 120px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,246 @@ |
|||
<template> |
|||
<div class="app-container"> |
|||
<div class="filter-container"> |
|||
<el-form |
|||
ref="formApiScope" |
|||
label-width="120px" |
|||
:model="apiScope" |
|||
:rules="apiScopeRules" |
|||
> |
|||
<el-form-item |
|||
prop="name" |
|||
:label="$t('identityServer.apiScopeName')" |
|||
> |
|||
<el-input |
|||
v-model="apiScope.name" |
|||
:placeholder="$t('pleaseInputBy', {key: $t('identityServer.apiScopeName')})" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="displayName" |
|||
:label="$t('identityServer.apiScopeDisplayName')" |
|||
> |
|||
<el-input |
|||
v-model="apiScope.displayName" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="description" |
|||
:label="$t('identityServer.apiScopeDescription')" |
|||
> |
|||
<el-input |
|||
v-model="apiScope.description" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="required" |
|||
:label="$t('identityServer.apiScopeRequired')" |
|||
> |
|||
<el-switch |
|||
v-model="apiScope.required" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="emphasize" |
|||
:label="$t('identityServer.apiScopeEmphasize')" |
|||
> |
|||
<el-switch |
|||
v-model="apiScope.emphasize" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="showInDiscoveryDocument" |
|||
:label="$t('identityServer.apiScopeShowInDiscoveryDocument')" |
|||
> |
|||
<el-switch |
|||
v-model="apiScope.showInDiscoveryDocument" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="userClaims" |
|||
:label="$t('identityServer.apiResourceUserClaims')" |
|||
> |
|||
<el-input-tag-ex |
|||
v-model="apiScope.userClaims" |
|||
label="type" |
|||
/> |
|||
</el-form-item> |
|||
|
|||
<el-form-item |
|||
style="text-align: center;" |
|||
label-width="0px" |
|||
> |
|||
<el-button |
|||
type="primary" |
|||
style="width:180px" |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Secrets.Create'])" |
|||
@click="onSaveApiScope" |
|||
> |
|||
{{ $t('identityServer.createApiScope') }} |
|||
</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
|
|||
<el-divider /> |
|||
|
|||
<el-table |
|||
row-key="value" |
|||
:data="apiScopes" |
|||
border |
|||
fit |
|||
highlight-current-row |
|||
style="width: 100%;" |
|||
> |
|||
<el-table-column |
|||
:label="$t('identityServer.apiScopeName')" |
|||
prop="name" |
|||
sortable |
|||
width="150px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.name }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('identityServer.apiScopeDisplayName')" |
|||
prop="displayName" |
|||
sortable |
|||
width="200px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.displayName }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('identityServer.apiScopeDescription')" |
|||
prop="description" |
|||
width="300px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.description }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('operaActions')" |
|||
align="center" |
|||
width="150px" |
|||
fixed="right" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<el-button |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Scope.Delete'])" |
|||
size="mini" |
|||
type="primary" |
|||
@click="handleDeleteApiScope(row.name)" |
|||
> |
|||
{{ $t('identityServer.deleteApiScope') }} |
|||
</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import ApiResourceService, { ApiScope, ApiScopeCreate } from '@/api/apiresources' |
|||
import { Component, Vue, Prop, Watch } from 'vue-property-decorator' |
|||
import { dateFormat } from '@/utils/index' |
|||
import { checkPermission } from '@/utils/permission' |
|||
import ElInputTagEx from '@/components/InputTagEx/index.vue' |
|||
|
|||
@Component({ |
|||
name: 'ApiScopeEditForm', |
|||
components: { |
|||
ElInputTagEx |
|||
}, |
|||
filters: { |
|||
dateTimeFilter(datetime: string) { |
|||
if (datetime) { |
|||
const date = new Date(datetime) |
|||
return dateFormat(date, 'YYYY-mm-dd HH:MM') |
|||
} |
|||
return '' |
|||
} |
|||
}, |
|||
methods: { |
|||
checkPermission |
|||
} |
|||
}) |
|||
export default class extends Vue { |
|||
@Prop({ default: '' }) |
|||
private apiResourceId!: string |
|||
|
|||
@Prop({ default: () => new Array<ApiScope>() }) |
|||
private apiScopes!: ApiScope[] |
|||
|
|||
private apiScopeChanged: boolean |
|||
private apiScope: ApiScopeCreate |
|||
private apiScopeRules = { |
|||
name: [ |
|||
{ required: true, message: this.l('pleaseInputBy', { key: this.l('identityServer.apiScopeName') }), trigger: 'blur' } |
|||
] |
|||
} |
|||
|
|||
constructor() { |
|||
super() |
|||
this.apiScopeChanged = false |
|||
this.apiScope = ApiScopeCreate.empty() |
|||
} |
|||
|
|||
@Watch('apiResourceId', { immediate: true }) |
|||
private onApiResourceIdChanged() { |
|||
this.apiScope.apiResourceId = this.apiResourceId |
|||
} |
|||
|
|||
private handleDeleteApiScope(name: string) { |
|||
this.$confirm(this.l('identityServer.deleteApiScopeByName', { name: name }), |
|||
this.l('identityServer.deleteApiScope'), { |
|||
callback: (action) => { |
|||
if (action === 'confirm') { |
|||
ApiResourceService.deleteApiScope(this.apiResourceId, name).then(() => { |
|||
const deleteScopeIndex = this.apiScopes.findIndex(scope => scope.name === name) |
|||
this.apiScopes.splice(deleteScopeIndex, 1) |
|||
this.$message.success(this.l('identityServer.deleteApiScopeSuccess', { name: name })) |
|||
this.$emit('apiScopeChanged') |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
private onSaveApiScope() { |
|||
const frmApiScope = this.$refs.formApiScope as any |
|||
frmApiScope.validate((valid: boolean) => { |
|||
if (valid) { |
|||
this.apiScope.apiResourceId = this.apiResourceId |
|||
ApiResourceService.addApiScope(this.apiScope).then(scope => { |
|||
this.apiScopes.push(scope) |
|||
const successMessage = this.l('identityServer.createApiScopeSuccess', { name: this.apiScope.name }) |
|||
this.$message.success(successMessage) |
|||
frmApiScope.resetFields() |
|||
this.$emit('apiScopeChanged') |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
public resetFields() { |
|||
const frmApiScope = this.$refs.formApiScope as any |
|||
frmApiScope.resetFields() |
|||
} |
|||
|
|||
private l(name: string, values?: any[] | { [key: string]: any }) { |
|||
return this.$t(name, values).toString() |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.full-select { |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,289 @@ |
|||
<template> |
|||
<div class="app-container"> |
|||
<div class="filter-container"> |
|||
<el-form |
|||
ref="formApiSecret" |
|||
label-width="100px" |
|||
:model="apiSecret" |
|||
:rules="apiSecretRules" |
|||
> |
|||
<el-form-item |
|||
prop="type" |
|||
:label="$t('identityServer.secretType')" |
|||
> |
|||
<el-select |
|||
v-model="apiSecret.type" |
|||
class="full-select" |
|||
:placeholder="$t('pleaseSelectBy', {key: $t('identityServer.secretType')})" |
|||
> |
|||
<el-option |
|||
key="JWK" |
|||
label="JsonWebKey" |
|||
value="JWK" |
|||
/> |
|||
<el-option |
|||
key="SharedSecret" |
|||
label="SharedSecret" |
|||
value="SharedSecret" |
|||
/> |
|||
<el-option |
|||
key="X509Name" |
|||
label="X509CertificateName" |
|||
value="X509Name" |
|||
/> |
|||
<el-option |
|||
key="X509CertificateBase64" |
|||
label="X509CertificateBase64" |
|||
value="X509CertificateBase64" |
|||
/> |
|||
<el-option |
|||
key="X509Thumbprint" |
|||
label="X509CertificateThumbprint" |
|||
value="X509Thumbprint" |
|||
/> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="hashType" |
|||
:label="$t('identityServer.secretHashType')" |
|||
> |
|||
<el-popover |
|||
ref="popHashType" |
|||
placement="top-start" |
|||
trigger="hover" |
|||
:content="$t('identityServer.hashOnlySharedSecret')" |
|||
/> |
|||
<el-select |
|||
v-model="apiSecret.hashType" |
|||
v-popover:popHashType |
|||
:disabled="apiSecret.type !== 'SharedSecret'" |
|||
class="full-select" |
|||
:placeholder="$t('pleaseSelectBy', {key: $t('identityServer.secretHashType')})" |
|||
> |
|||
<el-option |
|||
:key="0" |
|||
label="Sha256" |
|||
:value="0" |
|||
/> |
|||
<el-option |
|||
:key="1" |
|||
label="Sha512" |
|||
:value="1" |
|||
/> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="value" |
|||
:label="$t('identityServer.secretValue')" |
|||
> |
|||
<el-input |
|||
v-model="apiSecret.value" |
|||
:placeholder="$t('pleaseInputBy', {key: $t('identityServer.secretValue')})" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="description" |
|||
:label="$t('identityServer.secretDescription')" |
|||
> |
|||
<el-input |
|||
v-model="apiSecret.description" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="expiration" |
|||
:label="$t('identityServer.expiration')" |
|||
> |
|||
<el-date-picker |
|||
v-model="apiSecret.expiration" |
|||
class="full-select" |
|||
type="datetime" |
|||
/> |
|||
</el-form-item> |
|||
|
|||
<el-form-item |
|||
style="text-align: center;" |
|||
label-width="0px" |
|||
> |
|||
<el-button |
|||
type="primary" |
|||
style="width:180px" |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Secrets.Create'])" |
|||
@click="onSaveApiSecret" |
|||
> |
|||
{{ $t('identityServer.createApiSecret') }} |
|||
</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
|
|||
<el-divider /> |
|||
|
|||
<el-table |
|||
row-key="value" |
|||
:data="apiSecrets" |
|||
border |
|||
fit |
|||
highlight-current-row |
|||
style="width: 100%;" |
|||
> |
|||
<el-table-column |
|||
:label="$t('identityServer.secretType')" |
|||
prop="type" |
|||
sortable |
|||
width="150px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.type }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('identityServer.secretValue')" |
|||
prop="value" |
|||
sortable |
|||
width="200px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.value }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('identityServer.secretDescription')" |
|||
prop="description" |
|||
width="170px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.description }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('identityServer.expiration')" |
|||
prop="expiration" |
|||
width="170px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.expiration | dateTimeFilter }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('operaActions')" |
|||
align="center" |
|||
width="150px" |
|||
fixed="right" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<el-button |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Secrets.Delete'])" |
|||
size="mini" |
|||
type="primary" |
|||
@click="handleDeleteApiSecret(row.type, row.value)" |
|||
> |
|||
{{ $t('identityServer.deleteApiSecret') }} |
|||
</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import ApiResourceService, { ApiSecret, ApiSecretCreate } from '@/api/apiresources' |
|||
import { Component, Vue, Prop, Watch } from 'vue-property-decorator' |
|||
import { dateFormat } from '@/utils/index' |
|||
import { checkPermission } from '@/utils/permission' |
|||
|
|||
@Component({ |
|||
name: 'ApiSecretEditForm', |
|||
filters: { |
|||
dateTimeFilter(datetime: string) { |
|||
if (datetime) { |
|||
const date = new Date(datetime) |
|||
return dateFormat(date, 'YYYY-mm-dd HH:MM') |
|||
} |
|||
return '' |
|||
} |
|||
}, |
|||
methods: { |
|||
checkPermission |
|||
} |
|||
}) |
|||
export default class extends Vue { |
|||
@Prop({ default: '' }) |
|||
private apiResourceId!: string |
|||
|
|||
@Prop({ default: () => new Array<ApiSecret>() }) |
|||
private apiSecrets!: ApiSecret[] |
|||
|
|||
private apiSecretChanged: boolean |
|||
private apiSecret: ApiSecretCreate |
|||
private apiSecretRules = { |
|||
type: [ |
|||
{ required: true, message: this.l('pleaseSelectBy', { key: this.l('identityServer.secretType') }), trigger: 'change' } |
|||
], |
|||
value: [ |
|||
{ required: true, message: this.l('pleaseInputBy', { key: this.l('identityServer.secretValue') }), trigger: 'blur' } |
|||
] |
|||
} |
|||
|
|||
constructor() { |
|||
super() |
|||
this.apiSecretChanged = false |
|||
this.apiSecret = ApiSecretCreate.empty() |
|||
} |
|||
|
|||
@Watch('apiResourceId', { immediate: true }) |
|||
private onApiResourceIdChanged() { |
|||
this.apiSecret.apiResourceId = this.apiResourceId |
|||
} |
|||
|
|||
private handleDeleteApiSecret(type: string, value: string) { |
|||
this.$confirm(this.l('identityServer.deleteApiSecretByType', { type: value }), |
|||
this.l('identityServer.deleteApiSecret'), { |
|||
callback: (action) => { |
|||
if (action === 'confirm') { |
|||
ApiResourceService.deleteApiSecret(this.apiResourceId, type, value).then(() => { |
|||
const deleteSecretIndex = this.apiSecrets.findIndex(secret => secret.type === type) |
|||
this.apiSecrets.splice(deleteSecretIndex, 1) |
|||
this.$message.success(this.l('identityServer.deleteApiSecretSuccess', { type: value })) |
|||
this.$emit('apiSecretChanged') |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
private onSaveApiSecret() { |
|||
const frmApiSecret = this.$refs.formApiSecret as any |
|||
frmApiSecret.validate((valid: boolean) => { |
|||
if (valid) { |
|||
this.apiSecret.apiResourceId = this.apiResourceId |
|||
ApiResourceService.addApiSecret(this.apiSecret).then(secret => { |
|||
this.apiSecrets.push(secret) |
|||
const successMessage = this.l('identityServer.createApiSecretSuccess', { type: this.apiSecret.type }) |
|||
this.$message.success(successMessage) |
|||
frmApiSecret.resetFields() |
|||
this.$emit('apiSecretChanged') |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
public resetFields() { |
|||
const frmApiSecret = this.$refs.formApiSecret as any |
|||
frmApiSecret.resetFields() |
|||
} |
|||
|
|||
private l(name: string, values?: any[] | { [key: string]: any }) { |
|||
return this.$t(name, values).toString() |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.full-select { |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,402 @@ |
|||
<template> |
|||
<div class="app-container"> |
|||
<div class="filter-container"> |
|||
<label |
|||
class="radio-label" |
|||
style="padding-left:10px;" |
|||
>{{ $t('queryFilter') }}</label> |
|||
<el-input |
|||
v-model="apiResourceGetPagedFilter.filter" |
|||
:placeholder="$t('filterString')" |
|||
style="width: 250px;margin-left: 10px;" |
|||
class="filter-item" |
|||
/> |
|||
<el-button |
|||
class="filter-item" |
|||
style="margin-left: 10px; text-alignt" |
|||
type="primary" |
|||
@click="handleGetApiResources" |
|||
> |
|||
{{ $t('searchList') }} |
|||
</el-button> |
|||
<el-button |
|||
class="filter-item" |
|||
type="primary" |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Create'])" |
|||
@click="handleShowEditApiResourceForm()" |
|||
> |
|||
{{ $t('identityServer.createApiResource') }} |
|||
</el-button> |
|||
</div> |
|||
|
|||
<el-table |
|||
v-loading="apiResourceListLoading" |
|||
row-key="id" |
|||
:data="apiResourceList" |
|||
border |
|||
fit |
|||
highlight-current-row |
|||
style="width: 100%;" |
|||
@sort-change="handleSortChange" |
|||
> |
|||
<el-table-column |
|||
:label="$t('identityServer.apiResourceName')" |
|||
prop="name" |
|||
sortable |
|||
width="150px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.name }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('identityServer.apiResourceDisplayName')" |
|||
prop="displayName" |
|||
sortable |
|||
width="200px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.displayName }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('identityServer.apiResourceStatus')" |
|||
prop="enabled" |
|||
sortable |
|||
width="140px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<el-tag :type="row.enabled | statusFilter"> |
|||
{{ formatStatusText(row.enabled) }} |
|||
</el-tag> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('identityServer.apiResourceDescription')" |
|||
prop="description" |
|||
sortable |
|||
width="200px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.description }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('creationTime')" |
|||
prop="creationTime" |
|||
width="170px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span> |
|||
<el-tag> |
|||
{{ row.creationTime | datetimeFilter }} |
|||
</el-tag> |
|||
</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('lastModificationTime')" |
|||
prop="lastModificationTime" |
|||
width="170px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span> |
|||
<el-tag type="warning"> |
|||
{{ row.lastModificationTime | datetimeFilter }} |
|||
</el-tag> |
|||
</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('operaActions')" |
|||
align="center" |
|||
width="250px" |
|||
fixed="right" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<el-button |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Update'])" |
|||
size="mini" |
|||
type="primary" |
|||
@click="handleShowEditApiResourceForm(row)" |
|||
> |
|||
{{ $t('identityServer.updateApiResource') }} |
|||
</el-button> |
|||
<el-dropdown |
|||
class="options" |
|||
@command="handleCommand" |
|||
> |
|||
<el-button |
|||
v-permission="['IdentityServer.ApiResources']" |
|||
size="mini" |
|||
type="info" |
|||
> |
|||
{{ $t('identityServer.otherOpera') }}<i class="el-icon-arrow-down el-icon--right" /> |
|||
</el-button> |
|||
<el-dropdown-menu slot="dropdown"> |
|||
<el-dropdown-item |
|||
:command="{key: 'secret', row}" |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Secrets'])" |
|||
> |
|||
{{ $t('identityServer.apiResourceSecret') }} |
|||
</el-dropdown-item> |
|||
<el-dropdown-item |
|||
:command="{key: 'scope', row}" |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Scope'])" |
|||
> |
|||
{{ $t('identityServer.apiResourceScope') }} |
|||
</el-dropdown-item> |
|||
<el-dropdown-item |
|||
divided |
|||
:command="{key: 'delete', row}" |
|||
:disabled="!checkPermission(['IdentityServer.ApiResources.Delete'])" |
|||
> |
|||
{{ $t('identityServer.deleteApiResource') }} |
|||
</el-dropdown-item> |
|||
</el-dropdown-menu> |
|||
</el-dropdown> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
|
|||
<Pagination |
|||
v-show="apiResourceListCount>0" |
|||
:total="apiResourceListCount" |
|||
:page.sync="apiResourceGetPagedFilter.skipCount" |
|||
:limit.sync="apiResourceGetPagedFilter.maxResultCount" |
|||
@pagination="handleGetApiResources" |
|||
@sort-change="handleSortChange" |
|||
/> |
|||
|
|||
<el-dialog |
|||
v-el-draggable-dialog |
|||
width="800px" |
|||
:visible.sync="showEditApiResourceDialog" |
|||
:title="editApiResourceTitle" |
|||
custom-class="modal-form" |
|||
:show-close="false" |
|||
:close-on-click-modal="false" |
|||
:close-on-press-escape="false" |
|||
> |
|||
<ApiResourceCreateOrEditForm |
|||
:api-resource-id="editApiResource.id" |
|||
@closed="handleApiResourceEditFormClosed" |
|||
/> |
|||
</el-dialog> |
|||
|
|||
<el-dialog |
|||
v-el-draggable-dialog |
|||
width="800px" |
|||
:visible.sync="showEditApiSecretDialog" |
|||
:title="$t('identityServer.apiResourceSecret')" |
|||
custom-class="modal-form" |
|||
:show-close="false" |
|||
@closed="handleApiSecretEditFormClosed" |
|||
> |
|||
<ApiSecretEditForm |
|||
ref="formApiSecret" |
|||
:api-resource-id="editApiResource.id" |
|||
:api-secrets="editApiResource.secrets" |
|||
@apiSecretChanged="handleGetApiResources" |
|||
/> |
|||
</el-dialog> |
|||
|
|||
<el-dialog |
|||
v-el-draggable-dialog |
|||
width="800px" |
|||
:visible.sync="showEditApiScopeDialog" |
|||
:title="$t('identityServer.apiResourceScope')" |
|||
custom-class="modal-form" |
|||
:show-close="false" |
|||
@closed="handleApiScopeEditFormClosed" |
|||
> |
|||
<ApiScopeEditForm |
|||
ref="formApiScope" |
|||
:api-resource-id="editApiResource.id" |
|||
:api-scopes="editApiResource.scopes" |
|||
@apiSecretChanged="handleGetApiResources" |
|||
/> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { checkPermission } from '@/utils/permission' |
|||
import { Component, Vue } from 'vue-property-decorator' |
|||
import { dateFormat } from '@/utils/index' |
|||
import Pagination from '@/components/Pagination/index.vue' |
|||
import ApiScopeEditForm from './components/ApiResourceScopeEditForm.vue' |
|||
import ApiSecretEditForm from './components/ApiResourceSecretEditForm.vue' |
|||
import ApiResourceCreateOrEditForm from './components/ApiResourceCreateOrEditForm.vue' |
|||
import ApiResourceService, { ApiResource, ApiResourceGetByPaged } from '@/api/apiresources' |
|||
|
|||
@Component({ |
|||
name: 'IdentityServerApiResource', |
|||
components: { |
|||
Pagination, |
|||
ApiScopeEditForm, |
|||
ApiSecretEditForm, |
|||
ApiResourceCreateOrEditForm |
|||
}, |
|||
methods: { |
|||
checkPermission, |
|||
local(name: string) { |
|||
return this.$t(name) |
|||
} |
|||
}, |
|||
filters: { |
|||
statusFilter(status: boolean) { |
|||
if (status) { |
|||
return 'success' |
|||
} |
|||
return 'warning' |
|||
}, |
|||
datetimeFilter(val: string) { |
|||
const date = new Date(val) |
|||
return dateFormat(date, 'YYYY-mm-dd HH:MM') |
|||
} |
|||
} |
|||
}) |
|||
export default class extends Vue { |
|||
private editApiResource: ApiResource |
|||
private apiResourceListCount: number |
|||
private editApiResourceTitle: any |
|||
private apiResourceList: ApiResource[] |
|||
private apiResourceListLoading: boolean |
|||
private apiResourceGetPagedFilter: ApiResourceGetByPaged |
|||
|
|||
private showEditApiScopeDialog: boolean |
|||
private showEditApiSecretDialog: boolean |
|||
private showEditApiResourceDialog: boolean |
|||
|
|||
constructor() { |
|||
super() |
|||
this.apiResourceListCount = 0 |
|||
this.editApiResourceTitle = '' |
|||
this.apiResourceListLoading = false |
|||
this.editApiResource = new ApiResource() |
|||
this.apiResourceList = new Array<ApiResource>() |
|||
this.apiResourceGetPagedFilter = new ApiResourceGetByPaged() |
|||
|
|||
this.showEditApiScopeDialog = false |
|||
this.showEditApiSecretDialog = false |
|||
this.showEditApiResourceDialog = false |
|||
} |
|||
|
|||
mounted() { |
|||
this.handleGetApiResources() |
|||
} |
|||
|
|||
private handleGetApiResources() { |
|||
this.apiResourceListLoading = true |
|||
ApiResourceService.getApiResources(this.apiResourceGetPagedFilter).then(resources => { |
|||
this.apiResourceList = resources.items |
|||
this.apiResourceListCount = resources.totalCount |
|||
}).finally(() => { |
|||
this.apiResourceListLoading = false |
|||
}) |
|||
} |
|||
|
|||
private handleSortChange(column: any) { |
|||
this.apiResourceGetPagedFilter.sorting = column.prop |
|||
} |
|||
|
|||
private handleShowEditApiResourceForm(resource: ApiResource) { |
|||
if (resource) { |
|||
this.editApiResource = resource |
|||
this.editApiResourceTitle = this.l('identityServer.updateApiResourceByName', { name: this.editApiResource.name }) |
|||
} else { |
|||
this.editApiResource = ApiResource.empty() |
|||
this.editApiResourceTitle = this.l('identityServer.createApiResource') |
|||
} |
|||
this.showEditApiResourceDialog = true |
|||
} |
|||
|
|||
private handleApiResourceEditFormClosed(changed: boolean) { |
|||
this.editApiResourceTitle = '' |
|||
this.editApiResource = ApiResource.empty() |
|||
this.showEditApiResourceDialog = false |
|||
if (changed) { |
|||
this.handleGetApiResources() |
|||
} |
|||
} |
|||
|
|||
private handleApiSecretEditFormClosed() { |
|||
this.showEditApiSecretDialog = false |
|||
const frmApiSecret = this.$refs.formApiSecret as ApiSecretEditForm |
|||
frmApiSecret.resetFields() |
|||
} |
|||
|
|||
private handleApiScopeEditFormClosed() { |
|||
this.showEditApiScopeDialog = false |
|||
const frmApiScope = this.$refs.formApiScope as ApiScopeEditForm |
|||
frmApiScope.resetFields() |
|||
} |
|||
|
|||
private handleDeleteApiResource(id: string, name: string) { |
|||
this.$confirm(this.l('identityServer.deleteApiResourceByName', { name: name }), |
|||
this.l('identityServer.deleteApiResource'), { |
|||
callback: (action) => { |
|||
if (action === 'confirm') { |
|||
ApiResourceService.deleteApiResource(id).then(() => { |
|||
this.$message.success(this.l('identityServer.deleteApiResourceSuccess', { name: name })) |
|||
this.handleGetApiResources() |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
private handleCommand(command: {key: string, row: ApiResource}) { |
|||
this.editApiResource = command.row |
|||
switch (command.key) { |
|||
case 'secret' : |
|||
this.showEditApiSecretDialog = true |
|||
break |
|||
case 'scope' : |
|||
this.showEditApiScopeDialog = true |
|||
break |
|||
case 'delete' : |
|||
this.handleDeleteApiResource(command.row.id, command.row.name) |
|||
break |
|||
default: break |
|||
} |
|||
} |
|||
|
|||
private l(name: string, values?: any[] | { [key: string]: any }) { |
|||
return this.$t(name, values).toString() |
|||
} |
|||
|
|||
private formatStatusText(status: boolean) { |
|||
let statusText = '' |
|||
if (status) { |
|||
statusText = this.l('enabled') |
|||
} else { |
|||
statusText = this.l('disbled') |
|||
} |
|||
return statusText |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.roleItem { |
|||
width: 40px; |
|||
} |
|||
.options { |
|||
vertical-align: top; |
|||
margin-left: 20px; |
|||
} |
|||
.el-dropdown + .el-dropdown { |
|||
margin-left: 15px; |
|||
} |
|||
.el-icon-arrow-down { |
|||
font-size: 12px; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue