last ...
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using xExceptions.Attributes;
|
||||
|
||||
namespace xIdentityService.Constants {
|
||||
public enum XApiAccountEndpoint {
|
||||
namespace xIdentityService.Constants
|
||||
{
|
||||
public enum XApiAccountEndpoint
|
||||
{
|
||||
//
|
||||
#region Authentication ...
|
||||
[StringValue("Account/DiscoveryDocument")]
|
||||
@@ -193,5 +195,11 @@ namespace xIdentityService.Constants {
|
||||
[StringValue("Account/IsBanned/{userSelectByParam}")]
|
||||
IsBanned,
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Open Actions ...
|
||||
[StringValue("Account/GetUserInfo")]
|
||||
GetUserInfo,
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,9 @@ namespace xIdentityService.Constants {
|
||||
[StringValue ("actionToken")]
|
||||
XActionToken,
|
||||
|
||||
[StringValue ("request")]
|
||||
XRequest,
|
||||
|
||||
[StringValue ("scope")]
|
||||
XScope,
|
||||
}
|
||||
|
||||
@@ -10,11 +10,14 @@ using xIdentityModels.Models;
|
||||
using xIdentityModels.Navigations;
|
||||
using xModels.Dtos;
|
||||
|
||||
namespace xIdentityService.Interfaces {
|
||||
public partial interface IXIdentityProvider {
|
||||
namespace xIdentityService.Interfaces
|
||||
{
|
||||
public partial interface IXIdentityProvider
|
||||
{
|
||||
//
|
||||
string BaseUrl { get; }
|
||||
string RevisionSecretKey { get; }
|
||||
IXSecurityProvider SecurityProvider { get; }
|
||||
|
||||
//
|
||||
#region Tools ...
|
||||
@@ -279,5 +282,18 @@ namespace xIdentityService.Interfaces {
|
||||
string userSelectByParam
|
||||
);
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Open Actions ...
|
||||
Task<XOpenActionUserInfoDto> GetUserInfo(
|
||||
XDeviceDto device,
|
||||
string userSelectByParam
|
||||
);
|
||||
Task<XOpenActionUserInfoDto> GetUserInfo(XOpenActionInnerDto dto);
|
||||
Task<XOpenActionUserInfoDto> GetUserInfo(
|
||||
string token,
|
||||
string request
|
||||
);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using RestSharp;
|
||||
|
||||
namespace xIdentityService.Models
|
||||
{
|
||||
public class XBaseRestResponse<T>
|
||||
{
|
||||
public T Model { get; set; }
|
||||
public IRestResponse Response { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MongoDB.Bson;
|
||||
using xCommons.Constants;
|
||||
using xCommons.Extensions;
|
||||
using xExceptions.Constants;
|
||||
using xHttpService.Constants;
|
||||
using xIdentityModels.Dtos;
|
||||
using xIdentityService.Constants;
|
||||
using xModels.Dtos;
|
||||
using xModels.Extensions;
|
||||
|
||||
namespace xIdentityService.Providers
|
||||
{
|
||||
public partial class XIdentityProvider
|
||||
{
|
||||
public async Task<XOpenActionUserInfoDto> GetUserInfo(
|
||||
XDeviceDto device,
|
||||
string userSelectByParam
|
||||
)
|
||||
{
|
||||
//
|
||||
// Validate Args ...
|
||||
validationProvider.NotNull(device);
|
||||
validationProvider.NotEmpty(userSelectByParam);
|
||||
|
||||
//
|
||||
// Prepare Open Action Model ...
|
||||
var opaModel = new XOpenActionRequestDto
|
||||
{
|
||||
Device = device,
|
||||
Payload = userSelectByParam,
|
||||
Action = XOpenActions.GetUserInfo,
|
||||
Timestamp = DateTime.UtcNow.AddMinutes(5)
|
||||
};
|
||||
if (!opaModel.Validate())
|
||||
{
|
||||
XException.InvalidArgs.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Fill Checksum Filed ...
|
||||
var token = opaModel.ToOpenActionToken();
|
||||
opaModel.Checksum = token;
|
||||
|
||||
//
|
||||
// Prepare Request ...
|
||||
var opaJson = opaModel.ToJson();
|
||||
var requestString = SecurityProvider.Encrypt(opaJson);
|
||||
|
||||
//
|
||||
return await GetUserInfo(
|
||||
token: token,
|
||||
request: requestString
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<XOpenActionUserInfoDto> GetUserInfo(XOpenActionInnerDto dto)
|
||||
{
|
||||
//
|
||||
return await GetUserInfo(
|
||||
token: dto.Token,
|
||||
request: dto.Payload
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<XOpenActionUserInfoDto> GetUserInfo(
|
||||
string token,
|
||||
string request
|
||||
)
|
||||
{
|
||||
//
|
||||
// Validate Args ...
|
||||
validationProvider.NotEmpty(token);
|
||||
validationProvider.NotEmpty(request);
|
||||
|
||||
//
|
||||
// Retrieve Rest Client ...
|
||||
var client = GetRestClient();
|
||||
|
||||
//
|
||||
// Prepare Rest Request ...
|
||||
var requestU = GetRestRequet(
|
||||
XApiAccountEndpoint.GetUserInfo,
|
||||
@params: new Dictionary<string, string>
|
||||
{
|
||||
{ XParam.XRequest.GetStringValue(), request }
|
||||
},
|
||||
headers: new Dictionary<string, string>
|
||||
{
|
||||
{ XAuthentication.TOKEN, token}
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
var response = await RunRestRequestByResponse<string>(
|
||||
client,
|
||||
requestU,
|
||||
XHttpMethod.GET
|
||||
);
|
||||
|
||||
//
|
||||
// Now we Have to Validate the recieved response ...
|
||||
|
||||
//
|
||||
// Read token from Headers ...
|
||||
|
||||
//
|
||||
var responseToken = response.Response.Headers.First(h => h.Name == XAuthentication.TOKEN).ToString();
|
||||
if (responseToken.IsNullOrEmpty())
|
||||
{
|
||||
XException.ActionFailed.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
var responseJson = SecurityProvider.Decrypt(response.Model);
|
||||
if (responseJson.IsNullOrEmpty())
|
||||
{
|
||||
XException.ActionFailed.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Model and Validate it ...
|
||||
var responseModel = responseJson.FromJSON<XOpenActionRequestDto>();
|
||||
if (responseModel.IsNull() ||
|
||||
responseModel.Timestamp.IsExPired() ||
|
||||
responseModel.Payload.IsNullOrEmpty() ||
|
||||
// !responseModel.Device.IsSameAs(device) ||
|
||||
responseToken != responseModel.Checksum)
|
||||
{
|
||||
XException.ActionFailed.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Retrieve Model ...
|
||||
var result = responseModel.Payload.FromJSON<XOpenActionUserInfoDto>();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ using xIdentityModels.Models;
|
||||
using xIdentityService.Configuration;
|
||||
using xIdentityService.Constants;
|
||||
using xIdentityService.Interfaces;
|
||||
using xIdentityService.Models;
|
||||
|
||||
namespace xIdentityService.Providers {
|
||||
public partial class XIdentityProvider : IXIdentityProvider {
|
||||
@@ -30,16 +31,18 @@ namespace xIdentityService.Providers {
|
||||
private readonly XValidationProvider validationProvider;
|
||||
private readonly XIdentityServiceConfiguration identityConfiguration;
|
||||
|
||||
public ILogger<XIdentityProvider> Logger { get; }
|
||||
public IXSecurityProvider SecurityProvider { get; }
|
||||
|
||||
public string BaseUrl { get; }
|
||||
public string RevisionSecretKey { get; }
|
||||
|
||||
public bool ReadResponseAsString { get; set; }
|
||||
public ILogger<XIdentityProvider> Logger { get; }
|
||||
|
||||
public XIdentityProvider (
|
||||
IXTokenProvider tokenProvider,
|
||||
IHostingEnvironment environment,
|
||||
ILogger<XIdentityProvider> logger,
|
||||
IXSecurityProvider securityProvider,
|
||||
XIdentityServiceConfiguration identityConfiguration,
|
||||
XValidationProvider validationProvider
|
||||
) {
|
||||
@@ -50,6 +53,7 @@ namespace xIdentityService.Providers {
|
||||
//
|
||||
this.environment = environment;
|
||||
Logger = logger;
|
||||
SecurityProvider = securityProvider;
|
||||
|
||||
//
|
||||
this.identityConfiguration = identityConfiguration;
|
||||
@@ -345,6 +349,149 @@ namespace xIdentityService.Providers {
|
||||
//
|
||||
return response;
|
||||
}
|
||||
public async Task<XBaseRestResponse<T>> RunRestRequestByResponse<T> (
|
||||
RestClient client,
|
||||
RestRequest request,
|
||||
XHttpMethod method,
|
||||
bool supportRefreshingTokens = true
|
||||
) {
|
||||
//
|
||||
var response = await Task.Run (async () => {
|
||||
//
|
||||
IRestResponse resp = null;
|
||||
|
||||
//
|
||||
// Call Endpoint Service using Specified Method ...
|
||||
switch (method) {
|
||||
//
|
||||
// Get ...
|
||||
case XHttpMethod.GET:
|
||||
resp = client.Get (request);
|
||||
break;
|
||||
|
||||
//
|
||||
// Put ...
|
||||
case XHttpMethod.PUT:
|
||||
resp = client.Put (request);
|
||||
break;
|
||||
|
||||
//
|
||||
// Post ...
|
||||
case XHttpMethod.POST:
|
||||
resp = client.Post (request);
|
||||
break;
|
||||
|
||||
//
|
||||
// Delete ...
|
||||
case XHttpMethod.DELETE:
|
||||
resp = client.Delete (request);
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (!resp.IsSuccessful) {
|
||||
//
|
||||
// Log Exception ...
|
||||
Logger.LogError ($"Error: {resp.ErrorMessage}");
|
||||
Logger.LogError ($"Exception: {resp.ErrorException.ToJSON()}");
|
||||
if (!resp.ErrorMessage.IsNullOrEmpty () &&
|
||||
resp.ErrorMessage.Contains ("timed out")) {
|
||||
XException.Timeout.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Check UnAuthorized Status here for
|
||||
// Refresh Tokens or Issue Correct Exception ...
|
||||
if (supportRefreshingTokens &&
|
||||
resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
|
||||
//
|
||||
var isRefreshed = request.Parameters.Any (rp =>
|
||||
rp.Name == XParam.XIsRefreshed.GetStringValue () &&
|
||||
rp.Value.ToString ().ToNormalString () == true.ToJSON ());
|
||||
|
||||
//
|
||||
Logger.LogInformation ($"isRefreshed: {isRefreshed}");
|
||||
|
||||
//
|
||||
// Get Access Token ...
|
||||
XTokenResponse tokens = null;
|
||||
var accessToken = request.Parameters.FirstOrDefault (rp =>
|
||||
rp.Name.ToNormalString () == XAuthorization.Header.ToNormalString ()).Value.ToString ();
|
||||
if (!accessToken.IsNullOrEmpty ()) {
|
||||
//
|
||||
accessToken = accessToken.Replace (XAuthorization.TokenIdentifier, "");
|
||||
|
||||
//
|
||||
if (!accessToken.IsNullOrEmpty ()) {
|
||||
tokens = await tokenProvider.RetrieveToken (accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Refresh Token and then re do request ...
|
||||
if (!isRefreshed &&
|
||||
!accessToken.IsNullOrEmpty () &&
|
||||
!tokens.IsNull () &&
|
||||
tokens.IsRefreshable ()) {
|
||||
//
|
||||
request.AddHeader (XParam.XIsRefreshed.GetStringValue (), true.ToJSON ());
|
||||
|
||||
//
|
||||
// Refreshe Tokens ...
|
||||
var refreshedTokens = await RefreshTokens (tokens);
|
||||
|
||||
//
|
||||
// Renew Rest Client with Refreshed Tokens ...
|
||||
var timeout = client.Timeout;
|
||||
client = GetRestClient (refreshedTokens);
|
||||
client.Timeout = Timeout.Infinite;
|
||||
|
||||
//
|
||||
// Do Request Again using renew Client ...
|
||||
return await RunRestRequestByResponse<T> (
|
||||
client: client,
|
||||
request: request,
|
||||
method: method
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
var ex = resp.Content.ToXError ();
|
||||
if (!ex.IsNull ()) {
|
||||
throw ex.ToException ();
|
||||
}
|
||||
|
||||
//
|
||||
// UnAuthorized ...
|
||||
if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
|
||||
XException.NotAuthorized.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
// NotFound ...
|
||||
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound) {
|
||||
XException.NotFound.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
XException.ActionFailed.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
var result = new XBaseRestResponse<T>
|
||||
{
|
||||
Response = resp,
|
||||
Model = resp.Content.FromJSON<T> ()
|
||||
};
|
||||
|
||||
//
|
||||
return result;
|
||||
});
|
||||
|
||||
//
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get User SelectBy Param
|
||||
|
||||
Reference in New Issue
Block a user