Files
xSaherelmWorkspace/Documents/GeneratedContext/xDashboard-xIdentityService-20260807_230353.txt
T
2026-08-08 00:31:18 +03:30

8769 lines
279 KiB
Plaintext

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Configuration\XIdentityServiceConfiguration.cs
using xIdentityService.Constants;
namespace xIdentityService.Configuration {
public partial class XIdentityServiceConfiguration {
public string Authority { get; set; }
public string ApiName { get; set; }
public string ApiSecret { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string XPoweredValue { get; set; }
public XTokenType TokenType { get; set; }
public string XRevisionSecretKey { get; set; }
public int DefaultClientTimeout { get; set; } = 360;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Configuration\XProxyConfiguration.cs
using System.Collections.Generic;
using xModels.Base;
namespace xIdentityService.Configuration {
/// <summary>
/// XProxy Middleware Configuration ...
/// </summary>
public class XProxyConfiguration {
/// <summary>
/// Proxy Host Address for Clients Which Use XProxy Server ...
/// </summary>
/// <value></value>
public string Host { get; set; }
/// <summary>
/// if EnableXPoweredByAthorization property setted to true, this property determines
/// the header must be this value ...
/// </summary>
/// <value></value>
public string XPoweredValue { get; set; }
/// <summary>
/// Determines Proxy Http Handler Check SSL or not ...
/// </summary>
/// <value></value>
public bool DisableSSLCheck { get; set; }
/// <summary>
/// Determines Http Client Handler Allow Auto Redirect or not ...
/// </summary>
/// <value></value>
public bool AllowAutoRedirect { get; set; }
/// <summary>
/// Determines Proxy Server Log Received Requests or not ...
/// </summary>
/// <value></value>
public bool EnableLogging { get; set; }
/// <summary>
/// DefineRoutes for Handling ...
/// </summary>
/// <value></value>
public HashSet<XProxyRouteDescriptor> Routes { get; set; }
}
/// <summary>
/// Describe a Proxy Route ...
/// </summary>
public class XProxyRouteDescriptor : XBaseDescriptor {
/// <summary>
/// Determines which route can handled for Proxyfing ...
/// </summary>
/// <value></value>
public string Route { get; set; }
/// <summary>
/// Determines Proxy Server Handle Athorization or not ...
/// </summary>
/// <value></value>
public bool EnableAuthorization { get; set; }
/// <summary>
/// Determines Which Scopes allowed to this route if authorizations enabled ...
/// </summary>
/// <value></value>
public HashSet<string> AllowedScopes { get; set; }
/// <summary>
/// Determines Which Roles allowed to this route if authorizations enabled ...
/// </summary>
/// <value></value>
public HashSet<string> AllowedRoles { get; set; }
/// <summary>
/// Determines XProxy Can Check XPowered By Authorization or not ...
/// </summary>
/// <value></value>
public bool EnableXPoweredByAthorization { get; set; }
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\ConfigurationNodeNames.cs
namespace xIdentityService.Constants {
public partial struct ConfigurationNodeNames {
public const string XPROXY_CONFIGURATION_NODE_NAME = "ProxyConfiguration";
public const string IDENTITY_SERVICE_NODE_NAME = "IdentityServiceConfiguration";
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XApiAccountEndpoint.cs
using xExceptions.Attributes;
namespace xIdentityService.Constants
{
public enum XApiAccountEndpoint
{
//
#region Authentication ...
[StringValue("Account/DiscoveryDocument")]
DiscoveryDocument,
[StringValue("Account/RequestScopeAccessToken")]
RequestScopeAccessToken,
[StringValue("Account/Authenticate")]
Authenticate,
[StringValue("Account/Login")]
Login,
[StringValue("Account/RefreshTokens")]
RefreshTokens,
[StringValue("Account/ChangePassword")]
ChangePassword,
[StringValue("Account/ResetPassword")]
ResetPassword,
#endregion
//
#region Proile ...
[StringValue("Account/Profile/{ids}/GetNames")]
GetNames,
[StringValue("Account/Profile/GetNameIds")]
GetNameIds,
[StringValue("Account/Profile/{userSelectByParam}")]
GetProfile,
[StringValue("Account/Profile/Query")]
QueryProfiles,
[StringValue("Account/Profile/Avatars/Query/{userSelectByParam}")]
QueryAvatars,
[StringValue("Account/Profile/Update/{userSelectByParam}")]
UpdateProfile,
[StringValue("Account/Profile/{userSelectByParam}")]
FullUpdateProfile,
[StringValue("Account/Profile/Avatar")]
AddAvatar,
[StringValue("Account/Profile/Avatars")]
AddAvatars,
[StringValue("Account/Profile/Avatars/{ids}")]
RemoveAvatars,
[StringValue("Account/Profile/Avatars/{id}/Set")]
SetAvatar,
#endregion
//
#region Search ...
[StringValue("Account/OpenToSearch/Query")]
QueryOpenToSearchProfiles,
#endregion
//
#region Registration ...
[StringValue("Account/CanRegisterUserName/{userName}")]
CanRegisterUserName,
[StringValue("Account/CanRegisterMobileNumber/{mobileNumber}")]
CanRegisterMobileNumber,
[StringValue("Account/CanRegisterEmail/{email}")]
CanRegisterEmail,
[StringValue("Account/IsConfirmedEmail")]
IsConfirmedEmail,
[StringValue("Account/IsConfirmedMobile")]
IsConfirmedMobile,
[StringValue("Account/ConfirmRegistration")]
ConfirmRegistration,
[StringValue("Account/ConfirmMobileNumber")]
ConfirmMobileNumber,
[StringValue("Account/ConfirmEmailAddress")]
ConfirmEmailAddress,
[StringValue("Account/RequestConfirmMobile")]
RequestConfirmMobile,
[StringValue("Account/RequestConfirmEmail")]
RequestConfirmEmail,
[StringValue("Account/RequestResetPassword")]
RequestResetPassword,
[StringValue("Account/RequestConfirmRegistration")]
RequestConfirmRegistration,
[StringValue("Account/InviteUser")]
InviteUser,
[StringValue("Account/RequestRegistration")]
RequestRegistration,
[StringValue("Account/AddAccountInfo")]
AddAccountInfo,
[StringValue("Account/AttachProfileImage")]
AttachProfileImage,
[StringValue("Account/FinishRegistration")]
FinishRegistration,
#endregion
//
#region Friendship ...
[StringValue("Account/Friendship/{destUser}/Follow")]
Follow,
[StringValue("Account/Friendship/{destUser}/Cancel")]
Cancel,
[StringValue("Account/Friendship/{destUser}/UnFollowFollower")]
UnFollowFollower,
[StringValue("Account/Friendship/{destUser}/UnFollowFollowing")]
UnFollowFollowing,
[StringValue("Account/Friendship/{destUser}/Block")]
Block,
[StringValue("Account/Friendship/{destUser}/UnBlock")]
UnBlock,
[StringValue("Account/Friendship/{destUser}/AcceptRequest")]
AcceptRequest,
[StringValue("Account/Friendship/{destUser}/RejectRequest")]
RejectRequest,
[StringValue("Account/Friendship/{destUser}/FriendshipInfo")]
FriendshipInfo,
[StringValue("Account/Friendship/{destUser}/IsFollower")]
IsFollower,
[StringValue("Account/Friendship/{destUser}/FollowerState")]
FollowerState,
[StringValue("Account/Friendship/{destUser}/Follower")]
Follower,
[StringValue("Account/Friendship/Followers")]
Followers,
[StringValue("Account/Friendship/AllFollowers")]
AllFollowers,
[StringValue("Account/Friendship/FollowersList")]
FollowersList,
[StringValue("Account/Friendship/QueryFollowers")]
QueryFollowers,
[StringValue("Account/Friendship/{destUser}/IsFollowing")]
IsFollowing,
[StringValue("Account/Friendship/{destUser}/FollowingState")]
FollowingState,
[StringValue("Account/Friendship/{destUser}/Following")]
Following,
[StringValue("Account/Friendship/Followings")]
Followings,
[StringValue("Account/Friendship/AllFollowings")]
AllFollowings,
[StringValue("Account/Friendship/FollowingsList")]
FollowingsList,
[StringValue("Account/Friendship/QueryFollowings")]
QueryFollowings,
#endregion
//
#region Admin ...
[StringValue("Account/Ban")]
Ban,
[StringValue("Account/UnBan")]
UnBan,
[StringValue("Account/IsBanned/{userSelectByParam}")]
IsBanned,
#endregion
//
#region Open Actions ...
[StringValue("Account/Open")]
Open,
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XAuthenticationScheme.cs
using xExceptions.Attributes;
namespace xIdentityService.Constants {
public enum XAuthenticationScheme {
[StringValue ("token")]
XToken,
[StringValue ("introspection")]
XIntrospection,
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XHeader.cs
using xExceptions.Attributes;
namespace xIdentityService.Constants
{
/// <summary>
/// All Available Headers ...
/// </summary>
public enum XHeader
{
/// <summary>
/// Hub Connection ID Header Keys ...
/// </summary>
[StringValue("requestID")]
ConnectionId,
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XParam.cs
using xExceptions.Attributes;
namespace xIdentityService.Constants {
public enum XParam {
[StringValue ("Content-Type")]
XContentType,
[StringValue ("{boundary}")]
XBoundary,
[StringValue ("{userSelectByParam}")]
XUserSelectByParam,
[StringValue ("{destUser}")]
XDestUser,
[StringValue ("{id}")]
XId,
[StringValue ("{ids}")]
XIds,
[StringValue ("Origin")]
XOrigin,
[StringValue ("{userName}")]
XUserName,
[StringValue ("{mobileNumber}")]
XMobileNumber,
[StringValue ("{email}")]
XEmail,
[StringValue ("role")]
XRole,
[StringValue ("forceRole")]
XForceRole,
[StringValue ("IsRefreshed")]
XIsRefreshed,
[StringValue ("file")]
XFile,
[StringValue ("files")]
XFiles,
[StringValue ("actionToken")]
XActionToken,
[StringValue ("request")]
XRequest,
[StringValue ("scope")]
XScope,
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XProxyConstants.cs
namespace xIdentityService.Constants {
public struct XProxyConstants {
public const string XPROXY_HTTP_CLIENT = "XProxyHttpClient";
public const string XPROXY_FORWARD_HEADER = "xForwardHeader";
public const string XPROXY_ACCEPTED_HEADERS = "xAcceptedHeaders";
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XResponseContentTypes.cs
namespace xIdentityService.Constants {
public struct XResponseContentTypes {
public const string HTML = "text/html";
public const string JSON = "application/json";
public const string JavaScript = "text/javascript";
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XTokenType.cs
namespace xIdentityService.Constants {
public enum XTokenType {
//
// Summary:
// Self-contained Json Web Token
Jwt,
//
// Summary:
// Reference token
Reference
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityApiController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Attributes;
using xCommons.Configurations;
using xCommons.Providers;
using xIdentityService.Interfaces;
namespace xIdentityService.Controllers
{
/// <summary>
/// Base Identity Api Controller
/// </summary>
[ApiController]
[RequireXPowered(true)]
[Route("api/[controller]")]
[Produces("application/json")]
public abstract class XBaseIdentityApiController : XBaseIdentityController
{
protected XBaseIdentityApiController(
ILogger logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{ }
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityApiV1Controller.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Attributes;
using xCommons.Configurations;
using xCommons.Providers;
using xIdentityService.Interfaces;
namespace xIdentityService.Controllers
{
/// <summary>
/// Base Identity Api V1 Controller
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[RequireXPowered(true)]
[Route("api/v{version:apiVersion}/[controller]")]
public abstract class XBaseIdentityApiV1Controller : XBaseIdentityApiController
{
protected XBaseIdentityApiV1Controller(
ILogger logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{ }
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityController.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Constants;
using xCommons.Controllers;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Models;
using xIdentityService.Constants;
using xIdentityService.Interfaces;
namespace xIdentityService.Controllers
{
public abstract class XBaseIdentityController : XBaseController
{
//
public IXIdentityProvider IdentityProvider { get; }
protected XBaseIdentityController(
ILogger logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
validationProvider
)
{
IdentityProvider = identityProvider;
}
//
#region NonActions ...
/// <summary>
/// Retrieve Connection ID for Hubs ...
/// </summary>
/// <returns></returns>
[NonAction]
public string GetConnectionId()
{
//
var result = "";
//
var headerKey = XHeader.ConnectionId.GetStringValue();
//
// Check if Connection ID is Provided ...
if (Request.Headers.ContainsKey(headerKey))
{
result = Request.Headers[headerKey];
}
//
return result;
}
/// <summary>
/// Retrieve User Identifier Base on XActionRequest
/// </summary>
/// <param name="model"></param>
/// <param name="forceNotNull"></param>
/// <param name="excludes"></param>
/// <returns></returns>
[NonAction]
public string GetUserSelectByParam(
XActionRequest model,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(model);
//
var result = IdentityProvider.GetUserSelectByParam(
model,
forceNotNull,
excludes
);
//
return result;
}
/// <summary>
/// Retrieve Access Token
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<string> GetAccessToken()
{
//
var accessToken = Request.Headers[XAuthorization.Header].ToString();
if (accessToken.IsNullOrEmpty())
{
//
accessToken = await HttpContext
.GetTokenAsync(XAuthorization.AccessToken);
}
//
if (accessToken
.ToNormalString()
.Contains(XAuthorization.TokenIdentifier
.ToNormalString()))
{
//
accessToken = accessToken
.Remove(0, XAuthorization.TokenIdentifier.Length);
}
//
return accessToken;
}
/// <summary>
/// Retrieve Refresh Token
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<string> GetRefreshToken()
{
//
var refreshToken = Request.Headers[XAuthorization.RefreshToken].ToString();
if (refreshToken.IsNullOrEmpty())
{
//
refreshToken = await HttpContext
.GetTokenAsync(XAuthorization.RefreshToken);
}
//
return refreshToken;
}
/// <summary>
/// Retrieve Access Token Expiration Date
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<long> GetTokenExpiresAt()
{
//
var expiresAtStr = Request.Headers[XAuthorization.ExpiresAt].ToString();
if (expiresAtStr.IsNullOrEmpty())
{
//
expiresAtStr = await HttpContext
.GetTokenAsync(XAuthorization.ExpiresAt);
}
//
var expiresAt = expiresAtStr.ConvertTo<long>();
//
return expiresAt;
}
/// <summary>
/// Retrieve All Required Tokens
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<XLoginResponse> RetrieveTokensAsXLoginResponse()
{
//
var accessToken = await GetAccessToken();
var refreshToken = await GetRefreshToken();
var expiresAt = await GetTokenExpiresAt();
//
return new XLoginResponse
{
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
}
/// <summary>
/// Retrieve All Required Tokens
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<XTokenResponse> RetrieveTokensAsXTokenResponse()
{
//
var accessToken = await GetAccessToken();
var refreshToken = await GetRefreshToken();
var expiresAt = await GetTokenExpiresAt();
//
return new XTokenResponse
{
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
}
/// <summary>
/// Retrive UserInfo
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<XUserClaimsInfoDto> GetUserInfo()
{
//
var claims = User.Claims ?? null;
if (!claims.HasChild())
{
return null;
}
var xTokens = await RetrieveTokensAsXTokenResponse();
var result = new XUserClaimsInfoDto(
xTokens.AccessToken,
xTokens.RefreshToken,
xTokens.ExpiresAt,
User.Claims
);
//
return result;
}
/// <summary>
/// Validate User Authenticated and Retrieve User Info
/// </summary>
/// <returns></returns>
[NonAction]
public async Task<XUserClaimsInfoDto> ValidateAndGetUserInfo()
{
//
if (!User.Identity.IsAuthenticated)
{
XException.NotAuthorized.Throw();
}
//
var result = await GetUserInfo();
if (result.IsNull())
{
XException.NotAuthorized.Throw();
}
//
return result;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\DI\XDIHelperExtension.cs
using System;
using IdentityModel.AspNetCore.OAuth2Introspection;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Authorization;
using xCommons.Extensions;
using xIdentityService.Configuration;
using xIdentityService.Constants;
using xIdentityService.Interfaces;
using xIdentityService.Providers;
using xIdentityService.Security;
namespace xIdentityService.DI {
public static partial class XDIHelperExtension {
/// <summary>
/// Extract Module Configuration Structure from IConfiguration interface
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static XIdentityServiceConfiguration GetXIdentityServiceConfiguration (this IConfiguration config) {
//
var xIdentityServiceConfigSection = config.GetSection (ConfigurationNodeNames.IDENTITY_SERVICE_NODE_NAME);
return xIdentityServiceConfigSection.Get<XIdentityServiceConfiguration> ();
}
/// <summary>
/// Register Service and All it's Requirements
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXIdentityService (
this IServiceCollection services,
IConfiguration configuration,
ServiceLifetime lifeTime = ServiceLifetime.Singleton
) {
//
var identityConfiguration = configuration.GetXIdentityServiceConfiguration ();
AddIdentityService (
services,
identityConfiguration,
lifeTime
);
}
/// <summary>
/// Register Service and All it's Requirements
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXIdentityService (
this IServiceCollection services,
XIdentityServiceConfiguration configuration,
ServiceLifetime lifeTime = ServiceLifetime.Singleton
) {
AddIdentityService (services, configuration, lifeTime);
}
/// <summary>
/// Register Custome Token Provider
/// </summary>
/// <param name="services"></param>
/// <typeparam name="T"></typeparam>
public static void AddXTokenProvider<T> (
this IServiceCollection services,
ServiceLifetime lifetime = ServiceLifetime.Singleton)
where T : IXTokenProvider {
//
Console.WriteLine ("IdentityService: Add Custom Token Provider ...");
services.Add (new ServiceDescriptor (typeof (IXTokenProvider), typeof (T), lifetime));
}
/// <summary>
/// Use Authentication
/// </summary>
/// <param name="app"></param>
public static void UseXIdentityService (this IApplicationBuilder app) {
app.UseAuthentication ();
}
//
#region Private ...
private static void AddIdentityService (
this IServiceCollection services,
XIdentityServiceConfiguration config,
ServiceLifetime lifeTime = ServiceLifetime.Singleton
) {
//
services.AddSingleton<XIdentityServiceConfiguration> (config);
//
var builder = services
.AddAuthentication (XAuthenticationScheme.XToken.GetStringValue ());
//
// Add JWT Handler ...
builder.AddJwtBearer (
XAuthenticationScheme.XToken.GetStringValue (), options => {
//
options.Authority = config.Authority;
options.TokenValidationParameters.ValidateAudience = false;
options.TokenValidationParameters.ValidTypes = new [] { "at+jwt" };
//
options.ForwardDefaultSelector = context => {
//
var path = context.Request.Path.Value;
//
var fromHeader = TokenRetrieval.FromAuthorizationHeader ();
var fromQuery = TokenRetrieval.FromQueryString ();
var bearerToken = fromHeader (context.Request) ?? fromQuery (context.Request);
//
var result = XAuthenticationScheme.XToken.GetStringValue ();
if (!bearerToken.IsNull () && !bearerToken.Contains (".")) {
result = XAuthenticationScheme.XIntrospection.GetStringValue ();
}
//
return result;
};
});
//
// Add OAuthIntrospect ...
builder.AddOAuth2Introspection (
XAuthenticationScheme.XIntrospection.GetStringValue (), options => {
//
options.Authority = config.Authority;
options.ClientId = config.ApiName;
options.ClientSecret = config.ClientSecret;
//
options.TokenRetriever = new Func<HttpRequest, string> (req => {
//
var fromHeader = TokenRetrieval.FromAuthorizationHeader ();
var fromQuery = TokenRetrieval.FromQueryString ();
//
var bearerToken = fromHeader (req) ?? fromQuery (req);
//
return bearerToken;
});
});
//
// Register Authorization Handler ...
services.AddSingleton<IAuthorizationHandler, RequiredRolesHandler> ();
Console.WriteLine ("IdentityService: register Authorization Handlers ...");
//
// Register Identity Provider ...
services.Add (new ServiceDescriptor (typeof (IXIdentityProvider), typeof (XIdentityProvider), lifeTime));
Console.WriteLine ("IdentityService: Register IdentityProvider ...");
//
// Try To Register InMemoryTokenProvier if it's not Provided ...
IXTokenProvider xTokenProvider = null;
try {
xTokenProvider = services.GetRegisteredService<IXTokenProvider> ();
} catch { }
if (xTokenProvider.IsNull ()) {
//
Console.WriteLine ("IdentityService: there is no Custom Token Provider, Adding InMemoryTokenProvider instead ...");
services.Add (new ServiceDescriptor (typeof (IXTokenProvider), typeof (XInMemoryTokenProvider), lifeTime));
}
//
// Adding Security Provider ...
services.Add (new ServiceDescriptor (typeof (IXSecurityProvider), typeof (XSecurityProvider), lifeTime));
Console.WriteLine ("IdentityService: Register Security Provider ...");
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\AuthorizationPolicyBuilderExtensions.cs
using IdentityModel;
using Microsoft.AspNetCore.Authorization;
namespace xIdentityService.Extensions {
public static class AuthorizationPolicyBuilderExtensions {
/// <summary>
/// Adds a policy to check for required scopes.
/// </summary>
/// <param name="builder"></param>
/// <param name="scope">List of any required scopes. The token must contain at least one of the listed scopes.</param>
/// <returns></returns>
public static AuthorizationPolicyBuilder RequireScope (this AuthorizationPolicyBuilder builder, params string[] scope) {
return builder.RequireClaim (JwtClaimTypes.Scope, scope);
}
}
/// <summary>
/// Helper for creating scope-related policies
/// </summary>
public static class ScopePolicy {
/// <summary>
/// Creates a policy to check for required scopes.
/// </summary>
/// <param name="scopes">List of any required scopes. The token must contain at least one of the listed scopes.</param>
/// <returns></returns>
public static AuthorizationPolicy Create (params string[] scopes) {
return new AuthorizationPolicyBuilder ()
.RequireScope (scopes)
.Build ();
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\HttpContextExtensions.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Constants;
using xCommons.Extensions;
using xIdentityModels.Models;
using xIdentityService.Constants;
namespace xIdentityService.Extensions {
public static class HttpContextExtensions {
/// <summary>
/// Retrieve Authentication Service ...
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static IAuthenticationService GetAuthenticationService (this HttpContext context) {
//
var result = context.RequestServices
.GetRequiredService<IAuthenticationService> ();
//
return result;
}
/// <summary>
/// Retrieve Specific Token from HttpContext ...
/// </summary>
/// <param name="context"></param>
/// <param name="tokenName"></param>
/// <param name="scheme"></param>
/// <returns></returns>
public static async Task<string> GetXTokenAsync (
this HttpContext context,
string tokenName,
XAuthenticationScheme scheme = XAuthenticationScheme.XToken
) {
//
// Validate Args ...
if (tokenName.IsNullOrEmpty ()) {
return null;
}
//
var authService = context.GetAuthenticationService ();
if (authService.IsNull ()) {
return null;
}
//
var authResult = await authService
.AuthenticateAsync (
context,
scheme
.GetStringValue ()
);
//
var result = authResult?.Properties?
.GetTokenValue (tokenName);
return result;
}
/// <summary>
/// Retrieve Access Token
/// </summary>
/// <returns></returns>
public static async Task<string> GetAccessToken (this HttpContext context) {
//
var accessToken = context.Request.Headers[XAuthorization.Header]
.ToString ();
if (accessToken.IsNullOrEmpty ()) {
accessToken = await context
.GetTokenAsync (XAuthorization.AccessToken);
}
//
if (accessToken
.ToNormalString ()
.Contains (XAuthorization.TokenIdentifier
.ToNormalString ())) {
accessToken = accessToken
.Remove (0, XAuthorization.TokenIdentifier.Length);
}
//
return accessToken;
}
/// <summary>
/// Retrieve Refresh Token
/// </summary>
/// <returns></returns>
public static async Task<string> GetRefreshToken (this HttpContext context) {
//
var refreshToken = context.Request.Headers[XAuthorization.RefreshToken]
.ToString ();
if (refreshToken.IsNullOrEmpty ()) {
refreshToken = await context
.GetTokenAsync (XAuthorization.RefreshToken);
}
//
return refreshToken;
}
/// <summary>
/// Retrieve Access Token Expiration Date
/// </summary>
/// <returns></returns>
public static async Task<long> GetTokenExpiresAt (this HttpContext context) {
//
var expiresAtStr = context.Request.Headers[XAuthorization.ExpiresAt]
.ToString ();
if (expiresAtStr.IsNullOrEmpty ()) {
expiresAtStr = await context
.GetTokenAsync (XAuthorization.ExpiresAt);
}
//
var expiresAt = expiresAtStr.ConvertTo<long> ();
//
return expiresAt;
}
/// <summary>
/// Retrieve All Required Tokens
/// </summary>
/// <returns></returns>
public static async Task<XTokenResponse> RetrieveTokensAsXTokenResponse (HttpContext context) {
//
var accessToken = await GetAccessToken (context);
var refreshToken = await GetRefreshToken (context);
var expiresAt = await GetTokenExpiresAt (context);
//
return new XTokenResponse {
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\StreamExtensions.cs
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using xCommons.Extensions;
namespace xIdentityService.Extensions
{
public static partial class StreamExtensions
{
/// <summary>
/// Converts an Stream to Async Enumerable ...
/// </summary>
/// <param name="stream"></param>
/// <param name="bufferSize"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async IAsyncEnumerable<byte[]> ToAsyncEnumerable(
this Stream stream,
int bufferSize = 8192,
[System.Runtime.CompilerServices.EnumeratorCancellation]
CancellationToken cancellationToken = default
)
{
//
var buffer = new byte[bufferSize];
while (true)
{
//
int read = await stream
.ReadAsync(
buffer,
0,
buffer.Length,
cancellationToken
);
//
if (read == 0)
{
yield break;
}
//
yield return buffer.Take(read).ToArray();
}
}
/// <summary>
/// Converts an Stream to Async Enumerable ...
/// </summary>
/// <param name="stream"></param>
/// <param name="bufferSize"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(
this Stream stream,
int bufferSize = 8192,
[System.Runtime.CompilerServices.EnumeratorCancellation]
CancellationToken cancellationToken = default
)
{
//
var buffer = new byte[bufferSize];
while (true)
{
//
int read = await stream
.ReadAsync(
buffer,
0,
buffer.Length,
cancellationToken
);
if (read == 0)
{
yield break;
}
//
T chunk = default(T);
var readedBuffer = buffer.Take(read).ToArray();
var str = readedBuffer.FromBytes();
if (str.IsNullOrEmpty())
{
yield return chunk;
}
try
{
chunk = str.FromJSON<T>();
}
catch
{ }
//
yield return chunk;
}
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XModelExtensions.cs
using xIdentityModels.Dtos;
using xModels.Dtos;
namespace xIdentityService.Extensions
{
public static class XModelExtensions
{
public static XPersonDto ToXPersonDto(this XOpenActionUserInfoDto source)
{
//
var result = new XPersonDto
{
Avatar = source.Avatar,
Lastname = source.Lastname,
Username = source.Username,
Firstname = source.Firstname,
};
//
return result;
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XTokenExtensions.cs
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using xCommons.Constants;
using xCommons.Extensions;
using xExceptions.Constants;
using xExceptions.Models;
using xIdentityModels.Models;
using xIdentityService.Interfaces;
public static partial class XTokenExtensions {
/// <summary>
/// Retrieve Tokens From Headers
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XLoginResponse RetrieveTokens (this HttpRequest source) {
//
var accessToken = source.Headers[XAuthorization.Header].ToString ();
var refreshToken = source.Headers[XAuthorization.RefreshToken].ToString ();
//
var expiresAtStr = source.Headers[XAuthorization.ExpiresAt].ToString ();
long expiresAt = expiresAtStr.ConvertTo<long> ();
//
if (accessToken
.ToNormalString ()
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
}
//
return new XLoginResponse {
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
}
/// <summary>
/// Retrieve Tokens From HttpContext
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static async Task<XLoginResponse> RetrieveTokens (this HttpContext source) {
//
var accessToken = await source.GetTokenAsync (XAuthorization.AccessToken);
if (accessToken
.ToNormalString ()
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
}
var refreshToken = await source.GetTokenAsync (XAuthorization.RefreshToken);
var expiresAtStr = await source.GetTokenAsync (XAuthorization.ExpiresAt);
long expiresAt = expiresAtStr.ConvertTo<long> ();
//
var headerRequestTokens = source.Request.RetrieveTokens ();
//
var result = new XLoginResponse {
AccessToken = accessToken ?? headerRequestTokens.AccessToken,
RefreshToken = refreshToken ?? headerRequestTokens.RefreshToken,
ExpiresAt = expiresAt != 0 ? expiresAt : headerRequestTokens.ExpiresAt
};
//
return result;
}
/// <summary>
/// Retrieve Tokens From ActionExecutingContext
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static async Task<XLoginResponse> RetrieveTokens (this ActionExecutingContext source) {
//
var result = await source.HttpContext.RetrieveTokens ();
return result;
}
/// <summary>
/// Retrieve Tokens From XUserInfo instance
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XTokenResponse RetrieveTokens (this XUserClaimsInfoDto source) {
//
var result = new XLoginResponse {
AccessToken = source.AccessToken,
RefreshToken = source.RefreshToken,
ExpiresAt = source.ExpiresAt
};
//
return result;
}
/// <summary>
/// Retrieve Tokens From IHeader Dictionary
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XLoginResponse RetrieveTokens (this IHeaderDictionary source) {
//
var accessToken = source[XAuthorization.Header].ToString () ?? "";
if (accessToken
.ToNormalString ()
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
}
//
var refreshToken = source[XAuthorization.RefreshToken].ToString () ?? "";
//
var expiresAtStr = source[XAuthorization.ExpiresAt].ToString () ?? "";
var expiresAt = expiresAtStr.ConvertTo<long> ();
//
var result = new XLoginResponse {
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
//
return result;
}
/// <summary>
/// Retrieve IXIdentityProvider from HttpContext
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static IXIdentityProvider GetXApiIdentityProvider (this FilterContext source) {
//
var services = source.HttpContext.RequestServices;
return (IXIdentityProvider) services
.GetService (typeof (IXIdentityProvider));
}
/// <summary>
/// Generate XLoginResponse instance based on TokenResponse
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XLoginResponse CreateXLoginResponse (this TokenResponse source) {
//
if (source.IsNull () ||
source.IsError) {
XException.InvalidToken.Throw ();
}
//
var expiresAt = new DateTimeOffset (DateTime.UtcNow)
.ToUnixTimeSeconds () +
source.ExpiresIn;
//
var result = new XLoginResponse {
AccessToken = source.AccessToken,
RefreshToken = source.RefreshToken,
ExpiresAt = expiresAt
};
//
return result;
}
/// <summary>
/// Add Authorization Tokens in Headers of
/// Specific IHeaderDictionary instance
/// </summary>
/// <param name="source"></param>
/// <param name="model"></param>
public static void SetXAuthenticationTokens (this IHeaderDictionary source, XLoginResponse model, string secret = null) {
//
source.Remove (XAuthorization.Header);
source.Remove (XAuthorization.RefreshToken);
source.Remove (XAuthorization.ExpiresAt);
source.Remove (XAuthorization.RevisionChecksum);
//
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
//
if (!secret.IsNullOrEmpty ()) {
var revisionChecksum = model.GetRevisionChecksum (secret);
source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
}
}
/// <summary>
/// Add Authorization Tokens in Headers of
/// Specific IHeaderDictionary instance
/// </summary>
/// <param name="source"></param>
/// <param name="model"></param>
public static void SetXAuthenticationTokens (this HttpRequestHeaders source, XLoginResponse model) {
//
source.Remove (XAuthorization.Header);
source.Remove (XAuthorization.RefreshToken);
source.Remove (XAuthorization.ExpiresAt);
source.Remove (XAuthorization.RevisionChecksum);
//
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
}
/// <summary>
/// Add Authorization Tokens in Headers of
/// Specific HttpRequest instance
/// </summary>
/// <param name="source"></param>
/// <param name="model"></param>
public static void SetXAuthenticationTokens (this HttpRequest source, XLoginResponse model) {
source.Headers.SetXAuthenticationTokens (model);
}
/// <summary>
/// Add Authorization Tokens in Headers of
/// Specific HttpRequest instance
/// </summary>
/// <param name="source"></param>
/// <param name="model"></param>
public static void SetXAuthenticationTokens (this HttpRequestMessage source, XLoginResponse model) {
source.Headers.SetXAuthenticationTokens (model);
}
/// <summary>
/// Add ReNewed Authorization Tokens in Headers of
/// Specific Response.
/// Later in HttpInterceptors we can Look for AccessToken-ReNewed
/// header Value and Renew User Tokens based on it
/// </summary>
/// <param name="source"></param>
/// <param name="model"></param>
public static void SetXAuthenticationTokens (this HttpResponse source, XLoginResponse model, string secret) {
source.Headers.SetXAuthenticationTokens (model, secret);
}
/// <summary>
/// Determines a Token Can Refrsh or not
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static bool IsRefreshable (this XLoginResponse source) {
//
var containsTokenData = !source.IsNull () &&
!source.AccessToken.IsNullOrEmpty () &&
!source.RefreshToken.IsNullOrEmpty ();
if (!containsTokenData) {
return false;
}
//
var current = new DateTimeOffset (DateTime.UtcNow)
.ToUnixTimeSeconds ();
//
// var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
//
return result;
}
/// <summary>
/// Generate a Revision Checksum for new Tokens
/// </summary>
/// <param name="source"></param>
/// <param name="secret"></param>
/// <returns></returns>
public static string GetRevisionChecksum (this XLoginResponse source, string secret) {
return (source.AccessToken +
secret +
source.RefreshToken +
secret +
source.ExpiresAt.ToString ()
)
.ToMd5String ();
}
/// <summary>
/// Generate a Revision Checksum for new Tokens
/// </summary>
/// <param name="source"></param>
/// <param name="secret"></param>
/// <returns></returns>
public static string GetRevisionChecksum (this XTokenResponse source, string secret) {
return (source.AccessToken +
secret +
source.RefreshToken +
secret +
source.ExpiresAt.ToString ()
)
.ToMd5String ();
}
/// <summary>
/// Check an XLoginResponse instance is Valid with it's revision
/// </summary>
/// <param name="source"></param>
/// <param name="checksum"></param>
/// <param name="secret"></param>
/// <returns></returns>
public static bool ValidateRevisionChecksum (this XLoginResponse source, string checksum, string secret) {
//
var xChecksum = source.GetRevisionChecksum (secret);
return checksum == xChecksum;
}
/// <summary>
/// Check an XTokenResponse instance is Valid with it's revision
/// </summary>
/// <param name="source"></param>
/// <param name="checksum"></param>
/// <param name="secret"></param>
/// <returns></returns>
public static bool ValidateRevisionChecksum (this XTokenResponse source, string checksum, string secret) {
//
var xChecksum = source.GetRevisionChecksum (secret);
return checksum == xChecksum;
}
/// <summary>
/// Retrieve Exception Details if Fails
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static Exception GetException (this TokenResponse source) {
//
// Validate Args ...
if (source.IsNull () || !source.IsError) {
return XException.ActionFailed.ToException ();
}
//
XError error = source.ErrorDescription.FromJSON<XError> ();
return error.ToException ();
}
/// <summary>
/// Convert XTokenResponse to Header Dictionary
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static IDictionary<string, string> ToHeaderDictionary (this XTokenResponse source) {
//
var result = new Dictionary<string, string> { { XAuthorization.RefreshToken, source.RefreshToken },
{ XAuthorization.ExpiresAt, source.ExpiresAt.ToString () }
};
//
return result;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XUserClaimsInfoDtoExtensions.cs
using xCommons.Extensions;
using xIdentityModels.Constants;
using xIdentityModels.Models;
namespace xIdentityService.Extensions {
public static class XUserClaimsInfoDtoExtensions {
public static string GetUserSelectByParam (
this XUserClaimsInfoDto source,
XUserSelectBy userSelectBy = XUserSelectBy.Username
) {
//
var result = "";
//
switch (userSelectBy) {
//
case XUserSelectBy.ID:
result = source.UserId;
break;
//
case XUserSelectBy.Username:
result = source.UserName;
break;
//
case XUserSelectBy.Email:
result = source.Email;
break;
//
case XUserSelectBy.MobileNumber:
result = source.PhoneNumber;
break;
}
//
if (result.IsNullOrEmpty ()) {
//
if (!source.UserId.IsNullOrEmpty ()) {
result = source.UserId;
} else if (!source.UserName.IsNullOrEmpty ()) {
result = source.UserName;
} else if (!source.Email.IsNullOrEmpty ()) {
result = source.Email;
} else if (!source.PhoneNumber.IsNullOrEmpty ()) {
result = source.PhoneNumber;
}
}
//
return result;
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseIdentityHttpProvider.cs
using System;
using System.IO;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using RestSharp;
using xCommons.Providers;
using xHttpService.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Models;
using xIdentityService.Models;
namespace xIdentityService.Interfaces
{
/// <summary>
/// an interface for Identity Provided Http Based Services ...
/// </summary>
public interface IXBaseIdentityHttpProvider
{
/// <summary>
/// Client Base Url ...
/// </summary>
/// <value></value>
string BaseUrl { get; }
/// <summary>
/// Logger ...
/// </summary>
/// <value></value>
ILogger Logger { get; }
/// <summary>
/// Powered Value ...
/// </summary>
/// <value></value>
string XPoweredValue { get; }
/// <summary>
/// Default Client Timeout ...
/// </summary>
/// <value></value>
int DefaultClientTimeout { get; }
/// <summary>
/// Default Buffering Chunk Size ...
/// </summary>
/// <value></value>
int DefaultBufferingChunckSize { get; }
/// <summary>
/// Validation Provider ...
/// </summary>
/// <value></value>
XValidationProvider ValidationProvider { get; }
/// <summary>
/// Get an Instance of Http Client
/// </summary>
/// <returns></returns>
HttpClient GetHttpClient(XTokenResponse tokens = null);
HttpClient GetHttpClient(XUserClaimsInfoDto userInfo = null);
/// <summary>
/// Get an Instance of RestClient
/// </summary>
/// <returns></returns>
RestClient GetRestClient(XTokenResponse tokens = null);
RestClient GetRestClient(XUserClaimsInfoDto userInfo = null);
/// <summary>
/// Get an Instance of RestRequest
/// </summary>
/// <param name="endpoint"></param>
/// <param name="addXPoweredValue"></param>
/// <param name=""></param>
/// <param name="headers"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
RestRequest GetRestRequet(
Enum endpoint,
bool addXPoweredValue = true,
IDictionary<string, string> @params = null,
IDictionary<string, string> headers = null,
IDictionary<string, string> queryStrings = null
);
/// <summary>
/// Handle Call Specific Request and retrieve Response
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="method"></param>
/// <param name="supportRefreshingTokens"></param>
/// <param name="cancellationToken"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
Task<T> RunRestRequest<T>(
RestClient client,
RestRequest request,
XHttpMethod method,
bool supportRefreshingTokens = true,
CancellationToken cancellationToken = default
);
/// <summary>
/// Access a Get Request Stream as AsyncEnumerable ...
/// </summary>
/// <param name="endpoint"></param>
/// <param name="bufferLength"></param>
/// <param name="addXPoweredValue"></param>
/// <param name="tokens"></param>
/// <param name="@params"></param>
/// <param name="headers"></param>
/// <param name="queryStrings"></param>
/// <param name="cancellationToken"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
Task<Stream> StreamData(
Enum endpoint,
int bufferLength = 8194,
bool addXPoweredValue = true,
XTokenResponse tokens = null,
IDictionary<string, string> @params = null,
IDictionary<string, string> headers = null,
IDictionary<string, string> queryStrings = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Handle Call Specified Request and Retrieve XBaseRestResponse<T> ...
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="method"></param>
/// <param name="supportRefreshingTokens"></param>
/// <param name="cancellationToken"></param>
/// <typeparam name="T"></typeparam>
/// <returns>an instance of XBaseRestResponse<T></returns>
Task<XBaseRestResponse<T>> RunRestRequestByResponse<T>(
RestClient client,
RestRequest request,
XHttpMethod method,
bool supportRefreshingTokens = true,
CancellationToken cancellationToken = default
);
/// <summary>
/// Get User SelectBy Param
/// </summary>
/// <param name="model"></param>
/// <param name="forceNotNull"></param>
/// <param name="excludes"></param>
/// <returns></returns>
string GetUserSelectByParam(
XActionRequest model,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
);
/// <summary>
/// Converts UserInfo to TokenResponse model ...
/// </summary>
/// <param name="userInfo"></param>
/// <returns></returns>
XTokenResponse ToTokenResponse(XUserClaimsInfoDto userInfo = null);
/// <summary>
/// Prepare Url Address of Specified Enum by Filling Params
/// and Query Strings Attach ...
/// </summary>
/// <param name="endpoint"></param>
/// <param name="attachBaseUrl"></param>
/// <param name="@params"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
string PrepareUrl(
Enum endpoint,
bool attachBaseUrl = false,
IDictionary<string, string> @params = null,
IDictionary<string, string> queryStrings = null
);
/// <summary>
/// Prepare Url Address by Filling Params
/// and Query Strings Attach ...
/// </summary>
/// <param name="url"></param>
/// <param name="attachBaseUrl"></param>
/// <param name="@params"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
string PrepareUrl(
string url,
bool attachBaseUrl = false,
IDictionary<string, string> @params = null,
IDictionary<string, string> queryStrings = null
);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseReferenced.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using xDataService.Models;
using xIdentityModels.Models;
using xModels.Base;
namespace xIdentityService.Interfaces
{
/// <summary>
/// a Referenced Service is a Service which can Referenced to other Items ...
/// </summary>
public interface IXBaseReferenced<TEntity, TKey>
where TEntity : XBaseEntity<TKey>
{
/// <summary>
/// Get Reference Identifier for Specified Provider and Specified Item ...
/// </summary>
/// <param name="providedFor"></param>
/// <param name="forProvidedId"></param>
/// <returns></returns>
string GetIdentifier<TReferenceKey>(
string providedFor,
TReferenceKey forProvidedId
);
/// <summary>
/// Check Specified Item has Refernce to Provider ...
/// </summary>
/// <param name="providedFor"></param>
/// <param name="forProvidedId"></param>
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<bool> IsProvidedFor<TReferenceKey>(
string providedFor,
TReferenceKey forProvidedId,
TKey id,
CancellationToken cancellationToken = default
);
/// <summary>
/// Add Specified Reference to Specified Item ...
/// </summary>
/// <param name="providedFor"></param>
/// <param name="forProvidedId"></param>
/// <param name="id"></param>
/// <param name="forIndex"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task AddReference<TReferenceKey>(
string providedFor,
TReferenceKey forProvidedId,
TKey id,
int forIndex = 0,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Remove Specified Reference from Specified Item ...
/// </summary>
/// <param name="providedFor"></param>
/// <param name="forProvidedId"></param>
/// <param name="id"></param>
/// <param name="forIndex"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task RemoveReference<TReferenceKey>(
string providedFor,
TReferenceKey forProvidedId,
TKey id,
int forIndex = 0,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Get Specified References ...
/// </summary>
/// <param name="providedFor"></param>
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <typeparam name="TReferenceKey"></typeparam>
/// <returns></returns>
Task<IEnumerable<XReference<string>>> GetReferences(
string providedFor,
TKey id,
CancellationToken cancellationToken = default
);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseReferencedController.cs
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using xDataService.Models;
using xModels.Base;
namespace xIdentityService.Interfaces
{
public interface IXBaseReferencedController<TEntity, TKey>
where TEntity : XBaseEntity<TKey>
{
/// <summary>
/// Check an Item Has Reference to Specified ProvideFor and Specified forProvidedId ...
/// </summary>
/// <param name="id"></param>
/// <param name="providedFor"></param>
/// <param name="forProvidedId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("{id}/Reference/IsProvidedFor")]
Task<ActionResult<bool>> IsProvidedFor(
[FromRoute] TKey id,
[FromQuery] string providedFor,
[FromQuery] object forProvidedId,
CancellationToken cancellationToken = default
);
/// <summary>
/// Add a Reference to Item for Specified ProvideFor and Specified forProvidedId ...
/// </summary>
/// <param name="id"></param>
/// <param name="providedFor"></param>
/// <param name="forProvidedId"></param>
/// <param name="forIndex"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("{id}/Reference")]
Task<ActionResult> AddReference(
[FromRoute] TKey id,
[FromQuery] string providedFor,
[FromQuery] object forProvidedId,
[FromQuery] int forIndex = 0,
CancellationToken cancellationToken = default
);
/// <summary>
/// Remove a Reference from Item for Specified ProvideFor and Specified forProvidedId ...
/// </summary>
/// <param name="id"></param>
/// <param name="providedFor"></param>
/// <param name="forProvidedId"></param>
/// <param name="forIndex"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpDelete("{id}/Reference")]
Task<ActionResult> RemoveReference(
[FromRoute] TKey id,
[FromQuery] string providedFor,
[FromQuery] object forProvidedId,
[FromQuery] int forIndex = 0,
CancellationToken cancellationToken = default
);
/// <summary>
/// Retrieve References of Specified Itemfor providedFor ...
/// </summary>
/// <param name="id"></param>
/// <param name="providedFor"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("{id}/References")]
Task<ActionResult<IEnumerable<XReference<string>>>> GetReferences(
[FromRoute] TKey id,
[FromQuery] string providedFor,
CancellationToken cancellationToken = default
);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXIdentityBaseReferencedProvider.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using xDataService.Models;
using xIdentityModels.Models;
using xModels.Dtos;
namespace xIdentityService.Interfaces
{
/// <summary>
/// in Some Cases we have Entities Which Can Referenced for Specified
/// Provider and Types ...
/// this interface Globaly introduce all available Actions for those ...
///
/// TKey: type of Provider Models Keys ...
/// TModel: type of Dto which Referenced ...
/// </summary>
public interface IXIdentityBaseReferencedProvider<TModel, TKey>
{
//
#region Props ...
/// <summary>
/// Provider Identifier ...
/// </summary>
string Provider { get; }
#endregion
//
#region Referenced Actions ...
/// <summary>
/// Get Specified Indexed Reference for Specific Provided ID ...
/// </summary>
/// <param name="providedForId"></param>
/// <param name="forIndex"></param>
/// <returns></returns>
Task<TModel> GetReference(
TKey providedForId,
int forIndex = 0
);
/// <summary>
/// Retrieve all Exists References of Specific Provided ID ...
/// </summary>
/// <param name="providedForId"></param>
/// <returns></returns>
Task<IEnumerable<TModel>> GetAllReferences(TKey providedForId);
/// <summary>
/// Extract all Referencing Models for Specified Key ...
/// </summary>
/// <param name="providedForId"></param>
/// <returns></returns>
Task<IEnumerable<XReference<TKey>>> GetAllReferencings(TKey providedForId);
/// <summary>
/// Count References ...
/// </summary>
/// <param name="providedForId"></param>
/// <returns></returns>
Task<int> CountReferences(TKey providedForId);
/// <summary>
/// Retrieve References of Specific Provided ID as Query ...
/// </summary>
/// <param name="providedForId"></param>
/// <returns></returns>
Task<XQueryResult<TModel>> QueryReferences(
XQuery query,
TKey providedForId
);
/// <summary>
/// Add Reference a Model to Specific Provided ID ...
/// </summary>
/// <param name="model"></param>
/// <param name="providedForId"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <returns></returns>
Task<bool> AddReference(
TModel model,
TKey providedForId,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
/// <summary>
/// Add Reference a Model to Specific XRefence<TKey> ...
/// </summary>
/// <param name="model"></param>
/// <param name="reference"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <returns></returns>
Task<bool> AddReference(
TModel model,
XReference<TKey> reference,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
/// <summary>
/// Remove Reference a Model for Specific Provided ID ...
/// </summary>
/// <param name="model"></param>
/// <param name="providedForId"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <returns></returns>
Task<bool> RemoveReference(
TModel model,
TKey providedForId,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
/// <summary>
/// Remove Reference a Model for Specific XRefence<TKey> ...
/// </summary>
/// <param name="model"></param>
/// <param name="providedForId"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <returns></returns>
Task<bool> RemoveReference(
TModel model,
XReference<TKey> reference,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
/// <summary>
/// Remove All References to Specified Key ...
/// </summary>
/// <param name="providedForId"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <returns></returns>
Task<bool> RemoveReferences(
TKey providedForId,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXIdentityProvider.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Http;
using RestSharp;
using xHttpService.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
using xModels.Dtos;
namespace xIdentityService.Interfaces
{
public partial interface IXIdentityProvider
{
//
string BaseUrl { get; }
string RevisionSecretKey { get; }
IXSecurityProvider SecurityProvider { get; }
//
#region Tools ...
string GetUserSelectByParam(
XActionRequest model,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
);
#endregion
//
#region Tools ...
Task<T> RunRestRequest<T>(
RestClient client,
RestRequest request,
XHttpMethod method,
bool supportRefreshingTokens = false
);
#endregion
//
#region Authentication ...
Task<DiscoveryDocumentResponse> RequestDiscoveryDocument();
Task<XTokenResponse> RequestScopeAccessToken(string scope);
Task<TokenIntrospectionResponse> Introspection(XTokenResponse model);
Task<XLoginResponse> Login(XLoginRequest model);
Task Logout(XTokenResponse model);
Task<XTokenResponse> Authenticate(XLoginRequest model);
Task<XTokenResponse> RefreshTokens(XTokenResponse model);
Task ChangePassword(
XTokenResponse tokens,
XActionRequest model
);
#endregion
//
#region Profile ...
Task<IEnumerable<string>> GetUserNames(
XTokenResponse tokens,
string userIds
);
Task<IEnumerable<XUserNameIdResponse>> GetUserNameIds(
XTokenResponse tokens,
XUserNameIdRequest model
);
Task<XUserProfileDto> GetUserProfile(
XTokenResponse tokens,
string userSelectByParam
);
Task<XQueryResult<XUserProfileDto>> QueryUsers(
XTokenResponse tokens,
XQuery query
);
Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers(
XTokenResponse tokens,
string role,
XQuery query,
bool forceRole = false
);
Task<XQueryResult<XProfileImage>> QueryAvatars(
XTokenResponse tokens,
string userSelectByParam,
XQuery query
);
Task<XUserProfileDto> ProfileUpdateAsync(
XTokenResponse tokens,
string userSelectByParam,
XProfileUpdateRequest model
);
Task<XUserProfileDto> FullProfileUpdateAsync(
XTokenResponse tokens,
string userSelectByParam,
XProfileUpdateRequest request
);
Task<XUserProfileDto> AddAvatar(
XTokenResponse tokens,
IFormFile file
);
Task<XUserProfileDto> AddAvatars(
XTokenResponse tokens,
IFormFileCollection files
);
Task<XUserProfileDto> SetAvatar(
XTokenResponse tokens,
int avatarId
);
Task<XUserProfileDto> RemoveAvatars(
XTokenResponse tokens,
string avatarIds
);
#endregion
//
#region Search ...
/// <summary>
/// Query Open To Search User Profiles ...
/// </summary>
/// <param name="tokens">requested user's identifiers</param>
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
Task<XQueryResult<XUserProfileDto>> QueryOpenToSearchUsers(
XTokenResponse tokens,
XQuery query
);
#endregion
//
#region Registration ...
Task<bool> CanRegister(string userSelectByParam);
Task<XActionResponse> InviteUser(
XTokenResponse tokens,
XActionRequest model
);
Task<XActionResponse> RequestRegistration(
XActionRequest model
);
Task<XActionResponse> AddAccountInfo(
XActionRequest model
);
Task<XActionResponse> AttachProfileImage(
string actionToken,
IFormFile file
);
Task FinishRegistration(XActionRequest model);
Task<bool> IsConfirmedEmail(
XTokenResponse tokens,
string userSelectByParam
);
Task<bool> IsConfirmedMobile(
XTokenResponse tokens,
string userSelectByParam
);
Task RequestConfirmRegistration(XActionRequest model);
Task ConfirmRegistration(
XActionRequest model
);
Task<XActionResponse> RequestConfirmMobile(XActionRequest model);
Task<XActionResponse> ConfirmMobileNumber(XActionRequest model);
Task<XActionResponse> RequestConfirmEmail(XActionRequest model);
Task<XActionResponse> ConfirmEmailAddress(XActionRequest model);
Task<XActionResponse> RequestResetPassword(XActionRequest model);
Task ResetPassword(XActionRequest model);
#endregion
//
#region Friendship ...
Task<XFriendshipFollowing> Follow(
XTokenResponse tokens,
string destUser
);
Task<bool> Cancel(
XTokenResponse tokens,
string destUser
);
Task UnFollowFollower(
XTokenResponse tokens,
string destUser
);
Task UnFollowFollowing(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipFollowing> Block(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipFollowing> UnBlock(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipFollower> AcceptRequest(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipFollower> RejectRequest(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipInfoDto> GetFriendshipInfo(
XTokenResponse tokens,
string destUser
);
Task<bool> IsFollower(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipFollower> GetFollower(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipState> GetFollowerState(
XTokenResponse tokens,
string destUser
);
Task<IEnumerable<XFriendshipFollower>> GetFollowers(XTokenResponse tokens);
Task<IEnumerable<XFriendshipFollower>> GetAllFollowers(XTokenResponse tokens);
Task<IEnumerable<string>> GetFollowingList(XTokenResponse tokens);
Task<XQueryResult<XFriendDto>> QueryFollowers(
XQuery query,
string destUser,
XTokenResponse tokens
);
Task<bool> IsFollowing(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipFollowing> GetFollowing(
XTokenResponse tokens,
string destUser
);
Task<XFriendshipState> GetFollowingState(
XTokenResponse tokens,
string destUser
);
Task<IEnumerable<XFriendshipFollowing>> GetFollowings(XTokenResponse tokens);
Task<IEnumerable<XFriendshipFollowing>> GetAllFollowings(XTokenResponse tokens);
Task<IEnumerable<string>> GetFollowersList(XTokenResponse tokens);
Task<XQueryResult<XFriendDto>> QueryFollowings(
XQuery query,
string destUser,
XTokenResponse tokens
);
#endregion
//
#region Admin ...
Task<IEnumerable<string>> Ban(
XTokenResponse tokens,
XUserNameIdRequest model
);
Task<IEnumerable<string>> UnBan(
XTokenResponse tokens,
XUserNameIdRequest model
);
Task<bool> IsBanned(
XTokenResponse tokens,
string userSelectByParam
);
#endregion
//
#region Open Actions ...
//
XDeviceDto GetDevice();
//
Task<XOpenActionInnerDto> OpenGet(
XOpenActionInnerDto model
);
//
Task<XOpenActionUserInfoDto> GetUserInfo(
XDeviceDto device,
string userSelectByParam
);
Task<XOpenActionUserInfoDto> GetUserInfo(
XOpenActionInnerDto dto
);
Task<XOpenActionUserInfoDto> GetUserInfo(
string token,
string request
);
//
Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
XDeviceDto device,
string ids
);
Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
XOpenActionInnerDto dto
);
Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
string token,
string request
);
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXProxyHelper.cs
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using xIdentityService.Configuration;
namespace xIdentityService.Interfaces {
public interface IXProxyHelper {
/// <summary>
/// Proxy Configuration ...
/// </summary>
/// <value></value>
XProxyConfiguration Configuration { get; }
/// <summary>
/// retrie Normalize Host ...
/// </summary>
/// <returns></returns>
string NormalizeHost ();
/// <summary>
/// Validate XProxy Configuration for Client ...
/// </summary>
/// <returns></returns>
bool ValidateConfiguration ();
/// <summary>
/// Retrieve all Prepared url of Routes ...
/// </summary>
/// <returns></returns>
IEnumerable<string> GetRouteUrls ();
/// <summary>
/// retrieve all registred Routes ...
/// </summary>
/// <returns></returns>
IEnumerable<XProxyRouteDescriptor> GetRoutes ();
/// <summary>
/// Prepare a request url for a Proxy Route ...
/// </summary>
/// <param name="url"></param>
/// <param name="descriptor"></param>
/// <returns></returns>
string PrepareActionUrlForXProxyRoute (
string url,
XProxyRouteDescriptor descriptor
);
/// <summary>
/// Prepare a request url for a Selected Proxy Route ...
/// </summary>
/// <param name="url"></param>
/// <param name="whereClause"></param>
/// <returns></returns>
string PrepareActionUrlForXProxyRoute (
string url,
Expression<Func<XProxyRouteDescriptor, bool>> whereClause
);
/// <summary>
/// Find an Specific Route ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
XProxyRouteDescriptor FindRoute (Expression<Func<XProxyRouteDescriptor, bool>> whereClause);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXSecurityProvider.cs
namespace xIdentityService.Interfaces
{
public partial interface IXSecurityProvider
{
string Encrypt(string plainText);
string Decrypt(string cipherText);
string EncryptFromBytes(byte[] textBytes);
string DecryptFromBytes(byte[] cipherBytes);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXTokenProvider.cs
using System.Threading.Tasks;
using xIdentityModels.Models;
namespace xIdentityService.Interfaces {
public partial interface IXTokenProvider {
Task<bool> IsTokenExists (string accessToken);
Task<bool> IsTokenExists (XTokenResponse tokens);
Task<bool> RemoveToken (string accessToken);
Task<bool> RemoveToken (XTokenResponse tokens);
Task<XTokenResponse> RetrieveToken (string accessToken);
Task<bool> AddToken (XTokenResponse tokens);
Task<bool> UpdateToken (XTokenResponse tokens);
Task<bool> AddOrUpdateToken (XTokenResponse tokens);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Middlewares\XIdentityTokenRefresher.cs
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using xCommons.Constants;
using xCommons.Extensions;
using xIdentityModels.Extensions;
using xIdentityService.Interfaces;
namespace xIdentityService.Middlewares {
public partial class XIdentityTokenRefresherMiddleware {
//
#region Properties ...
private readonly ILogger logger;
private readonly RequestDelegate next;
private readonly IXTokenProvider tokenProvider;
private readonly IXIdentityProvider identityProvider;
#endregion
//
#region Constructor ...
public XIdentityTokenRefresherMiddleware (
RequestDelegate next,
ILoggerFactory loggerFactory,
IXTokenProvider tokenProvider,
IXIdentityProvider identityProvider
) {
//
this.next = next;
this.tokenProvider = tokenProvider;
this.identityProvider = identityProvider;
this.logger = loggerFactory
.CreateLogger<XIdentityTokenRefresherMiddleware> ();
}
#endregion
//
#region Actions ...
public async Task Invoke (HttpContext context) {
//
// Handle Request ...
await HandleRequest (context);
//
// Do Main Task ...
try {
await next.Invoke (context);
} catch (Exception ex) {
logger.LogError ($"Error: {ex.Message}");
}
//
// Handle Response ...
await HandleResponse (context);
}
#endregion
//
#region Private ...
private async Task HandleRequest (HttpContext context) {
//
// Log ...
logger.LogInformation ($"Start Process Request ...");
//
// Check Access Token ...
var hasAccessToken = HasAccessToken (context);
if (!hasAccessToken) {
return;
}
//
// Check Access Token ...
var accessToken = GetAccessToken (context);
var isExists = await tokenProvider
.IsTokenExists (accessToken);
if (!isExists) {
return;
}
//
// Try Check is Refreshable ...
var tokens = await tokenProvider
.RetrieveToken (accessToken);
if (tokens.IsNull ()) {
return;
}
//
// Check is Expired or Refreshable ...
var isRefreshable = tokens.IsRefreshable ();
if (!isRefreshable) {
return;
}
//
// Refresh Token ...
var refreshedTokens = await identityProvider
.RefreshTokens (tokens);
if (refreshedTokens.IsNull ()) {
return;
}
//
// Set Refreshed AccessToken to Request ...
context
.Request
.Headers[XAuthorization.Header] =
$"{XAuthorization.TokenIdentifier}{refreshedTokens.AccessToken}";
}
private async Task HandleResponse (HttpContext context) {
//
// Log ...
logger.LogInformation ($"Start Process Response ...");
//
await Task.Run (() => { });
}
private bool HasAccessToken (HttpContext context) {
//
// Check Headers ...
if (context.IsNull () ||
context.Request.IsNull () ||
context.Request.Headers.IsNull ()) {
return false;
}
//
var result = context
.Request
.Headers
.ContainsKey (
XAuthorization.Header
);
//
return result;
}
private string GetAccessToken (HttpContext context) {
//
var hasAccessToken = HasAccessToken (context);
if (!hasAccessToken) {
return string.Empty;
}
//
// Get Result ...
var result = context
.Request
.Headers[
XAuthorization.Header
];
result = result
.ToString ()
.Replace (
XAuthorization.TokenIdentifier,
""
);
//
return result;
}
#endregion
}
/// <summary>
/// Provide all DI Requirements for XIdentityTokenRefresher Middleware
/// </summary>
public static class XIdentityTokenRefresherDIHelper {
/// <summary>
/// Use XTokenValidator Middleware
/// </summary>
/// <param name="app"></param>
public static void UseXIdentityTokenRefresher (this IApplicationBuilder app) {
app.UseMiddleware<XIdentityTokenRefresherMiddleware> ();
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Middlewares\XProxyMiddleware.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using IdentityModel;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityService.Configuration;
using xIdentityService.Constants;
using xIdentityService.Interfaces;
using xIdentityService.Providers;
using xModels.Base;
namespace xIdentityService.Middlewares {
/// <summary>
/// Proxy Server Middleware ...
/// </summary>
public class XProxyMiddleware : XBaseClass {
//
#region Pros ...
private readonly HttpClient HTTP_CLIENT;
private readonly RequestDelegate NEXT_MIDDLEWARE;
private readonly XProxyConfiguration CONFIGURATION;
#endregion
//
#region Constructor ...
public XProxyMiddleware (
ILoggerFactory loggerFactory,
RequestDelegate nextMiddleware,
XProxyConfiguration configuration,
IHttpClientFactory httpClientFactory
) : base (loggerFactory) {
//
this.CONFIGURATION = configuration;
this.NEXT_MIDDLEWARE = nextMiddleware;
//
// Create Http Client ...
this.HTTP_CLIENT = httpClientFactory
.CreateClient (XProxyConstants.XPROXY_HTTP_CLIENT);
//
// Logging Server Configuration ...
LogXProxyServerConfig ();
}
#endregion
//
#region Public ...
public async Task InvokeAsync (HttpContext context) {
//
#region Bussiness Logic ...
//
var routeDescriptor = GetRouteDescriptor (context.Request);
if (!routeDescriptor.IsNull ()) {
//
#region Handle Authorization ...
//
try {
//
// Handle XPowered ...
if (routeDescriptor.EnableXPoweredByAthorization) {
//
var isPoweredByPass = context.Request.Headers
.Any (h => h.Key
.ToNormalString () == xCommons.Constants.XAuthorization.XPoweredBy
.ToNormalString () &&
h.Value
.ToString ()
.ToNormalString () == CONFIGURATION.XPoweredValue
.ToNormalString ()
);
//
if (!isPoweredByPass) {
ThrowNotAuthorizedException ();
}
}
//
// Handle EndableAuthorization ...
if (routeDescriptor.EnableAuthorization) {
//
// Retrieve User Info for Authentication ...
var userName = context.User.Identity.Name;
var isUserAuthenticated = !userName.IsNull () &&
context.User.Identity.IsAuthenticated;
if (!isUserAuthenticated &&
!routeDescriptor.AllowedScopes.HasChild ()
) {
ThrowNotAuthorizedException ();
}
//
// Check Allowed Scopes Authorization ...
if (routeDescriptor.AllowedScopes.HasChild ()) {
//
var scopeClaims = context.User.Claims
.Where (c => c.Type == JwtClaimTypes.Scope)
.Select (c => c.Value);
var isScopePassed = scopeClaims.HasChild () &&
scopeClaims.Any (c => routeDescriptor.AllowedScopes
.Any (allowedScope => allowedScope
.ToNormalString () == c
.ToNormalString ()
)
);
if (!isScopePassed) {
ThrowNotAuthorizedException ();
}
}
//
// Check Allowed Roles Authorization ...
if (
isUserAuthenticated &&
routeDescriptor.AllowedRoles.HasChild ()
) {
//
var roleClaim = context.User.Claims
.FirstOrDefault (c => c.Type == JwtClaimTypes.Role);
var isRolePassed = !roleClaim.IsNull () &&
routeDescriptor.AllowedRoles
.Any (role => role
.ToNormalString () == roleClaim.Value
.ToNormalString ());
if (!isRolePassed) {
ThrowNotAuthorizedException ();
}
}
}
} catch {
context.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
return;
}
#endregion
//
// Extract Request Uri from Received Request ...
var requestUri = GetUri (context.Request);
if (!requestUri.IsNull ()) {
//
// Retrieve Request based on current ...
var request = GetRequestMessage (
uri: requestUri,
context: context
);
//
SendLog ($"Send Request to Recieve Response ...", LogLevel.Information);
//
// Send Request and Retrieve Response ...
try {
//
var response = await HTTP_CLIENT.SendAsync (
request,
HttpCompletionOption.ResponseContentRead
);
//
// Set Current Response Status Code ...
context.Response.StatusCode = (int) response.StatusCode;
//
// Retrieve Response Headers and Set To Current Response ...
HandleResponseHeaders (context, response);
//
// Processing Response Content ...
await ProcessResponseContent (context, response);
} catch (Exception ex) {
//
LogMessage ($"Exception: {ex.Message}", LogLevel.Error);
//
context.Response.StatusCode = (int) HttpStatusCode.BadRequest;
}
//
return;
}
}
#endregion
//
await NEXT_MIDDLEWARE (context);
}
#endregion
//
#region Private ...
/// <summary>
/// Throw Required Exception ...
/// </summary>
private void ThrowNotAuthorizedException () {
throw XException.NotAuthorized.ToException ();
}
/// <summary>
/// Show propper logs if Enabled ...
/// </summary>
/// <param name="message"></param>
/// <param name="logLevel"></param>
private void SendLog (string message, LogLevel logLevel = LogLevel.Information) {
//
if (!CONFIGURATION.EnableLogging) {
return;
}
//
LogMessage (
message: message,
logLevel: logLevel
);
}
/// <summary>
/// Log Proxy Server Configuration ...
/// </summary>
private void LogXProxyServerConfig () {
//
// Retrieve XProxyConfiguration class from Configurations and Validate them ...
if (CONFIGURATION.IsNull ()) {
throw XException.InvalidConfiguration.ToException ();
}
//
// Try to Log Proxy Configuration ...
ConsoleMessage ("===============================");
ConsoleMessage ("= Proxy Server Configurations: ");
ConsoleMessage ("===============================");
//
ConsoleMessage ($"Host: {CONFIGURATION.Host}");
ConsoleMessage ($"XPoweredValue: {CONFIGURATION.XPoweredValue}");
ConsoleMessage ($"EnableLogging: {CONFIGURATION.EnableLogging}");
ConsoleMessage ($"DisableSSLCheck: {CONFIGURATION.DisableSSLCheck}");
ConsoleMessage ($"AllowAutoRedirect: {CONFIGURATION.AllowAutoRedirect}");
ConsoleMessage ($" ");
ConsoleMessage ($"Routes: ");
ConsoleMessage ($" ");
//
CONFIGURATION.Routes
.ToList ()
.ForEach (routeDescriptor => {
ConsoleMessage ("===============================");
ConsoleMessage ($"= Rote => {routeDescriptor.Route}");
ConsoleMessage ("===============================");
ConsoleMessage ($"AllowedRoles: {routeDescriptor.AllowedRoles.ToJSON()}");
ConsoleMessage ($"AllowedScopes: {routeDescriptor.AllowedScopes.ToJSON()}");
ConsoleMessage ($"EnableAuthorization: {routeDescriptor.EnableAuthorization}");
ConsoleMessage ($"EnableXPoweredByAthorization: {routeDescriptor.EnableXPoweredByAthorization}");
ConsoleMessage ($" ");
});
}
/// <summary>
/// Retrieve Destination Request Path based on Current Request ...
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private Uri GetUri (HttpRequest request) {
//
// Create temp result ...
Uri result = null;
var requestPath = "";
//
SendLog ($"Receive Request: {request.Path} ...", LogLevel.Information);
//
// Try to Findout Route Descriptor ...
var routeDescriptor = GetRouteDescriptor (request);
//
// Route Descriptor Exists && Path for Delegating ...
if (!routeDescriptor.IsNull () &&
request.Path
.StartsWithSegments (routeDescriptor.Route)
) {
//
// Prepare Request Path by Cleaning Starter Path Segment ...
requestPath = request.Path
.ToString ()
.Replace (routeDescriptor.Route, "");
if (requestPath.StartsWith ("/")) {
requestPath = requestPath.Substring (1);
}
//
// Decoding URL ...
requestPath = HttpUtility.UrlDecode (requestPath);
//
var colonIndex = requestPath.IndexOf (":");
if (colonIndex > -1) {
//
var doubleSlash = requestPath.Substring (colonIndex + 1, 2);
var isDoubleSlash = doubleSlash == "//";
//
if (!isDoubleSlash) {
//
var protocol = requestPath
.Substring (0, colonIndex);
var section = requestPath
.Substring (colonIndex + 2, requestPath.Length - colonIndex - 2);
//
requestPath = $"{protocol}://{section}";
}
}
}
//
// Validate Request Path ...
if (!requestPath.IsNullOrEmpty ()) {
//
result = new Uri (requestPath);
//
SendLog ($"Process Request: {requestPath} ...", LogLevel.Information);
}
//
return result;
}
/// <summary>
/// Retrieve Propper Request Message based on HttpContext and uri ...F
/// </summary>
/// <param name="context"></param>
/// <param name="uri"></param>
/// <returns></returns>
private HttpRequestMessage GetRequestMessage (
HttpContext context,
Uri uri
) {
//
var result = new HttpRequestMessage ();
FillRequest (context, result);
//
// Handle Queries ...
SendLog ($"Start Processing Queries: ");
foreach (var query in context.Request.Query) {
//
var key = query.Key;
var value = HttpUtility.UrlDecode (query.Value);
//
uri = new Uri (
QueryHelpers.AddQueryString (
uri.OriginalString,
new Dictionary<string, string> {
[key] = value
}
)
);
//
SendLog ($"Query : {key}:{value} was Processed ...");
}
//
result.RequestUri = uri;
result.Headers.Host = uri.Host;
//
// Retrieve Request Method ...
result.Method = GetMethod (context.Request.Method);
//
return result;
}
/// <summary>
/// Fill Request Message by provide HttpContext ...
/// </summary>
/// <param name="context"></param>
/// <param name="message"></param>
private void FillRequest (
HttpContext context,
HttpRequestMessage message
) {
//
var requestMethod = context.Request.Method;
//
if (!HttpMethods.IsGet (requestMethod) &&
!HttpMethods.IsHead (requestMethod) &&
!HttpMethods.IsTrace (requestMethod) &&
!HttpMethods.IsDelete (requestMethod)
) {
//
var streamContent = new StreamContent (context.Request.Body);
message.Content = streamContent;
}
//
// Handle Base Headers ...
var regularHeaders = context.Request.Headers
.Where (hr => hr.Key != XProxyConstants.XPROXY_ACCEPTED_HEADERS &&
!hr.Key
.Contains (
XProxyConstants.XPROXY_FORWARD_HEADER
)
);
//
// Handle Aceepted Headers ...
IEnumerable<string> acceptedHeaders = null;
var acceptedHeadersKeyValue = context.Request.Headers
.FirstOrDefault (hr =>
hr.Key == XProxyConstants.XPROXY_ACCEPTED_HEADERS
);
if (!acceptedHeadersKeyValue.IsNull ()) {
//
acceptedHeaders = acceptedHeadersKeyValue.Value
.ToString ()
.ParseListString<string> ();
//
// Filter Regular Headers ...
if (
regularHeaders.HasChild () &&
acceptedHeaders.HasChild ()
) {
//
regularHeaders = regularHeaders
.Where (rhr => acceptedHeaders
.Contains (rhr.Key)
);
}
}
foreach (var header in regularHeaders) {
//
SendLog ($"Adding Header: {header.Key}:{header.Value} ...");
//
message.Headers.Add (
header.Key,
header.Value
.ToString ()
);
}
//
// Handle ForWarded Headers ...
// Since Forward Headers is Custom kind, this means user actually need this
// Header, so there is no need to put them on AcceptedHeaders ...
var forwardHeaders = context.Request.Headers
.Where (hr => hr.Key
.Contains (
XProxyConstants.XPROXY_FORWARD_HEADER
)
);
foreach (var header in forwardHeaders) {
//
var key = header.Key
.Replace (
XProxyConstants.XPROXY_FORWARD_HEADER,
string.Empty
);
//
SendLog ($"Forwarding Header: {header.Key} to {key} ...");
//
message.Headers
.Add (
key,
header.Value
.ToString ()
);
}
}
/// <summary>
/// Retreive and Extract Method Type of HttpRequest ...
/// </summary>
/// <param name="method"></param>
/// <returns></returns>
private static HttpMethod GetMethod (string method) {
//
if (HttpMethods.IsDelete (method)) {
return HttpMethod.Delete;
} else if (HttpMethods.IsGet (method)) {
return HttpMethod.Get;
} else if (HttpMethods.IsHead (method)) {
return HttpMethod.Head;
} else if (HttpMethods.IsOptions (method)) {
return HttpMethod.Options;
} else if (HttpMethods.IsPost (method)) {
return HttpMethod.Post;
} else if (HttpMethods.IsPut (method)) {
return HttpMethod.Put;
} else if (HttpMethods.IsTrace (method)) {
return HttpMethod.Trace;
}
//
return new HttpMethod (method);
}
/// <summary>
/// add all headers exists in HttpResponse MEssage to Current Context Response Headers ...
/// </summary>
/// <param name="context"></param>
/// <param name="message"></param>
private void HandleResponseHeaders (
HttpContext context,
HttpResponseMessage message
) {
//
// Handle Message Headers ...
foreach (var header in message.Headers) {
context.Response.Headers[header.Key] = header.Value
.ToArray ();
}
//
// Handle Message Content Headers ...
foreach (var header in message.Content.Headers) {
context.Response.Headers[header.Key] = header.Value
.ToArray ();
}
//
context.Response.Headers.Remove ("transfer-encoding");
}
/// <summary>
/// Processing Response Content and Handle it on HttpContextResponse ...
/// </summary>
/// <param name="context"></param>
/// <param name="response"></param>
/// <returns></returns>
private async Task ProcessResponseContent (
HttpContext context,
HttpResponseMessage message
) {
//
// Reading Content as Byte Array ...
var contentBytes = await message.Content
.ReadAsByteArrayAsync ();
//
// Check ContentType of Response ...
if (
IsContentOfType (message, XResponseContentTypes.HTML) ||
IsContentOfType (message, XResponseContentTypes.JSON) ||
IsContentOfType (message, XResponseContentTypes.JavaScript)
) {
//
// If their String Content ...
var stringContent = Encoding.UTF8.GetString (contentBytes);
//
// TODO: here we can change String Contents ...
//
// Writing new Content to Response ...
await context.Response
.WriteAsync (
stringContent,
Encoding.UTF8
);
} else {
//
// if they have non string content ...
await context.Response.Body
.WriteAsync (
buffer: contentBytes,
offset: 0,
count: contentBytes.Length
);
}
//
SendLog ($"Response Content Processed ...", LogLevel.Information);
}
/// <summary>
/// Check Content Type of Specific Response ...
/// </summary>
/// <param name="response"></param>
/// <param name="type"></param>
/// <returns></returns>
private bool IsContentOfType (
HttpResponseMessage response,
string type
) {
//
// Create EMpty Result ...
var result = false;
//
// Retrieve and Check Content Type of Response ...
if (response.Content?.Headers?.ContentType != null) {
result = response.Content.Headers.ContentType.MediaType == type;
}
//
return result;
}
/// <summary>
/// Retrieve and Extract Route Descriptor ...
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private XProxyRouteDescriptor GetRouteDescriptor (HttpRequest request) {
//
// Validate Args ...
if (
CONFIGURATION.IsNull () ||
!CONFIGURATION.Routes.HasChild ()
) {
return null;
}
//
var result = CONFIGURATION.Routes
.FirstOrDefault (rd => !rd.Route.IsNullOrEmpty () &&
request.Path
.StartsWithSegments (rd.Route
.ToNormalString ()
)
);
//
return result;
}
#endregion
}
/// <summary>
/// Provide all requirements for Dependency Injection Handler ...
/// </summary>
public static class XDIHelperExtension {
/// <summary>
/// Retrieve XProxy Middelware Configuration from Configuration ...
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static XProxyConfiguration GetXProxyConfiguration (this IConfiguration config) {
//
var xProxyConfiguration = config.GetSection (ConfigurationNodeNames.XPROXY_CONFIGURATION_NODE_NAME);
return xProxyConfiguration.Get<XProxyConfiguration> ();
}
/// <summary>
/// Register HTTP Handler for XProxy Server ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="httpHandler"></param>
public static void AddXProxyHttpHandler (
this IServiceCollection services,
IConfiguration configuration,
HttpClientHandler httpHandler = null
) {
//
var proxyConfig = configuration.GetXProxyConfiguration ();
if (proxyConfig.IsNull ()) {
throw XException.InvalidConfiguration.ToException ();
}
//
services.AddXProxyHttpHandler (
httpHandler: httpHandler,
configuration: proxyConfig
);
}
/// <summary>
/// Register HTTP Handler for XProxy Server ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="httpHandler"></param>
public static void AddXProxyHttpHandler (
this IServiceCollection services,
XProxyConfiguration configuration,
HttpClientHandler httpHandler = null
) {
//
if (configuration.IsNull ()) {
throw XException.InvalidConfiguration.ToException ();
}
//
if (httpHandler.IsNull ()) {
httpHandler = new HttpClientHandler ();
}
//
httpHandler.AllowAutoRedirect = configuration.AllowAutoRedirect;
//
if (configuration.DisableSSLCheck) {
httpHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
}
//
services
.AddHttpClient (XProxyConstants.XPROXY_HTTP_CLIENT)
.ConfigurePrimaryHttpMessageHandler (() => {
return httpHandler;
});
}
/// <summary>
/// Register XProxy On Server ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="httpHandler"></param>
public static void AddXProxyServer (
this IServiceCollection services,
IConfiguration configuration,
HttpClientHandler httpHandler = null
) {
//
var proxyConfig = configuration.GetXProxyConfiguration ();
//
services.AddXProxyServer (
httpHandler: httpHandler,
configuration: proxyConfig
);
}
/// <summary>
/// Register XProxy On Server ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="httpHandler"></param>
public static void AddXProxyServer (
this IServiceCollection services,
XProxyConfiguration configuration,
HttpClientHandler httpHandler = null
) {
//
// Validate Args ...
if (configuration.IsNull ()) {
throw XException.InvalidConfiguration.ToException ();
}
//
// Register Proxy Configuration ...
services.AddSingleton<XProxyConfiguration> (configuration);
//
// Regiter Proxy Handler ...
services.AddXProxyHttpHandler (
httpHandler: httpHandler,
configuration: configuration
);
}
/// <summary>
/// Register XProxy On Server ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXProxyClient (
this IServiceCollection services,
IConfiguration configuration
) {
//
var proxyConfig = configuration.GetXProxyConfiguration ();
//
services.AddXProxyClient (
configuration: proxyConfig
);
}
/// <summary>
/// Register XProxy On Client ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXProxyClient (
this IServiceCollection services,
XProxyConfiguration configuration
) {
//
// Validate Args ...
if (configuration.IsNull ()) {
throw XException.InvalidConfiguration.ToException ();
}
//
// Register Proxy Configuration ...
services.AddSingleton<XProxyConfiguration> (configuration);
//
// Register IXProxyHelper ...
services.AddSingleton<IXProxyHelper, XProxyHelper> ();
}
/// <summary>
/// Adding XProxy Middleware to Applications ...
/// </summary>
/// <param name="app"></param>
public static void UseXProxy (this IApplicationBuilder app) {
app.UseMiddleware<XProxyMiddleware> ();
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Models\XBaseRestResponse.cs
using RestSharp;
namespace xIdentityService.Models
{
public class XBaseRestResponse<T>
{
public T Model { get; set; }
public IRestResponse Response { get; set; }
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Admin.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using xCommons.Extensions;
using xHttpService.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityService.Constants;
namespace xIdentityService.Providers {
public partial class XIdentityProvider {
//
#region Admin ...
/// <summary>
/// Ban Specific Users
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
/// <returns>a list of banned users identifiers</returns>
public async Task<IEnumerable<string>> Ban (
XTokenResponse tokens,
XUserNameIdRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (
tokens,
model
)
.AddNotEmpty (tokens.AccessToken)
.AddNotZeroChilds (model.Ids)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.Ban);
request.AddJsonBody (model);
//
var response = await RunRestRequest<IEnumerable<string>> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// UnBann Specific Users
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
/// <returns>a list of unbanned users identifiers</returns>
public async Task<IEnumerable<string>> UnBan (
XTokenResponse tokens,
XUserNameIdRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (
tokens,
model
)
.AddNotEmpty (tokens.AccessToken)
.AddNotZeroChilds (model.Ids)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.UnBan);
request.AddJsonBody (model);
//
var response = await RunRestRequest<IEnumerable<string>> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Check Specific User is Banned or not
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <returns>a boolean value which represent user banned or not</returns>
public async Task<bool> IsBanned (
XTokenResponse tokens,
string userSelectByParam
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotEmpty (
userSelectByParam,
tokens.AccessToken
)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.IsBanned,
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam } }
);
//
var response = await RunRestRequest<bool> (
client,
request,
XHttpMethod.GET
);
return response;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Authentication.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using IdentityModel.Client;
using xCommons.Extensions;
using xExceptions.Constants;
using xHttpService.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityService.Constants;
namespace xIdentityService.Providers {
public partial class XIdentityProvider {
//
#region Authentication Handlers ...
/// <summary>
/// Request for Discovery Document
/// </summary>
/// <returns>an instance of DiscoveryDocumentResponse</returns>
public async Task<DiscoveryDocumentResponse> RequestDiscoveryDocument () {
//
var httpClient = GetHttpClient ();
//
try {
//
var result = httpClient
.GetDiscoveryDocumentAsync (identityConfiguration.Authority)
.ContinueWith (docTask => {
//
httpClient.Dispose ();
return docTask.Result;
});
//
return await result;
} catch {
throw XException.ActionFailed.ToException ();
}
}
/// <summary>
/// Request AccessToken for Specific XApiScope
/// </summary>
/// <param name="scope">a member of <see>XApiScope</see></param>
/// <returns>an instance of <see>XTokenResponse</see></returns>
public async Task<XTokenResponse> RequestScopeAccessToken (string scope) {
//
// Validate Args ...
var scopeName = string.Empty;
try {
scopeName = scope; // scope.GetStringValue ();
} catch { }
if (scopeName.IsNullOrEmpty ()) {
XException.InvalidArgs.Throw ();
}
//
var client = GetRestClient ();
var request = GetRestRequet (
XApiAccountEndpoint.RequestScopeAccessToken,
headers : new Dictionary<string, string> { { XParam.XScope.GetStringValue (), scope.ToString () } });
//
var response = await RunRestRequest<XTokenResponse> (
client,
request,
XHttpMethod.POST
);
//
// Save Token ...
if (!response.IsNull ()) {
await tokenProvider.AddOrUpdateToken (response);
}
//
return response;
}
/// <summary>
/// Validate a token
/// </summary>
/// <param name="model">Authentication Tokens</param>
/// <returns>an instance of TokenIntrospectionResponse</returns>
public async Task<TokenIntrospectionResponse> Introspection (XTokenResponse model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (model.AccessToken)
.ValidateGroupAsync ();
//
var httpClient = GetHttpClient ();
//
try {
//
var discoDoc = await RequestDiscoveryDocument ();
if (discoDoc.IsError) {
XException.ActionFailed.Throw ();
}
//
var response = await httpClient.IntrospectTokenAsync (new TokenIntrospectionRequest {
//
Address = discoDoc.IntrospectionEndpoint,
ClientId = identityConfiguration.ClientId,
ClientSecret = identityConfiguration.ClientSecret,
//
Token = model.AccessToken
});
if (response.IsError) {
throw new Exception (response.Error);
}
//
return response;
} catch {
throw XException.ActionFailed.ToException ();
}
}
/// <summary>
/// Authenticate a User
/// </summary>
/// <param name="model">User Login Required Info, an instance of <see>XLoginRequest</see></param>
/// <returns>an instance of <see>XTokenResponse</see></returns>
public async Task<XTokenResponse> Authenticate (XLoginRequest model) {
//
// Validate Args ...
validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (
model.UserSelectBy,
model.Password
)
.ValidateGroup ();
//
var client = GetRestClient ();
var request = GetRestRequet (XApiAccountEndpoint.Authenticate);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XTokenResponse> (
client,
request,
XHttpMethod.POST
);
//
// Save Token ...
if (!response.IsNull ()) {
await tokenProvider.AddOrUpdateToken (response);
}
//
return response;
}
/// <summary>
/// Do Login based on XLoginRequest
/// </summary>
/// <param name="model">User Login Required Info, an instance of <see>XLoginRequest</see></param>
/// <returns>an instance of <see>XTokenResponse</see></returns>
public async Task<XLoginResponse> Login (XLoginRequest model) {
//
// Validate Args ...
validationProvider
.GroupValidationBuilder ()
.AddNotNull (model, model.Device)
.AddNotEmpty (
model.UserSelectBy,
model.Password
)
.ValidateGroup ();
//
var client = GetRestClient ();
var request = GetRestRequet (XApiAccountEndpoint.Login);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XLoginResponse> (
client,
request,
XHttpMethod.POST
);
//
if (!response.IsNull ()) {
//
var tokens = response.ToXTokenResponse ();
await tokenProvider.AddOrUpdateToken (tokens);
}
//
return response;
}
/// <summary>
/// Logout from System
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task Logout (XTokenResponse model) {
//
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (model.AccessToken)
.ValidateGroupAsync ();
//
var isExists = await tokenProvider
.IsTokenExists (model.AccessToken);
if (isExists) {
await tokenProvider
.RemoveToken (model.AccessToken);
}
}
/// <summary>
/// Refresh Tokens
/// </summary>
/// <param name="model">Authentication Tokens</param>
/// <returns>an instance of <see>XTokenResponse</see></returns>
public async Task<XTokenResponse> RefreshTokens (XTokenResponse model) {
//
// Validate Args ...
validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (
model.AccessToken,
model.RefreshToken
)
.ValidateGroup ();
//
var client = GetRestClient (model);
//
var request = GetRestRequet (
XApiAccountEndpoint.RefreshTokens,
headers : model.ToHeaderDictionary ());
request.AddJsonBody (model);
//
var response = await RunRestRequest<XTokenResponse> (
client,
request,
XHttpMethod.POST
);
if (!response.IsNull ()) {
await tokenProvider.UpdateToken (response);
}
//
return response;
}
#endregion
//
#region Password Actions Handlers ...
/// <summary>
/// Change Password
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
public async Task ChangePassword (
XTokenResponse tokens,
XActionRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens, model)
.AddNotEmpty (
model.Lang,
model.Password,
model.NewPassword,
model.ReturnUrl)
.AddNotNull (model.Device)
.ValidateGroupAsync ();
//
// Validate User Select By Param ...
var userSelectByParam = GetUserSelectByParam (
model,
forceNotNull : true,
excludes : null);
//
var client = GetRestClient (tokens);
var request = GetRestRequet (
XApiAccountEndpoint.ChangePassword,
headers : tokens.ToHeaderDictionary ());
request.AddJsonBody (model);
//
var response = await RunRestRequest<Object> (
client,
request,
XHttpMethod.POST
);
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Friendship.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using xCommons.Extensions;
using xHttpService.Constants;
using xHttpService.Extensions;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
using xIdentityService.Constants;
using xModels.Dtos;
namespace xIdentityService.Providers
{
public partial class XIdentityProvider
{
//
#region Friendship ...
/// <summary>
/// Follow a User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
public async Task<XFriendshipFollowing> Follow(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.Follow,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipFollowing>(
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Cancel Following Request
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>a boolean value</returns>
public async Task<bool> Cancel(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.Cancel,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<bool>(
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Unfollow a Follower
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns></returns>
public async Task UnFollowFollower(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.UnFollowFollower,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<object>(
client,
request,
XHttpMethod.POST
);
}
/// <summary>
/// Unfollow Following
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns></returns>
public async Task UnFollowFollowing(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.UnFollowFollowing,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<object>(
client,
request,
XHttpMethod.POST
);
}
/// <summary>
/// Block a Follower
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
public async Task<XFriendshipFollowing> Block(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.Block,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipFollowing>(
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Unblock a Blocked User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
public async Task<XFriendshipFollowing> UnBlock(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.UnBlock,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipFollowing>(
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Accept a Following Request
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
public async Task<XFriendshipFollower> AcceptRequest(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.AcceptRequest,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipFollower>(
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Reject a Following Request
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
public async Task<XFriendshipFollower> RejectRequest(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.RejectRequest,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipFollower>(
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Get Friendship Info Model between Specific User and Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipInfoDto</see></returns>
public async Task<XFriendshipInfoDto> GetFriendshipInfo(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.FriendshipInfo,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipInfoDto>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Check a User IsFollower of Requested User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsFollower(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.IsFollower,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<bool>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Get Specific Follower
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
public async Task<XFriendshipFollower> GetFollower(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.Follower,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipFollower>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Get Follower State of a User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipState</see></returns>
public async Task<XFriendshipState> GetFollowerState(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.FollowerState,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipState>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Get Followers List Of Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
public async Task<IEnumerable<XFriendshipFollower>> GetFollowers(
XTokenResponse tokens
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.Followers);
//
var response = await RunRestRequest<IEnumerable<XFriendshipFollower>>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Get All Followers List Includes Blocked, Requested and etc
/// of Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
public async Task<IEnumerable<XFriendshipFollower>> GetAllFollowers(
XTokenResponse tokens
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.AllFollowers);
//
var response = await RunRestRequest<IEnumerable<XFriendshipFollower>>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Return Followers UserName's List of Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <returns>a collection of UserNames</returns>
public async Task<IEnumerable<string>> GetFollowersList(
XTokenResponse tokens
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.FollowersList);
//
var response = await RunRestRequest<IEnumerable<string>>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Retrieve All User's Followers based on Query Model ...
/// </summary>
/// <param name="query">Query Model Descriptor</param>
/// <param name="destUser">Dest User for Reading Followers</param>
/// <param name="tokens">Requester User's Descriptor</param>
/// <returns></returns>
public async Task<XQueryResult<XFriendDto>> QueryFollowers(
XQuery query,
string destUser,
XTokenResponse tokens
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(destUser)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.QueryFollowers);
//
// Attach XQuery to Request ...
request = request.AttachXQuery(query);
request = request.AttachDestUser(destUser);
//
var response = await RunRestRequest<XQueryResult<XFriendDto>>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Check a User is in Followings of Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsFollowing(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.IsFollowing,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<bool>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Get Specific Following Model
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
public async Task<XFriendshipFollowing> GetFollowing(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.Following,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipFollowing>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Get Following State Relation between Specific User
/// and Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipState</see></returns>
public async Task<XFriendshipState> GetFollowingState(
XTokenResponse tokens,
string destUser
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(
destUser,
tokens.AccessToken
)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(
XApiAccountEndpoint.FollowingState,
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
}
);
//
var response = await RunRestRequest<XFriendshipState>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Get Followings of Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
public async Task<IEnumerable<XFriendshipFollowing>> GetFollowings(
XTokenResponse tokens
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.Followings);
//
var response = await RunRestRequest<IEnumerable<XFriendshipFollowing>>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Get All Following List Includes Blocked, Requested and etc
/// of Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
public async Task<IEnumerable<XFriendshipFollowing>> GetAllFollowings(
XTokenResponse tokens
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.AllFollowings);
//
var response = await RunRestRequest<IEnumerable<XFriendshipFollowing>>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Return Following UserName's List of Current User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <returns>a collection of UserNames</returns>
public async Task<IEnumerable<string>> GetFollowingList(
XTokenResponse tokens
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.FollowingsList);
//
var response = await RunRestRequest<IEnumerable<string>>(
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Retrieve All User's Followings based on Query Model ...
/// </summary>
/// <param name="query">Query Model Descriptor</param>
/// <param name="destUser">Dest User for Reading Followers</param>
/// <param name="tokens">Requester User's Descriptor</param>
/// <returns></returns>
public async Task<XQueryResult<XFriendDto>> QueryFollowings(
XQuery query,
string destUser,
XTokenResponse tokens
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens)
.AddNotEmpty(destUser)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.QueryFollowings);
//
// Attach XQuery to Request ...
request = request.AttachXQuery(query);
request = request.AttachDestUser(destUser);
//
var response = await RunRestRequest<XQueryResult<XFriendDto>>(
client,
request,
XHttpMethod.GET
);
return response;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Open.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
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;
namespace xIdentityService.Providers
{
public partial class XIdentityProvider
{
/// <summary>
/// Prepare API Based Device to Open Actions ...
/// </summary>
/// <returns></returns>
public XDeviceDto GetDevice()
{
//
var os = "XSaherElmOS";
bool isOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
if (isOSX)
{
os = "MacOs";
}
else if (isLinux)
{
os = "Linux";
}
else if (isWindows)
{
os = "Windows";
}
var agent = RuntimeInformation.FrameworkDescription;
if (agent.IsNullOrEmpty())
{
agent = "XSaherElmOSAgent";
}
var version = RuntimeInformation.OSArchitecture + ", " + RuntimeInformation.OSDescription;
if (version.IsNullOrEmpty())
{
version = "XSaherElmOSVersion";
}
var browser = "XSaherElmBrowser_" + RevisionSecretKey.ToMd5String();
//
var result = new XDeviceDto
{
Os = os,
Browser = browser,
UserAgent = agent,
OsVersion = version,
DeviceType = XDeviceType.Desktop,
};
//
return result;
}
//
#region OpenGet ...
public async Task<XOpenActionInnerDto> OpenGet(
XOpenActionInnerDto model
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(model)
.AddNotEmpty(model.Token)
.AddNotEmpty(model.Payload)
.ValidateGroupAsync();
//
var result = await OpenGet(
token: model.Token,
actionRequest: model.Payload
);
//
return result;
}
public async Task<XOpenActionInnerDto> OpenGet(
string token,
string actionRequest
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotEmpty(token)
.AddNotEmpty(actionRequest)
.ValidateGroupAsync();
//
// Retrieve Rest Client ...
var client = GetRestClient();
//
// Prepare Rest Request ...
var request = GetRestRequet(
XApiAccountEndpoint.Open,
headers: new Dictionary<string, string>
{
{ XAuthentication.TOKEN, token}
},
queryStrings: new Dictionary<string, string>
{
{ XParam.XRequest.GetStringValue(), actionRequest }
}
);
//
// Run Request and Retrieve Response ...
var response = await RunRestRequestByResponse<string>(
client,
request,
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).Value.ToString();
if (responseToken.IsNullOrEmpty())
{
XException.ActionFailed.Throw();
}
//
// Decript Recieve Response ...
var responseJson = response.Model; // SecurityProvider.Decrypt(response.Model);
if (responseJson.IsNullOrEmpty())
{
XException.ActionFailed.Throw();
}
//
var result = new XOpenActionInnerDto
{
Token = responseToken,
Payload = responseJson
};
//
// Retrieve Model and Validate it ...
var responseModel = responseJson.FromJSON<XOpenActionRequestDto>();
if (responseModel.IsNull() ||
responseModel.Payload.IsNullOrEmpty() ||
responseToken != responseModel.Checksum ||
responseModel.Timestamp.FromTimestamp().IsExPired())
{
XException.ActionFailed.Throw();
}
//
return result;
}
#endregion
//
#region GetUserInfo ...
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).ToTimestamp().ToString()
};
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 and Validate Response ...
var response = await OpenGet(
token: token,
actionRequest: request
);
if (response.IsNull() ||
response.Token.IsNullOrEmpty() ||
response.Payload.IsNullOrEmpty())
{
XException.ActionFailed.Throw();
}
//
// Now we Have to Converts Repose Payload to Result Model ...
// Note that the respose Model's payload here is Decrypted and
// actually is Json Representation of Result Model ...
var requestModel = response.Payload.FromJSON<XOpenActionRequestDto>();
if (requestModel.IsNull())
{
XException.ActionFailed.Throw();
}
//
var resultJson = SecurityProvider.Decrypt(requestModel.Payload);
var result = resultJson.FromJSON<XOpenActionUserInfoDto>();
if (result.IsNull())
{
XException.NotFound.Throw();
}
//
return result;
}
#endregion
//
#region GetUserInfos ...
public async Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
XDeviceDto device,
string ids
)
{
//
// Validate Args ...
validationProvider.NotNull(device);
validationProvider.NotEmpty(ids);
//
// Prepare Open Action Model ...
var opaModel = new XOpenActionRequestDto
{
Payload = ids,
Device = device,
Action = XOpenActions.GetUserInfos,
Timestamp = DateTime.UtcNow.AddMinutes(5).ToTimestamp().ToString()
};
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 GetUserInfos(
token: token,
request: requestString
);
}
public async Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
XOpenActionInnerDto dto
)
{
//
return await GetUserInfos(
token: dto.Token,
request: dto.Payload
);
}
public async Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
string token,
string request
)
{
//
// Validate Args ...
validationProvider.NotEmpty(token);
validationProvider.NotEmpty(request);
//
// Retrieve and Validate Response ...
var response = await OpenGet(
token: token,
actionRequest: request
);
if (response.IsNull() ||
response.Token.IsNullOrEmpty() ||
response.Payload.IsNullOrEmpty())
{
XException.ActionFailed.Throw();
}
//
// Now we Have to Converts Repose Payload to Result Model ...
// Note that the respose Model's payload here is Decrypted and
// actually is Json Representation of Result Model ...
var requestModel = response.Payload.FromJSON<XOpenActionRequestDto>();
if (requestModel.IsNull())
{
XException.ActionFailed.Throw();
}
//
var resultJson = SecurityProvider.Decrypt(requestModel.Payload);
var result = resultJson.FromJSON<IEnumerable<XOpenActionUserInfoDto>>();
if (result.IsNull())
{
XException.NotFound.Throw();
}
//
return result;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Profile.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using xCommons.Extensions;
using xHttpService.Constants;
using xHttpService.Extensions;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
using xIdentityService.Constants;
using xModels.Dtos;
namespace xIdentityService.Providers {
public partial class XIdentityProvider {
//
#region User Actions ...
/// <summary>
/// Retrieve User Names based on UserIds
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="ids">a comma seperated list of UserIds</param>
/// <returns>a collection of UserNames</returns>
public async Task<IEnumerable<string>> GetUserNames (
XTokenResponse tokens,
string ids
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotEmpty (ids, tokens.AccessToken)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
var request = GetRestRequet (
XApiAccountEndpoint.GetNames,
@params : new Dictionary<string, string> { { XParam.XIds.GetStringValue (), ids } }
);
//
var response = await RunRestRequest<IEnumerable<string>> (
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// get user ids and retrieve corresponding user names
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represent required UserIds collection</param>
/// <returns>a collection of <see>XUserNameIdResponse</see> instance</returns>
public async Task<IEnumerable<XUserNameIdResponse>> GetUserNameIds (
XTokenResponse tokens,
XUserNameIdRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (model, tokens)
.AddNotZeroChilds (model.Ids)
.AddNotEmpty (tokens.AccessToken)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
var request = GetRestRequet (XApiAccountEndpoint.GetNameIds);
request.AddJsonBody (model);
//
var response = await RunRestRequest<IEnumerable<XUserNameIdResponse>> (
client,
request,
XHttpMethod.POST
);
return response;
}
#endregion
//
#region Profile Actions ...
/// <summary>
/// Get Profile Object of Specific User
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> GetUserProfile (
XTokenResponse tokens,
string userSelectByParam
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotEmpty (userSelectByParam, tokens.AccessToken)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.GetProfile,
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam } }
);
//
var response = await RunRestRequest<XUserProfileDto> (
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Retrieve Users Based On Query
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
public async Task<XQueryResult<XUserProfileDto>> QueryUsers (
XTokenResponse tokens,
XQuery query
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens, query)
.AddNotEmpty (tokens.AccessToken)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.QueryProfiles);
//
// Attach XQuery to Request ...
request = request.AttachXQuery (query);
//
var response = await RunRestRequest<XQueryResult<XUserProfileDto>> (
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Retrieve Users Based On Query and Specified role
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="role">an string which represent user role</param>
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
/// <param name="forceRole">if it's true the user must has exact role, otherwise top level users also listed</param>
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
public async Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers (
XTokenResponse tokens,
string role,
XQuery query,
bool forceRole = false
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens, query)
.AddNotEmpty (tokens.AccessToken, role)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.QueryProfiles,
headers : new Dictionary<string, string> { { XParam.XRole.GetStringValue (), role },
{ XParam.XForceRole.GetStringValue (), forceRole.AsHttpParamString () }
}
);
//
// Attach XQuery to Request ...
request = request.AttachXQuery (query);
//
var response = await RunRestRequest<XQueryResult<XUserProfileDto>> (
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Query Specified User's Profile Images
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
/// <returns>an instance of <see>XQueryResult</see> of <see>XProfileImage</see></returns>
public async Task<XQueryResult<XProfileImage>> QueryAvatars (
XTokenResponse tokens,
string userSelectByParam,
XQuery query
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens, query)
.AddNotEmpty (tokens.AccessToken, userSelectByParam)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.QueryAvatars,
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam }
}
);
//
// Attach XQuery to Request ...
request = request.AttachXQuery (query);
//
var response = await RunRestRequest<XQueryResult<XProfileImage>> (
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Update User Profile based on <see>XProfileUpdateRequest</see> (FirstName/LastName/DateOfBirth)
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> ProfileUpdateAsync (
XTokenResponse tokens,
string userSelectByParam,
XProfileUpdateRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens, model)
.AddNotEmpty (tokens.AccessToken, userSelectByParam)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.UpdateProfile,
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam }
}
);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XUserProfileDto> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Update a User Profile based on <see>XProfileUpdateRequest</see> Full
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> FullProfileUpdateAsync (
XTokenResponse tokens,
string userSelectByParam,
XProfileUpdateRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens, model)
.AddNotEmpty (tokens.AccessToken, userSelectByParam)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.FullUpdateProfile,
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam }
}
);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XUserProfileDto> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Add a New Profile Image
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="file">an specific File to upload, <see>IFormFile</see></param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> AddAvatar (
XTokenResponse tokens,
IFormFile file
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens, file)
.AddNotEmpty (tokens.AccessToken)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.AddAvatar);
request.AlwaysMultipartFormData = true;
request.AddFileBytes (
XParam.XFile.GetStringValue (),
file.ToByteArray (),
file.FileName,
file.ContentType
);
//
var response = await RunRestRequest<XUserProfileDto> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Add a New Collection of Profile Images
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="files">a collection of Files to upload, <see>IFormFileCollection</see></param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> AddAvatars (
XTokenResponse tokens,
IFormFileCollection files
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotZeroChilds (files)
.AddNotEmpty (tokens.AccessToken)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.AddAvatars);
request.AlwaysMultipartFormData = true;
//
// Add Files ...
foreach (var file in files) {
//
// Add Single file ...
request.AddFileBytes (
XParam.XFiles.GetStringValue (),
file.ToByteArray (),
file.FileName,
file.ContentType
);
}
//
var response = await RunRestRequest<XUserProfileDto> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// set Specified Profile Image as Avatar
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="id">an integer which reperesent AvatarId to set as current Avatar</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> SetAvatar (
XTokenResponse tokens,
int id
) {
//
// Validate Args ...
id.ValidateIntId ();
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotEmpty (tokens.AccessToken)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.SetAvatar,
@params : new Dictionary<string, string> { { XParam.XId.GetStringValue (), id.ToString () }
}
);
//
var response = await RunRestRequest<XUserProfileDto> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Remove Profile Images
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="avatarIds">a comma seperated list of avatarIds to remove</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> RemoveAvatars (
XTokenResponse tokens,
string avatarIds
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotEmpty (avatarIds, tokens.AccessToken)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.RemoveAvatars,
@params : new Dictionary<string, string> { { XParam.XIds.GetStringValue (), avatarIds }
}
);
//
var response = await RunRestRequest<XUserProfileDto> (
client,
request,
XHttpMethod.DELETE
);
return response;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Registration.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using xCommons.Extensions;
using xExceptions.Constants;
using xHttpService.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityService.Constants;
namespace xIdentityService.Providers {
public partial class XIdentityProvider {
//
#region Registration ...
/// <summary>
/// Check a User Selector is Available for Registration or Not
/// </summary>
/// <param name="userSelectByParam">an string value which reperesent a user</param>
/// <returns>a boolean value</returns>
public async Task<bool> CanRegister (string userSelectByParam) {
//
// Validate ARgs ...
validationProvider.NotEmpty (userSelectByParam);
//
var client = GetRestClient ();
//
// Check Endpoint ...
var endpoint = XApiAccountEndpoint.CanRegisterUserName;
var @params = new Dictionary<string, string> { { XParam.XUserName.GetStringValue (), userSelectByParam } };
//
// Check UserSelectByType ...
var type = userSelectByParam.GetUserSelectByType ();
switch (type) {
//
case XUserSelectBy.Username:
break;
//
case XUserSelectBy.MobileNumber:
//
endpoint = XApiAccountEndpoint.CanRegisterMobileNumber;
@params = new Dictionary<string, string> { { XParam.XMobileNumber.GetStringValue (), userSelectByParam } };
break;
//
case XUserSelectBy.Email:
//
endpoint = XApiAccountEndpoint.CanRegisterEmail;
@params = new Dictionary<string, string> { { XParam.XEmail.GetStringValue (), userSelectByParam } };
break;
//
default:
throw XException.InvalidData.ToException ();
}
//
var request = GetRestRequet (
endpoint,
@params: @params
);
//
var response = await RunRestRequest<bool> (
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Invite a User to Register on Dashboard
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> InviteUser (
XTokenResponse tokens,
XActionRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (
tokens,
model,
model.Device)
.AddNotEmpty (
tokens.AccessToken,
model.Lang,
model.Email,
model.ReturnUrl)
.AddEmailAddress (model.Email)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.InviteUser);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Recieve some Basic Informations and Start Registration Proccess
/// if they Valid
///
/// Registration Proccess Starts with Invoking this Action
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestRegistration (
XActionRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (
model,
model.Device,
model.DateOfBirth)
.AddNotEmpty (
model.Lang,
model.FirstName,
model.LastName)
.ValidateGroupAsync ();
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.RequestRegistration);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Add User Account Informations
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> AddAccountInfo (
XActionRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (
model,
model.Device)
.AddNotEmpty (
model.Lang,
model.UserName,
model.Password,
model.ActionToken)
.ValidateGroupAsync ();
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.AddAccountInfo);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Upload and Attach a Profile Image for User. this is an Optional Step
/// </summary>
/// <param name="actionToken">user's requested action token</param>
/// <param name="file">an instance of <see>IFormFile</see> for user's Avatar</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> AttachProfileImage (
string actionToken,
IFormFile file
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (file)
.AddNotEmpty (actionToken)
.ValidateGroupAsync ();
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.AttachProfileImage);
//
// Prepare Request Data ...
request.AddParameter (XParam.XActionToken.GetStringValue (), actionToken);
request.AddFileBytes (
XParam.XFile.GetStringValue (),
file.ToByteArray (),
file.FileName,
file.ContentType
);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Finish Registrationn Proccess
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
public async Task FinishRegistration (XActionRequest model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotEmpty (
model.Lang,
model.Password,
model.ReturnUrl)
.AddNotNull (model.Device)
.AddUrl (model.ReturnUrl)
.ValidateGroupAsync ();
//
// Create Http Client ...
var client = GetRestClient ();
//
// Create Request ...
var request = GetRestRequet (XApiAccountEndpoint.FinishRegistration);
//
// Prepare Request Data ...
request.AddJsonBody (model);
//
var response = await RunRestRequest<object> (
client,
request,
XHttpMethod.POST
);
}
/// <summary>
/// Check User is Confirmed Email or not
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="userSelectByParam">an string value which reperesent a user</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsConfirmedEmail (
XTokenResponse tokens,
string userSelectByParam
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotEmpty (
tokens.AccessToken,
userSelectByParam)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.IsConfirmedEmail);
//
var response = await RunRestRequest<bool> (
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Check User is Confirmed Mobile or not
/// </summary>
/// <param name="tokens">Authentication Tokens</param>
/// <param name="userSelectByParam">an string value which reperesent a user</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsConfirmedMobile (
XTokenResponse tokens,
string userSelectByParam
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotEmpty (
tokens.AccessToken,
userSelectByParam)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.IsConfirmedMobile);
//
var response = await RunRestRequest<bool> (
client,
request,
XHttpMethod.GET
);
return response;
}
/// <summary>
/// Request Registration Confirm
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
public async Task RequestConfirmRegistration (XActionRequest model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotEmpty (
model.Lang,
model.Password,
model.ReturnUrl)
.AddNotNull (model.Device)
.AddUrl (model.ReturnUrl)
.ValidateGroupAsync ();
//
// Get UserSelect By Param ...
var userSelectByParam = model.GetUserSelectByParam ();
validationProvider.NotEmpty (userSelectByParam);
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.RequestConfirmRegistration);
request.AddJsonBody (model);
//
var response = await RunRestRequest<object> (
client,
request,
XHttpMethod.POST
);
}
/// <summary>
/// Confirm Registration
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
public async Task ConfirmRegistration (
XActionRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotEmpty (
model.Lang,
model.ActionToken,
model.ReturnUrl
)
.AddNotNull (model.Device)
.ValidateGroupAsync ();
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.ConfirmRegistration);
request.AddJsonBody (model);
//
var response = await RunRestRequest<object> (
client,
request,
XHttpMethod.POST
);
}
/// <summary>
/// Request For Mobile Number Change/Confirm
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestConfirmMobile (XActionRequest model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotEmpty (
model.Lang,
model.Password,
model.MobileNumber
)
.AddNotNull (model.Device)
.AddMobileNumber (model.MobileNumber)
.ValidateGroupAsync ();
//
// Get UserSelect By Param ...
var userSelectByParam = GetUserSelectByParam (
model,
excludes : new List<XUserSelectBy> {
XUserSelectBy.Email,
XUserSelectBy.MobileNumber
});
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.RequestConfirmMobile);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Confirm Requested Mobile Number
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> ConfirmMobileNumber (XActionRequest model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotEmpty (
model.Lang,
model.ActionToken,
model.MobileVerificationCode
)
.AddNotNull (model.Device)
.ValidateGroupAsync ();
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.ConfirmMobileNumber);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Request For Email Address Change/Confirm
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestConfirmEmail (XActionRequest model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotEmpty (
model.Lang,
model.Email,
model.Password)
.AddNotNull (model.Device)
.AddEmailAddress (model.Email)
.ValidateGroupAsync ();
//
// Get UserSelect By Param ...
var userSelectByParam = GetUserSelectByParam (
model,
excludes : new List<XUserSelectBy> {
XUserSelectBy.Email,
XUserSelectBy.MobileNumber
});
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.RequestConfirmEmail);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Confirm Requested Email Address
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> ConfirmEmailAddress (XActionRequest model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotEmpty (
model.Lang,
model.ActionToken,
model.EmailVerificationCode
)
.AddNotNull (model.Device)
.ValidateGroupAsync ();
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.ConfirmEmailAddress);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Request Reset Password Action
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestResetPassword (XActionRequest model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotEmpty (
model.Lang,
model.ReturnUrl)
.AddNotNull (model.Device)
.AddUrl (model.ReturnUrl)
.ValidateGroupAsync ();
//
// Get UserSelect By Param ...
var userSelectByParam = GetUserSelectByParam (
model,
excludes : new List<XUserSelectBy> {
XUserSelectBy.Email,
XUserSelectBy.MobileNumber
});
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.RequestResetPassword);
request.AddJsonBody (model);
//
var response = await RunRestRequest<XActionResponse> (
client,
request,
XHttpMethod.POST
);
return response;
}
/// <summary>
/// Reset a User's Password
/// </summary>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
public async Task ResetPassword (XActionRequest model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (
model.Lang,
model.ActionToken,
model.NewPassword,
model.ReturnUrl)
.AddNotNull (model.Device)
.ValidateGroupAsync ();
//
var client = GetRestClient ();
//
var request = GetRestRequet (XApiAccountEndpoint.ResetPassword);
request.AddJsonBody (model);
//
var response = await RunRestRequest<object> (
client,
request,
XHttpMethod.POST
);
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Search.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using xHttpService.Constants;
using xHttpService.Extensions;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityService.Constants;
using xModels.Dtos;
namespace xIdentityService.Providers
{
public partial class XIdentityProvider
{
//
#region Actions ...
/// <summary>
/// Query Open To Search User Profiles ...
/// </summary>
/// <param name="tokens">requested user's identifiers</param>
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
public async Task<XQueryResult<XUserProfileDto>> QueryOpenToSearchUsers(
XTokenResponse tokens,
XQuery query
)
{
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder()
.AddNotNull(tokens, query)
.AddNotEmpty(tokens.AccessToken)
.ValidateGroupAsync();
//
var client = GetRestClient(tokens);
//
var request = GetRestRequet(XApiAccountEndpoint.QueryOpenToSearchProfiles);
//
// Attach XQuery to Request ...
request = request.AttachXQuery(query);
//
var response = await RunRestRequest<XQueryResult<XUserProfileDto>>(
client,
request,
XHttpMethod.GET
);
return response;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Providers\XBaseIdentityHttpProvider.cs
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using RestSharp;
using RestSharp.Authenticators;
using xCommons.Constants;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
using xHttpService.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityService.Constants;
using xIdentityService.Interfaces;
using xIdentityService.Models;
using xIdentityService.Extensions;
using System.Diagnostics.Tracing;
using MySqlX.XDevAPI.Common;
namespace xIdentityService.Providers
{
/// <summary>
/// an abstraction Implementation for Identity Provided Http Based Services ...
/// </summary>
public abstract class XBaseIdentityHttpProvider : IXBaseIdentityHttpProvider
{
/// <summary>
/// Client Base Url ...
/// </summary>
/// <value></value>
public string BaseUrl { get; }
/// <summary>
/// Logger ...
/// </summary>
/// <value></value>
public ILogger Logger { get; }
/// <summary>
/// Powered Value ...
/// </summary>
/// <value></value>
public string XPoweredValue { get; }
/// <summary>
/// Default Client Timeout ...
/// </summary>
/// <value></value>
public int DefaultClientTimeout { get; }
/// <summary>
/// Default Buffering Chunk Size ...
/// </summary>
/// <value></value>
public int DefaultBufferingChunckSize { get; }
/// <summary>
/// Validation Provider ...
/// </summary>
/// <value></value>
public XValidationProvider ValidationProvider { get; }
/// <summary>
/// Token Provider ...
/// </summary>
private readonly IXTokenProvider tokenProvider;
/// <summary>
/// Identity Provider ...
/// </summary>
private readonly IXIdentityProvider identityProvider;
public XBaseIdentityHttpProvider(
string baseUrl,
ILogger logger,
string poweredValue,
int defaultClientTimeout,
IXTokenProvider tokenProvider,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider,
int defaultBufferingChunckSize = 8192
)
{
//
Logger = logger;
BaseUrl = baseUrl;
XPoweredValue = poweredValue;
this.tokenProvider = tokenProvider;
ValidationProvider = validationProvider;
this.identityProvider = identityProvider;
DefaultClientTimeout = defaultClientTimeout;
DefaultBufferingChunckSize = defaultBufferingChunckSize;
}
//
#region Tools ...
/// <summary>
/// Get an Instance of Http Client
/// </summary>
/// <returns></returns>
public HttpClient GetHttpClient(XTokenResponse tokens = null)
{
//
HttpClient httpClient = null;
//
// httpClient = new HttpClient ();
var httpClientHandler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
//
Logger.LogInformation(
$"XSSL Handler: {Environment.NewLine}, sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
);
//
return true;
},
ClientCertificateOptions = ClientCertificateOption.Manual,
};
httpClient = new HttpClient(httpClientHandler);
//
// Set Authenticator ...
if (!tokens.IsNull() &&
!tokens.AccessToken.IsNullOrEmpty())
{
//
httpClient.DefaultRequestHeaders
.Add(
XAuthorization.Header,
$"{XAuthentication.BEARER} {tokens.AccessToken}");
}
//
// Refresh Token ...
if (!tokens.IsNull() &&
!tokens.RefreshToken.IsNullOrEmpty())
{
//
httpClient.DefaultRequestHeaders
.Add(
XAuthorization.RefreshToken,
tokens.RefreshToken);
}
//
// ExpiresAt ...
if (!tokens.IsNull() &&
tokens.ExpiresAt > 0)
{
//
httpClient.DefaultRequestHeaders
.Add(
XAuthorization.ExpiresAt,
tokens.ExpiresAt.AsHttpParamString());
}
//
// Set Default Timeout ...
httpClient.Timeout = TimeSpan.FromSeconds(DefaultClientTimeout == -1 ? 10000 : DefaultClientTimeout);
//
return httpClient;
}
public HttpClient GetHttpClient(XUserClaimsInfoDto userInfo = null)
{
//
XTokenResponse tokens = ToTokenResponse(userInfo);
//
return GetHttpClient(tokens);
}
/// <summary>
/// Get an Instance of RestClient
/// </summary>
/// <returns></returns>
public RestClient GetRestClient(XTokenResponse tokens = null)
{
//
var client = new RestClient(BaseUrl);
//
// Set Authenticator ...
if (!tokens.IsNull() &&
!tokens.AccessToken.IsNullOrEmpty())
{
client.Authenticator = new JwtAuthenticator(tokens.AccessToken);
}
//
// Refresh Token ...
if (!tokens.IsNull() &&
!tokens.RefreshToken.IsNullOrEmpty())
{
client.AddDefaultHeader(XAuthorization.RefreshToken, tokens.RefreshToken);
}
//
// ExpiresAt ...
if (!tokens.IsNull() &&
tokens.ExpiresAt > 0)
{
client.AddDefaultHeader(XAuthorization.ExpiresAt, tokens.ExpiresAt.AsHttpParamString());
}
//
// Set Default Timeout ...
client.Timeout = DefaultClientTimeout;
//
// SSL Validation Handler ...
client.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
//
Logger.LogInformation(
$"XSSL Handler: {Environment.NewLine}, sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
);
//
return true;
};
//
return client;
}
public RestClient GetRestClient(XUserClaimsInfoDto userInfo = null)
{
//
XTokenResponse tokens = ToTokenResponse(userInfo);
//
return GetRestClient(tokens);
}
/// <summary>
/// Get an Instance of RestRequest
/// </summary>
/// <param name="endpoint"></param>
/// <param name="addXPoweredValue"></param>
/// <param name=""></param>
/// <param name="headers"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
public RestRequest GetRestRequet(
Enum endpoint,
bool addXPoweredValue = true,
IDictionary<string, string> @params = null,
IDictionary<string, string> headers = null,
IDictionary<string, string> queryStrings = null
)
{
//
var url = PrepareUrl(
@params: @params,
endpoint: endpoint,
queryStrings: queryStrings
);
//
// Create request ...
var request = new RestRequest(url, DataFormat.Json);
//
if (addXPoweredValue)
{
request.AddHeader(XAuthorization.XPoweredBy, XPoweredValue);
}
//
// Add Headers to request ...
if (!headers.IsNull() && headers.Count > 0)
{
//
var enumerator = headers.GetEnumerator();
while (enumerator.MoveNext())
{
//
var item = enumerator.Current;
request.AddHeader(item.Key, item.Value);
}
}
//
return request;
}
/// <summary>
/// Handle Call Specific Request and retrieve Response
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="method"></param>
/// <param name="supportRefreshingTokens"></param>
/// <param name="cancellationToken"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public async Task<T> RunRestRequest<T>(
RestClient client,
RestRequest request,
XHttpMethod method,
bool supportRefreshingTokens = true,
CancellationToken cancellationToken = default
)
{
//
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 identityProvider
.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 RunRestRequest<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 = resp.Content.FromJSON<T>();
return result;
},
cancellationToken: cancellationToken);
//
return response;
}
/// <summary>
/// Access a Get Request Stream as AsyncEnumerable ...
/// </summary>
/// <param name="endpoint"></param>
/// <param name="bufferLength"></param>
/// <param name="addXPoweredValue"></param>
/// <param name="tokens"></param>
/// <param name="@params"></param>
/// <param name="headers"></param>
/// <param name="queryStrings"></param>
/// <param name="cancellationToken"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public async Task<Stream> StreamData(
Enum endpoint,
int bufferLength = 8194,
bool addXPoweredValue = true,
XTokenResponse tokens = null,
IDictionary<string, string> @params = null,
IDictionary<string, string> headers = null,
IDictionary<string, string> queryStrings = null,
[System.Runtime.CompilerServices.EnumeratorCancellation]
CancellationToken cancellationToken = default
)
{
//
var url = PrepareUrl(
@params: @params,
endpoint: endpoint,
attachBaseUrl: true,
queryStrings: queryStrings
);
var client = GetHttpClient(tokens);
if (addXPoweredValue)
{
//
client.DefaultRequestHeaders
.Add(
XAuthorization.XPoweredBy,
XPoweredValue
);
}
//
// For SSE, you might want to set the Accept header, though not strictly necessary for just streaming
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept
.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/event-stream"));
//
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
response.EnsureSuccessStatusCode();
//
var stream = await response.Content.ReadAsStreamAsync();
//
return stream;
// using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
// {
// //
// int readedBuffers = 0;
// response.EnsureSuccessStatusCode();
// var buffer = new byte[bufferLength];
// var stream = await response.Content.ReadAsStreamAsync();
// //
// while ((readedBuffers = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
// {
// //
// var content = buffer.FromBytes();
// Console.WriteLine(content);
// }
// // await foreach (var message in stream) {
// // Console.WriteLine(message);
// // }
// // await foreach (var item in stream.ToAsyncEnumerable<byte[]>(cancellationToken: cancellationToken))
// // {
// // //
// // Console.WriteLine(item);
// // // T value = item.IsNull()
// // // ? default(T)
// // // : item.FromBytes().FromJSON<T>();
// // // //
// // // yield return value;
// // }
// }
///
///
///
///
//
// var eventSource = new EventSource(url);
// // eventSource.
// // var client = GetHttpClient(tokens);
// // if (addXPoweredValue)
// // {
// // //
// // client.DefaultRequestHeaders
// // .Add(
// // XAuthorization.XPoweredBy,
// // XPoweredValue);
// // }
// // //
// // // For SSE, you might want to set the Accept header, though not strictly necessary for just streaming
// // client.DefaultRequestHeaders.Accept.Clear();
// // client.DefaultRequestHeaders.Accept
// // .Add(
// // new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/event-stream"));
// // //
// // using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
// // {
// // //
// // response.EnsureSuccessStatusCode();
// // var stream = await response.Content.ReadAsStreamAsync();
// // await foreach (var item in stream.ToAsyncEnumerable<byte[]>(cancellationToken: cancellationToken))
// // {
// // //
// // T value = item.IsNull()
// // ? default(T)
// // : item.FromBytes().FromJSON<T>();
// // //
// // yield return value;
// // }
// // }
}
/// <summary>
/// Handle Call Specified Request and Retrieve XBaseRestResponse<T> ...
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="method"></param>
/// <param name="supportRefreshingTokens"></param>
/// <param name="cancellationToken"></param>
/// <typeparam name="T"></typeparam>
/// <returns>an instance of XBaseRestResponse<T></returns>
public async Task<XBaseRestResponse<T>> RunRestRequestByResponse<T>(
RestClient client,
RestRequest request,
XHttpMethod method,
bool supportRefreshingTokens = true,
CancellationToken cancellationToken = default
)
{
//
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 identityProvider
.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;
},
cancellationToken: cancellationToken);
//
return response;
}
/// <summary>
/// Get User SelectBy Param
/// </summary>
/// <param name="model"></param>
/// <param name="forceNotNull"></param>
/// <param name="excludes"></param>
/// <returns></returns>
public string GetUserSelectByParam(
XActionRequest model,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(model);
//
var id = model.UserId;
var userName = model.UserName;
var email = model.Email;
var phoneNumber = model.MobileNumber;
//
if (excludes != null)
{
//
if (excludes.Contains(XUserSelectBy.ID))
{
id = null;
}
if (excludes.Contains(XUserSelectBy.Email))
{
email = null;
}
if (excludes.Contains(XUserSelectBy.MobileNumber))
{
phoneNumber = null;
}
if (excludes.Contains(XUserSelectBy.Username))
{
userName = null;
}
}
var selectByParam =
id.IsNullOrEmpty() ?
userName.IsNullOrEmpty() ?
email.IsNullOrEmpty() ?
phoneNumber.IsNullOrEmpty() ? null : phoneNumber : email : userName : id;
//
// Check result ...
if (forceNotNull &&
selectByParam.IsNullOrEmpty())
{
XException.InvalidData.Throw();
}
//
return selectByParam;
}
/// <summary>
/// Prepare Url Address of Specified Enum by Filling Params
/// and Query Strings Attach ...
/// </summary>
/// <param name="endpoint"></param>
/// <param name="attachBaseUrl"></param>
/// <param name="@params"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
public string PrepareUrl(
Enum endpoint,
bool attachBaseUrl = false,
IDictionary<string, string> @params = null,
IDictionary<string, string> queryStrings = null
)
{
//
// Retrieving Url Template ...
var url = endpoint.GetStringValue();
//
// Filling Parmas and Query Strings of Url ...
url = PrepareUrl(
url: url,
@params: @params,
queryStrings: queryStrings,
attachBaseUrl: attachBaseUrl
);
//
return url;
}
/// <summary>
/// Prepare Url Address by Filling Params
/// and Query Strings Attach ...
/// </summary>
/// <param name="url"></param>
/// <param name="attachBaseUrl"></param>
/// <param name="@params"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
public string PrepareUrl(
string url,
bool attachBaseUrl = false,
IDictionary<string, string> @params = null,
IDictionary<string, string> queryStrings = null
)
{
//
if (attachBaseUrl)
{
//
var baseUrl = BaseUrl;
if (!baseUrl.EndsWith("/"))
{
baseUrl = $"{baseUrl}/";
}
//
url = $"{baseUrl}{url}";
}
//
// Add Route Payloads ...
if (!@params.IsNull() && @params.Count > 0)
{
//
var enumerator = @params.GetEnumerator();
while (enumerator.MoveNext())
{
//
var item = enumerator.Current;
//
url = url.Replace(item.Key, item.Value.ToUrlEncoded());
}
}
//
// Add Query Strings ...
if (!queryStrings.IsNull() && queryStrings.Count > 0)
{
//
url = $"{url}?";
var enumerator = queryStrings.GetEnumerator();
while (enumerator.MoveNext())
{
//
var item = enumerator.Current;
//
url += $"{item.Key}={item.Value.ToUrlEncoded()}&";
}
//
// remove lates & ...
if (url.EndsWith("&"))
{
url = url.Substring(0, url.Length - 1);
}
}
//
return url;
}
/// <summary>
/// Converts UserInfo to TokenResponse model ...
/// </summary>
/// <param name="userInfo"></param>
/// <returns></returns>
public XTokenResponse ToTokenResponse(XUserClaimsInfoDto userInfo = null)
{
//
XTokenResponse result = null;
//
if (!userInfo.IsNull())
{
//
result = new XTokenResponse
{
AccessToken = userInfo.AccessToken.IsNullOrEmpty()
? ""
: userInfo.AccessToken,
RefreshToken = userInfo.RefreshToken.IsNullOrEmpty()
? ""
: userInfo.RefreshToken,
ExpiresAt = userInfo.ExpiresAt,
};
//
if (userInfo.AccessToken.IsNullOrEmpty())
{
result = null;
}
}
//
return result;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Providers\XIdentityProvider.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using RestSharp;
using RestSharp.Authenticators;
using xCommons.Constants;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
using xHttpService.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityService.Configuration;
using xIdentityService.Constants;
using xIdentityService.Interfaces;
using xIdentityService.Models;
namespace xIdentityService.Providers {
public partial class XIdentityProvider : IXIdentityProvider {
private readonly IXTokenProvider tokenProvider;
private readonly IHostingEnvironment environment;
private JsonSerializerSettings jsonSerializerSettings;
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 XIdentityProvider (
IXTokenProvider tokenProvider,
IHostingEnvironment environment,
ILogger<XIdentityProvider> logger,
IXSecurityProvider securityProvider,
XIdentityServiceConfiguration identityConfiguration,
XValidationProvider validationProvider
) {
//
BaseUrl = identityConfiguration.Authority;
RevisionSecretKey = identityConfiguration.XRevisionSecretKey;
//
this.environment = environment;
Logger = logger;
SecurityProvider = securityProvider;
//
this.identityConfiguration = identityConfiguration;
this.validationProvider = validationProvider;
this.jsonSerializerSettings = new JsonSerializerSettings {
ContractResolver = new CamelCasePropertyNamesContractResolver ()
};
//
this.tokenProvider = tokenProvider;
}
//
#region Tools ...
/// <summary>
/// Get an Instance of Http Client
/// </summary>
/// <returns></returns>
public HttpClient GetHttpClient () {
//
HttpClient httpClient = null;
//
// httpClient = new HttpClient ();
var httpClientHandler = new HttpClientHandler () {
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => {
//
Logger.LogInformation (
$"XSSL Handler: {Environment.NewLine}, sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
);
//
return true;
},
ClientCertificateOptions = ClientCertificateOption.Manual,
};
httpClient = new HttpClient (httpClientHandler);
//
// Set Timeout ...
// TODO: Fix this ...
// httpClient.Timeout = TimeSpan
// .FromSeconds (identityConfiguration.DefaultClientTimeout);
//
return httpClient;
}
/// <summary>
/// Get an Instance of RestClient
/// </summary>
/// <returns></returns>
public RestClient GetRestClient (XTokenResponse tokens = null) {
//
var client = new RestClient (BaseUrl);
//
// Set Authenticator ...
if (!tokens.IsNull () &&
!tokens.AccessToken.IsNullOrEmpty ()) {
client.Authenticator = new JwtAuthenticator (tokens.AccessToken);
}
//
// Refresh Token ...
if (!tokens.IsNull () &&
!tokens.RefreshToken.IsNullOrEmpty ()) {
client.AddDefaultHeader (XAuthorization.RefreshToken, tokens.RefreshToken);
}
//
// ExpiresAt ...
if (!tokens.IsNull () &&
tokens.ExpiresAt > 0) {
client.AddDefaultHeader (XAuthorization.ExpiresAt, tokens.ExpiresAt.AsHttpParamString ());
}
//
// Set Default Timeout ...
client.Timeout = identityConfiguration.DefaultClientTimeout;
//
// SSL Validation Handler ...
client.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => {
//
Logger.LogInformation (
$"XSSL Handler: {Environment.NewLine}, sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
);
//
return true;
};
//
return client;
}
/// <summary>
/// Get an Instance of RestRequest
/// </summary>
public RestRequest GetRestRequet (
XApiAccountEndpoint endpoint,
bool addXPoweredValue = true,
IDictionary<string, string> @params = null,
IDictionary<string, string> headers = null,
IDictionary<string, string> queryStrings = null
) {
//
var url = endpoint.GetStringValue ();
//
// Add Route Payloads ...
if (!@params.IsNull () && @params.Count > 0) {
//
var enumerator = @params.GetEnumerator ();
while (enumerator.MoveNext ()) {
//
var item = enumerator.Current;
//
url = url.Replace (item.Key, item.Value.ToUrlEncoded ());
}
}
//
// Add Query Strings ...
if (!queryStrings.IsNull () && queryStrings.Count > 0) {
//
url = $"{url}?";
var enumerator = queryStrings.GetEnumerator ();
while (enumerator.MoveNext ()) {
//
var item = enumerator.Current;
//
url += $"{item.Key}={item.Value.ToUrlEncoded ()}&";
}
//
// remove lates & ...
if (url.EndsWith ("&")) {
url = url.Substring (0, url.Length - 1);
}
}
//
// Create request ...
var request = new RestRequest (url, DataFormat.Json);
//
if (addXPoweredValue) {
request.AddHeader (XAuthorization.XPoweredBy, identityConfiguration.XPoweredValue);
}
//
// Add Headers to request ...
if (!headers.IsNull () && headers.Count > 0) {
//
var enumerator = headers.GetEnumerator ();
while (enumerator.MoveNext ()) {
//
var item = enumerator.Current;
request.AddHeader (item.Key, item.Value);
}
}
//
return request;
}
/// <summary>
/// Handle Call Specific Request and retrieve Response
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="method"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public async Task<T> RunRestRequest<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 RunRestRequest<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 = resp.Content.FromJSON<T> ();
return result;
});
//
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
/// </summary>
/// <param name="model"></param>
/// <param name="forceNotNull"></param>
/// <param name="excludes"></param>
/// <returns></returns>
public string GetUserSelectByParam (
XActionRequest model,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
) {
//
// Validate Args ...
validationProvider.NotNull (model);
//
var id = model.UserId;
var userName = model.UserName;
var email = model.Email;
var phoneNumber = model.MobileNumber;
//
if (excludes != null) {
//
if (excludes.Contains (XUserSelectBy.ID)) {
id = null;
}
if (excludes.Contains (XUserSelectBy.Email)) {
email = null;
}
if (excludes.Contains (XUserSelectBy.MobileNumber)) {
phoneNumber = null;
}
if (excludes.Contains (XUserSelectBy.Username)) {
userName = null;
}
}
var selectByParam =
id.IsNullOrEmpty () ?
userName.IsNullOrEmpty () ?
email.IsNullOrEmpty () ?
phoneNumber.IsNullOrEmpty () ? null : phoneNumber : email : userName : id;
//
// Check result ...
if (forceNotNull &&
selectByParam.IsNullOrEmpty ()) {
XException.InvalidData.Throw ();
}
//
return selectByParam;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Providers\XInMemoryTokenProvider.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using xCommons.Extensions;
using xIdentityModels.Models;
using xIdentityService.Interfaces;
namespace xIdentityService.Providers {
public partial class XInMemoryTokenProvider : IXTokenProvider {
private IDictionary<string, XTokenResponse> DbContext;
public XInMemoryTokenProvider () {
//
this.DbContext = new Dictionary<string, XTokenResponse> ();
}
public async Task<bool> IsTokenExists (string accessToken) {
//
// Validate Args ...
if (accessToken.IsNullOrEmpty ()) {
return false;
}
//
// Process Result ...
var result = DbContext.Keys.Any (k => k == accessToken);
return await Task.FromResult (result);
}
public async Task<bool> IsTokenExists (XTokenResponse tokens) {
//
// Validate Args ...
if (tokens.IsNull () ||
tokens.AccessToken.IsNullOrEmpty () ||
!await IsTokenExists (tokens.AccessToken)) {
return false;
};
//
// Process Result ...
var result = await IsTokenExists (tokens.AccessToken);
return result;
}
public async Task<bool> RemoveToken (string accessToken) {
//
// Validate Args ...
if (accessToken.IsNullOrEmpty ()) {
return false;
}
//
// Process Result ...
var result = DbContext.Remove (accessToken);
return await Task.FromResult (result);
}
public async Task<bool> RemoveToken (XTokenResponse tokens) {
//
// Validate Args ...
if (tokens.IsNull () ||
tokens.AccessToken.IsNullOrEmpty () ||
!await IsTokenExists (tokens.AccessToken)) {
return false;
};
//
// Process Result ...
var result = await RemoveToken (tokens.AccessToken);
return result;
}
public async Task<XTokenResponse> RetrieveToken (string accessToken) {
//
// Validate Args ...
if (accessToken.IsNullOrEmpty () ||
!await IsTokenExists (accessToken)) {
return null;
}
//
// Process Result ...
var result = DbContext[accessToken];
return result;
}
public async Task<bool> AddToken (XTokenResponse tokens) {
//
// Validate Args ...
if (tokens.IsNull () ||
tokens.AccessToken.IsNullOrEmpty () ||
await IsTokenExists (tokens.AccessToken)) {
return false;
};
//
// Process Result ...
try {
//
DbContext.Add (tokens.AccessToken, tokens);
return true;
} catch {
return false;
}
}
public async Task<bool> UpdateToken (XTokenResponse tokens) {
//
// Validate Args ...
if (tokens.IsNull () ||
tokens.AccessToken.IsNullOrEmpty () ||
!await IsTokenExists (tokens.AccessToken)) {
return false;
};
//
// Process Result ...
try {
//
DbContext[tokens.AccessToken] = tokens;
return true;
} catch {
return false;
}
}
public async Task<bool> AddOrUpdateToken (XTokenResponse tokens) {
//
// Validate Args ...
if (tokens.IsNull () ||
tokens.AccessToken.IsNullOrEmpty ()
) {
return false;
};
//
// Process Result ...
try {
//
var isExists = await IsTokenExists (tokens);
if (isExists) {
return await UpdateToken (tokens);
} else {
return await AddToken (tokens);
}
} catch {
return false;
}
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Providers\XProxyHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityService.Configuration;
using xIdentityService.Interfaces;
namespace xIdentityService.Providers {
public class XProxyHelper : IXProxyHelper {
//
#region Props ...
public XProxyConfiguration Configuration { get; }
#endregion
//
#region Constructor ...
public XProxyHelper (XProxyConfiguration configuration) {
this.Configuration = configuration;
}
#endregion
//
#region Actions ...
/// <summary>
/// Validate XProxy Configuration for Client ...
/// </summary>
/// <returns></returns>
public bool ValidateConfiguration () {
//
var result = !Configuration.IsNull () &&
!Configuration.Host.IsNullOrEmpty () &&
Configuration.Host.IsValidUrl () &&
Configuration.Routes.HasChild ();
//
return result;
}
/// <summary>
/// retrie Normalize Host ...
/// </summary>
/// <returns></returns>
public string NormalizeHost () {
//
var result = string.Empty;
//
if (!Configuration.IsNull () &&
!Configuration.Host.IsNullOrEmpty () &&
Configuration.Host.IsValidUrl ()
) {
//
result = Configuration.Host
.ToNormalString ();
//
if (result.EndsWith ("/")) {
result = result.Substring (0, result.Length - 1);
}
}
//
return result;
}
/// <summary>
/// retrieve all registred Routes ...
/// </summary>
/// <returns></returns>
public IEnumerable<XProxyRouteDescriptor> GetRoutes () {
//
// Validate Args ...
if (Configuration.IsNull ()) {
return null;
}
//
return Configuration.Routes;
}
/// <summary>
/// Retrieve all Prepared url of Routes ...
/// </summary>
/// <returns></returns>
public IEnumerable<string> GetRouteUrls () {
//
var normalHost = NormalizeHost ();
if (normalHost.IsNullOrEmpty ()) {
return null;
}
//
var result = GetRoutes ()
.Select (r => $"{normalHost}{r.Route}");
//
return result;
}
/// <summary>
/// Find an Specific Route ...
/// </summary>
/// <param name="whereClause"></param>
/// <returns></returns>
public XProxyRouteDescriptor FindRoute (Expression<Func<XProxyRouteDescriptor, bool>> whereClause) {
//
// Validate Arg ...
if (whereClause.IsNull ()) {
return null;
}
//
var whereFunc = whereClause
.Compile ();
//
var result = GetRoutes ()
.FirstOrDefault (whereFunc);
//
return result;
}
/// <summary>
/// Prepare a request url for a Proxy Route ...
/// </summary>
/// <param name="url"></param>
/// <param name="descriptor"></param>
/// <returns></returns>
public string PrepareActionUrlForXProxyRoute (
string url,
XProxyRouteDescriptor descriptor
) {
//
if (!url.IsValidUrl () ||
url.IsNullOrEmpty () ||
!ValidateConfiguration ()
) {
throw XException.InvalidArgs.ToException ();
}
//
// find Route ...
var routeDescriptor = GetRoutes ()
.FirstOrDefault (r => r
.IsSameContent (descriptor)
);
//
// Validate Route Descriptor ...
if (
routeDescriptor.IsNull () ||
routeDescriptor.Route.IsNullOrEmpty ()
) {
throw XException.InvalidArgs.ToException ();
}
//
// Retrieve and Validate Host Address ...
var host = NormalizeHost ();
if (!host.IsValidUrl () ||
host.IsNullOrEmpty ()
) {
throw XException.InvalidArgs.ToException ();
}
//
url = $"{host}{routeDescriptor.Route}/{HttpUtility.UrlEncode(url)}";
//
return url;
}
/// <summary>
/// Prepare a request url for a Selected Proxy Route ...
/// </summary>
/// <param name="url"></param>
/// <param name="whereClause"></param>
/// <returns></returns>
public string PrepareActionUrlForXProxyRoute (
string url,
Expression<Func<XProxyRouteDescriptor, bool>> whereClause
) {
//
if (!url.IsValidUrl () ||
url.IsNullOrEmpty () ||
whereClause.IsNull () ||
!ValidateConfiguration ()
) {
throw XException.InvalidArgs.ToException ();
}
//
var descriptor = FindRoute (whereClause);
//
// find Route ...
var result = PrepareActionUrlForXProxyRoute (
url: url,
descriptor: descriptor
);
//
return result;
}
#endregion
//
#region Private ...
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Security\XSecurityProvider.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using xCommons.Extensions;
using xCommons.Helpers;
using xCommons.Providers;
using xIdentityService.Configuration;
using xIdentityService.Interfaces;
namespace xIdentityService.Security {
public partial class XSecurityProvider : IXSecurityProvider {
private readonly string secretKey;
private readonly byte[] iv;
private readonly byte[] key;
private readonly XValidationProvider validationProvider;
public XSecurityProvider (
XIdentityServiceConfiguration identityConfiguration,
XValidationProvider validationProvider
) {
//
this.secretKey = identityConfiguration.XRevisionSecretKey.ToMd5String ();
this.validationProvider = validationProvider;
//
var ivBytes = new byte[16];
var keyBytes = new byte[32];
var secretBytes = Encoding.UTF8.GetBytes (this.secretKey);
//
Array.Copy (
secretBytes,
ivBytes,
secretBytes.Length < ivBytes.Length ?
secretBytes.Length :
ivBytes.Length
);
this.iv = ivBytes;
//
Array.Copy (
secretBytes,
keyBytes,
secretBytes.Length < keyBytes.Length ?
secretBytes.Length :
keyBytes.Length
);
this.key = keyBytes;
// Encoding.UTF8.GetBytes (this.secretKey);
}
public string Encrypt (string plainText) {
//
validationProvider.NotEmpty (plainText);
//
var textBytes = Encoding.UTF8.GetBytes (plainText);
var result = EncryptFromBytes (textBytes);
//
return result;
}
public string Decrypt (string cipherText) {
//
validationProvider.NotEmpty (cipherText);
//
var cipherBytes = Convert.FromBase64String (cipherText);
var result = DecryptFromBytes (cipherBytes);
//
return result;
}
public string EncryptFromBytes (byte[] textBytes) {
//
// Validate Args ...
validationProvider.NotNull (textBytes);
// Declare the string used to hold
// the decrypted text.
byte[] encryptedBytes = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new RijndaelManaged ()) {
//Settings
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.PKCS7;
// rijAlg.FeedbackSize = 128;
rijAlg.Key = key;
rijAlg.IV = iv;
//
using (var encryptor = rijAlg.CreateEncryptor (rijAlg.Key, rijAlg.IV)) {
encryptedBytes = encryptor.TransformFinalBlock (textBytes, 0, textBytes.Length);
}
}
//
return Convert.ToBase64String (encryptedBytes);
}
public string DecryptFromBytes (byte[] cipherBytes) {
//
// Validate Args ...
validationProvider.NotNull (cipherBytes);
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new RijndaelManaged ()) {
//Settings
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.PKCS7;
// rijAlg.FeedbackSize = 128;
rijAlg.Key = key;
rijAlg.IV = iv;
// Create a decrytor to perform the stream transform.
var decryptor = rijAlg.CreateDecryptor (rijAlg.Key, rijAlg.IV);
// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream (cipherBytes)) {
using (var csDecrypt = new CryptoStream (msDecrypt, decryptor, CryptoStreamMode.Read)) {
using (var srDecrypt = new StreamReader (csDecrypt)) {
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd ();
}
}
}
}
//
return plaintext;
}
}
}