From 5085fc54a4849bbf8976772b5311029a6260d3c5 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 9 Oct 2026 23:17:51 +0330 Subject: [PATCH] last ... --- .../ApplicationsController+ApiKey.cs | 10 +-- .../ApplicationsController+ApiKeyUsage.cs | 12 ++-- .../ApplicationsController+Application.cs | 12 ++-- .../ApplicationsController+Custom.cs | 65 ++++++++++++++++-- Interfaces/IXApplicationProvider.cs | 17 +++++ .../XApplicationProvider+ApiKey.cs | 9 ++- .../XApplicationProvider+Custom.cs | 66 ++++++++++++++++++- Startup.cs | 5 +- 8 files changed, 168 insertions(+), 28 deletions(-) diff --git a/Controllers/Applications/ApplicationsController+ApiKey.cs b/Controllers/Applications/ApplicationsController+ApiKey.cs index 8c70a74..ed90f59 100644 --- a/Controllers/Applications/ApplicationsController+ApiKey.cs +++ b/Controllers/Applications/ApplicationsController+ApiKey.cs @@ -27,8 +27,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpGet("ApiKeys/{id}")] [Authorize(LocalApi.PolicyName)] - [HttpGet("Applications/ApiKeys/{id}")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> GetApiKey( [FromRoute] Guid id, @@ -75,8 +75,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpDelete("ApiKeys/{id}")] [Authorize(LocalApi.PolicyName)] - [HttpDelete("Applications/ApiKeys/{id}")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> RemoveApiKey( [FromRoute] Guid id, @@ -123,8 +123,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpPut("ApiKeys/{id}")] [Authorize(LocalApi.PolicyName)] - [HttpPut("Applications/ApiKeys/{id}")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> UpdateApiKey( [FromRoute] Guid id, @@ -173,8 +173,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpGet("ApiKeys")] [Authorize(LocalApi.PolicyName)] - [HttpGet("Applications/ApiKeys")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task>> GetAllApiKeys( CancellationToken cancellationToken = default @@ -213,8 +213,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpGet("ApiKeys/Query")] [Authorize(LocalApi.PolicyName)] - [HttpGet("Applications/ApiKeys/Query")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task>> QueryApiKeys( [FromRoute] XQuery query, diff --git a/Controllers/Applications/ApplicationsController+ApiKeyUsage.cs b/Controllers/Applications/ApplicationsController+ApiKeyUsage.cs index dd16669..16462a5 100644 --- a/Controllers/Applications/ApplicationsController+ApiKeyUsage.cs +++ b/Controllers/Applications/ApplicationsController+ApiKeyUsage.cs @@ -27,8 +27,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpPost("ApiKeys/Usages")] [Authorize(LocalApi.PolicyName)] - [HttpPost("Applications/ApiKeys/Usages")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> AddApiKeyUsage( [FromBody] XApiKeyUsageDto item, @@ -74,8 +74,8 @@ namespace xIds.Controllers /// [RequireXPowered] [Authorize(LocalApi.PolicyName)] + [HttpGet("ApiKeys/Usages/{id}")] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpGet("Applications/ApiKeys/Usages/{id}")] public async Task> GetApiKeyUsage( [FromRoute] long id, CancellationToken cancellationToken = default @@ -122,8 +122,8 @@ namespace xIds.Controllers /// [RequireXPowered] [Authorize(LocalApi.PolicyName)] + [HttpDelete("ApiKeys/Usages/{id}")] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpDelete("Applications/ApiKeys/Usages/{id}")] public async Task> RemoveApiKeyUsage( [FromRoute] long id, CancellationToken cancellationToken = default @@ -170,8 +170,8 @@ namespace xIds.Controllers /// [RequireXPowered] [Authorize(LocalApi.PolicyName)] + [HttpPut("ApiKeys/Usages/{id}")] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpPut("Applications/ApiKeys/Usages/{id}")] public async Task> UpdateApiKeyUsage( [FromRoute] long id, [FromBody] XApiKeyUsageDto item, @@ -219,8 +219,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpGet("ApiKeys/Usages")] [Authorize(LocalApi.PolicyName)] - [HttpGet("Applications/ApiKeys/Usages")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task>> GetAllApiKeyUsages( CancellationToken cancellationToken = default @@ -260,7 +260,7 @@ namespace xIds.Controllers /// [RequireXPowered] [Authorize(LocalApi.PolicyName)] - [HttpGet("Applications/ApiKeys/Usages/Query")] + [HttpGet("ApiKeys/Usages/Query")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task>> QueryApiKeyUsages( [FromRoute] XQuery query, diff --git a/Controllers/Applications/ApplicationsController+Application.cs b/Controllers/Applications/ApplicationsController+Application.cs index 3f2c525..82cbce0 100644 --- a/Controllers/Applications/ApplicationsController+Application.cs +++ b/Controllers/Applications/ApplicationsController+Application.cs @@ -36,8 +36,8 @@ namespace xIds.Controllers /// /// /// + [HttpPost("")] [RequireXPowered] - [HttpPost("Applications")] [Authorize(LocalApi.PolicyName)] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> CreateApplication( @@ -93,8 +93,8 @@ namespace xIds.Controllers /// /// /// + [HttpPut("")] [RequireXPowered] - [HttpPut("Applications")] [Authorize(LocalApi.PolicyName)] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> UpdateApplication( @@ -141,8 +141,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpDelete("{id}")] [Authorize(LocalApi.PolicyName)] - [HttpDelete("Applications/{id}")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> RemoveApplication( [FromRoute] int id, @@ -188,8 +188,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpGet("{id}")] [Authorize(LocalApi.PolicyName)] - [HttpGet("Applications/{id}")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> GetApplication( [FromRoute] int id, @@ -234,9 +234,9 @@ namespace xIds.Controllers /// /// /// + [HttpGet("")] [RequireXPowered] [Authorize(LocalApi.PolicyName)] - [HttpGet("Applications")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task>> GetAllApplications( CancellationToken cancellationToken = default @@ -275,8 +275,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpGet("Query")] [Authorize(LocalApi.PolicyName)] - [HttpGet("Applications/Query")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task>> QueryApplications( [FromRoute] XQuery query, diff --git a/Controllers/Applications/ApplicationsController+Custom.cs b/Controllers/Applications/ApplicationsController+Custom.cs index 88506e0..b02fa7e 100644 --- a/Controllers/Applications/ApplicationsController+Custom.cs +++ b/Controllers/Applications/ApplicationsController+Custom.cs @@ -18,6 +18,57 @@ namespace xIds.Controllers { public partial class ApplicationsController { + /// + /// Show Api Key ... + /// + /// + /// + /// + /// + [RequireXPowered] + [Authorize(LocalApi.PolicyName)] + [Authorize(Policy = XPolicies.EnabledUser)] + [HttpGet("{applicationId}/ApiKeys/{apiKeyId}/Show")] + public async Task> ShowApiKey( + [FromRoute] Guid apiKeyId, + [FromRoute] int applicationId, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if ( + apiKeyId.IsDefaultGuid() || + !applicationId.IsValidIntId()) + { + XException.InvalidArgs.Throw(); + } + + // + var userInfo = await GetUserInfo(); + + // + var result = await provider.ShowApiKey( + userInfo: userInfo, + apiKeyId: apiKeyId, + applicationId: applicationId, + cancellationToken: cancellationToken + ); + + // + return Ok(result); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + /// /// Create Api Key ... /// @@ -28,7 +79,7 @@ namespace xIds.Controllers [RequireXPowered] [Authorize(LocalApi.PolicyName)] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpPost("Applications/{applicationId}/ApiKeys/Create")] + [HttpPost("{applicationId}/ApiKeys/Create")] public async Task> CreateApiKey( [FromRoute] int applicationId, [FromBody] XCreateApiKeyRequest request, @@ -116,7 +167,7 @@ namespace xIds.Controllers [RequireXPowered] [Authorize(LocalApi.PolicyName)] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpDelete("Applications/{applicationId}/ApiKeys/{apiKeyId}")] + [HttpDelete("{applicationId}/ApiKeys/{apiKeyId}")] public async Task> RemoveApiKey( [FromRoute] Guid apiKeyId, [FromRoute] int applicationId, @@ -181,7 +232,7 @@ namespace xIds.Controllers [RequireXPowered] [Authorize(LocalApi.PolicyName)] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpPost("Applications/{applicationId}/ApiKeys/{apiKeyId}")] + [HttpPost("{applicationId}/ApiKeys/{apiKeyId}")] public async Task> RotateApiKey( [FromRoute] Guid apiKeyId, [FromRoute] int applicationId, @@ -262,7 +313,7 @@ namespace xIds.Controllers [RequireXPowered] [Authorize(LocalApi.PolicyName)] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpPost("Applications/{applicationId}/ApiKeys/{apiKeyId}/Revoke")] + [HttpPost("{applicationId}/ApiKeys/{apiKeyId}/Revoke")] public async Task> RevokeApiKey( [FromRoute] Guid apiKeyId, [FromRoute] int applicationId, @@ -323,8 +374,8 @@ namespace xIds.Controllers /// [RequireXPowered] [Authorize(LocalApi.PolicyName)] + [HttpGet("{applicationId}/ApiKeys")] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpPost("Applications/{applicationId}/ApiKeys")] public async Task>> GetApiKeys( [FromRoute] int applicationId, CancellationToken cancellationToken = default @@ -384,7 +435,7 @@ namespace xIds.Controllers [RequireXPowered] [Authorize(LocalApi.PolicyName)] [Authorize(Policy = XPolicies.EnabledUser)] - [HttpPost("Applications/{applicationId}/ApiKeys/{apiKeyId}/Usages")] + [HttpGet("{applicationId}/ApiKeys/{apiKeyId}/Usages")] public async Task>> GetApiKeyUsages( [FromRoute] Guid apiKeyId, [FromRoute] int applicationId, @@ -460,8 +511,8 @@ namespace xIds.Controllers /// /// [RequireXPowered] + [HttpPost("ApiKeys/Validate")] [Authorize(LocalApi.PolicyName)] - [HttpPost("Applications/ApiKeys/Validate")] public async Task> ValidateApiKey( [FromBody] XApiKeyValidationRequest request, CancellationToken cancellationToken = default diff --git a/Interfaces/IXApplicationProvider.cs b/Interfaces/IXApplicationProvider.cs index 2dbf7d3..d20fdcc 100644 --- a/Interfaces/IXApplicationProvider.cs +++ b/Interfaces/IXApplicationProvider.cs @@ -176,11 +176,13 @@ namespace xIds.Interfaces /// Add Specified Item ... /// /// + /// /// /// /// Task AddApiKeyAsync( XApiKeyDto item, + string apiKey = null, XUserClaimsInfoDto userInfo = null, CancellationToken cancellationToken = default ); @@ -480,6 +482,21 @@ namespace xIds.Interfaces // #region Custom Actions ... + /// + /// Show Specifid Api Key ... + /// + /// + /// + /// + /// + /// + Task ShowApiKey( + Guid apiKeyId, + int applicationId, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ); + /// /// Generate a New ApiKey and Add It to DB ... /// diff --git a/Providers/XApplicationProvider/XApplicationProvider+ApiKey.cs b/Providers/XApplicationProvider/XApplicationProvider+ApiKey.cs index becf3f9..0bc68b0 100644 --- a/Providers/XApplicationProvider/XApplicationProvider+ApiKey.cs +++ b/Providers/XApplicationProvider/XApplicationProvider+ApiKey.cs @@ -26,11 +26,13 @@ namespace xIds.Providers /// Add Specified Item ... /// /// + /// /// /// /// public async Task AddApiKeyAsync( XApiKeyDto item, + string apiKey = null, XUserClaimsInfoDto userInfo = null, CancellationToken cancellationToken = default ) @@ -85,7 +87,12 @@ namespace xIds.Providers item.CreatedOn = DateTime.UtcNow; // - var entity = item.MapConvert(); + var entity = item.MapConvert(mapperConfigurationExp); + if (!apiKey.IsNullOrEmpty()) + { + entity.Key = apiKey; + } + var entry = await dbContext.ApiKeys.AddAsync( entity: entity, cancellationToken: cancellationToken diff --git a/Providers/XApplicationProvider/XApplicationProvider+Custom.cs b/Providers/XApplicationProvider/XApplicationProvider+Custom.cs index c738fa1..735afb5 100644 --- a/Providers/XApplicationProvider/XApplicationProvider+Custom.cs +++ b/Providers/XApplicationProvider/XApplicationProvider+Custom.cs @@ -17,6 +17,67 @@ namespace xIds.Providers { // #region Custom Actions ... + /// + /// Show Specifid Api Key ... + /// + /// + /// + /// + /// + /// + public async Task ShowApiKey( + Guid apiKeyId, + int applicationId, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) + { + // + // Validate ... + if ( + apiKeyId.IsDefaultGuid() || + userInfo.IsNullOrDefault() || + !applicationId.IsValidIntId() + ) + { + XException.InvalidArgs.Throw(); + } + + // + // Check Application Exists ... + var application = await GetApplicationAsync( + id: applicationId, + userInfo: userInfo, + includeBuilder: null, + ignoreSoftDeleteds: true, + cancellationToken: cancellationToken + ); + if (application.IsNullOrDefault()) + { + XException.NotFound.Throw(); + } + + // + // Validate Owner ... + if (!IsOwned(application, userInfo)) + { + XException.NotAllowed.Throw(); + } + + // + // Retrieve ApiKey Entity ... + // Since ApiKey is Only Exists on ApiKey Entity ... + var entity = await dbContext.ApiKeys + .FirstOrDefaultAsync(x => x.Id == apiKeyId); + if (entity.IsNullOrDefault()) + { + XException.NotFound.Throw(); + } + + // + return entity.Key; + } + /// /// Generate a New ApiKey and Add It to DB ... /// @@ -114,6 +175,7 @@ namespace xIds.Providers // Add Item to Database ... result = await AddApiKeyAsync( item: result, + apiKey: plainKey, userInfo: userInfo, cancellationToken: cancellationToken ); @@ -371,8 +433,8 @@ namespace xIds.Providers .ParseListString(); var allowedScopes = (keyModel.AllowedScopes ?? string.Empty) .FromJSON>(); - result.Scopes = [..allowedScopes]; - + result.Scopes = [.. allowedScopes]; + // // Check Application is Exists and Active ... var application = await dbContext.Applications diff --git a/Startup.cs b/Startup.cs index 000389d..546448b 100644 --- a/Startup.cs +++ b/Startup.cs @@ -67,7 +67,10 @@ namespace xIds // // Register Authentication ... - services.AddXIdentityServerAuthentication(Configuration); + services.AddXIdentityServerAuthentication( + configuration: Configuration, + addApiKeyAuthentication: true + ); // // Register Authorization ...