106 changed files with 2864 additions and 39 deletions
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
@ -1 +0,0 @@ |
|||
05d2e1f53650cb86c4348471113d51741fb76ff0 |
|||
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
@ -1 +0,0 @@ |
|||
061f3f9088fee775a74c51e73c470d50ddb271db |
|||
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
@ -1 +0,0 @@ |
|||
5b7167ef84bb508f25e00864dde6d86ec3356ce7 |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
@ -0,0 +1,23 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\IdentityServer\Localization\Resources\en.json" /> |
|||
<None Remove="LINGYUN\Abp\IdentityServer\Localization\Resources\zh-Hans.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\Localization\Resources\en.json" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\Localization\Resources\zh-Hans.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application" Version="2.7.0" /> |
|||
<PackageReference Include="Volo.Abp.IdentityServer.Domain.Shared" Version="2.7.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,29 @@ |
|||
using Volo.Abp.Application; |
|||
using Volo.Abp.IdentityServer; |
|||
using Volo.Abp.IdentityServer.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
[DependsOn(new[] { typeof(AbpDddApplicationModule) })] |
|||
[DependsOn(new[] { typeof(AbpIdentityServerDomainSharedModule) })] |
|||
public class AbpIdentityServerApplicationContractsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpIdentityServerApplicationContractsModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<AbpIdentityServerResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/IdentityServer/Localization/Resources"); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
public class AbpIdentityServerConsts |
|||
{ |
|||
/// <summary>
|
|||
/// 远程服务名称
|
|||
/// </summary>
|
|||
public const string RemoteServiceName = "IdentityServer"; |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
public class AbpIdentityServerErrorConsts |
|||
{ |
|||
/// <summary>
|
|||
/// 客户端标识已经存在
|
|||
/// </summary>
|
|||
public const string ClientIdExisted = "ClientIdExisted"; |
|||
|
|||
/// <summary>
|
|||
/// 客户端声明不存在
|
|||
/// </summary>
|
|||
public const string ClientClaimNotFound = "ClientClaimNotFound"; |
|||
|
|||
/// <summary>
|
|||
/// 客户端密钥不存在
|
|||
/// </summary>
|
|||
public const string ClientSecretNotFound = "ClientSecretNotFound"; |
|||
|
|||
/// <summary>
|
|||
/// 客户端属性不存在
|
|||
/// </summary>
|
|||
public const string ClientPropertyNotFound = "ClientPropertyNotFound"; |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.IdentityServer.Localization; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
public class AbpIdentityServerPermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var identityServerGroup = context.AddGroup(AbpIdentityServerPermissions.GroupName, L("Permissions:IdentityServer")); |
|||
|
|||
var clientPermissions = identityServerGroup.AddPermission(AbpIdentityServerPermissions.Clients.Default, L("Permissions:Clients")); |
|||
clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Create, L("Permissions:Create")); |
|||
clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Update, L("Permissions:Update")); |
|||
clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Enabled, L("Permissions:Enabled")); |
|||
clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Disabled, L("Permissions:Disabled")); |
|||
clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Delete, L("Permissions:Delete")); |
|||
var clientClaimPermissiosn = clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Claims.Default, L("Permissions:Clients:Claims")); |
|||
clientClaimPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Claims.Create, L("Permissions:Create")); |
|||
clientClaimPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Claims.Update, L("Permissions:Update")); |
|||
clientClaimPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Claims.Delete, L("Permissions:Delete")); |
|||
} |
|||
|
|||
protected virtual LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AbpIdentityServerResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
public class AbpIdentityServerPermissions |
|||
{ |
|||
public const string GroupName = "IdentityServer"; |
|||
|
|||
public static class Clients |
|||
{ |
|||
public const string Default = GroupName + ".Clients"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Delete = Default + ".Delete"; |
|||
public const string Enabled = Default + ".Enabled"; |
|||
public const string Disabled = Default + ".Disabled"; |
|||
|
|||
public static class Claims |
|||
{ |
|||
public const string Default = Clients.Default + ".Claims"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Delete = Default + ".Delete"; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientClaimCreateDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientClaimConsts.TypeMaxLength)] |
|||
public string Type { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientClaimConsts.ValueMaxLength)] |
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientClaimDto |
|||
{ |
|||
public string Type { get; set; } |
|||
|
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientClaimGetByKeyInputDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientClaimConsts.TypeMaxLength)] |
|||
public string Type { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientClaimUpdateDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientClaimConsts.TypeMaxLength)] |
|||
public string Type { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientClaimConsts.ValueMaxLength)] |
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientCorsOriginDto : EntityDto |
|||
{ |
|||
public string Origin { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientCreateDto |
|||
{ |
|||
[Required] |
|||
[StringLength(ClientConsts.ClientIdMaxLength)] |
|||
public string ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientConsts.ClientNameMaxLength)] |
|||
public string ClientName { get; set; } |
|||
|
|||
[StringLength(ClientConsts.DescriptionMaxLength)] |
|||
public string Description { get; set; } |
|||
|
|||
public List<ClientGrantTypeDto> AllowedGrantTypes { get; set; } |
|||
public ClientCreateDto() |
|||
{ |
|||
AllowedGrantTypes = new List<ClientGrantTypeDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,113 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientDto : FullAuditedEntityDto<Guid> |
|||
{ |
|||
public string ClientId { get; set; } |
|||
|
|||
public string ClientName { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public string ClientUri { get; set; } |
|||
|
|||
public string LogoUri { get; set; } |
|||
|
|||
public bool Enabled { get; set; } |
|||
|
|||
public string ProtocolType { get; set; } |
|||
|
|||
public bool RequireClientSecret { get; set; } |
|||
|
|||
public bool RequireConsent { get; set; } |
|||
|
|||
public bool AllowRememberConsent { get; set; } |
|||
|
|||
public bool AlwaysIncludeUserClaimsInIdToken { get; set; } |
|||
|
|||
public bool RequirePkce { get; set; } |
|||
|
|||
public bool AllowPlainTextPkce { get; set; } |
|||
|
|||
public bool AllowAccessTokensViaBrowser { get; set; } |
|||
|
|||
public string FrontChannelLogoutUri { get; set; } |
|||
|
|||
public bool FrontChannelLogoutSessionRequired { get; set; } |
|||
|
|||
public string BackChannelLogoutUri { get; set; } |
|||
|
|||
public bool BackChannelLogoutSessionRequired { get; set; } |
|||
|
|||
public bool AllowOfflineAccess { get; set; } |
|||
|
|||
public int IdentityTokenLifetime { get; set; } |
|||
|
|||
public int AccessTokenLifetime { get; set; } |
|||
|
|||
public int AuthorizationCodeLifetime { get; set; } |
|||
|
|||
public int? ConsentLifetime { get; set; } |
|||
|
|||
public int AbsoluteRefreshTokenLifetime { get; set; } |
|||
|
|||
public int SlidingRefreshTokenLifetime { get; set; } |
|||
|
|||
public int RefreshTokenUsage { get; set; } |
|||
|
|||
public bool UpdateAccessTokenClaimsOnRefresh { get; set; } |
|||
|
|||
public int RefreshTokenExpiration { get; set; } |
|||
|
|||
public int AccessTokenType { get; set; } |
|||
|
|||
public bool EnableLocalLogin { get; set; } |
|||
|
|||
public bool IncludeJwtId { get; set; } |
|||
|
|||
public bool AlwaysSendClientClaims { get; set; } |
|||
|
|||
public string ClientClaimsPrefix { get; set; } |
|||
|
|||
public string PairWiseSubjectSalt { get; set; } |
|||
|
|||
public int? UserSsoLifetime { get; set; } |
|||
|
|||
public string UserCodeType { get; set; } |
|||
|
|||
public int DeviceCodeLifetime { get; set; } |
|||
|
|||
public List<ClientScopeDto> AllowedScopes { get; set; } |
|||
|
|||
public List<ClientSecretDto> ClientSecrets { get; set; } |
|||
|
|||
public List<ClientGrantTypeDto> AllowedGrantTypes { get; set; } |
|||
|
|||
public List<ClientCorsOriginDto> AllowedCorsOrigins { get; set; } |
|||
|
|||
public List<ClientRedirectUriDto> RedirectUris { get; set; } |
|||
|
|||
public List<ClientPostLogoutRedirectUriDto> PostLogoutRedirectUris { get; set; } |
|||
|
|||
public List<ClientIdPRestrictionDto> IdentityProviderRestrictions { get; set; } |
|||
|
|||
public List<ClientClaimDto> Claims { get; set; } |
|||
|
|||
public List<ClientPropertyDto> Properties { get; set; } |
|||
public ClientDto() |
|||
{ |
|||
Claims = new List<ClientClaimDto>(); |
|||
Properties = new List<ClientPropertyDto>(); |
|||
AllowedScopes = new List<ClientScopeDto>(); |
|||
ClientSecrets = new List<ClientSecretDto>(); |
|||
RedirectUris = new List<ClientRedirectUriDto>(); |
|||
AllowedGrantTypes = new List<ClientGrantTypeDto>(); |
|||
AllowedCorsOrigins = new List<ClientCorsOriginDto>(); |
|||
PostLogoutRedirectUris = new List<ClientPostLogoutRedirectUriDto>(); |
|||
IdentityProviderRestrictions = new List<ClientIdPRestrictionDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientGetByIdInputDto |
|||
{ |
|||
[Required] |
|||
public Guid Id { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientGetByPagedInputDto : PagedAndSortedResultRequestDto |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientGrantTypeDto : EntityDto |
|||
{ |
|||
public string GrantType { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientIdPRestrictionDto : EntityDto |
|||
{ |
|||
public string Provider { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientPostLogoutRedirectUriDto : EntityDto |
|||
{ |
|||
public string PostLogoutRedirectUri { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientPropertyCreateDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientPropertyConsts.KeyMaxLength)] |
|||
public string Key { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientPropertyConsts.ValueMaxLength)] |
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientPropertyDto : EntityDto |
|||
{ |
|||
public string Key { get; set; } |
|||
|
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientPropertyGetByKeyDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientPropertyConsts.KeyMaxLength)] |
|||
public string Key { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientPropertyUpdateDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientPropertyConsts.KeyMaxLength)] |
|||
public string Key { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(ClientPropertyConsts.ValueMaxLength)] |
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientRedirectUriDto : EntityDto |
|||
{ |
|||
public string RedirectUri { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientScopeDto : EntityDto |
|||
{ |
|||
public string Scope { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientSecretCreateDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.TypeMaxLength)] |
|||
public string Type { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.ValueMaxLength)] |
|||
public string Value { get; set; } |
|||
|
|||
[StringLength(SecretConsts.DescriptionMaxLength)] |
|||
public string Description { get; set; } |
|||
|
|||
public DateTime? Expiration { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientSecretDto : SecretBaseDto |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientSecretGetByTypeDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.TypeMaxLength)] |
|||
public string Type { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientSecretUpdateDto |
|||
{ |
|||
[Required] |
|||
public Guid ClientId { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.TypeMaxLength)] |
|||
public string Type { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(SecretConsts.ValueMaxLength)] |
|||
public string Value { get; set; } |
|||
|
|||
[StringLength(SecretConsts.DescriptionMaxLength)] |
|||
public string Description { get; set; } |
|||
|
|||
public DateTime? Expiration { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientUpdateDto |
|||
{ |
|||
[Required] |
|||
public Guid Id { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(1000)] |
|||
public string ConcurrencyStamp { get; set; } |
|||
|
|||
[StringLength(ClientConsts.ClientIdMaxLength)] |
|||
public string ClientId { get; set; } |
|||
|
|||
[StringLength(ClientConsts.ClientNameMaxLength)] |
|||
public string ClientName { get; set; } |
|||
|
|||
[StringLength(ClientConsts.DescriptionMaxLength)] |
|||
public string Description { get; set; } |
|||
|
|||
[StringLength(ClientConsts.ClientUriMaxLength)] |
|||
public string ClientUri { get; set; } |
|||
|
|||
[StringLength(ClientConsts.LogoUriMaxLength)] |
|||
public string LogoUri { get; set; } |
|||
|
|||
public bool? Enabled { get; set; } |
|||
|
|||
[StringLength(ClientConsts.ProtocolTypeMaxLength)] |
|||
public string ProtocolType { get; set; } |
|||
|
|||
public bool? RequireClientSecret { get; set; } |
|||
|
|||
public bool? RequireConsent { get; set; } |
|||
|
|||
public bool? AllowRememberConsent { get; set; } |
|||
|
|||
public bool? AlwaysIncludeUserClaimsInIdToken { get; set; } |
|||
|
|||
public bool? RequirePkce { get; set; } |
|||
|
|||
public bool? AllowPlainTextPkce { get; set; } |
|||
|
|||
public bool? AllowAccessTokensViaBrowser { get; set; } |
|||
|
|||
[StringLength(ClientConsts.FrontChannelLogoutUriMaxLength)] |
|||
public string FrontChannelLogoutUri { get; set; } |
|||
|
|||
public bool? FrontChannelLogoutSessionRequired { get; set; } |
|||
|
|||
[StringLength(ClientConsts.BackChannelLogoutUriMaxLength)] |
|||
public string BackChannelLogoutUri { get; set; } |
|||
|
|||
public bool? BackChannelLogoutSessionRequired { get; set; } |
|||
|
|||
public bool? AllowOfflineAccess { get; set; } |
|||
|
|||
public int? IdentityTokenLifetime { get; set; } |
|||
|
|||
public int? AccessTokenLifetime { get; set; } |
|||
|
|||
public int? AuthorizationCodeLifetime { get; set; } |
|||
|
|||
public int? ConsentLifetime { get; set; } |
|||
|
|||
public int? AbsoluteRefreshTokenLifetime { get; set; } |
|||
|
|||
public int? SlidingRefreshTokenLifetime { get; set; } |
|||
|
|||
public int? RefreshTokenUsage { get; set; } |
|||
|
|||
public bool? UpdateAccessTokenClaimsOnRefresh { get; set; } |
|||
|
|||
public int? RefreshTokenExpiration { get; set; } |
|||
|
|||
public int? AccessTokenType { get; set; } |
|||
|
|||
public bool? EnableLocalLogin { get; set; } |
|||
|
|||
public bool? IncludeJwtId { get; set; } |
|||
|
|||
public bool? AlwaysSendClientClaims { get; set; } |
|||
|
|||
[StringLength(ClientConsts.ClientClaimsPrefixMaxLength)] |
|||
public string ClientClaimsPrefix { get; set; } |
|||
|
|||
[StringLength(ClientConsts.PairWiseSubjectSaltMaxLength)] |
|||
public string PairWiseSubjectSalt { get; set; } |
|||
|
|||
public int? UserSsoLifetime { get; set; } |
|||
|
|||
[StringLength(ClientConsts.UserCodeTypeMaxLength)] |
|||
public string UserCodeType { get; set; } |
|||
|
|||
public int? DeviceCodeLifetime { get; set; } |
|||
|
|||
public List<ClientScopeDto> AllowedScopes { get; set; } |
|||
|
|||
public List<ClientGrantTypeDto> AllowedGrantTypes { get; set; } |
|||
|
|||
public List<ClientCorsOriginDto> AllowedCorsOrigins { get; set; } |
|||
|
|||
public List<ClientRedirectUriDto> RedirectUris { get; set; } |
|||
|
|||
public List<ClientPostLogoutRedirectUriDto> PostLogoutRedirectUris { get; set; } |
|||
|
|||
public List<ClientIdPRestrictionDto> IdentityProviderRestrictions { get; set; } |
|||
public ClientUpdateDto() |
|||
{ |
|||
Enabled = true; |
|||
DeviceCodeLifetime = 300; |
|||
AllowedScopes = new List<ClientScopeDto>(); |
|||
RedirectUris = new List<ClientRedirectUriDto>(); |
|||
AllowedGrantTypes = new List<ClientGrantTypeDto>(); |
|||
AllowedCorsOrigins = new List<ClientCorsOriginDto>(); |
|||
PostLogoutRedirectUris = new List<ClientPostLogoutRedirectUriDto>(); |
|||
IdentityProviderRestrictions = new List<ClientIdPRestrictionDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public interface IClientAppService : IApplicationService |
|||
{ |
|||
Task<ClientDto> GetAsync(ClientGetByIdInputDto clientGetById); |
|||
|
|||
Task<PagedResultDto<ClientDto>> GetAsync(ClientGetByPagedInputDto clientGetByPaged); |
|||
|
|||
Task<ClientDto> CreateAsync(ClientCreateDto clientCreate); |
|||
|
|||
Task<ClientDto> UpdateAsync(ClientUpdateDto clientUpdate); |
|||
|
|||
Task DeleteAsync(ClientGetByIdInputDto clientGetByIdInput); |
|||
|
|||
Task<ClientClaimDto> AddClaimAsync(ClientClaimCreateDto clientClaimCreate); |
|||
|
|||
Task<ClientClaimDto> UpdateClaimAsync(ClientClaimUpdateDto clientClaimUpdate); |
|||
|
|||
Task DeleteClaimAsync(ClientClaimGetByKeyInputDto clientClaimGetByKey); |
|||
|
|||
Task<ClientPropertyDto> AddPropertyAsync(ClientPropertyCreateDto clientPropertyCreate); |
|||
|
|||
Task<ClientPropertyDto> UpdatePropertyAsync(ClientPropertyUpdateDto clientPropertyUpdate); |
|||
|
|||
Task DeletePropertyAsync(ClientPropertyGetByKeyDto clientPropertyGetByKey); |
|||
|
|||
Task<ClientSecretDto> AddSecretAsync(ClientSecretCreateDto clientSecretCreate); |
|||
|
|||
Task<ClientSecretDto> UpdateSecretAsync(ClientSecretUpdateDto clientSecretUpdate); |
|||
|
|||
Task DeleteSecretAsync(ClientSecretGetByTypeDto clientSecretGetByType); |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Permission:IdentityServer": "IdentityServer", |
|||
"Permissions:Create": "Create", |
|||
"Permissions:Update": "Update", |
|||
"Permissions:Enabled": "Enabled", |
|||
"Permissions:Disabled": "Disabled", |
|||
"Permissions:Delete": "Delete", |
|||
"Permissions:Clients": "Clients", |
|||
"Permissions:Clients:Claims": "Client claim", |
|||
"ClientIdExisted": "Client id: {0} already exists!", |
|||
"ClientClaimNotFound": "Client claim: {0} not found!", |
|||
"ClientSecretNotFound": "Client secret: {0} not found!", |
|||
"ClientPropertyNotFound": "Client property: {0} not found!" |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Permission:IdentityServer": "IdentityServer管理", |
|||
"Permissions:Create": "新增", |
|||
"Permissions:Update": "修改", |
|||
"Permissions:Enabled": "启用", |
|||
"Permissions:Disabled": "停用", |
|||
"Permissions:Delete": "删除", |
|||
"Permissions:Clients": "客户端管理", |
|||
"Permissions:Clients:Claims": "客户端声明", |
|||
"ClientIdExisted": "客户端标识: {0} 已经存在!", |
|||
"ClientClaimNotFound": "客户端声明: {0} 不存在!", |
|||
"ClientSecretNotFound": "客户端密钥: {0} 不存在!", |
|||
"ClientPropertyNotFound": "客户端属性: {0} 不存在!" |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
public abstract class SecretBaseDto : EntityDto |
|||
{ |
|||
public string Type { get; set; } |
|||
|
|||
public string Value { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public DateTime? Expiration { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
@ -0,0 +1,16 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.IdentityServer.Domain" Version="2.7.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.IdentityServer.Application.Contracts\LINGYUN.IdentityServer.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,13 @@ |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.IdentityServer.Localization; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
public abstract class AbpIdentityServerAppServiceBase : ApplicationService |
|||
{ |
|||
protected AbpIdentityServerAppServiceBase() |
|||
{ |
|||
LocalizationResource = typeof(AbpIdentityServerResource); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.IdentityServer; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpIdentityServerDomainModule), |
|||
typeof(AbpIdentityServerApplicationContractsModule), |
|||
typeof(AbpAutoMapperModule) |
|||
)] |
|||
public class AbpIdentityServerApplicationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.Configurators.Add(ctx => |
|||
{ |
|||
ctx.MapperConfiguration.AddProfile<AbpIdentityServerAutoMapperProfile>(); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using AutoMapper; |
|||
using LINGYUN.Abp.IdentityServer.Clients; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
public class AbpIdentityServerAutoMapperProfile : Profile |
|||
{ |
|||
public AbpIdentityServerAutoMapperProfile() |
|||
{ |
|||
CreateMap<ClientSecret, ClientSecretDto>(); |
|||
CreateMap<ClientClaim, ClientClaimDto>(); |
|||
CreateMap<ClientCorsOrigin, ClientCorsOriginDto>(); |
|||
CreateMap<ClientGrantType, ClientGrantTypeDto>(); |
|||
CreateMap<ClientIdPRestriction, ClientIdPRestrictionDto>(); |
|||
CreateMap<ClientPostLogoutRedirectUri, ClientPostLogoutRedirectUriDto>(); |
|||
CreateMap<ClientProperty, ClientPropertyDto>(); |
|||
CreateMap<ClientRedirectUri, ClientRedirectUriDto>(); |
|||
CreateMap<ClientScope, ClientScopeDto>(); |
|||
CreateMap<Client, ClientDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,310 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.IdentityServer.Clients; |
|||
using Volo.Abp.Security.Encryption; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.Clients |
|||
{ |
|||
public class ClientAppService : AbpIdentityServerAppServiceBase, IClientAppService |
|||
{ |
|||
private IStringEncryptionService _encryptionService; |
|||
protected IStringEncryptionService EncryptionService => LazyGetRequiredService(ref _encryptionService); |
|||
|
|||
protected IClientRepository ClientRepository { get; } |
|||
|
|||
public ClientAppService(IClientRepository clientRepository) |
|||
{ |
|||
ClientRepository = clientRepository; |
|||
} |
|||
|
|||
public virtual async Task<ClientClaimDto> AddClaimAsync(ClientClaimCreateDto clientClaimCreate) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientClaimCreate.ClientId); |
|||
|
|||
client.AddClaim(clientClaimCreate.Value, clientClaimCreate.Type); |
|||
var clientClaim = client.FindClaim(clientClaimCreate.Value, clientClaimCreate.Type); |
|||
|
|||
return ObjectMapper.Map<ClientClaim, ClientClaimDto>(clientClaim); |
|||
} |
|||
|
|||
public virtual async Task<ClientPropertyDto> AddPropertyAsync(ClientPropertyCreateDto clientPropertyCreate) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientPropertyCreate.ClientId); |
|||
|
|||
client.AddProperty(clientPropertyCreate.Key, clientPropertyCreate.Value); |
|||
var clientProperty = client.FindProperty(clientPropertyCreate.Key, clientPropertyCreate.Value); |
|||
|
|||
return ObjectMapper.Map<ClientProperty, ClientPropertyDto>(clientProperty); |
|||
} |
|||
|
|||
public virtual async Task<ClientSecretDto> AddSecretAsync(ClientSecretCreateDto clientSecretCreate) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientSecretCreate.ClientId); |
|||
|
|||
var clientSecretValue = EncryptionService.Encrypt(clientSecretCreate.Value); |
|||
|
|||
client.AddSecret(clientSecretValue, clientSecretCreate.Expiration, |
|||
clientSecretCreate.Type, clientSecretCreate.Description); |
|||
|
|||
var clientSecret = client.FindSecret(clientSecretValue, clientSecretCreate.Type); |
|||
|
|||
return ObjectMapper.Map<ClientSecret, ClientSecretDto>(clientSecret); |
|||
} |
|||
|
|||
public virtual async Task<ClientDto> CreateAsync(ClientCreateDto clientCreate) |
|||
{ |
|||
var clientIdExists = await ClientRepository.CheckClientIdExistAsync(clientCreate.ClientId); |
|||
if(clientIdExists) |
|||
{ |
|||
throw new UserFriendlyException(L[AbpIdentityServerErrorConsts.ClientIdExisted, clientCreate.ClientId]); |
|||
} |
|||
var client = new Client(GuidGenerator.Create(), clientCreate.ClientId); |
|||
client.ClientName = clientCreate.ClientName; |
|||
client.Description = clientCreate.Description; |
|||
foreach(var grantType in clientCreate.AllowedGrantTypes) |
|||
{ |
|||
client.AddGrantType(grantType.GrantType); |
|||
} |
|||
|
|||
client = await ClientRepository.InsertAsync(client, true); |
|||
|
|||
return ObjectMapper.Map<Client, ClientDto>(client); |
|||
} |
|||
|
|||
public virtual async Task DeleteAsync(ClientGetByIdInputDto clientGetByIdInput) |
|||
{ |
|||
await ClientRepository.DeleteAsync(clientGetByIdInput.Id); |
|||
} |
|||
|
|||
public virtual async Task DeleteClaimAsync(ClientClaimGetByKeyInputDto clientClaimGetByKey) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientClaimGetByKey.ClientId); |
|||
client.Claims.RemoveAll(claim => claim.Type.Equals(clientClaimGetByKey.Type)); |
|||
} |
|||
|
|||
public virtual async Task DeletePropertyAsync(ClientPropertyGetByKeyDto clientPropertyGetByKey) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientPropertyGetByKey.ClientId); |
|||
client.Properties.RemoveAll(property => property.Key.Equals(clientPropertyGetByKey.Key)); |
|||
} |
|||
|
|||
public virtual async Task DeleteSecretAsync(ClientSecretGetByTypeDto clientSecretGetByType) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientSecretGetByType.ClientId); |
|||
client.ClientSecrets.RemoveAll(secret => secret.Type.Equals(clientSecretGetByType.Type)); |
|||
} |
|||
|
|||
public virtual async Task<ClientDto> GetAsync(ClientGetByIdInputDto clientGetById) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientGetById.Id); |
|||
|
|||
return ObjectMapper.Map<Client, ClientDto>(client); |
|||
} |
|||
|
|||
public virtual async Task<PagedResultDto<ClientDto>> GetAsync(ClientGetByPagedInputDto clientGetByPaged) |
|||
{ |
|||
// Abp官方IdentityServer项目不支持Filter过滤...
|
|||
var clients = await ClientRepository.GetListAsync(clientGetByPaged.Sorting, |
|||
clientGetByPaged.SkipCount, clientGetByPaged.MaxResultCount, true); |
|||
|
|||
var clientCount = await ClientRepository.GetCountAsync(); |
|||
|
|||
return new PagedResultDto<ClientDto>(clientCount, |
|||
ObjectMapper.Map<List<Client>, List<ClientDto>>(clients)); |
|||
} |
|||
|
|||
public virtual async Task<ClientDto> UpdateAsync(ClientUpdateDto clientUpdate) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientUpdate.Id); |
|||
|
|||
#region Basic Property
|
|||
client.ConcurrencyStamp = clientUpdate.ConcurrencyStamp; |
|||
client.ClientId = clientUpdate.ClientId ?? client.ClientId; |
|||
client.ClientUri = clientUpdate.ClientUri ?? client.ClientUri; |
|||
client.ClientName = clientUpdate.ClientName ?? client.ClientName; |
|||
client.AbsoluteRefreshTokenLifetime = clientUpdate.AbsoluteRefreshTokenLifetime |
|||
?? client.AbsoluteRefreshTokenLifetime; |
|||
client.AccessTokenLifetime = clientUpdate.AccessTokenLifetime |
|||
?? client.AccessTokenLifetime; |
|||
client.AccessTokenType = clientUpdate.AccessTokenType ?? client.AccessTokenType; |
|||
client.AllowAccessTokensViaBrowser = clientUpdate.AllowAccessTokensViaBrowser |
|||
?? client.AllowAccessTokensViaBrowser; |
|||
client.AllowOfflineAccess = clientUpdate.AllowOfflineAccess |
|||
?? client.AllowOfflineAccess; |
|||
client.AllowPlainTextPkce = clientUpdate.AllowPlainTextPkce ?? client.AllowPlainTextPkce; |
|||
client.AllowRememberConsent = clientUpdate.AllowRememberConsent ?? client.AllowRememberConsent; |
|||
client.AlwaysIncludeUserClaimsInIdToken = clientUpdate.AlwaysIncludeUserClaimsInIdToken |
|||
?? client.AlwaysIncludeUserClaimsInIdToken; |
|||
client.AlwaysSendClientClaims = clientUpdate.AlwaysSendClientClaims ?? client.AlwaysSendClientClaims; |
|||
client.AuthorizationCodeLifetime = clientUpdate.AuthorizationCodeLifetime |
|||
?? client.AuthorizationCodeLifetime; |
|||
client.BackChannelLogoutSessionRequired = clientUpdate.BackChannelLogoutSessionRequired |
|||
?? client.BackChannelLogoutSessionRequired; |
|||
|
|||
client.BackChannelLogoutUri = clientUpdate.BackChannelLogoutUri |
|||
?? client.BackChannelLogoutUri; |
|||
client.ClientClaimsPrefix = clientUpdate.ClientClaimsPrefix ?? client.ClientClaimsPrefix; |
|||
client.ConsentLifetime = clientUpdate.ConsentLifetime ?? client.ConsentLifetime; |
|||
client.Description = clientUpdate.Description ?? client.Description; |
|||
client.DeviceCodeLifetime = clientUpdate.DeviceCodeLifetime ?? client.DeviceCodeLifetime; |
|||
client.Enabled = clientUpdate.Enabled ?? client.Enabled; |
|||
client.EnableLocalLogin = clientUpdate.EnableLocalLogin ?? client.EnableLocalLogin; |
|||
client.FrontChannelLogoutSessionRequired = clientUpdate.FrontChannelLogoutSessionRequired |
|||
?? client.FrontChannelLogoutSessionRequired; |
|||
client.FrontChannelLogoutUri = clientUpdate.FrontChannelLogoutUri ?? client.FrontChannelLogoutUri; |
|||
|
|||
client.IdentityTokenLifetime = clientUpdate.IdentityTokenLifetime ?? client.IdentityTokenLifetime; |
|||
client.IncludeJwtId = clientUpdate.IncludeJwtId ?? client.IncludeJwtId; |
|||
client.LogoUri = clientUpdate.LogoUri ?? client.LogoUri; |
|||
client.PairWiseSubjectSalt = clientUpdate.PairWiseSubjectSalt ?? client.PairWiseSubjectSalt; |
|||
client.ProtocolType = clientUpdate.ProtocolType ?? client.ProtocolType; |
|||
client.RefreshTokenExpiration = clientUpdate.RefreshTokenExpiration ?? client.RefreshTokenExpiration; |
|||
client.RefreshTokenUsage = clientUpdate.RefreshTokenUsage ?? client.RefreshTokenUsage; |
|||
client.RequireClientSecret = clientUpdate.RequireClientSecret ?? client.RequireClientSecret; |
|||
client.RequireConsent = clientUpdate.RequireConsent ?? client.RequireConsent; |
|||
|
|||
client.RequirePkce = clientUpdate.RequirePkce ?? client.RequirePkce; |
|||
client.SlidingRefreshTokenLifetime = clientUpdate.SlidingRefreshTokenLifetime |
|||
?? client.SlidingRefreshTokenLifetime; |
|||
client.UpdateAccessTokenClaimsOnRefresh = clientUpdate.UpdateAccessTokenClaimsOnRefresh |
|||
?? client.UpdateAccessTokenClaimsOnRefresh; |
|||
|
|||
client.UserCodeType = clientUpdate.UserCodeType ?? client.UserCodeType; |
|||
client.UserSsoLifetime = clientUpdate.UserSsoLifetime ?? client.UserSsoLifetime; |
|||
#endregion
|
|||
|
|||
#region AllowScope
|
|||
|
|||
foreach(var scope in clientUpdate.AllowedScopes) |
|||
{ |
|||
var clientScope = client.FindScope(scope.Scope); |
|||
if (clientScope == null) |
|||
{ |
|||
client.AddScope(scope.Scope); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region RedirectUris
|
|||
|
|||
foreach(var redirect in clientUpdate.RedirectUris) |
|||
{ |
|||
var clientRedirect = client.FindRedirectUri(redirect.RedirectUri); |
|||
if(clientRedirect == null) |
|||
{ |
|||
client.AddRedirectUri(redirect.RedirectUri); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region AllowedGrantTypes
|
|||
|
|||
foreach (var grantType in clientUpdate.AllowedGrantTypes) |
|||
{ |
|||
var clientGrantType = client.FindGrantType(grantType.GrantType); |
|||
if (clientGrantType == null) |
|||
{ |
|||
client.AddGrantType(grantType.GrantType); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region AllowedCorsOrigins
|
|||
|
|||
foreach (var corgOrigin in clientUpdate.AllowedCorsOrigins) |
|||
{ |
|||
var clientCorsOrigin = client.FindCorsOrigin(corgOrigin.Origin); |
|||
if (clientCorsOrigin == null) |
|||
{ |
|||
client.AddCorsOrigin(corgOrigin.Origin); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region PostLogoutRedirectUris
|
|||
|
|||
foreach (var logoutRedirect in clientUpdate.PostLogoutRedirectUris) |
|||
{ |
|||
var clientLogoutRedirect = client.FindPostLogoutRedirectUri(logoutRedirect.PostLogoutRedirectUri); |
|||
if (clientLogoutRedirect == null) |
|||
{ |
|||
client.AddPostLogoutRedirectUri(logoutRedirect.PostLogoutRedirectUri); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region IdentityProviderRestrictions
|
|||
|
|||
foreach (var provider in clientUpdate.IdentityProviderRestrictions) |
|||
{ |
|||
var clientIdentityProvider = client.FindIdentityProviderRestriction(provider.Provider); |
|||
if (clientIdentityProvider == null) |
|||
{ |
|||
client.AddIdentityProviderRestriction(provider.Provider); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
client = await ClientRepository.UpdateAsync(client, true); |
|||
|
|||
return ObjectMapper.Map<Client, ClientDto>(client); |
|||
} |
|||
|
|||
public virtual async Task<ClientClaimDto> UpdateClaimAsync(ClientClaimUpdateDto clientClaimUpdate) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientClaimUpdate.ClientId); |
|||
|
|||
var clientClaim = client.Claims.FirstOrDefault(claim => claim.Type.Equals(clientClaimUpdate.Type)); |
|||
if(clientClaim == null) |
|||
{ |
|||
throw new UserFriendlyException(L[AbpIdentityServerErrorConsts.ClientClaimNotFound, clientClaimUpdate.Type]); |
|||
} |
|||
clientClaim.Value = clientClaimUpdate.Value; |
|||
|
|||
return ObjectMapper.Map<ClientClaim, ClientClaimDto>(clientClaim); |
|||
} |
|||
|
|||
public virtual async Task<ClientPropertyDto> UpdatePropertyAsync(ClientPropertyUpdateDto clientPropertyUpdate) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientPropertyUpdate.ClientId); |
|||
|
|||
var clientProperty = client.Properties |
|||
.FirstOrDefault(property => property.Key.Equals(clientPropertyUpdate.Key)); |
|||
if (clientProperty == null) |
|||
{ |
|||
throw new UserFriendlyException( |
|||
L[AbpIdentityServerErrorConsts.ClientPropertyNotFound, clientPropertyUpdate.Key]); |
|||
} |
|||
clientProperty.Value = clientPropertyUpdate.Value; |
|||
|
|||
return ObjectMapper.Map<ClientProperty, ClientPropertyDto>(clientProperty); |
|||
} |
|||
|
|||
public virtual async Task<ClientSecretDto> UpdateSecretAsync(ClientSecretUpdateDto clientSecretUpdate) |
|||
{ |
|||
var client = await ClientRepository.GetAsync(clientSecretUpdate.ClientId); |
|||
|
|||
var clientSecret = client.ClientSecrets |
|||
.FirstOrDefault(secret => secret.Type.Equals(clientSecretUpdate.Type)); |
|||
if (clientSecret == null) |
|||
{ |
|||
throw new UserFriendlyException( |
|||
L[AbpIdentityServerErrorConsts.ClientSecretNotFound, clientSecretUpdate.Type]); |
|||
} |
|||
clientSecret.Value = EncryptionService.Encrypt(clientSecretUpdate.Value); |
|||
|
|||
return ObjectMapper.Map<ClientSecret, ClientSecretDto>(clientSecret); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
@ -0,0 +1,16 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="2.7.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.IdentityServer.Application.Contracts\LINGYUN.IdentityServer.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,21 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpIdentityServerApplicationContractsModule), |
|||
typeof(AbpAspNetCoreMvcModule) |
|||
)] |
|||
public class AbpIdentityServerHttpApiModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpIdentityServerHttpApiModule).Assembly); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,116 @@ |
|||
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.Clients |
|||
{ |
|||
[RemoteService(Name = AbpIdentityServerConsts.RemoteServiceName)] |
|||
[Area("IdentityServer")] |
|||
[Route("api/IdentityServer/Clients")] |
|||
public class ClientController : AbpController, IClientAppService |
|||
{ |
|||
protected IClientAppService ClientAppService { get; } |
|||
public ClientController(IClientAppService clientAppService) |
|||
{ |
|||
ClientAppService = clientAppService; |
|||
} |
|||
|
|||
[HttpPost] |
|||
public virtual async Task<ClientDto> CreateAsync(ClientCreateDto clientCreate) |
|||
{ |
|||
return await ClientAppService.CreateAsync(clientCreate); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{Id}")] |
|||
public virtual async Task DeleteAsync(ClientGetByIdInputDto clientGetByIdInput) |
|||
{ |
|||
await ClientAppService.DeleteAsync(clientGetByIdInput); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{Id}")] |
|||
public virtual async Task<ClientDto> GetAsync(ClientGetByIdInputDto clientGetById) |
|||
{ |
|||
return await ClientAppService.GetAsync(clientGetById); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public virtual async Task<PagedResultDto<ClientDto>> GetAsync(ClientGetByPagedInputDto clientGetByPaged) |
|||
{ |
|||
return await ClientAppService.GetAsync(clientGetByPaged); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{Id}")] |
|||
public virtual async Task<ClientDto> UpdateAsync(ClientUpdateDto clientUpdate) |
|||
{ |
|||
return await ClientAppService.UpdateAsync(clientUpdate); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("Claims")] |
|||
public virtual async Task<ClientClaimDto> AddClaimAsync(ClientClaimCreateDto clientClaimCreate) |
|||
{ |
|||
return await ClientAppService.AddClaimAsync(clientClaimCreate); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("Claims")] |
|||
public virtual async Task<ClientClaimDto> UpdateClaimAsync(ClientClaimUpdateDto clientClaimUpdate) |
|||
{ |
|||
return await ClientAppService.UpdateClaimAsync(clientClaimUpdate); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("Claims")] |
|||
public virtual async Task DeleteClaimAsync(ClientClaimGetByKeyInputDto clientClaimGetByKey) |
|||
{ |
|||
await ClientAppService.DeleteClaimAsync(clientClaimGetByKey); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("Properties")] |
|||
public virtual async Task<ClientPropertyDto> AddPropertyAsync(ClientPropertyCreateDto clientPropertyCreate) |
|||
{ |
|||
return await ClientAppService.AddPropertyAsync(clientPropertyCreate); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("Properties")] |
|||
public virtual async Task<ClientPropertyDto> UpdatePropertyAsync(ClientPropertyUpdateDto clientPropertyUpdate) |
|||
{ |
|||
return await ClientAppService.UpdatePropertyAsync(clientPropertyUpdate); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("Properties")] |
|||
public virtual async Task DeletePropertyAsync(ClientPropertyGetByKeyDto clientPropertyGetByKey) |
|||
{ |
|||
await ClientAppService.DeletePropertyAsync(clientPropertyGetByKey); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("Secrets")] |
|||
public virtual async Task<ClientSecretDto> AddSecretAsync(ClientSecretCreateDto clientSecretCreate) |
|||
{ |
|||
return await ClientAppService.AddSecretAsync(clientSecretCreate); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("Secrets")] |
|||
public virtual async Task DeleteSecretAsync(ClientSecretGetByTypeDto clientSecretGetByType) |
|||
{ |
|||
await ClientAppService.DeleteSecretAsync(clientSecretGetByType); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("Secrets")] |
|||
public virtual async Task<ClientSecretDto> UpdateSecretAsync(ClientSecretUpdateDto clientSecretUpdate) |
|||
{ |
|||
return await ClientAppService.UpdateSecretAsync(clientSecretUpdate); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
@ -0,0 +1,7 @@ |
|||
bin |
|||
obj |
|||
Logs |
|||
appsettings.*.json |
|||
node_modules |
|||
yarn.lock |
|||
package-lock.json |
|||
Binary file not shown.
@ -0,0 +1,133 @@ |
|||
|
|||
import ApiService from './serviceBase' |
|||
import { FullAuditedEntityDto, PagedAndSortedResultRequestDto, PagedResultDto } from './types' |
|||
|
|||
const serviceUrl = process.env.VUE_APP_BASE_API |
|||
|
|||
export default class ClientService { |
|||
public static getClientById(id: string) { |
|||
let _url = '/api/IdentityServer/Clients/' |
|||
_url += id |
|||
return ApiService.Get<Client>(_url, serviceUrl) |
|||
} |
|||
|
|||
public static getClients(payload: ClientGetByPaged) { |
|||
let _url = '/api/IdentityServer/Clients' |
|||
_url += '?sorting=' + payload.sorting |
|||
_url += '&skipCount=' + payload.skipCount |
|||
_url += '&maxResultCount=' + payload.maxResultCount |
|||
return ApiService.Get<PagedResultDto<Client>>(_url, serviceUrl) |
|||
} |
|||
} |
|||
|
|||
export class ClientGetById { |
|||
id!: string |
|||
} |
|||
|
|||
export class ClientGetByPaged extends PagedAndSortedResultRequestDto { |
|||
filter?: string |
|||
} |
|||
|
|||
export class ClientSecret { |
|||
type!: string |
|||
value!: string |
|||
description: string | undefined |
|||
expiration: Date | undefined |
|||
} |
|||
|
|||
export class ClientRedirectUri { |
|||
redirectUri!: string |
|||
} |
|||
|
|||
export class ClientClaim { |
|||
type!: string |
|||
value!: string |
|||
} |
|||
|
|||
export class ClientCorsOrigin { |
|||
origin!: string |
|||
} |
|||
|
|||
export class ClientGrantType { |
|||
grantType!: string |
|||
} |
|||
|
|||
export class ClientIdPRestriction { |
|||
provider!: string |
|||
} |
|||
|
|||
export class ClientPostLogoutRedirectUri { |
|||
postLogoutRedirectUri!: string |
|||
} |
|||
|
|||
export class ClientProperty { |
|||
key!: string |
|||
value!: string |
|||
} |
|||
|
|||
export class ClientScope { |
|||
scope!: string |
|||
} |
|||
|
|||
export class Client extends FullAuditedEntityDto { |
|||
id!: string |
|||
clientId!: string |
|||
clientName!: string |
|||
description?: string |
|||
clientUri?: string |
|||
logoUri?: string |
|||
enabled!: boolean |
|||
protocolType!: string |
|||
requireClientSecret!: boolean |
|||
requireConsent!: boolean |
|||
allowRememberConsent!: boolean |
|||
alwaysIncludeUserClaimsInIdToken!: boolean |
|||
requirePkce!: boolean |
|||
allowPlainTextPkce!: boolean |
|||
allowAccessTokensViaBrowser!: boolean |
|||
frontChannelLogoutUri?: string |
|||
frontChannelLogoutSessionRequired!: boolean |
|||
backChannelLogoutUri?: string |
|||
backChannelLogoutSessionRequired!: boolean |
|||
allowOfflineAccess!: boolean |
|||
identityTokenLifetime?: number |
|||
accessTokenLifetime?: number |
|||
authorizationCodeLifetime?: number |
|||
consentLifetime?: number |
|||
absoluteRefreshTokenLifetime?: number |
|||
slidingRefreshTokenLifetime?: number |
|||
refreshTokenUsage?: number |
|||
updateAccessTokenClaimsOnRefresh!: boolean |
|||
refreshTokenExpiration?: number |
|||
accessTokenType?: number |
|||
enableLocalLogin!: boolean |
|||
includeJwtId!: boolean |
|||
alwaysSendClientClaims!: boolean |
|||
clientClaimsPrefix?: string |
|||
pairWiseSubjectSalt?: string |
|||
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>() |
|||
} |
|||
} |
|||
@ -0,0 +1,203 @@ |
|||
<template> |
|||
<div style="width:auto; height:auto;"> |
|||
<div |
|||
class="el-input-tag input-tag-wrapper" |
|||
:class="[size ? 'el-input-tag--' + size : '']" |
|||
@click="foucusTagInput" |
|||
> |
|||
<span v-if="data.length>0"> |
|||
<el-tag |
|||
v-for="(tag, idx) in data" |
|||
:key="idx" |
|||
:size="size" |
|||
:closable="!readOnly" |
|||
:disable-transitions="false" |
|||
@close="remove(idx)" |
|||
> |
|||
{{ tag[label] }} |
|||
</el-tag> |
|||
</span> |
|||
<input |
|||
v-if="!readOnly" |
|||
v-model="newTag" |
|||
:size="size" |
|||
:class="[size ? 'tag-input--' + size : 'tag-input']" |
|||
@keydown="addNew" |
|||
@blur="addNew" |
|||
> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { Component, Vue, Prop } from 'vue-property-decorator' |
|||
import { AppModule } from '@/store/modules/app' |
|||
|
|||
/* eslint-disable */ |
|||
const regExpValidate: { [key: string]: RegExp } = { |
|||
url: /^(?=^.{3,255}$)((http|https|ftp)?:\/\/)?(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/)?(?:\/(.+)\/?$)?(\/\w+\.\w+)*([\?&]\w+=\w*|[\u4e00-\u9fa5]+)*$/ |
|||
} |
|||
/* eslint-enable */ |
|||
|
|||
@Component({ |
|||
name: 'ElInputTagEx' |
|||
}) |
|||
export default class extends Vue { |
|||
@Prop({ default: () => new Array<any>() }) |
|||
private data!: any[] |
|||
|
|||
@Prop({ default: 'key' }) |
|||
private label!: string |
|||
|
|||
@Prop({ default: () => [13, 188, 9] }) |
|||
private addTagOnKeys!: Array<number> |
|||
|
|||
@Prop({ default: false }) |
|||
private readOnly!: boolean |
|||
|
|||
@Prop({ default: 'none' }) |
|||
private validate!: string |
|||
// 'none' | 'email' | 'phone' | 'ipaddress' | 'ip:port' | 'key:value' | 'url' |
|||
|
|||
private size = AppModule.size |
|||
public newTag: string |
|||
|
|||
constructor() { |
|||
super() |
|||
this.newTag = '' |
|||
} |
|||
|
|||
private foucusTagInput() { |
|||
const tagInputClass = this.size ? '.tag-input--' + this.size : '.tag-input' |
|||
if (this.readOnly || !this.$el.querySelector(tagInputClass)) { |
|||
|
|||
} else { |
|||
const tagInput = this.$el.querySelector(tagInputClass) as any |
|||
tagInput.focus() |
|||
} |
|||
} |
|||
|
|||
private addNew(e: any) { |
|||
if (e && (!this.addTagOnKeys.includes(e.keyCode)) && (e.type !== 'blur')) { |
|||
return false |
|||
} |
|||
if (e) { |
|||
e.stopPropagation() |
|||
e.preventDefault() |
|||
} |
|||
let addSuucess = false |
|||
if (this.newTag.includes(',')) { |
|||
this.newTag.split(',').forEach(item => { |
|||
if (this.addTag(item.trim())) { |
|||
addSuucess = true |
|||
} |
|||
}) |
|||
} else { |
|||
if (this.addTag(this.newTag.trim())) { |
|||
addSuucess = true |
|||
} |
|||
} |
|||
if (addSuucess) { |
|||
this.tagChange() |
|||
this.newTag = '' |
|||
} |
|||
} |
|||
|
|||
private addTag(tag: string) { |
|||
if (!tag) { |
|||
return false |
|||
} |
|||
tag = tag.trim() |
|||
if (!regExpValidate[this.validate].test(tag)) { |
|||
// validate |
|||
return false |
|||
} |
|||
if (!this.data.every(d => d[this.label] === tag)) { |
|||
this.data.push({ [this.label]: tag }) |
|||
return true |
|||
} |
|||
return false |
|||
} |
|||
|
|||
private remove(index: number) { |
|||
this.data.splice(index, 1) |
|||
this.tagChange() |
|||
} |
|||
|
|||
private removeLastTa() { |
|||
if (this.newTag) { |
|||
return false |
|||
} |
|||
this.data.pop() |
|||
this.tagChange() |
|||
} |
|||
|
|||
private tagChange() { |
|||
this.$emit('input', this.data) |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.input-tag-wrapper { |
|||
position: relative; |
|||
font-size: 14px; |
|||
background-color: #fff; |
|||
background-image: none; |
|||
border-radius: 4px; |
|||
border: 1px solid #dcdfe6; |
|||
box-sizing: border-box; |
|||
color: #606266; |
|||
display: inline-block; |
|||
outline: none; |
|||
padding: 0 5px 0 5px; |
|||
transition: border-color .2s cubic-bezier(.645,.045,.355,1); |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
.el-tag { |
|||
margin-right: 4px; |
|||
margin-top: 4px; |
|||
} |
|||
|
|||
.tag-input--default { |
|||
background: transparent; |
|||
border: 0; |
|||
font-size: 14px; |
|||
height: 38px; |
|||
outline: none; |
|||
padding-left: 0; |
|||
width: 150px; |
|||
} |
|||
|
|||
.tag-input--mini{ |
|||
background: transparent; |
|||
border: 0; |
|||
font-size: 14px; |
|||
height: 26px; |
|||
outline: none; |
|||
padding-left: 0; |
|||
width: 150px; |
|||
} |
|||
|
|||
.tag-input--small{ |
|||
background: transparent; |
|||
border: 0; |
|||
font-size: 14px; |
|||
height: 30px; |
|||
outline: none; |
|||
padding-left: 0; |
|||
width: 150px; |
|||
} |
|||
|
|||
.tag-input--medium{ |
|||
background: transparent; |
|||
border: 0; |
|||
font-size: 14px; |
|||
height: 34px; |
|||
outline: none; |
|||
padding-left: 0; |
|||
width: 150px; |
|||
} |
|||
</style> |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue