Files
xSaherelmWorkspace/Documents/GeneratedContext/xDashboard-xIds-20261004_145906.txt
T
2026-10-04 18:11:59 +03:30

23129 lines
762 KiB
Plaintext

### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace xIds
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Startup.cs
using System;
using System.IO;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using xCommons.Configurations;
using xCommons.Extensions;
using xStorageService.DI;
using xIds.Constants;
using xIds.DI;
using xIds.Interfaces;
using xIds.Providers;
namespace xIds
{
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
//
// Register Validation Provider and all XCommons Module Services ...
services.AddXCommons();
//
// Register App Configuration ...
services.AddXAppConfiguration(Configuration);
var appConfiguration = services.GetRegisteredService<XAppConfiguration>();
//
// Register XDataService Configuration ...
services.AddXDataServiceConfiguration(Configuration, ConnectionStringNames.IDENTITY_CONNECTION_NAME);
//
// Register Allowed Origins ...
services.AddXCors(appConfiguration.AllowedOrigins);
//
// Register Swagger ...
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
services.AddXSwagger(Configuration, xmlFilePath: xmlPath);
//
// Register IdentityServer to DI ...
// services.AddInMemoryXIdentityServer (Configuration);
services.AddEfSupportXIdentityServer(Configuration);
//
services.AddControllers()
.AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);
//
// Register Authentication ...
services.AddXIdentityServerAuthentication(Configuration);
//
// Register Authorization ...
services.AddXAuthorization();
//
// Register Security Provider ...
services.AddSingleton<IXSecurityProvider, XSecurityProvider>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
//
if (env.IsDevelopment())
{
//
app.UseDeveloperExceptionPage();
//
// app.UseXRequestLogger();
}
//
// Use Swagger Middleware ...
app.UseXSwagger();
//
app.UseHttpsRedirection();
app.UseXForwardOptions();
//
// Using Cors ...
app.UseXCors();
//
// Force App to Use IdentityServer ...
app.UseXIdentityServer(logger);
//
// Force app to Use Storage Service ...
app.UseXStorageService();
//
app.UseRouting();
//
app.UseAuthentication();
app.UseAuthorization();
//
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Configurations\CertificatesConfigurations.cs
namespace xIds.Configurations
{
public class CertificatesConfigurations
{
public struct CertificateNames
{
public const string IdentityServerSigning = "IdentityServerSigning";
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Configurations\XDataServiceConfiguration.cs
using xIds.Constants;
namespace xIds.Configurations
{
/// <summary>
/// Represent Configurations of DataService Module ...
/// </summary>
public partial class XDataServiceConfiguration
{
/// <summary>
/// Provider Type ...
/// </summary>
/// <value></value>
public XDbProviders Provider { get; set; }
/// <summary>
/// Connection String which provide Requires Data to Connect to Db Provider ...
/// </summary>
/// <value></value>
public string ConnectionString { get; set; }
/// <summary>
/// Enable Tracking of Entities ...
/// Only Used on EFCore ...
/// </summary>
/// <value></value>
public bool EnableTracking { get; set; } = false;
/// <summary>
/// Enable Logging Details of Errors ...
/// Only Used on EFCore ...
/// </summary>
/// <value></value>
public bool EnableDetailedErrors { get; set; } = false;
/// <summary>
/// Enable Logging Sensitive Data ...
/// Only Used on EFCore ...
/// </summary>
/// <value></value>
public bool EnableSensitiveDataLogging { get; set; } = false;
/// <summary>
/// this is a way to provide Default Pagination Data on XQuery based requests ...
/// </summary>
/// <returns></returns>
public PagingConfiguration PagingConfiguration { get; set; } = new PagingConfiguration();
}
/// <summary>
/// this is a way to provide Default Pagination Data on XQuery based requests ...
/// </summary>
public partial class PagingConfiguration
{
/// <summary>
/// Default Page Size ...
/// </summary>
/// <value></value>
public int DefaultPageSize { get; set; } = XDataServiceConstants.DEFAULT_PAGE_SIZE;
/// <summary>
/// restrict Maximum Page Size ...
/// </summary>
/// <value></value>
public int MaxAvailablePageSize { get; set; } = XDataServiceConstants.MAX_AVAILABLE_PAGE_SIZE;
/// <summary>
/// restrice Minimum Page Size ...
/// </summary>
/// <value></value>
public int MinAvailablePageSize { get; set; } = XDataServiceConstants.MIN_AVAILABLE_PAGE_SIZE;
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Configurations\XIdentityResourceConfiguration.cs
namespace xIds.Configurations
{
/// <summary>
/// determines a resource and it's connection info
/// </summary>
public partial class XIdentityResourceConfiguration
{
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 string XRevisionSecretKey { get; set; }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Constants\ConfigurationNodeNames.cs
namespace xIds.Constants
{
public struct ConfigurationNodeNames
{
public const string DB_SEED_NODE_NAME = "DbSeeder";
public const string PROVIDER_NODE_NAME = "DbProvider";
public const string IDENTITY_NODE_NAME = "IdentityConfiguration";
public const string DATA_SERVICE_NODE_NAME = "DataServiceConfiguration";
public const string IDENTITY_RESOURCE_NODE_NAME = "IdentityResourceConfiguration";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Constants\ConnectionStringNames.cs
namespace xIds.Constants
{
public struct ConnectionStringNames
{
public const string IDENTITY_CONNECTION_NAME = "IdentityDb";
public const string CONFIGURATION_CONNECTION_NAME = "ConfigurationDb";
public const string PRESISTED_GRANTS_CONNECTION_NAME = "PersistedGrantDb";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Constants\IdentityMessagesKeys.cs
namespace xIds.Constants
{
public struct IdentityMessagesKeys
{
public const string Terms = "terms";
public const string InviteMsg = "user_invite_msg";
public const string RegistrationApproveMsg = "registration_approve_msg";
public const string RegisteredMsg = "registered_msg";
public const string VerificationCodeMsg = "verification_code_msg";
public const string ChangePasswordMsg = "change_password_msg";
public const string PasswordChangedMsg = "password_changed_msg";
public const string NewDeviceLoggedInMsg = "new_device_logged_in_msg";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Constants\XDataServiceConstants.cs
namespace xIds.Constants
{
/// <summary>
/// /// Default Pagination Values ...
/// </summary>
public partial struct XDataServiceConstants
{
public static int DEFAULT_PAGE_SIZE = 50;
public static int MAX_AVAILABLE_PAGE_SIZE = 500;
public static int MIN_AVAILABLE_PAGE_SIZE = 20;
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Constants\XDbProviderConfigurations.cs
namespace xIds.Constants
{
public partial class XDbProviderConfigurations
{
/// <summary>
/// Default ConnectionString Name ...
/// </summary>
public const string DEFAULT_CONNECTION_NAME = "DataConnection";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Constants\XDbProviders.cs
namespace xIds.Constants
{
/// <summary>
/// /// Represent Supported DBMS for Managing Data ...
/// </summary>
public enum XDbProviders
{
None,
MySQL,
SQLite,
SQLServer,
}
/// <summary>
/// Represent Supported DBMS for Managing Data ...
/// </summary>
public partial struct ProviderType
{
public const string MySQL = "MYSQL";
public const string SQLite = "SQLITE";
public const string SQLServer = "SQLSERVER";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\AccountController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Providers;
using xIds.Controllers.Base;
using xIds.Interfaces;
namespace xIds.Controllers
{
/// <summary>
/// Provide all available tools for manipulating users and accounts
/// </summary>
[ApiController]
public partial class AccountController : XIBaseController
{
public AccountController(
IXIdentityManager identityManager,
ILogger<AccountController> logger,
XAppConfiguration appConfiguration,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityManager,
validationProvider
)
{ }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\StartupController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Controllers;
using xCommons.Providers;
namespace xIds.Controllers
{
/// <summary>
/// Startup and Running Controller
/// </summary>
[Route("")]
[AllowAnonymous]
public class StartupController : XBaseController
{
public StartupController(
ILogger<StartupController> logger,
XAppConfiguration appConfiguration,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
validationProvider
)
{ }
/// <summary>
/// Show Configured Welcome Message
/// </summary>
/// <returns>an string message</returns>
[HttpGet("")]
[AllowAnonymous]
public virtual ActionResult<string> Index()
{
//
var controllerName = GetControllerName();
var message = $"{AppConfiguration.WelcomeMessage}";
//
return Ok(message);
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Admin.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using xIdentityHelper;
using xCommons.Attributes;
using xCommons.Extensions;
using xIdentityModels.Dtos;
using static IdentityServer4.IdentityServerConstants;
namespace xIds.Controllers
{
public partial class AccountController
{
//
#region Admin Actions ...
/// <summary>
/// Ban Specific Users
/// </summary>
/// <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>
[RequireXPowered]
[HttpPost("Ban")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledAdmin)]
public async Task<ActionResult<IEnumerable<string>>> Ban(
[FromBody] XUserNameIdRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(model)
.AddNotZeroChilds(model.Ids)
.ValidateGroupAsync();
//
var result = await IdentityManager
.Ban(
User.Identity.Name,
model
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// UnBann Specific Users
/// </summary>
/// <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>
[RequireXPowered]
[HttpPost("UnBan")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledAdmin)]
public async Task<ActionResult<IEnumerable<string>>> UnBan(
[FromBody] XUserNameIdRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(model)
.AddNotZeroChilds(model.Ids)
.ValidateGroupAsync();
//
var result = await IdentityManager
.UnBan(
User.Identity.Name,
model
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Check Specific User is Banned or not
/// </summary>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <returns>a boolean value which represent user banned or not</returns>
[RequireXPowered]
[Authorize(Policy = LocalApi.PolicyName)]
[HttpGet("IsBanned/{userSelectByParam?}")]
[Authorize(Policy = XPolicies.EnabledAdmin)]
[Authorize(Policy = XPolicies.EnabledAgent)]
public async Task<ActionResult<bool>> IsBanned(
[FromRoute] string userSelectByParam = null
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (userSelectByParam.IsNullOrEmpty())
{
userSelectByParam = User.Identity.Name;
}
ValidationProvider.NotEmpty(userSelectByParam);
//
var result = await IdentityManager
.IsBanned(
User.Identity.Name,
userSelectByParam
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Authentication.cs
using System;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using xIdentityHelper;
using xCommons.Attributes;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using static IdentityServer4.IdentityServerConstants;
using static xIdentityHelper.XApiScopeHelper;
using Microsoft.Extensions.Logging;
namespace xIds.Controllers
{
public partial class AccountController
{
//
#region Authentication Actions ...
/// <summary>
/// Retrieve OAuth Discovery Document
/// </summary>
/// <returns>an instance of <see>DiscoveryDocumentResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpGet("DiscoveryDocument")]
public async Task<ActionResult<DiscoveryDocumentResponse>> GetDiscoveryDocument()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.RequestDiscoveryDocument();
//
// Ceck Response Result ...
if (result.IsError)
{
XException.InvalidConfiguration.Throw();
}
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <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>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("RequestScopeAccessToken")]
public async Task<ActionResult<XTokenResponse>> RequestScopeAccessToken(
[FromHeader] XApiScope scope
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
var scopeName = string.Empty;
try
{
scopeName = scope.GetStringValue();
}
catch { }
ValidationProvider.NotEmpty(scopeName);
//
var result = await IdentityManager
.RequestScopeAccessToken(scopeName);
//
// Ceck Response Result ...
if (result.IsError)
{
XException.InvalidConfiguration.Throw();
}
//
return Ok(result
.CreateXTokenResponse()
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Authenticate User
/// </summary>
/// <remarks>
/// Sample request:
///
/// {
/// "password": "",
/// "userSelectBy": "",
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
/// <returns>an instance of <see>XTokenResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("Authenticate")]
public async Task<ActionResult<XTokenResponse>> Authenticate(
[FromBody] XLoginRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(model)
.AddNotEmpty(
model.UserSelectBy,
model.Password
)
.ValidateGroupAsync();
//
var result = await IdentityManager
.Authenticate(model);
//
// Check Result ...
if (result.IsError)
{
throw result.GetException();
}
//
// Return Result ...
return Ok(result
.CreateXTokenResponse()
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Authenticate User
/// </summary>
/// <remarks>
/// Sample request:
///
/// {
/// "language": "fa-IR"
/// "password": "",
/// "userSelectBy": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
/// <returns>an instance of <see>XLoginResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("Login")]
public async Task<ActionResult<XLoginResponse>> Login(
[FromBody] XLoginRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(
model,
model.Device)
.AddNotEmpty(
model.Language,
model.UserSelectBy,
model.Password
)
.ValidateGroupAsync();
//
var result = await IdentityManager
.Login(model);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Refresh Expired Tokens
/// </summary>
/// <remarks>
/// in addition to AccessToken, you had to pass RefreshToken due to Headers
/// </remarks>
/// <returns>an instance of <see>XTokenResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("RefreshTokens")]
public async Task<ActionResult<XTokenResponse>> RefreshTokens()
{
//
// Do Action ...
try
{
//
// Retrieve Toke Response ...
var model = await RetrieveTokensAsXTokenResponse();
//
// Validate Args ...
ValidationProvider
.GroupValidationBuilder()
.AddNotNull(model)
.AddNotEmpty(
model.AccessToken,
model.RefreshToken)
.ValidateGroup();
//
var result = await IdentityManager
.RefreshTokens(model);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Password Actions ...
/// <summary>
/// Change a User's Password ...
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - Password: user's current active password.
/// - NewPassword: user's new password to change.
/// - Device: user's client device which is an instance of XDevice.
/// - ReturnUrl: client application Login URL.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "password": ""
/// "newPassword": "",
/// "returnUrl": "http://localhost/login",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
[RequireXPowered]
[HttpPost("ChangePassword")]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = XPolicies.EnabledUser)]
[Authorize(Policy = LocalApi.PolicyName)]
public async Task<ActionResult> ChangePassword(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(
model,
model.Device
)
.AddNotEmpty(
model.Lang,
model.Password,
model.NewPassword,
model.ReturnUrl
)
.ValidateGroupAsync();
//
// Get User Select By ...
var userSelectByParam = GetUserSelectByParam(
model,
forceNotNull: false
);
if (userSelectByParam.IsNullOrEmpty())
{
userSelectByParam = User.Identity.Name;
}
ValidationProvider.NotEmpty(userSelectByParam);
//
// Get Request ...
await IdentityManager
.ChangePassword(
model.Lang,
model.Device,
userSelectByParam,
model.Password,
model.NewPassword,
model.ReturnUrl
);
//
return Ok();
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Friendship.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using xCommons.Attributes;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityHelper;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Navigations;
using xModels.Dtos;
using static IdentityServer4.IdentityServerConstants;
namespace xIds.Controllers
{
public partial class AccountController
{
//
#region Friendship Actions ...
//
#region Actions ...
/// <summary>
/// Follow a User
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
[RequireXPowered]
[HttpPost("Friendship/{destUser}/Follow")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XFriendshipFollowing>> Follow(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.Follow(
User.Identity.Name,
destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Cancel Following
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>a boolean value</returns>
[HttpPost("Friendship/{destUser}/Cancel")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<bool>> Cancel(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.Cancel(
User.Identity.Name,
destUser
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Unfollow a Follower
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns></returns>
[HttpPost("Friendship/{destUser}/UnFollowFollower")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult> UnFollowFollower(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
await IdentityManager
.UnFollowFollower(
User.Identity.Name,
destUser
);
//
return Ok();
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Unfollow Following
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns></returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpPost("Friendship/{destUser}/UnFollowFollowing")]
public async Task<ActionResult> UnFollowFollowing(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
await IdentityManager
.UnFollowFollowing(
User.Identity.Name,
destUser
);
//
return Ok();
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Block a Follower
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
[HttpPost("Friendship/{destUser}/Block")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XFriendshipFollowing>> Block(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.Block(
User.Identity.Name,
destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
//
return exResult;
}
}
/// <summary>
/// Unblock a Blocked User
/// </summary>
/// <param name="destUser">an instance of <see>XFriendshipFollowing</see></param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
[HttpPost("Friendship/{destUser}/UnBlock")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XFriendshipFollowing>> UnBlock(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.UnBlock(
User.Identity.Name,
destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
#endregion
//
#region Request Handlers ...
/// <summary>
/// Accept a Following Request
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpPost("Friendship/{destUser}/AcceptRequest")]
public async Task<ActionResult<XFriendshipFollower>> AcceptRequest(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.AcceptRequest(
User.Identity.Name,
destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Reject a Following Request
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpPost("Friendship/{destUser}/RejectRequest")]
public async Task<ActionResult<XFriendshipFollower>> RejectRequest(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.RejectRequest(
User.Identity.Name,
destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
#endregion
//
#region Getters ...
/// <summary>
/// Check a User IsFollower of Requested User
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>a boolean value</returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpGet("Friendship/{destUser}/IsFollower")]
public async Task<ActionResult<bool>> IsFollower(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.IsFollower(
User.Identity.Name,
destUser
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get Follower State of a User
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipState</see></returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpGet("Friendship/{destUser}/FollowerState")]
public async Task<ActionResult<XFriendshipState>> FollowerState(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.GetFollowerState(
User.Identity.Name,
destUser
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get Specific Follower
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpGet("Friendship/{destUser}/Follower")]
public async Task<ActionResult<XFriendshipFollower>> Follower(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.GetFollower(
User.Identity.Name,
destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get Followers List Of Current User
/// </summary>
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
[HttpGet("Friendship/Followers")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<IEnumerable<XFriendshipFollower>>> Followers()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.GetFollowers(User.Identity.Name);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
//
return exResult;
}
}
/// <summary>
/// Get All Followers List Includes Blocked, Requested and etc
/// of Current User
/// </summary>
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
[HttpGet("Friendship/AllFollowers")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<IEnumerable<XFriendshipFollower>>> AllFollowers()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.GetAllFollowers(User.Identity.Name);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get All Followers List Includes Blocked, Requested and etc
/// of Current User based On Query Model ...
/// </summary>
/// <returns>a Query Result of <see>XFriendDto</see></returns>
[HttpGet("Friendship/QueryFollowers")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XQueryResult<XFriendDto>>> QueryFollowers(
[FromQuery] XQuery query,
[FromQuery] string destUser
)
{
//
// Do Action ...
try
{
//
// Normalizing Dest User ...
var userInfo = await GetUserInfo();
bool isAdmin = userInfo.Roles.Contains(XUserRoles.ADMIN);
if (destUser.IsNullOrEmpty())
{
destUser = userInfo.UserName;
}
bool isDestUserValid = isAdmin || destUser == userInfo.UserId || destUser == userInfo.Email || destUser == userInfo.PhoneNumber || destUser == userInfo.UserName;
if (!isDestUserValid)
{
XException.NotAllowed.Throw();
}
//
var result = await IdentityManager
.QueryFollowers(
query: query,
userSelectByParam: destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Check a User is in Followings of Current User
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>a boolean value</returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpGet("Friendship/{destUser}/IsFollowing")]
public async Task<ActionResult<bool>> IsFollowing(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.IsFollowing(
User.Identity.Name,
destUser
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get Following State Relation between Specific User
/// and Current User
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipState</see></returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpGet("Friendship/{destUser}/FollowingState")]
public async Task<ActionResult<XFriendshipState>> FollowingState(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.GetFollowingState(
User.Identity.Name,
destUser
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get Specific Following Model
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpGet("Friendship/{destUser}/Following")]
public async Task<ActionResult<XFriendshipFollowing>> Following(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(destUser);
//
var result = await IdentityManager
.GetFollowing(
User.Identity.Name,
destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get Followings of Current User
/// </summary>
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
[HttpGet("Friendship/Followings")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<IEnumerable<XFriendshipFollowing>>> Followings()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.GetFollowings(User.Identity.Name);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get All Following List Includes Blocked, Requested and etc
/// of Current User
/// </summary>
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
[HttpGet("Friendship/AllFollowings")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<IEnumerable<XFriendshipFollowing>>> AllFollowings()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.GetAllFollowings(User.Identity.Name);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get All Following List Includes Blocked, Requested and etc
/// of Current User based On Query Model ...
/// </summary>
/// <returns>a Query Result of <see>XFriendDto</see></returns>
[HttpGet("Friendship/QueryFollowings")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XQueryResult<XFriendDto>>> QueryFollowings(
[FromQuery] XQuery query,
[FromQuery] string destUser
)
{
//
// Do Action ...
try
{
//
// Normalizing Dest User ...
var userInfo = await GetUserInfo();
bool isAdmin = userInfo.Roles.Contains(XUserRoles.ADMIN);
if (destUser.IsNullOrEmpty())
{
destUser = userInfo.UserName;
}
bool isDestUserValid = isAdmin || destUser == userInfo.UserId || destUser == userInfo.Email || destUser == userInfo.PhoneNumber || destUser == userInfo.UserName;
if (!isDestUserValid)
{
XException.NotAllowed.Throw();
}
//
var result = await IdentityManager
.QueryFollowings(
query: query,
userSelectByParam: destUser
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
#endregion
//
#region Others ...
/// <summary>
/// Return Following UserName's List of Current User
/// </summary>
/// <returns>a collection of UserNames</returns>
[HttpGet("Friendship/FollowingsList")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<IEnumerable<string>>> FollowingsList()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.GetFollowingList(User.Identity.Name);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Return Followers UserName's List of Current User
/// </summary>
/// <returns>a collection of UserNames</returns>
[HttpGet("Friendship/FollowersList")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<IEnumerable<string>>> FollowersList()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.GetFollowersList(User.Identity.Name);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Get Friendship Info Model between Specific User and Current User
/// </summary>
/// <param name="destUser">a user identifier which represent destination user</param>
/// <returns>an instance of <see>XFriendshipInfoDto</see></returns>
[HttpGet("Friendship/{destUser}/FriendshipInfo")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XFriendshipInfoDto>> FriendshipInfo(
[FromRoute] string destUser
)
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.GetFriendshipInfo(User.Identity.Name, destUser);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
#endregion
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Open.cs
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using xCommons.Attributes;
using xCommons.Constants;
using xIdentityModels.Dtos;
namespace xIds.Controllers
{
public partial class AccountController
{
//
// Implememnt all Open Actions here ...
//
#region Open Actions ...
[AllowAnonymous]
[RequireXPowered]
[HttpGet("Open")]
public async Task<ActionResult<string>> Get(
[FromHeader] string token,
[FromQuery] string request
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(token)
.AddNotEmpty(request)
.ValidateGroupAsync();
//
// Prepare Inner Dto Model ...
var dto = new XOpenActionInnerDto
{
Token = token,
Payload = request
};
//
// Do Action ...
var resultDto = await IdentityManager.OpenGet(dto);
Response.Headers.Add(XAuthentication.TOKEN, resultDto.Token);
//
// Return Result
return Ok(resultDto.Payload);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Private ...
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Profile.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using xIdentityHelper;
using xCommons.Attributes;
using xCommons.Extensions;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xModels.Dtos;
using static IdentityServer4.IdentityServerConstants;
namespace xIds.Controllers
{
public partial class AccountController
{
//
#region Retrieve Actions ...
/// <summary>
/// Retrieve User Names based on UserIds
/// </summary>
/// <param name="ids">a comma seperated list of UserIds</param>
/// <returns>a collection of UserNames</returns>
[HttpGet("Profile/{ids}/GetNames")]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<IEnumerable<string>>> GetNames(
[FromRoute] string ids
)
{
//
// Do Action ...
try
{
//
ValidationProvider.NotEmpty(ids);
//
var xIdList = ids.ParseListString<string>();
var result = await IdentityManager.GetUserNamesAsync(
xIdList
);
//
// Return Result
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// get user ids and retrieve corresponding user names
/// </summary>
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represent required UserIds collection</param>
/// <returns>a collection of <see>XUserNameIdResponse</see> instance</returns>
[HttpPost("Profile/GetNameIds")]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<IEnumerable<XUserNameIdResponse>>> GetNameIds(
[FromBody] XUserNameIdRequest model
)
{
//
// Do Action ...
try
{
//
ValidationProvider.NotNull(model);
//
var result = await IdentityManager.GetUserNameIdsAsync(
model
);
//
// Return Result
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Get Profile Object of Specific User
/// </summary>
/// <param name="userSelectByParam">specifies which user profile must be retrieved</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
[RequireXPowered]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
[HttpGet("Profile/{userSelectByParam?}")]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XUserProfileDto>> GetProfile(
[FromRoute] string userSelectByParam = ""
)
{
//
// Do Action ...
try
{
//
if (userSelectByParam.IsNullOrEmpty())
{
userSelectByParam = User.Identity.Name;
}
//
var result = await IdentityManager
.GetUserProfileAsync(
userSelectByParam,
User.Identity.Name
);
//
// Return Result
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Query Users
/// for specifiy users role for query user 'role: string' and 'forceRole: boolean' in header
/// </summary>
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
/// <param name="role">an string which represent user role</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>
[RequireXPowered]
[HttpGet("Profile/Query")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledAdmin)]
[Authorize(Policy = XPolicies.EnabledAgent)]
public async Task<ActionResult<XQueryResult<XUserProfileDto>>> QueryProfiles(
[FromQuery] XQuery query, [FromHeader] string role, [FromHeader] bool forceRole = false
)
{
//
// Do Action ...
try
{
//
var userId = User.Identity.Name;
//
var result = new XQueryResult<XUserProfileDto>();
if (role.IsNullOrEmpty())
{
//
result = await IdentityManager.QueryUsers(
userId,
query
);
}
else
{
//
result = await IdentityManager.QueryInRoleUsers(
userId,
role,
query,
forceRole
);
}
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exception = GetExceptionActionResult(ex);
return exception;
}
}
/// <summary>
/// Query Specified User's Profile Images
/// </summary>
/// <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>
[RequireXPowered]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[Authorize(Policy = XPolicies.EnabledAdmin)]
[HttpGet("Profile/Avatars/Query/{userSelectByParam?}")]
public async Task<ActionResult<XQueryResult<XProfileImageDto>>> QueryAvatars(
[FromQuery] XQuery query, [FromRoute] string userSelectByParam = null
)
{
//
// Do Action ...
try
{
//
if (userSelectByParam.IsNullOrEmpty())
{
userSelectByParam = User.Identity.Name;
}
//
var result = await IdentityManager.QueryAvatars(
userSelectByParam,
query
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exception = GetExceptionActionResult(ex);
return exception;
}
}
#endregion
//
#region Update Actions ...
/// <summary>
/// Update User Profile based on XProfileUpdateRequest (FirstName/LastName/DateOfBirth)
/// </summary>
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
[RequireXPowered]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
[HttpPost("Profile/Update/{userSelectByParam?}")]
public async Task<ActionResult<XUserProfileDto>> UpdateProfile(
[FromBody] XProfileUpdateRequest model, [FromRoute] string userSelectByParam = null
)
{
//
// Do Action ...
try
{
//
if (userSelectByParam.IsNullOrEmpty())
{
userSelectByParam = User.Identity.Name;
}
//
var result = await IdentityManager.ProfileUpdateAsync(
userSelectByParam,
User.Identity.Name,
model
);
//
// Return Result
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Update a User Profile based on XProfileUpdateRequest Full
/// </summary>
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
[RequireXPowered]
[Authorize(Policy = LocalApi.PolicyName)]
[HttpPost("Profile/{userSelectByParam?}")]
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
public async Task<ActionResult<XUserProfileDto>> FullUpdateProfile(
[FromBody] XProfileUpdateRequest model, [FromRoute] string userSelectByParam = null
)
{
//
// Do Action ...
try
{
//
if (userSelectByParam.IsNullOrEmpty())
{
userSelectByParam = User.Identity.Name;
}
//
var result = await IdentityManager.FullProfileUpdateAsync(
userSelectByParam,
User.Identity.Name,
model
);
//
// Return Result
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Avatar Actions ...
/// <summary>
/// Add a New Profile Image
/// </summary>
/// <param name="file">an specific File to upload, <see>IFormFile</see></param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
[RequireXPowered]
[HttpPost("Profile/Avatar")]
[RequestSizeLimit(966_367_641)]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XUserProfileDto>> AddAvatar(
[FromForm] IFormFile file
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotNull(file);
//
// Get Request ...
var result = await IdentityManager
.AddAvatar(
User.Identity.Name,
file
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Add a New Collection of Profile Images
/// </summary>
/// <param name="files">a collection of Files to upload, <see>IFormFileCollection</see></param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
[RequireXPowered]
[HttpPost("Profile/Avatars")]
[RequestSizeLimit(966_367_641)]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XUserProfileDto>> AddAvatars(
[FromForm] IFormFileCollection files
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
ValidationProvider.NotZeroChilds(files);
//
// Get Request ...
var result = await IdentityManager.AddAvatars(
User.Identity.Name,
files
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Remove Profile Images
/// </summary>
/// <param name="ids">a comma seperated list of avatarIds to remove</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
[RequireXPowered]
[Authorize(Policy = XPolicies.User)]
[HttpDelete("Profile/Avatars/{ids}")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XUserProfileDto>> RemoveAvatars(
[FromRoute] string ids
)
{
//
// Do Action ...
try
{
//
ValidationProvider.NotEmpty(ids);
var idList = ids.Split(",");
var idCollection = new Collection<int>();
//
foreach (var s in idList)
{
idCollection.Add(int.Parse(s));
}
//
// Get Request ...
var result = await IdentityManager
.RemoveAvatar(
User.Identity.Name,
idCollection.ToArray()
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// set Specified Profile Image as Avatar
/// </summary>
/// <param name="id">an integer which reperesent AvatarId to set as current Avatar</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
[RequireXPowered]
[HttpPost("Profile/Avatars/{id:int}/Set")]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XUserProfileDto>> SetAvatar(
[FromRoute] int id
)
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.SetAvatar(
User.Identity.Name,
id
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exception = GetExceptionActionResult(ex);
return exception;
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Query.cs
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using xCommons.Attributes;
using xCommons.Extensions;
using xIdentityHelper;
using xModels.Dtos;
using static IdentityServer4.IdentityServerConstants;
namespace xIds.Controllers
{
public partial class AccountController
{
/// <summary>
/// Query Users
/// for specifiy users role for query user 'role: string' and 'forceRole: boolean' in header
/// </summary>
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
/// <param name="role">an string which represent user role</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>
[RequireXPowered]
[HttpGet("Users/Query")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XQueryResult<string>>> QueryUsers(
[FromQuery] XQuery query,
[FromHeader] string role,
[FromHeader] bool forceRole = false
)
{
//
// Do Actions ...
try
{
//
// Retrieve User Info ...
var userInfo = await GetUserInfo();
//
// Retrieve Result Based on Provided Query ...
var result = await IdentityManager.QueryUsers(
role: role,
query: query,
forceRole: forceRole,
requestedUserSelectByParam: userInfo.UserId
);
//
// Return result ...
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exception = GetExceptionActionResult(ex);
return exception;
}
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Registration.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using xIdentityHelper;
using xCommons.Attributes;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Models;
using static IdentityServer4.IdentityServerConstants;
namespace xIds.Controllers
{
public partial class AccountController
{
//
#region CanRegister ...
/// <summary>
/// Check a UserName is Available For Registration or not
/// </summary>
/// <param name="userName">an string value which represent desired username</param>
/// <returns>a boolean value</returns>
[AllowAnonymous]
[RequireXPowered]
[HttpGet("CanRegisterUserName/{userName?}")]
public async Task<ActionResult<bool>> CanRegisterUserName(
[FromRoute] string userName
)
{
//
// Validate Args ...
if (userName.IsNullOrEmpty())
{
return BadRequest(
XException.InvalidArgs
.ToXError()
);
}
//
// Do Action ...
try
{
//
var result = await IdentityManager
.CanRegister(userName);
//
// Return Result
return Ok(result);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
//
return result;
}
}
/// <summary>
/// Check a Mobile Number is Available For Registration or not
/// </summary>
/// <param name="mobileNumber">an string value which represent desired mobile number</param>
/// <returns>a boolean value</returns>
[AllowAnonymous]
[RequireXPowered]
[HttpGet("CanRegisterMobileNumber/{mobileNumber?}")]
public async Task<ActionResult<bool>> CanRegisterMobileNumber(
[FromRoute] string mobileNumber
)
{
//
// Validate Args ...
if (mobileNumber.IsNullOrEmpty())
{
return BadRequest(
XException.InvalidArgs
.ToXError()
);
}
if (!mobileNumber.IsValidMobileNumber())
{
return BadRequest(
XException.InvalidMobileNumber
.ToXError()
);
}
//
// Do Action ...
try
{
//
var result = await IdentityManager
.CanRegister(mobileNumber);
//
// Return Result
return Ok(result);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
//
return result;
}
}
/// <summary>
/// Check a Email Address is Available For Registration or not
/// </summary>
/// <param name="email">an string value which represent desired email address</param>
/// <returns>a boolean value</returns>
[AllowAnonymous]
[RequireXPowered]
[HttpGet("CanRegisterEmail/{email?}")]
public async Task<ActionResult<bool>> CanRegisterEmail(
[FromRoute] string email
)
{
//
// Validate Args ...
if (email.IsNullOrEmpty())
{
return BadRequest(
XException.InvalidArgs
.ToXError()
);
}
if (!email.IsValidEmail())
{
return BadRequest(
XException.InvalidEmailAddress
.ToXError()
);
}
//
// Do Action ...
try
{
//
var result = await IdentityManager
.CanRegister(email);
//
// Return Result
return Ok(result);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
//
return result;
}
}
#endregion
//
#region Confirmations ...
/// <summary>
/// Check User is Confirmed Email or not
/// </summary>
/// <returns>a boolean value</returns>
[RequireXPowered]
[HttpGet("IsConfirmedEmail")]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
public async Task<ActionResult<bool>> IsConfirmedEmail()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.IsConfirmedEmail(User.Identity.Name);
//
// Return Result
return Ok(result);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
//
return result;
}
}
/// <summary>
/// Check User is Confirmed Mobile or not
/// </summary>
/// <returns>a boolean value</returns>
[RequireXPowered]
[HttpGet("IsConfirmedMobile")]
[Authorize(Policy = XPolicies.User)]
[Authorize(Policy = LocalApi.PolicyName)]
public async Task<ActionResult<bool>> IsConfirmedMobile()
{
//
// Do Action ...
try
{
//
var result = await IdentityManager
.IsConfirmedMobile(User.Identity.Name);
//
// Return Result
return Ok(result);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
//
return result;
}
}
/// <summary>
/// Confirm Registration
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - ActionToken: user's requested action token for this action.
/// - Device: user's client device which is an instance of XDevice.
/// - ReturnUrl: client application Login URL.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "actionToken": ""
/// "returnUrl": "http://localhost/login",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("ConfirmRegistration")]
public async Task<ActionResult> ConfirmRegistration(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.ActionToken,
model.ReturnUrl
)
.AddNotNull(model.Device)
.ValidateGroupAsync();
//
// Get Request ...
await IdentityManager
.ConfirmRegistration(
model.Lang,
model.Device,
model.ActionToken,
model.ReturnUrl
);
//
return Ok();
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Confirm Requested Mobile Number
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - ActionToken: user's requested action token for this action.
/// - Device: user's client device which is an instance of XDevice.
/// - MobileVerificationCode: a verification code which produced due Request Action.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "actionToken": ""
/// "mobileVerificationCode": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("ConfirmMobileNumber")]
public async Task<ActionResult<XActionResponse>> ConfirmMobileNumber(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.ActionToken,
model.MobileVerificationCode
)
.AddNotNull(model.Device)
.ValidateGroupAsync();
//
// Get Request ...
var result = await IdentityManager
.ConfirmMobileNumber(
model.Lang,
model.Device,
model.ActionToken,
model.MobileVerificationCode
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Confirm Requested Email Address
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - ActionToken: user's requested action token for this action.
/// - Device: user's client device which is an instance of XDevice.
/// - EmailVerificationCode: a verification code which produced due Request Action.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "actionToken": ""
/// "emailVerificationCode": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("ConfirmEmailAddress")]
public async Task<ActionResult<XActionResponse>> ConfirmEmailAddress(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.ActionToken,
model.EmailVerificationCode
)
.AddNotNull(model.Device)
.ValidateGroupAsync();
//
// Get Request ...
var result = await IdentityManager
.ConfirmEmailAddress(
model.Lang,
model.Device,
model.ActionToken,
model.EmailVerificationCode
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
#endregion
//
#region Request for Actions ...
/// <summary>
/// Request For Mobile Number Change/Confirm
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - Password: user's current active password.
/// - MobileNumber: which phone number is going to confirm.
/// - Device: user's client device which is an instance of XDevice.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "password": "",
/// "mobileNumber": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("RequestConfirmMobile")]
public async Task<ActionResult<XActionResponse>> RequestConfirmMobile(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
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
});
//
// Get Request ...
var result = await IdentityManager
.RequestConfirmMobile(
model.Lang,
model.Device,
userSelectByParam,
model.Password,
model.MobileNumber
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Request For Email Address Change/Confirm
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - Password: user's current active password.
/// - Email: which email address is going to confirm.
/// - Device: user's client device which is an instance of XDevice.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "password": "",
/// "email": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("RequestConfirmEmail")]
public async Task<ActionResult<XActionResponse>> RequestConfirmEmail(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
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
});
//
// Get Request ...
var result = await IdentityManager
.RequestConfirmEmail(
model.Lang,
model.Device,
userSelectByParam,
model.Password,
model.Email
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Request Reset Password Action
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - Device: user's client device which is an instance of XDevice.
/// - ReturnUrl: client application ResetPassword URL.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "returnUrl": "http://localhost/reset-password",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("RequestResetPassword")]
public async Task<ActionResult<XActionResponse>> RequestResetPassword(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.ReturnUrl)
.AddNotNull(model.Device)
.AddUrl(model.ReturnUrl)
.ValidateGroupAsync();
//
// Get UserSelect By Param ...
var userSelectByParam = GetUserSelectByParam(model);
//
// Get Request ...
var result = await IdentityManager
.RequestResetPassword(
model.Lang,
model.Device,
userSelectByParam,
model.ReturnUrl
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Reset a User's Password
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - ActionToken: user's requested action token for this action.
/// - NewPassword: user's new password to change.
/// - Device: user's client device which is an instance of XDevice.
/// - ReturnUrl: client application Login URL.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "actionToken": "",
/// "newPassword": "",
/// "returnUrl": "http://localhost/login",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("ResetPassword")]
public async Task<ActionResult> ResetPassword(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.ActionToken,
model.NewPassword,
model.ReturnUrl)
.AddNotNull(model.Device)
.ValidateGroupAsync();
//
// Get Request ...
await IdentityManager
.ResetPassword(
model.Lang,
model.Device,
model.ActionToken,
model.NewPassword,
model.ReturnUrl
);
//
return Ok();
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Request Registration Confirm
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - a UserSelectedBy identifier which represet User.
/// - Lang: client device currently used locale, such as: en-US.
/// - Password: user's current active password.
/// - Device: user's client device which is an instance of XDevice.
/// - ReturnUrl: client application Confirm Registration URL.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "userId": ""
/// "password": "",
/// "returnUrl": "http://localhost/confirm",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("RequestConfirmRegistration")]
public async Task<ActionResult> RequestConfirmRegistration(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.Password,
model.ReturnUrl)
.AddNotNull(model.Device)
.AddUrl(model.ReturnUrl)
.ValidateGroupAsync();
//
// Get UserSelect By Param ...
var userSelectByParam = GetUserSelectByParam(model);
//
// Get Request ...
await IdentityManager
.RequestConfirmRegistration(
model.Lang,
model.Device,
userSelectByParam,
model.Password,
model.ReturnUrl
);
//
return Ok();
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
#endregion
//
#region Registration ...
/// <summary>
/// Invite a User to Register on Dashboard
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - Email: which email address is going to invite.
/// - Device: user's client device which is an instance of XDevice.
/// - ReturnUrl: client application Registration URL.
/// notice in this step you had to provide all this informations as FormData
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "email": "",
/// "returnUrl": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
[RequireXPowered]
[HttpPost("InviteUser")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledAdmin)]
[Authorize(Policy = XPolicies.EnabledAgent)]
public async Task<ActionResult<XActionResponse>> InviteUser(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
//
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.Email,
model.ReturnUrl)
.AddEmailAddress(model.Email)
.AddNotNull(model.Device)
.ValidateGroupAsync();
//
var result = await IdentityManager
.InviteUser(
model.Lang,
model.Device,
model.Email,
model.ReturnUrl);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Recieve some Basic Informations and Start Registration Proccess
/// if they Valid
///
/// Registration Proccess Starts with Invoking this Action
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - FirstName: user's FirstName.
/// - LastName: user's LastName.
/// - DateOfBirth: user's dob date.
/// - MobileNumber: user's MobileNumber optional.
/// - Email: user's Email optional.
/// - ActionToken: user's requested action token for this action (if user invited).
/// - Device: user's client device which is an instance of XDevice.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "firstName": "",
/// "lastName": "",
/// "dateOfBirth": "",
/// "email": "",
/// "mobileNumber": "",
/// "actionToken": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("RequestRegistration")]
public async Task<ActionResult<XActionResponse>> RequestRegistration(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.FirstName,
model.LastName)
.AddNotNull(
model.Device,
model.DateOfBirth)
.ValidateGroupAsync();
//
// Check Date Of Birth ...
if (!model.DateOfBirth.HasValue)
{
XException.InvalidArgs.Throw(); ;
}
//
// Validate Mobile Number if Exists ...
if (!model.MobileNumber.IsNullOrEmpty())
{
ValidationProvider.MobileNumber(model.MobileNumber);
}
//
// Validate Email Address if Exists ...
if (!model.Email.IsNullOrEmpty())
{
ValidationProvider.EmailAddress(model.Email);
}
//
// Get Request ...
var result = await IdentityManager
.RequestRegistration(
model.Lang,
model.Device,
model.ActionToken,
model.FirstName,
model.LastName,
model.DateOfBirth.GetValueOrDefault(),
model.MobileNumber,
model.Email
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
//
return exResult;
}
}
/// <summary>
/// Add User Account Informations
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - Lang: client device currently used locale, such as: en-US.
/// - ActionToken: user's requested action token for this action.
/// - UserName: user name.
/// - Password: assigne password.
/// - Device: user's client device which is an instance of XDevice.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "userName": "",
/// "password": "",
/// "actionToken": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("AddAccountInfo")]
public async Task<ActionResult<XActionResponse>> AddAccountInfo(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.ActionToken,
model.UserName,
model.Password)
.AddNotNull(model.Device)
.ValidateGroupAsync();
//
// Get Request ...
var result = await IdentityManager
.AddAcountInfo(
model.Lang,
model.Device,
model.ActionToken,
model.UserName,
model.Password);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <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>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("AttachProfileImage")]
public async Task<ActionResult<XActionResponse>> AttachProfileImage(
[FromForm] string actionToken, [FromForm] IFormFile file
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(actionToken)
.AddNotNull(file)
.ValidateGroupAsync();
//
var result = await IdentityManager
.AttachProfileImage(actionToken, file);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
return exResult;
}
}
/// <summary>
/// Finish Registrationn Proccess
/// </summary>
/// <remarks>
/// for this action you have to provide:
/// - a proper User Identifier such as: (UserId, UserName, Email or MobileNumber).
/// - Lang: client device currently used locale, such as: en-US.
/// - ActionToken: user's requested action token for this action.
/// - Password: assigne password.
/// - Device: user's client device which is an instance of XDevice.
/// - ReturnUrl: client application Login URL.
///
/// Sample request:
///
/// {
/// "lang": "fa-IR",
/// "userName": "",
/// "password": "",
/// "returnUrl": "",
/// "device": {
/// "os":"Mac",
/// "browser":"Chrome",
/// "osVersion":"mac-os-x-15",
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
/// "deviceType":3,
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
/// }
/// }
///
/// </remarks>
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
/// <returns></returns>
[AllowAnonymous]
[RequireXPowered]
[HttpPost("FinishRegistration")]
public async Task<ActionResult> FinishRegistration(
[FromBody] XActionRequest model
)
{
//
// Do Action ...
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
model.Lang,
model.Password,
model.ReturnUrl)
.AddNotNull(model.Device)
.AddUrl(model.ReturnUrl)
.ValidateGroupAsync();
//
var userSelectByParam = IdentityManager
.GetUserSelectByParam(model);
ValidationProvider
.NotEmpty(userSelectByParam);
//
// Get Request ...
await IdentityManager
.FinishRegistration(
model.Lang,
model.Device,
userSelectByParam,
model.Password,
model.ReturnUrl
);
//
return Ok();
}
catch (Exception ex)
{
//
var exResult = GetExceptionActionResult(ex);
//
return exResult;
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Search.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using xCommons.Attributes;
using xCommons.Extensions;
using xIdentityHelper;
using xIdentityModels.Dtos;
using xModels.Dtos;
using static IdentityServer4.IdentityServerConstants;
namespace xIds.Controllers
{
/// <summary>
/// Actions which related to Search and Suggest Users for
/// Friendship or Detecting ...
/// </summary>
public partial class AccountController
{
//
#region Actions of Search ...
/// <summary>
/// Query Open To Search Users Profiles ...
/// Query all Users Which their Profiles is Open To Search ...
/// </summary>
/// <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>
[RequireXPowered]
[HttpGet("OpenToSearch/Query")]
[Authorize(Policy = LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XQueryResult<XUserProfileDto>>> QueryOpenToSearchProfiles(
[FromQuery] XQuery query)
{
//
// Do Action ...
try
{
//
var userId = User.Identity.Name;
//
var result = await IdentityManager.QueryOpenToSearchUsers(
userId,
query
);
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var exception = GetExceptionActionResult(ex);
return exception;
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Test.cs
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using xIdentityHelper;
using xCommons.Attributes;
using static IdentityServer4.IdentityServerConstants;
namespace xIds.Controllers
{
public partial class AccountController
{
//
#region Test Actions ...
/// <summary>
/// API Read Scope
/// </summary>
/// <returns>string message</returns>
[RequireXPowered]
[Authorize(LocalApi.PolicyName)]
[HttpGet("Test/PassReadAccess")]
[Authorize(Policy = XPolicies.ReadAccess)]
public ActionResult<string> PassReadAccess()
{
return Ok("Read Access Passed ...");
}
/// <summary>
/// API Write Scope
/// </summary>
/// <returns>string message</returns>
[RequireXPowered]
[Authorize(LocalApi.PolicyName)]
[HttpGet("Test/PassWriteAccess")]
[Authorize(Policy = XPolicies.WriteAccess)]
public ActionResult<string> PassWriteAccess()
{
return Ok("Write Access Passed ...");
}
/// <summary>
/// API Admin Scope
/// </summary>
/// <returns>string message</returns>
[RequireXPowered]
[Authorize(LocalApi.PolicyName)]
[HttpGet("Test/PassAdminAccess")]
[Authorize(Policy = XPolicies.AdminAccess)]
public ActionResult<string> PassAdminAccess()
{
return Ok("Admin Access Passed ...");
}
/// <summary>
/// API Manage Scop
/// </summary>
/// <returns>string message</returns>
[RequireXPowered]
[Authorize(LocalApi.PolicyName)]
[HttpGet("Test/PassManageAccess")]
[Authorize(Policy = XPolicies.ManageAccess)]
public ActionResult<string> PassManageAccess()
{
return Ok("Manage Access Passed ...");
}
/// <summary>
/// a simple Action which returns a List of Authenticated User Claims
/// </summary>
/// <returns>string message which represent current user's claims</returns>
[RequireXPowered]
[HttpGet("Test/HiClaims")]
[Authorize(LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.User)]
public ActionResult<string> HiClaims()
{
//
var result = new
{
name = User.Identity.Name,
claims = User.Claims.Select(c => new
{
c.Type,
c.Value
})
};
//
return Ok(result);
}
/// <summary>
/// a simple Hello User for Checking Authentication and Policy
/// </summary>
/// <returns>string message which contains authenticated user name</returns>
[RequireXPowered]
[HttpGet("Test/HiUser")]
[Authorize(LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.User)]
public ActionResult<string> HiUser()
{
//
var result = $"Hi User: {User.Identity.Name} ...";
//
return Ok(result);
}
/// <summary>
/// a simple Hello User for Checking Authentication and Policy
/// </summary>
/// <returns>string message which contains authenticated user name</returns>
[RequireXPowered]
[HttpGet("Test/HiEnabledUser")]
[Authorize(LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledUser)]
public ActionResult<string> HiEnabledUser()
{
//
var result = $"Hi User: {User.Identity.Name} is Enabled ...";
//
return Ok(result);
}
/// <summary>
/// a simple Hello User for Checking Authentication and Policy
/// </summary>
/// <returns>string message which contains authenticated user name</returns>
[RequireXPowered]
[HttpGet("Test/HiAdmin")]
[Authorize(LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.Admin)]
public ActionResult<string> HiAdmin()
{
//
var result = $"Hi Admin: {User.Identity.Name} ...";
//
return Ok(result);
}
/// <summary>
/// a simple Hello User for Checking Authentication and Policy
/// </summary>
/// <returns>string message which contains authenticated user name</returns>
[RequireXPowered]
[HttpGet("Test/HiEnabledAdmin")]
[Authorize(LocalApi.PolicyName)]
[Authorize(Policy = XPolicies.EnabledAdmin)]
public ActionResult<string> HiEnabledAdmin()
{
//
var result = $"Hi Admin: {User.Identity.Name} is Enabled ...";
//
return Ok(result);
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Controllers\Base\XIBaseController.cs
using System;
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 xIds.Interfaces;
namespace xIds.Controllers.Base
{
public abstract class XIBaseController : XBaseController
{
public IXIdentityManager IdentityManager { get; }
protected XIBaseController(
ILogger logger,
XAppConfiguration appConfiguration,
IXIdentityManager identityManager,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
validationProvider
)
{
IdentityManager = identityManager;
}
//
#region User Handlers NonActions ...
/// <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 = IdentityManager.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);
}
//
Logger.LogInformation($"Token: {accessToken}");
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);
}
//
Logger.LogInformation($"Refresh Token: {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>();
//
Logger.LogInformation($"Token ExpiresAt: {expiresAtStr}");
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
//
#region NonActions ...
/// <summary>
/// Convert an Exception to Propper Error Result
/// </summary>
/// <param name="ex"></param>
/// <returns></returns>
[NonAction]
public new ActionResult GetExceptionActionResult(Exception ex)
{
//
var exception = GetExceptionResult(ex);
var error = ex.Message.ToXError();
//
Logger.LogError($"exception: {exception}, error: {error}");
//
try
{
var xError = exception.Message.ToXError();
var xException = (XException)xError.Id;
//
switch (xException)
{
//
case XException.NotFound:
return NotFound(error);
//
case XException.NotAuthorized:
return Unauthorized(error);
}
}
catch { }
//
return BadRequest(error);
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\DbContext\XIdentityDbContext.cs
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using xIdentityModels;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
namespace xIds.DbContext
{
public class XIdentityDbContext : IdentityDbContext
{
//
#region Props/DbSets ...
public DbSet<XToken> Tokens { get; set; }
public DbSet<XDevice> Devices { get; set; }
public DbSet<XProfileImage> Avatars { get; set; }
public DbSet<XBannedDevice> BannedDevices { get; set; }
public DbSet<XFriendshipFollower> Followers { get; set; }
public DbSet<XFriendshipFollowing> Followings { get; set; }
public DbSet<XVerificationRequest> VerificationRequests { get; set; }
#endregion
public XIdentityDbContext(DbContextOptions<XIdentityDbContext> options) : base(options)
{
//
try
{
Database.EnsureCreated();
Database.Migrate();
}
catch { }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//
base.OnModelCreating(modelBuilder);
//
// Fix XUser GUID Generator on Add ...
modelBuilder
.Entity<IdentityUser>()
.Property(e => e.Id)
.ValueGeneratedOnAdd();
//
// Handle Role List ...
modelBuilder.Entity<XUser>(u =>
{
u.HasMany(x => x.Roles)
.WithOne()
.HasForeignKey(ur => ur.UserId)
.IsRequired();
});
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\DI\XDIHelperExtension.cs
using System.Collections.Generic;
using IdentityServer4;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using xCommons.Authorization;
using xCommons.Constants;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityHelper;
using xIdentityModels;
using xIdentityModels.Configurations;
using xIds.Configurations;
using xIds.Constants;
using xIds.DbContext;
using xIds.Extensions;
using xIds.Helpers;
using xIds.Interfaces;
using xIds.Providers;
using xIds.Validators;
using xMessageService.DI;
using xMessageService.Interfaces;
using xStorageService.DI;
using xStorageService.Interfaces;
namespace xIds.DI
{
public static class XDIHelperExtension
{
/// <summary>
/// Register Application DataProvider
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXDataProvider(
this IServiceCollection services,
IConfiguration configuration
)
{
//
// Retrieve DbInfo ...
var dbInfo = configuration.GetXDbInfo();
var identityDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.IDENTITY_CONNECTION_NAME);
//
// Register Db Context for EF ...
services.AddDbContext<XIdentityDbContext>(builder =>
{
//
builder.PrepareXDbContextOptionsBuilder(
dbInfo,
identityDbConnectionString
);
});
}
/// <summary>
/// Extract Connection String From IConfiguration
/// </summary>
/// <param name="config"></param>
/// <param name="connectionName"></param>
/// <returns></returns>
public static string GetXConnectionString(
this IConfiguration config,
string connectionName = null
)
{
//
if (connectionName.IsNullOrEmpty())
{
connectionName = XDbProviderConfigurations.DEFAULT_CONNECTION_NAME;
}
//
return config.GetConnectionString(connectionName);
}
/// <summary>
/// Retrive XDataService Configurations
/// </summary>
/// <param name="source"></param>
/// <param name="connectionName"></param>
/// <returns></returns>
public static XDataServiceConfiguration GetXDataServiceConfiguration(
this IConfiguration source,
string connectionName = null
)
{
//
var xDataServiceConfigSection = source
.GetSection(Constants.ConfigurationNodeNames.DATA_SERVICE_NODE_NAME);
var result = xDataServiceConfigSection.Get<XDataServiceConfiguration>();
if (result.IsNull())
{
result = new XDataServiceConfiguration();
}
//
result.Provider = source.GetXDbProviderType();
result.ConnectionString = source.GetXConnectionString(connectionName);
//
return result;
}
/// <summary>
/// Register XDataService Configuration
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="connectionName"></param>
public static void AddXDataServiceConfiguration(
this IServiceCollection services,
IConfiguration configuration,
string connectionName = null
)
{
//
var dataServiceConfiguration = configuration
.GetXDataServiceConfiguration(connectionName);
//
services.AddSingleton<XDataServiceConfiguration>(dataServiceConfiguration);
}
/// <summary>
/// Register All Requirements For XIdentityServer Usage
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXIdentityServerRequirements(
this IServiceCollection services,
IConfiguration configuration
)
{
//
services.AddXDataProvider(configuration);
//
// Register XIdentityMessageProvider ...
services.AddXIdentityMessageProvider();
//
// Register IdentityManager Service ...
var xIdentityManager = services.GetRegisteredService<IXIdentityManager>();
if (xIdentityManager.IsNull())
{
services.AddXIdentityManager();
}
//
// Check XMessage Service Registered or not and Register it if not ...
var xMessageProvider = services.GetRegisteredService<IXMessageProvider>();
if (xMessageProvider.IsNull())
{
services.AddXMessageService(configuration);
}
//
// Check Storage Service Registered or not and Register it if not ...
var xStorageProvider = services.GetRegisteredService<IXStorageProvider>();
if (xStorageProvider.IsNull())
{
services.AddXStorageService(configuration);
}
//
// Register XIdentityConfiguration ...
var xIdentityConfiguration = configuration.GetXIdentityConfiguration();
services.AddSingleton<XIdentityConfiguration>(xIdentityConfiguration);
//
// Register XIdentityHelper ...
services.AddSingleton<IXIdentityHelper, XIdentityHelper>();
var xIdentityHelper = services.GetRegisteredService<IXIdentityHelper>();
//
// Register Asp.net Identity ...
services.AddXIdentity();
}
/// <summary>
/// Add IdentityServer with Support of Ef
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddEfSupportXIdentityServer(
this IServiceCollection services,
IConfiguration configuration
)
{
//
// Register All Requirements ...
services.AddXIdentityServerRequirements(configuration);
//
// add DbSeeder Config ...
services.AddXDebSeederDescriptor(configuration);
//
// Retrieve Certificate ...
var identityServerSigningCertificate = configuration.GetCertificate(CertificatesConfigurations.CertificateNames.IdentityServerSigning);
//
// Retrieve DbInfo ...
var dbInfo = configuration.GetXDbInfo();
//
// Retrieve Connection String Names ...
var configDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.CONFIGURATION_CONNECTION_NAME);
var persistedGrantDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.PRESISTED_GRANTS_CONNECTION_NAME);
//
// Register IdentityServer ...
services.AddIdentityServer(options =>
{
//
options.Discovery.CustomEntries.Add("account_api", "~/account");
//
// options.Events.RaiseErrorEvents = true;
// options.Events.RaiseFailureEvents = true;
// options.Events.RaiseSuccessEvents = true;
// options.Events.RaiseInformationEvents = true;
})
.LoadSigningCredentialFrom(identityServerSigningCertificate)
.AddXDbProvider(configuration)
.AddAspNetIdentity<XUser>()
.AddProfileService<XIdentityProfileService>()
.AddResourceOwnerValidator<XResourceOwnerPasswordValidator>();
}
/// <summary>
/// force app to use IdentityServer
/// </summary>
/// <param name="app"></param>
/// <param name="logger"></param>
public static void UseXIdentityServer(
this IApplicationBuilder app,
ILogger logger
)
{
//
// Update XIdentityServer Configurations before Use Identity Server ...
app.SeedData(logger)
.GetAwaiter()
.GetResult();
//
// Use Identity Server ...
app.UseIdentityServer();
}
/// <summary>
/// Register Asp.net Identity as User Store
/// </summary>
/// <param name="services"></param>
public static void AddXIdentity(this IServiceCollection services)
{
//
var xIdentityConfiguration = services.GetRegisteredService<XIdentityConfiguration>();
if (xIdentityConfiguration.IsNull())
{
XException.InvalidConfiguration.Throw();
}
//
var xIdentityHelper = services.GetRegisteredService<IXIdentityHelper>();
if (xIdentityHelper.IsNull())
{
XException.InvalidConfiguration.Throw();
}
//
// Add Identity for User Persists ...
services.AddIdentity<XUser, IdentityRole>(options =>
{
//
var mLockoutSpan = xIdentityHelper.GetLockoutTimeSpan();
//
// Lockout Setting ...
options.Lockout.DefaultLockoutTimeSpan = mLockoutSpan;
options.Lockout.MaxFailedAccessAttempts = xIdentityConfiguration.Policy.Lockout.MaxFailedAccessAttempts;
options.Lockout.AllowedForNewUsers = xIdentityConfiguration.Policy.Lockout.AllowedForNewUsers;
//
// Password settings ...
options.Password.RequireDigit = xIdentityConfiguration.Policy.Password.RequireDigit;
options.Password.RequireLowercase = xIdentityConfiguration.Policy.Password.RequireLowercase;
options.Password.RequireNonAlphanumeric = xIdentityConfiguration.Policy.Password.RequireNonAlphanumeric;
options.Password.RequireUppercase = xIdentityConfiguration.Policy.Password.RequireUppercase;
options.Password.RequiredLength = xIdentityConfiguration.Policy.Password.RequiredLength;
options.Password.RequiredUniqueChars = xIdentityConfiguration.Policy.Password.RequiredUniqueChars;
//
// SignIn settings ...
options.SignIn.RequireConfirmedEmail = xIdentityConfiguration.Policy.SignIn.RequireConfirmedEmail;
options.SignIn.RequireConfirmedPhoneNumber = xIdentityConfiguration.Policy.SignIn.RequireConfirmedPhoneNumber;
//
// User settings ...
options.User.AllowedUserNameCharacters = xIdentityConfiguration.Policy.User.AllowedUserNameCharacters;
options.User.RequireUniqueEmail = xIdentityConfiguration.Policy.User.RequireUniqueEmail;
})
.AddEntityFrameworkStores<XIdentityDbContext>()
.AddDefaultTokenProviders();
}
/// <summary>
/// Register IdentityServer Based Authentication
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXIdentityServerAuthentication(
this IServiceCollection services,
IConfiguration configuration
)
{
//
services.AddXIdentityResourceConfiguration(configuration);
services.AddAuthentication()
.AddJwtBearer(options =>
{
//
options.SaveToken = true;
options.RequireHttpsMetadata = false;
//
options.ForwardDefault = XAuthentication.IDENTITY_SERVER_LOCAL_API;
})
.AddLocalApi();
}
/// <summary>
/// Register Authorization Policies
/// </summary>
/// <param name="services"></param>
/// <param name="policies"></param>
public static void AddXAuthorization(
this IServiceCollection services,
IDictionary<string, AuthorizationPolicy> policies = null
)
{
//
services.AddAuthorization(options =>
{
//
if (!policies.IsNull())
{
//
// Fill Policies ...
using (var policiesEnumerator = policies.GetEnumerator())
{
while (policiesEnumerator.MoveNext())
{
var policyDescriptor = policiesEnumerator.Current;
options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value);
}
}
}
//
var xPolicies = XAuthorizationHelper.GetXAuthorizationPolicies();
if (!xPolicies.IsNull())
{
//
// Fill Policies ...
using (var policiesEnumerator = xPolicies.GetEnumerator())
{
while (policiesEnumerator.MoveNext())
{
var policyDescriptor = policiesEnumerator.Current;
options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value);
}
}
}
//
// Add Local APi Policy ...
options.AddPolicy(IdentityServerConstants.LocalApi.PolicyName, policy =>
{
//
policy.AddAuthenticationSchemes(IdentityServerConstants.LocalApi.AuthenticationScheme);
policy.RequireAuthenticatedUser();
});
});
//
services.AddSingleton<IAuthorizationHandler, RequiredRolesHandler>();
}
/// <summary>
/// Use Forward Headers Options for resolving behind a proxy issues ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static void UseXForwardOptions(this IApplicationBuilder source)
{
//
var forwardOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
RequireHeaderSymmetry = false
};
//
forwardOptions.KnownNetworks.Clear();
forwardOptions.KnownProxies.Clear();
//
// ref: https://github.com/aspnet/Docs/issues/2384
source.UseForwardedHeaders(forwardOptions);
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Extensions\DbExtensions.cs
using System;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MySql.EntityFrameworkCore.Infrastructure;
using xCommons.Extensions;
using xIdentityModels.Configurations;
using xIds.Configurations;
using xIds.Constants;
using xIds.Models;
namespace xIds.Extensions
{
public static class DbExtensions
{
/// <summary>
/// Retrieve Data Provider Type from Configurations
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XDbProviders GetXDbProviderType(this IConfiguration source)
{
//
var dbProvider = (source[$"{ConfigurationNodeNames.PROVIDER_NODE_NAME}"])
.ToNormalString();
//
return dbProvider == ProviderType.SQLServer.ToNormalString() ?
XDbProviders.SQLServer :
dbProvider == ProviderType.SQLite.ToNormalString() ?
XDbProviders.SQLite :
dbProvider == ProviderType.MySQL.ToNormalString() ?
XDbProviders.MySQL :
XDbProviders.None;
}
/// <summary>
/// Retrieve AspNet Identity Configurations
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XIdentityConfiguration GetXIdentityConfiguration(this IConfiguration source)
{
//
var xIdentityConfigSection = source
.GetSection(ConfigurationNodeNames.IDENTITY_NODE_NAME);
return xIdentityConfigSection.Get<XIdentityConfiguration>();
}
/// <summary>
/// Retrieve XIdentityResource Configuration from AppSettings
/// </summary>
/// <param name="configuration"></param>
/// <returns></returns>
public static XIdentityResourceConfiguration GetXIdentityResourceConfiguration(this IConfiguration configuration)
{
//
var xIdentityResourceSection = configuration.GetSection(ConfigurationNodeNames.IDENTITY_RESOURCE_NODE_NAME);
return xIdentityResourceSection.Get<XIdentityResourceConfiguration>();
}
/// <summary>
/// Register XIdentityResourceConfiguration
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXIdentityResourceConfiguration(
this IServiceCollection services,
IConfiguration configuration
)
{
//
var xIdentityResourceConfiguration = configuration.GetXIdentityResourceConfiguration();
if (!xIdentityResourceConfiguration.IsNull())
{
services.AddSingleton<XIdentityResourceConfiguration>(xIdentityResourceConfiguration);
}
}
/// <summary>
/// Converts DbInfo Options Builder for MySql Usage
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static Action<MySQLDbContextOptionsBuilder> GetMySqlOptionsBuilder(this XDbInfo source)
{
return ((Action<MySQLDbContextOptionsBuilder>)source.OptionsBuilder);
}
/// <summary>
/// Converts DbInfo Options Builder for SQLite Usage
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static Action<SqliteDbContextOptionsBuilder> GetSQLiteOptionsBuilder(this XDbInfo source)
{
return ((Action<SqliteDbContextOptionsBuilder>)source.OptionsBuilder);
}
/// <summary>
/// Converts DbInfo Options Builder for SQLServer Usage
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static Action<SqlServerDbContextOptionsBuilder> GetSQLServerOptionsBuilder(this XDbInfo source)
{
return ((Action<SqlServerDbContextOptionsBuilder>)source.OptionsBuilder);
}
/// <summary>
/// Retrieve Required Informations to Register DbContexts into Di as XDbInfo instance
/// </summary>
/// <param name="configuration"></param>
/// <returns></returns>
public static XDbInfo GetXDbInfo(this IConfiguration configuration)
{
return new XDbInfo
{
ProviderType = configuration.GetXDbProviderType(),
MigrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name
};
}
/// <summary>
/// Prepare DbContextOptionsBuilder with Propper data to Support Configured DbProvider
/// </summary>
/// <param name="source"></param>
/// <param name="dbInfo"></param>
/// <param name="connectionString"></param>
public static void PrepareXDbContextOptionsBuilder(
this DbContextOptionsBuilder source,
XDbInfo dbInfo,
string connectionString
)
{
//
if (dbInfo.ProviderType == XDbProviders.MySQL)
{
//
// Add Support for MySql ...
source.UseMySQL(
connectionString,
dbInfo.GetMySqlOptionsBuilder()
);
}
else if (dbInfo.ProviderType == XDbProviders.SQLite)
{
//
// Add Support for SQLite ...
source.UseSqlite(
connectionString,
dbInfo.GetSQLiteOptionsBuilder()
);
}
else if (dbInfo.ProviderType == XDbProviders.SQLServer)
{
//
// Add Support for SQLServer ...
source.UseSqlServer(
connectionString,
dbInfo.GetSQLServerOptionsBuilder()
);
}
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Extensions\IdentityExtensions.cs
using Microsoft.Extensions.DependencyInjection;
using xIds.Interfaces;
using xIds.Providers;
namespace xIds.Extensions
{
public static class IdentityExtensions
{
/// <summary>
/// Register IdentityManager
/// </summary>
/// <param name="source"></param>
public static void AddXIdentityManager(this IServiceCollection source)
{
source.AddScoped<IXIdentityManager, XIdentityManager>();
}
/// <summary>
/// Register IdentityMessage Provider
/// </summary>
/// <param name="source"></param>
public static void AddXIdentityMessageProvider(
this IServiceCollection source
)
{
source.AddScoped<IXIdentityMessageProvider, XIdentityMessageProvider>();
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Extensions\IIdentityServerBuilderExtensions.cs
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Extensions;
using xCommons.Models;
using xIds.Constants;
namespace xIds.Extensions
{
public static class IIdentityServerBuilderExtensions
{
/// <summary>
/// Add Support for Configured XDbProvider to IdentityServer
/// </summary>
/// <param name="source"></param>
/// <param name="configuration"></param>
/// <returns></returns>
public static IIdentityServerBuilder AddXDbProvider(
this IIdentityServerBuilder source,
IConfiguration configuration
)
{
//
// Retrieve DB Info ...
var dbInfo = configuration.GetXDbInfo();
dbInfo.OptionsBuilder = (optionsBuilder) =>
{
optionsBuilder.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
};
//
// Retrieve Connection String Names ...
var identityDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.IDENTITY_CONNECTION_NAME);
var configDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.CONFIGURATION_CONNECTION_NAME);
var persistedGrantDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.PRESISTED_GRANTS_CONNECTION_NAME);
//
// Add Operational Store ...
source.AddOperationalStore(opt =>
{
opt.ConfigureDbContext =
builder =>
{
//
builder.PrepareXDbContextOptionsBuilder(
dbInfo,
persistedGrantDbConnectionString
);
//
builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
};
//
// this enables automatic token cleanup. this is optional.
opt.EnableTokenCleanup = true;
opt.TokenCleanupInterval = 3600;
});
//
// Add Configuration Store ...
source.AddConfigurationStore(opt =>
{
opt.ConfigureDbContext =
builder =>
{
//
builder.PrepareXDbContextOptionsBuilder(
dbInfo,
configDbConnectionString
);
};
});
//
return source;
}
/// <summary>
/// Set Configured Certificate File to IdentityServer
/// </summary>
/// <param name="builder"></param>
/// <param name="certificate"></param>
/// <returns></returns>
public static IIdentityServerBuilder LoadSigningCredentialFrom(
this IIdentityServerBuilder builder,
XCertificate certificate
)
{
//
if (!certificate.IsNull() &&
!certificate.Path.IsNullOrEmpty() &&
!certificate.Secret.IsNullOrEmpty()
)
{
try
{
builder.AddSigningCredential(new X509Certificate2(certificate.Path, certificate.Secret));
}
catch
{
builder.AddDeveloperSigningCredential();
}
}
else
{
builder.AddDeveloperSigningCredential();
}
//
return builder;
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Extensions\IQueryableExtensions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using xCommons.Extensions;
using xExceptions.Constants;
using xModels.Base;
using xIds.Constants;
namespace xIds.Extensions
{
public static class IQueryableExtensions
{
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Extensions\XDbSeederExtensions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Mappers;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xIdentityModels.Descriptors;
using xIdentityModels.Extensions;
using xIds.Constants;
using xIds.Interfaces;
using xIds.Models;
namespace xIds.Extensions
{
public static class XDbSeeder
{
/// <summary>
/// Retrieve DbSeedDescriptor from appSetting Configuration
/// </summary>
/// <param name="configuration"></param>
/// <returns></returns>
public static XDbSeedDescriptor GetXDbSeedDescriptor(this IConfiguration configuration)
{
//
var dbSeedSection = configuration.GetSection(ConfigurationNodeNames.DB_SEED_NODE_NAME);
return dbSeedSection.Get<XDbSeedDescriptor>();
}
/// <summary>
/// Register XDbSeedDescriptor as Singleton Service
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXDebSeederDescriptor(
this IServiceCollection services,
IConfiguration configuration
)
{
//
var dbSeedDescriptor = configuration.GetXDbSeedDescriptor();
if (!dbSeedDescriptor.IsNull())
{
services.AddSingleton<XDbSeedDescriptor>(dbSeedDescriptor);
}
else
{
Console.WriteLine("Error: DbSeeder Configuration not found in AppSetting ...");
}
}
/// <summary>
/// Add Base Required Data to XIdentitySer DbContexts
/// </summary>
/// <param name="app"></param>
/// <param name="logger"></param>
/// <returns></returns>
public static async Task SeedData(
this IApplicationBuilder app,
ILogger logger
)
{
//
logger.LogInformation($"Start Add/Update XIdentityServer Descriptors ...");
//
// Create Scope ...
using (var scope = app.ApplicationServices.CreateScope())
{
//
// Retrieve Required Configurations ...
var dbSeedDescriptor = scope.ServiceProvider.GetService<XDbSeedDescriptor>();
if (dbSeedDescriptor.IsNull())
{
//
Console.WriteLine("DbSeeder is Null ...");
return;
}
logger.LogInformation($"Update Exists Descriptors: {dbSeedDescriptor.UpdateExists.ToString()}");
//
// Retrieve Required Services ...
var identityProvider = scope.ServiceProvider.GetService<IXIdentityManager>();
//
// Retrieve DbContexts ...
var grantDbContext = scope.ServiceProvider.GetService<PersistedGrantDbContext>();
var configDbContext = scope.ServiceProvider.GetService<ConfigurationDbContext>();
//
#region Clients ...
//
logger.LogInformation($"Start Seeding Clients ...");
//
var dClients = dbSeedDescriptor.Clients;
var hasClient = configDbContext.Clients.Any();
if ((!hasClient ||
(hasClient && dbSeedDescriptor.UpdateExists)) &&
dClients.HasChild())
{
//
var clientEntities = dClients.Select(dc => dc.ToEntity());
//
foreach (var client in clientEntities)
{
//
logger.LogInformation($"Add/Update: {client.ClientId}");
//
// Retrieve Exists Client ...
var existsClient = configDbContext.Clients
.Include(c => c.AllowedCorsOrigins)
.Include(c => c.AllowedGrantTypes)
.Include(c => c.AllowedScopes)
.Include(c => c.Claims)
.Include(c => c.ClientSecrets)
.FirstOrDefault(cl => cl.ClientId == client.ClientId);
//
var isExistsClient = !existsClient.IsNull();
var isSameContent = isExistsClient &&
existsClient.IsSameContent(client, propertyBlackList: new[] { nameof(existsClient.Id) });
//
if (isExistsClient)
{
//
if (!isSameContent)
{
//
logger.LogInformation($"Update Client: {existsClient.ClientId}");
//
existsClient = existsClient.UpdateData(client, propertyBlackList: new[] { nameof(existsClient.Id) });
configDbContext.Clients.Update(existsClient);
}
}
else
{
//
logger.LogInformation($"Add Client: {client.ClientId}");
//
await configDbContext.Clients.AddAsync(client);
}
}
//
// Save Changes on Config Db Context ...
await configDbContext.SaveChangesAsync();
}
//
logger.LogInformation($"Finish Seeding Clients ...");
#endregion
//
#region IdentityResources ...
//
logger.LogInformation($"Start Seeding Identity Resources ...");
//
var dIdentityResources = dbSeedDescriptor.IdentityResources;
var hasIdentityResources = configDbContext.IdentityResources.Any();
if ((!hasIdentityResources ||
(hasIdentityResources && dbSeedDescriptor.UpdateExists)) &&
dIdentityResources.HasChild())
{
//
var identityResourceEntities = dIdentityResources.Select(di => di.ToEntity());
//
foreach (var identityResource in identityResourceEntities)
{
//
logger.LogInformation($"Add/Update: {identityResource.DisplayName}");
//
// Retrieve Exists IdentityResource ...
var existsIdentityResource = configDbContext.IdentityResources
.AsNoTracking()
.FirstOrDefault(ir => ir.Name == identityResource.Name);
//
var isExistsResource = !existsIdentityResource.IsNull();
var isSameContent = isExistsResource &&
existsIdentityResource.IsSameContent(identityResource, propertyBlackList: new[] { nameof(existsIdentityResource.Id) });
//
if (isExistsResource &&
dbSeedDescriptor.UpdateExists)
{
//
if (!isSameContent)
{
//
logger.LogInformation($"Update IdentityResource: {identityResource.DisplayName}");
//
existsIdentityResource = existsIdentityResource.UpdateData(identityResource, propertyBlackList: new[] { nameof(existsIdentityResource.Id) });
configDbContext.IdentityResources.Update(existsIdentityResource);
}
}
else
{
//
logger.LogInformation($"Add IdentityResource: {identityResource.DisplayName}");
//
await configDbContext.IdentityResources.AddAsync(identityResource);
}
}
//
// Save Changes on Config Db Context ...
// await configDbContext.SaveChangesAsync();
}
//
logger.LogInformation($"Finish Seeding Identity Resources ...");
#endregion
//
#region Api Resources ...
//
logger.LogInformation($"Start Seeding Api Resources ...");
//
var dApiResources = dbSeedDescriptor.ApiResources;
var hasApiResources = configDbContext.ApiResources.Any();
if ((!hasApiResources ||
(hasApiResources && dbSeedDescriptor.UpdateExists)) &&
dApiResources.HasChild())
{
//
var apiResourceEntities = dApiResources.Select(da => da.ToEntity());
//
foreach (var apiResource in apiResourceEntities)
{
//
logger.LogInformation($"Add/Update: {apiResource.DisplayName}");
//
// Retrieve Exists ApiResource ...
var existsApiResource = configDbContext.ApiResources
.Include(r => r.Secrets)
.Include(r => r.Scopes)
.FirstOrDefault(ar => ar.Name == apiResource.Name);
//
var isExistsResource = !existsApiResource.IsNull();
var isSameContent = isExistsResource &&
existsApiResource.IsSameContent(apiResource, propertyBlackList: new[] { nameof(existsApiResource.Id) });
//
if (isExistsResource &&
dbSeedDescriptor.UpdateExists)
{
//
if (!isSameContent)
{
//
logger.LogInformation($"Update ApiResource: {existsApiResource.DisplayName}");
//
existsApiResource = existsApiResource.UpdateData(apiResource, propertyBlackList: new[] { nameof(existsApiResource.Id) });
configDbContext.ApiResources.Update(existsApiResource);
}
}
else
{
//
logger.LogInformation($"Add ApiResource: {apiResource.DisplayName}");
//
await configDbContext.ApiResources.AddAsync(apiResource);
}
}
//
// Save Changes on Config Db Context ...
// await configDbContext.SaveChangesAsync();
}
//
logger.LogInformation($"Finish Seeding Api Resources ...");
#endregion
//
#region Api Scopes ...
//
logger.LogInformation($"Start Seeding Scopes ...");
//
var dScopes = dbSeedDescriptor.ApiScopes;
var hasScope = configDbContext.ApiScopes.Any();
if ((!hasScope ||
(hasScope && dbSeedDescriptor.UpdateExists)) &&
dScopes.HasChild())
{
//
var apiScopeEntities = dScopes.Select(dc => dc.ToEntity());
//
foreach (var apiScope in apiScopeEntities)
{
//
logger.LogInformation($"Add/Update: {apiScope.DisplayName}");
//
// Retrieve Exists Client ...
var existsScope = configDbContext.ApiScopes
.FirstOrDefault(sc => sc.Name == apiScope.Name);
//
var isExistsScope = !existsScope.IsNull();
var isSameContent = isExistsScope &&
existsScope.IsSameContent(apiScope, propertyBlackList: new[] { nameof(existsScope.Id) });
//
if (isExistsScope &&
dbSeedDescriptor.UpdateExists)
{
//
if (!isSameContent)
{
//
logger.LogInformation($"Update ApiScope: {existsScope.Name}");
//
existsScope = existsScope.UpdateData(apiScope, propertyBlackList: new[] { nameof(existsScope.Id) });
configDbContext.ApiScopes.Update(existsScope);
}
}
else
{
//
logger.LogInformation($"Add ApiScope: {apiScope.Name}");
//
await configDbContext.ApiScopes.AddAsync(apiScope);
}
}
//
// Save Changes on Config Db Context ...
await configDbContext.SaveChangesAsync();
}
//
logger.LogInformation($"Finish Seeding Scopes ...");
#endregion
//
#region Users ...
//
logger.LogInformation($"Start Seeding Users ...");
//
var configUsers = dbSeedDescriptor.Users;
var hasUser = identityProvider.GetUsersDbSet().Any();
if ((!hasUser ||
(hasUser && dbSeedDescriptor.UpdateExists)) &&
configUsers.HasChild())
{
foreach (var user in configUsers)
{
//
logger.LogInformation($"Add/Update User: {user.UserName}");
//
var isUserExists = await identityProvider.IsUserExistsAsync(user.UserName);
if (isUserExists &&
dbSeedDescriptor.UpdateExists)
{
//
var existsUser = await identityProvider.GetUserAsync(user.UserName);
var isSame = existsUser.IsSameAs(user);
if (!isSame)
{
//
// Update Entity ...
existsUser = existsUser.UpdateData(user, propertyWhiteList: new[] {
nameof (XIdentityUserDescriptor.FirstName),
nameof (XIdentityUserDescriptor.LastName),
nameof (XIdentityUserDescriptor.UserName),
nameof (XIdentityUserDescriptor.Email),
nameof (XIdentityUserDescriptor.EmailConfirmed),
nameof (XIdentityUserDescriptor.PhoneNumber),
nameof (XIdentityUserDescriptor.PhoneNumberConfirmed),
nameof (XIdentityUserDescriptor.IsEnable),
nameof (XIdentityUserDescriptor.IsBanned),
nameof (XIdentityUserDescriptor.DateOfBirth)
}, propertyValueProviders: new[] {
new KeyValuePair<string, Func<XIdentityUserDescriptor, object>> (
nameof (XIdentityUserDescriptor.DateOfBirth),
(user) => DateTime.Parse (user.DateOfBirth))
});
//
await identityProvider.UpdateUserAsync(existsUser, false, false);
}
}
else
{
await identityProvider.CreateUserAsync(user);
}
}
}
//
logger.LogInformation($"Finish Seeding Users ...");
#endregion
}
//
logger.LogInformation($"Finish Add/Update XIdentityServer Descriptors ...");
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Extensions\XModelExtensions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using xCommons.Extensions;
using xDataService.Configuration;
using xIdentityModels.Models;
namespace xIds.Extensions
{
public static class XModelExtensions
{
/// <summary>
/// Determine a banned time is passed or not
/// </summary>
/// <param name="source"></param>
/// <param name="delaySeconds"></param>
/// <returns></returns>
public static bool IsDelayTimePassed(
this XBannedDevice source,
int delaySeconds
)
{
//
var passedTime = source.BannedOn.AddSeconds(delaySeconds);
//
var result = DateTime.UtcNow >= passedTime;
//
return result;
}
/// <summary>
/// Applying Filter to IQueryable
/// /// </summary>
/// <typeparam name="T"></typeparam>
public static async Task<IQueryable<T>> ApplyFilterAsync<T>(
this IQueryable<T> source,
string filter
) where T : class
{
//
// Apply Filter ...
if (!filter.IsNullOrEmpty())
{
//
var items = source.AsAsyncEnumerable();
var filteredItems = new List<T>();
await
foreach (var item in items)
{
//
if (item.GetPropValues()
.ToNormalString()
.Contains(filter
.ToNormalString()))
{
//
filteredItems.Add(item);
}
}
//
return filteredItems.AsQueryable();
}
//
return source;
}
public static XDataServiceConfiguration ToXDataServiceConfig(this Configurations.XDataServiceConfiguration config)
{
//
var result = new XDataServiceConfiguration();
//
if (!config.IsNullOrDefault())
{
//
result.PagingConfiguration.DefaultPageSize = config.PagingConfiguration.DefaultPageSize;
result.PagingConfiguration.MaxAvailablePageSize = config.PagingConfiguration.MaxAvailablePageSize;
result.PagingConfiguration.MinAvailablePageSize = config.PagingConfiguration.MinAvailablePageSize;
}
//
return result;
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Helpers\XIdentityHelper.cs
using System;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
using xIdentityModels.Configurations;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIds.Interfaces;
namespace xIds.Helpers
{
public class XIdentityHelper : IXIdentityHelper
{
private readonly XIdentityConfiguration configurations;
private readonly JwtSecurityTokenHandler tokenHandler;
private readonly XValidationProvider dataValidationHelper;
public XIdentityHelper(
XIdentityConfiguration configurations,
XValidationProvider dataValidationHelper
)
{
//
this.configurations = configurations;
this.tokenHandler = new JwtSecurityTokenHandler();
this.dataValidationHelper = dataValidationHelper;
}
//
#region Configuration Parser ...
/// <summary>
/// Generate a Key for Signing JWT Tokens
/// </summary>
/// <returns></returns>
public SymmetricSecurityKey GetTokenSecretKey()
{
//
dataValidationHelper
.NotEmpty(configurations.IdentitySecretKey);
//
var result = new SymmetricSecurityKey(configurations
.IdentitySecretKey.ToBytes());
//
return result;
}
/// <summary>
/// Generate Security Token Signing Key
/// </summary>
/// <returns></returns>
public SigningCredentials GetTokenSigningCredentials()
{
//
var key = GetTokenSecretKey();
dataValidationHelper
.NotNull(key);
//
var result = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
//
return result;
}
/// <summary>
/// Get Token Validation Parameters
/// </summary>
/// <returns></returns>
public TokenValidationParameters GetTokenValidationParams()
{
//
var key = GetTokenSecretKey();
var issuer = configurations.IdentityIssuer;
var audience = configurations.IdentityAudience;
//
dataValidationHelper
.NotNull(key);
dataValidationHelper
.NotEmpty(issuer, audience);
//
var result = new TokenValidationParameters
{
ValidIssuer = issuer,
ValidAudience = audience,
ValidateLifetime = true,
IssuerSigningKey = key
};
//
return result;
}
/// <summary>
/// Get Account Lockout Time Span after Max Fail Reached
/// </summary>
/// <returns></returns>
public TimeSpan GetLockoutTimeSpan()
{
//
dataValidationHelper
.NotNull(configurations.Policy, configurations.Policy.Lockout);
//
var timeSpanString = configurations.Policy.Lockout.LockoutTimeSpanProvider;
dataValidationHelper
.NotEmpty(timeSpanString);
//
var mExpireValue = 0;
var mExpireValueStr = timeSpanString.GetDigits();
var mExpireUnit = timeSpanString.Replace(mExpireValueStr, "");
dataValidationHelper
.NotEmpty(mExpireUnit);
dataValidationHelper
.NotEmpty(mExpireValueStr);
//
var isParsed = int.TryParse(mExpireValueStr, out mExpireValue);
//
switch (mExpireUnit)
{
case "d":
return TimeSpan.FromDays(mExpireValue);
case "h":
return TimeSpan.FromHours(mExpireValue);
case "m":
return TimeSpan.FromMinutes(mExpireValue);
case "s":
return TimeSpan.FromSeconds(mExpireValue);
case "ms":
default:
return TimeSpan.FromMilliseconds(mExpireValue);
}
}
/// <summary>
/// Generate Security Token Descriptor for Tokenize another
/// </summary>
/// <returns></returns>
public SecurityTokenDescriptor GetActionTokenDescriptor()
{
//
dataValidationHelper
.NotNull(configurations);
//
var issuer = configurations.IdentityIssuer;
var audience = configurations.IdentityAudience;
dataValidationHelper
.NotEmpty(issuer, audience);
//
var expDate = GetActionTokenExpirationDate();
var signingCreds = GetTokenSigningCredentials();
dataValidationHelper
.NotNull(expDate, signingCreds);
//
var descriptor = new SecurityTokenDescriptor
{
Issuer = issuer,
Audience = audience,
Expires = expDate,
SigningCredentials = signingCreds
};
//
return descriptor;
}
/// <summary>
/// Get Action Token Expiration Date
/// </summary>
/// <returns></returns>
public DateTime GetActionTokenExpirationDate()
{
//
dataValidationHelper
.NotNull(configurations);
//
var expDateProvider = configurations
.ActionTokenExpirationDateProvider;
dataValidationHelper
.NotEmpty(expDateProvider);
//
var result = GetExpirationTime(expDateProvider);
dataValidationHelper
.NotNull(result);
//
return result;
}
#endregion
//
#region Action Token Handlers ...
public bool ValidateToken(string token)
{
//
// Validate Args ...
dataValidationHelper
.NotEmpty(token);
dataValidationHelper
.NotNull(tokenHandler);
//
// Prepare Requirements ...
var tokenValidationParams = GetTokenValidationParams();
dataValidationHelper
.NotNull(tokenValidationParams);
//
var result = token
.ValidateToken(tokenHandler, tokenValidationParams);
//
return result;
}
/// <summary>
/// Converts a Token string to SecurityToken instance
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public SecurityToken ToSecurityToken(string token)
{
//
dataValidationHelper
.NotEmpty(token);
//
// Validate token ...
var isTokenValid = ValidateToken(token);
if (!isTokenValid)
{
XException.InvalidToken.Throw();
}
//
// Prepare and Validate Requirements ...
var tokenValidationParams = GetTokenValidationParams();
dataValidationHelper
.NotNull(tokenHandler, tokenValidationParams);
//
var result = token
.ToSecurityToken(tokenHandler, tokenValidationParams);
dataValidationHelper
.NotNull(result);
//
return result;
}
/// <summary>
/// Convert an ActionRequest to Token Object
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public SecurityToken ToSecurityToken(XActionRequestToken request)
{
//
var tokenDescriptor = GetActionTokenDescriptor();
//
dataValidationHelper.NotNull(request, tokenHandler, tokenDescriptor);
//
var result = request.ToJwtToken(tokenHandler, tokenDescriptor);
//
return result;
}
/// <summary>
/// Retrieve a Token Exiration Date
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public DateTime GetTokenExpirationDate(string token)
{
//
var tokenObj = ToSecurityToken(token);
dataValidationHelper.NotNull(tokenObj);
//
var result = tokenObj.ValidTo;
//
return result;
}
public XActionRequestToken ParseActionRequestToken(string token)
{
//
dataValidationHelper
.NotEmpty(token);
//
// Validate token ...
var isTokenValid = ValidateToken(token);
if (!isTokenValid)
{
XException.InvalidToken.Throw();
}
//
// Prepare and Validate Requirements ...
var tokenValidationParams = GetTokenValidationParams();
dataValidationHelper
.NotNull(tokenHandler, tokenValidationParams);
//
var result = token
.ParseActionRequestToken(tokenHandler, tokenValidationParams);
dataValidationHelper
.NotNull(result);
//
return result;
}
/// <summary>
/// Convert a JWT Security Token Object to
/// it's String Representation
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public string ToTokenString(JwtSecurityToken token)
{
//
dataValidationHelper.NotNull(token);
//
var result = tokenHandler
.WriteToken(token);
//
return result;
}
/// <summary>
/// Convert an Action Token Object to it's String Representation
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public string ToTokenString(SecurityToken token)
{
//
// Validate Args ...
dataValidationHelper
.NotNull(token, tokenHandler);
//
// Generate and return Result ...
var result = token.ToTokenString(tokenHandler);
dataValidationHelper
.NotEmpty(result);
//
return result;
}
#endregion
//
#region Private Actions ...
/// <summary>
/// Calculating Date Difference Provider String
/// and Generate Date based on UTC Time
/// </summary>
/// <param name="expirationProvider"></param>
/// <returns></returns>
private DateTime GetExpirationTime(string expirationProvider)
{
//
dataValidationHelper
.NotEmpty(expirationProvider);
//
var mExpireValue = 0;
var mExpireValueStr = expirationProvider.GetDigits();
var mExpireUnit = expirationProvider.Replace(mExpireValueStr, "");
dataValidationHelper
.NotEmpty(mExpireUnit);
dataValidationHelper
.NotEmpty(mExpireValueStr);
//
var isParsed = int.TryParse(mExpireValueStr, out mExpireValue);
//
switch (mExpireUnit)
{
case "d":
return DateTime.UtcNow.AddDays(mExpireValue);
case "h":
return DateTime.UtcNow.AddHours(mExpireValue);
case "m":
return DateTime.UtcNow.AddMinutes(mExpireValue);
case "s":
return DateTime.UtcNow.AddSeconds(mExpireValue);
case "ms":
default:
return DateTime.UtcNow.AddMilliseconds(mExpireValue);
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Interfaces\IXIdentityHelper.cs
using System;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using xIdentityModels.Models;
namespace xIds.Interfaces
{
public interface IXIdentityHelper
{
//
#region Configuration Parser ...
SymmetricSecurityKey GetTokenSecretKey();
SigningCredentials GetTokenSigningCredentials();
TokenValidationParameters GetTokenValidationParams();
TimeSpan GetLockoutTimeSpan();
#endregion
//
#region Action Token Handlers ...
bool ValidateToken(string token);
SecurityToken ToSecurityToken(string token);
SecurityToken ToSecurityToken(XActionRequestToken request);
string ToTokenString(SecurityToken token);
string ToTokenString(JwtSecurityToken token);
DateTime GetTokenExpirationDate(string token);
XActionRequestToken ParseActionRequestToken(string token);
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Interfaces\IXIdentityManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using xCommons.Providers;
using xIdentityModels;
using xIdentityModels.Constants;
using xIdentityModels.Descriptors;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
using xIds.DbContext;
using xModels.Dtos;
namespace xIds.Interfaces
{
public interface IXIdentityManager
{
XIdentityDbContext DbContext { get; }
UserManager<XUser> UserManager { get; }
ILogger<IXIdentityManager> Logger { get; }
SignInManager<XUser> SignInManager { get; }
IXSecurityProvider SecurityProvider { get; }
RoleManager<IdentityRole> RoleManager { get; }
XValidationProvider ValidationProvider { get; }
//
#region Class Getter (s) Methods ...
IQueryable<XUser> GetUsersDbSet(
bool containsDetail = false
);
IQueryable<XUser> GetUsersFullDbSet(bool enableTracking = false);
#endregion
//
#region Tools ...
string GetUserSelectByParam(
XActionRequest model,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
);
Task<XUser> ValidateUserExistsAndRetrieve(
string userSelectByParam,
bool containsDetail = false,
bool checkCanLoginPolicies = false,
bool checkIsBanned = true,
bool ignoreDisabledUser = false,
bool forceAdmin = false,
Exception exception = null
);
#endregion
//
#region Default Identity Preparation Actions ...
Task CreateIdentityRoles();
Task CreateUserAsync(XIdentityUserDescriptor user);
#endregion
//
#region Identity Actions ...
HttpClient GetHttpClient();
Task<IdentityModel.Client.TokenResponse> RequestScopeAccessToken(string scope);
Task<DiscoveryDocumentResponse> RequestDiscoveryDocument();
Task<IdentityModel.Client.TokenResponse> Authenticate(XLoginRequest model);
Task<XLoginResponse> Login(XLoginRequest model);
Task<XTokenResponse> RefreshTokens(XTokenResponse model);
#endregion
//
#region Role Handlers ...
Task<bool> IsRoleExistsAsync(string roleName);
Task<IdentityResult> CreateRoleAsync(string roleName);
Task<IdentityRole> GetRoleAsync(string roleName);
Task<IdentityResult> AddUserToRoleAsync(XUser user, string roleName);
Task<string> GetRoleNameAsync(string roleId);
Task<IEnumerable<string>> GetRoleNamesAsync(
string userSelectByParam,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
);
Task<IdentityResult> RemoveFromRoleAsync(XUser user, string roleName);
Task<IdentityResult> RemoveFromRolesAsync(XUser user, IEnumerable<string> roleNames);
#endregion
//
#region User Handlers ...
Task<bool> CanRegister(string userSelectByParam);
Task<bool> IsUserExistsAsync(string userSelectByParam);
Task<XUser> GetUserAsync(
string userSelectByParam,
bool containsDetail = false);
Task<IdentityResult> CreateUserAsync(
XUser user,
string password,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
);
Task<IdentityResult> UpdateUserAsync(
XUser user,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
);
Task<IEnumerable<string>> GetUserNamesAsync(
IEnumerable<string> userIds
);
Task<IEnumerable<XUserNameIdResponse>> GetUserNameIdsAsync(
XUserNameIdRequest model
);
Task<Claim[]> ToJwtClaims(
XUser user,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
);
Task<SignInResult> CheckPasswordSignInAsync(
XUser user,
string password,
XDevice device,
string language,
bool lockoutOnFailure,
bool isForced = true
);
#endregion
//
#region User Profile Handlers ...
Task<XUserProfileDto> GetUserProfileAsync(
string userSelectByParam,
string requestedUserSelectByParam,
bool forceCheckRequestedUser = true,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
);
Task<XQueryResult<XUserProfileDto>> QueryUsers(
string requestedUserSelectByParam,
XQuery query
);
Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers(
string requestedUserSelectByParam,
string role,
XQuery query,
bool forceRole = false
);
Task<IEnumerable<XUserProfileDto>> GetUserProfilesAsync(
ICollection<string> ids,
string requestedUserSelectByParam,
bool forceCheckRequestedUser = true,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
);
Task<XQueryResult<XProfileImage>> QueryAvatars(
string userSelectByParam,
XQuery query
);
Task<XUserProfileDto> ProfileUpdateAsync(
string userSelectByParam,
string requestedUserSelectByParam,
XProfileUpdateRequest request
);
Task<XUserProfileDto> FullProfileUpdateAsync(
string userSelectByParam,
string requestedUserSelectByParam,
XProfileUpdateRequest request
);
Task<XActionResponse> RequestConfirmMobile(
string lang,
XDevice device,
string userSelectByParam,
string password,
string mobileNumber = null
);
Task<XActionResponse> RequestConfirmEmail(
string lang,
XDevice device,
string userSelectByParam,
string password,
string emailAddress = null
);
Task<XActionResponse> RequestResetPassword(
string lang,
XDevice device,
string userSelectByParam,
string returnUrl
);
Task RequestConfirmRegistration(
string lang,
XDevice device,
string userSelectByParam,
string password,
string returnUrl
);
Task ChangePassword(
string lang,
XDevice device,
string userSelectByParam,
string password,
string newPassword,
string returnUrl
);
Task ResetPassword(
string lang,
XDevice device,
string actionHash,
string newPassword,
string returnUrl
);
Task<XUserProfileDto> AddAvatar(
string userSelectByParam,
IFormFile file
);
Task<XUserProfileDto> AddAvatars(
string userSelectByParam,
IFormFileCollection files
);
Task<XUserProfileDto> SetAvatar(
string userSelectByParam,
int profileImageId
);
Task<XUserProfileDto> RemoveAvatar(
string userSelectByParam,
ICollection<int> profileImageIds
);
Task ConfirmRegistration(
string lang,
XDevice device,
string actionHash,
string returnUrl
);
Task<XActionResponse> ConfirmMobileNumber(
string lang,
XDevice device,
string registrationHash,
string verificationCode
);
Task<XActionResponse> ConfirmEmailAddress(
string lang,
XDevice device,
string registrationHash,
string verificationCode
);
Task<bool> IsConfirmedEmail(string userSelectByParam);
Task<bool> IsConfirmedMobile(string userSelectByParam);
#endregion
//
#region Registration Handlers ...
Task<XActionResponse> InviteUser(
string lang,
XDevice device,
string email,
string handlerUrl
);
Task<XActionResponse> RequestRegistration(
string lang,
XDevice device,
string invitationHash,
string firstName,
string lastName,
DateTime dateOfBirth,
string mobileNumber = null,
string emailAddress = null
);
Task<XActionResponse> AddAcountInfo(
string lang,
XDevice device,
string registrationHash,
string userName,
string password
);
Task<XActionResponse> AttachProfileImage(
string tokenHash,
IFormFile file
);
Task FinishRegistration(
string lang,
XDevice device,
string userSelectByParam,
string password,
string returnUrl
);
#endregion
//
#region Friendship Handlers ...
//
#region Actions ...
Task<XFriendshipFollowing> Follow(
string userSelectByParam,
string destUserSelectByParam
);
Task<bool> Cancel(
string userSelectByParam,
string destUserSelectByParam
);
Task UnFollowFollower(
string userSelectByParam,
string destUserSelectByParam
);
Task UnFollowFollowing(
string userSelectByParam,
string destUserSelectByParam
);
Task<XFriendshipFollowing> Block(
string userSelectByParam,
string destUserSelectByParam
);
Task<XFriendshipFollowing> UnBlock(
string userSelectByParam,
string destUserSelectByParam
);
#endregion
//
#region Request Handlers ...
Task<XFriendshipFollower> AcceptRequest(
string userSelectByParam,
string destUserSelectByParam
);
Task<XFriendshipFollower> RejectRequest(
string userSelectByParam,
string destUserSelectByParam
);
#endregion
//
#region Getters ...
Task<bool> IsFollower(
string userSelectByParam,
string destUserSelectByParam,
bool checkIsBanned = true,
bool checkCanLoginPolicies = true
);
Task<XFriendshipState> GetFollowerState(
string userSelectByParam,
string destUserSelectByParam,
bool checkIsBanned = true,
bool checkCanLoginPolicies = true
);
Task<XFriendshipFollower> GetFollower(
string userSelectByParam,
string destUserSelectByParam
);
Task<IEnumerable<XFriendshipFollower>> GetFollowers(string userSelectByParam);
Task<IEnumerable<XFriendshipFollower>> GetAllFollowers(string userSelectByParam);
Task<ICollection<string>> GetFollowersList(string userSelectByParam);
Task<XQueryResult<XFriendDto>> QueryFollowers(
XQuery query,
string userSelectByParam
);
Task<bool> IsFollowing(
string userSelectByParam,
string destUserSelectByParam,
bool checkIsBanned = true,
bool checkCanLoginPolicies = true
);
Task<XFriendshipState> GetFollowingState(
string userSelectByParam,
string destUserSelectByParam,
bool checkIsBanned = true,
bool checkCanLoginPolicies = true
);
Task<XFriendshipFollowing> GetFollowing(
string userSelectByParam,
string destUserSelectByParam
);
Task<IEnumerable<XFriendshipFollowing>> GetFollowings(string userSelectByParam);
Task<IEnumerable<XFriendshipFollowing>> GetAllFollowings(string userSelectByParam);
Task<ICollection<string>> GetFollowingList(string userSelectByParam);
Task<XQueryResult<XFriendDto>> QueryFollowings(
XQuery query,
string userSelectByParam
);
#endregion
//
Task<XFriendshipInfoDto> GetFriendshipInfo(
string userSelectByParam,
string destUserSelectByParam,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
);
#endregion
//
#region Admin Actions ...
Task<ICollection<string>> Ban(
string userSelectByParam,
XUserNameIdRequest model
);
Task<ICollection<string>> UnBan(
string userSelectByParam,
XUserNameIdRequest model
);
Task<bool> IsBanned(
string userSelectByParam,
string destUserSelectByParam
);
#endregion
//
#region Open Actions ...
//
#region OpenGet ...
Task<XOpenActionInnerDto> OpenGet(
XOpenActionInnerDto model
);
Task<XOpenActionInnerDto> OpenGet(
string token,
string actionRequest
);
#endregion
Task<XOpenActionUserInfoDto> GetUserInfo(
XOpenActionRequestDto dto
);
Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
XOpenActionRequestDto dto
);
#endregion
//
#region Search ...
/// <summary>
/// Query Open To Search User Profiles ...
/// </summary>
/// <param name="requestedUserSelectByParam">requested user's identifier</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(
string requestedUserSelectByParam,
XQuery query
);
#endregion
//
#region Query Service ...
/// <summary>
/// Retrieve Users as Query Model for Query Service ...
/// </summary>
/// <param name="requestedUserSelectByParam"></param>
/// <param name="query"></param>
/// <param name="role"></param>
/// <param name="forceRole"></param>
/// <returns></returns>
public Task<XQueryResult<string>> QueryUsers(
string requestedUserSelectByParam,
XQuery query,
string role = null,
bool forceRole = false
);
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Interfaces\IXIdentityMessageProvider.cs
namespace xIds.Interfaces
{
public interface IXIdentityMessageProvider
{
string InviteMsg { get; }
string RegistrationApproveMsg { get; }
string RegisteredMsg { get; }
string VerificationCodeMsg { get; }
string ChangePasswordMsg { get; }
string PasswordChangedMsg { get; }
string NewDeviceLoggedInMsg { get; }
bool IsReady();
void PrepareMessages(string lang);
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Interfaces\IXSecurityProvider.cs
namespace xIds.Interfaces
{
public interface IXSecurityProvider
{
string Encrypt(string plainText);
string Decrypt(string cipherText);
string EncryptFromBytes(byte[] textBytes);
string DecryptFromBytes(byte[] cipherBytes);
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\20260906032642_InitialConfigurationMigration.cs
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace xIds.Migrations
{
public partial class InitialConfigurationMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ApiResources",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Enabled = table.Column<bool>(type: "INTEGER", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
DisplayName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
Description = table.Column<string>(type: "TEXT", maxLength: 1000, nullable: true),
AllowedAccessTokenSigningAlgorithms = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
ShowInDiscoveryDocument = table.Column<bool>(type: "INTEGER", nullable: false),
Created = table.Column<DateTime>(type: "TEXT", nullable: false),
Updated = table.Column<DateTime>(type: "TEXT", nullable: true),
LastAccessed = table.Column<DateTime>(type: "TEXT", nullable: true),
NonEditable = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiResources", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ApiScopes",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Enabled = table.Column<bool>(type: "INTEGER", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
DisplayName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
Description = table.Column<string>(type: "TEXT", maxLength: 1000, nullable: true),
Required = table.Column<bool>(type: "INTEGER", nullable: false),
Emphasize = table.Column<bool>(type: "INTEGER", nullable: false),
ShowInDiscoveryDocument = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiScopes", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Clients",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Enabled = table.Column<bool>(type: "INTEGER", nullable: false),
ClientId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
ProtocolType = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
RequireClientSecret = table.Column<bool>(type: "INTEGER", nullable: false),
ClientName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
Description = table.Column<string>(type: "TEXT", maxLength: 1000, nullable: true),
ClientUri = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: true),
LogoUri = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: true),
RequireConsent = table.Column<bool>(type: "INTEGER", nullable: false),
AllowRememberConsent = table.Column<bool>(type: "INTEGER", nullable: false),
AlwaysIncludeUserClaimsInIdToken = table.Column<bool>(type: "INTEGER", nullable: false),
RequirePkce = table.Column<bool>(type: "INTEGER", nullable: false),
AllowPlainTextPkce = table.Column<bool>(type: "INTEGER", nullable: false),
RequireRequestObject = table.Column<bool>(type: "INTEGER", nullable: false),
AllowAccessTokensViaBrowser = table.Column<bool>(type: "INTEGER", nullable: false),
FrontChannelLogoutUri = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: true),
FrontChannelLogoutSessionRequired = table.Column<bool>(type: "INTEGER", nullable: false),
BackChannelLogoutUri = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: true),
BackChannelLogoutSessionRequired = table.Column<bool>(type: "INTEGER", nullable: false),
AllowOfflineAccess = table.Column<bool>(type: "INTEGER", nullable: false),
IdentityTokenLifetime = table.Column<int>(type: "INTEGER", nullable: false),
AllowedIdentityTokenSigningAlgorithms = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
AccessTokenLifetime = table.Column<int>(type: "INTEGER", nullable: false),
AuthorizationCodeLifetime = table.Column<int>(type: "INTEGER", nullable: false),
ConsentLifetime = table.Column<int>(type: "INTEGER", nullable: true),
AbsoluteRefreshTokenLifetime = table.Column<int>(type: "INTEGER", nullable: false),
SlidingRefreshTokenLifetime = table.Column<int>(type: "INTEGER", nullable: false),
RefreshTokenUsage = table.Column<int>(type: "INTEGER", nullable: false),
UpdateAccessTokenClaimsOnRefresh = table.Column<bool>(type: "INTEGER", nullable: false),
RefreshTokenExpiration = table.Column<int>(type: "INTEGER", nullable: false),
AccessTokenType = table.Column<int>(type: "INTEGER", nullable: false),
EnableLocalLogin = table.Column<bool>(type: "INTEGER", nullable: false),
IncludeJwtId = table.Column<bool>(type: "INTEGER", nullable: false),
AlwaysSendClientClaims = table.Column<bool>(type: "INTEGER", nullable: false),
ClientClaimsPrefix = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
PairWiseSubjectSalt = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
Created = table.Column<DateTime>(type: "TEXT", nullable: false),
Updated = table.Column<DateTime>(type: "TEXT", nullable: true),
LastAccessed = table.Column<DateTime>(type: "TEXT", nullable: true),
UserSsoLifetime = table.Column<int>(type: "INTEGER", nullable: true),
UserCodeType = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
DeviceCodeLifetime = table.Column<int>(type: "INTEGER", nullable: false),
NonEditable = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Clients", x => x.Id);
});
migrationBuilder.CreateTable(
name: "IdentityResources",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Enabled = table.Column<bool>(type: "INTEGER", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
DisplayName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
Description = table.Column<string>(type: "TEXT", maxLength: 1000, nullable: true),
Required = table.Column<bool>(type: "INTEGER", nullable: false),
Emphasize = table.Column<bool>(type: "INTEGER", nullable: false),
ShowInDiscoveryDocument = table.Column<bool>(type: "INTEGER", nullable: false),
Created = table.Column<DateTime>(type: "TEXT", nullable: false),
Updated = table.Column<DateTime>(type: "TEXT", nullable: true),
NonEditable = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityResources", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ApiResourceClaims",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ApiResourceId = table.Column<int>(type: "INTEGER", nullable: false),
Type = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiResourceClaims", x => x.Id);
table.ForeignKey(
name: "FK_ApiResourceClaims_ApiResources_ApiResourceId",
column: x => x.ApiResourceId,
principalTable: "ApiResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ApiResourceProperties",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ApiResourceId = table.Column<int>(type: "INTEGER", nullable: false),
Key = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
Value = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiResourceProperties", x => x.Id);
table.ForeignKey(
name: "FK_ApiResourceProperties_ApiResources_ApiResourceId",
column: x => x.ApiResourceId,
principalTable: "ApiResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ApiResourceScopes",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Scope = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
ApiResourceId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiResourceScopes", x => x.Id);
table.ForeignKey(
name: "FK_ApiResourceScopes_ApiResources_ApiResourceId",
column: x => x.ApiResourceId,
principalTable: "ApiResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ApiResourceSecrets",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ApiResourceId = table.Column<int>(type: "INTEGER", nullable: false),
Description = table.Column<string>(type: "TEXT", maxLength: 1000, nullable: true),
Value = table.Column<string>(type: "TEXT", maxLength: 4000, nullable: false),
Expiration = table.Column<DateTime>(type: "TEXT", nullable: true),
Type = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
Created = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiResourceSecrets", x => x.Id);
table.ForeignKey(
name: "FK_ApiResourceSecrets_ApiResources_ApiResourceId",
column: x => x.ApiResourceId,
principalTable: "ApiResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ApiScopeClaims",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ScopeId = table.Column<int>(type: "INTEGER", nullable: false),
Type = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiScopeClaims", x => x.Id);
table.ForeignKey(
name: "FK_ApiScopeClaims_ApiScopes_ScopeId",
column: x => x.ScopeId,
principalTable: "ApiScopes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ApiScopeProperties",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ScopeId = table.Column<int>(type: "INTEGER", nullable: false),
Key = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
Value = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiScopeProperties", x => x.Id);
table.ForeignKey(
name: "FK_ApiScopeProperties_ApiScopes_ScopeId",
column: x => x.ScopeId,
principalTable: "ApiScopes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientClaims",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Type = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
Value = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
ClientId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientClaims", x => x.Id);
table.ForeignKey(
name: "FK_ClientClaims_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientCorsOrigins",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Origin = table.Column<string>(type: "TEXT", maxLength: 150, nullable: false),
ClientId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientCorsOrigins", x => x.Id);
table.ForeignKey(
name: "FK_ClientCorsOrigins_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientGrantTypes",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GrantType = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
ClientId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientGrantTypes", x => x.Id);
table.ForeignKey(
name: "FK_ClientGrantTypes_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientIdPRestrictions",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Provider = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
ClientId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientIdPRestrictions", x => x.Id);
table.ForeignKey(
name: "FK_ClientIdPRestrictions_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientPostLogoutRedirectUris",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
PostLogoutRedirectUri = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: false),
ClientId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientPostLogoutRedirectUris", x => x.Id);
table.ForeignKey(
name: "FK_ClientPostLogoutRedirectUris_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientProperties",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ClientId = table.Column<int>(type: "INTEGER", nullable: false),
Key = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
Value = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientProperties", x => x.Id);
table.ForeignKey(
name: "FK_ClientProperties_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientRedirectUris",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
RedirectUri = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: false),
ClientId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientRedirectUris", x => x.Id);
table.ForeignKey(
name: "FK_ClientRedirectUris_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientScopes",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Scope = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
ClientId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientScopes", x => x.Id);
table.ForeignKey(
name: "FK_ClientScopes_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ClientSecrets",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ClientId = table.Column<int>(type: "INTEGER", nullable: false),
Description = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: true),
Value = table.Column<string>(type: "TEXT", maxLength: 4000, nullable: false),
Expiration = table.Column<DateTime>(type: "TEXT", nullable: true),
Type = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
Created = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClientSecrets", x => x.Id);
table.ForeignKey(
name: "FK_ClientSecrets_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "IdentityResourceClaims",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
IdentityResourceId = table.Column<int>(type: "INTEGER", nullable: false),
Type = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityResourceClaims", x => x.Id);
table.ForeignKey(
name: "FK_IdentityResourceClaims_IdentityResources_IdentityResourceId",
column: x => x.IdentityResourceId,
principalTable: "IdentityResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "IdentityResourceProperties",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
IdentityResourceId = table.Column<int>(type: "INTEGER", nullable: false),
Key = table.Column<string>(type: "TEXT", maxLength: 250, nullable: false),
Value = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityResourceProperties", x => x.Id);
table.ForeignKey(
name: "FK_IdentityResourceProperties_IdentityResources_IdentityResourceId",
column: x => x.IdentityResourceId,
principalTable: "IdentityResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ApiResourceClaims_ApiResourceId",
table: "ApiResourceClaims",
column: "ApiResourceId");
migrationBuilder.CreateIndex(
name: "IX_ApiResourceProperties_ApiResourceId",
table: "ApiResourceProperties",
column: "ApiResourceId");
migrationBuilder.CreateIndex(
name: "IX_ApiResources_Name",
table: "ApiResources",
column: "Name",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ApiResourceScopes_ApiResourceId",
table: "ApiResourceScopes",
column: "ApiResourceId");
migrationBuilder.CreateIndex(
name: "IX_ApiResourceSecrets_ApiResourceId",
table: "ApiResourceSecrets",
column: "ApiResourceId");
migrationBuilder.CreateIndex(
name: "IX_ApiScopeClaims_ScopeId",
table: "ApiScopeClaims",
column: "ScopeId");
migrationBuilder.CreateIndex(
name: "IX_ApiScopeProperties_ScopeId",
table: "ApiScopeProperties",
column: "ScopeId");
migrationBuilder.CreateIndex(
name: "IX_ApiScopes_Name",
table: "ApiScopes",
column: "Name",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ClientClaims_ClientId",
table: "ClientClaims",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_ClientCorsOrigins_ClientId",
table: "ClientCorsOrigins",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_ClientGrantTypes_ClientId",
table: "ClientGrantTypes",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_ClientIdPRestrictions_ClientId",
table: "ClientIdPRestrictions",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_ClientPostLogoutRedirectUris_ClientId",
table: "ClientPostLogoutRedirectUris",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_ClientProperties_ClientId",
table: "ClientProperties",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_ClientRedirectUris_ClientId",
table: "ClientRedirectUris",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_Clients_ClientId",
table: "Clients",
column: "ClientId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ClientScopes_ClientId",
table: "ClientScopes",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_ClientSecrets_ClientId",
table: "ClientSecrets",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_IdentityResourceClaims_IdentityResourceId",
table: "IdentityResourceClaims",
column: "IdentityResourceId");
migrationBuilder.CreateIndex(
name: "IX_IdentityResourceProperties_IdentityResourceId",
table: "IdentityResourceProperties",
column: "IdentityResourceId");
migrationBuilder.CreateIndex(
name: "IX_IdentityResources_Name",
table: "IdentityResources",
column: "Name",
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ApiResourceClaims");
migrationBuilder.DropTable(
name: "ApiResourceProperties");
migrationBuilder.DropTable(
name: "ApiResourceScopes");
migrationBuilder.DropTable(
name: "ApiResourceSecrets");
migrationBuilder.DropTable(
name: "ApiScopeClaims");
migrationBuilder.DropTable(
name: "ApiScopeProperties");
migrationBuilder.DropTable(
name: "ClientClaims");
migrationBuilder.DropTable(
name: "ClientCorsOrigins");
migrationBuilder.DropTable(
name: "ClientGrantTypes");
migrationBuilder.DropTable(
name: "ClientIdPRestrictions");
migrationBuilder.DropTable(
name: "ClientPostLogoutRedirectUris");
migrationBuilder.DropTable(
name: "ClientProperties");
migrationBuilder.DropTable(
name: "ClientRedirectUris");
migrationBuilder.DropTable(
name: "ClientScopes");
migrationBuilder.DropTable(
name: "ClientSecrets");
migrationBuilder.DropTable(
name: "IdentityResourceClaims");
migrationBuilder.DropTable(
name: "IdentityResourceProperties");
migrationBuilder.DropTable(
name: "ApiResources");
migrationBuilder.DropTable(
name: "ApiScopes");
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropTable(
name: "IdentityResources");
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\20260906032642_InitialConfigurationMigration.Designer.cs
// <auto-generated />
using System;
using IdentityServer4.EntityFramework.DbContexts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace xIds.Migrations
{
[DbContext(typeof(ConfigurationDbContext))]
[Migration("20260906032642_InitialConfigurationMigration")]
partial class InitialConfigurationMigration
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "5.0.2");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AllowedAccessTokenSigningAlgorithms")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<string>("DisplayName")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("Enabled")
.HasColumnType("INTEGER");
b.Property<DateTime?>("LastAccessed")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("NonEditable")
.HasColumnType("INTEGER");
b.Property<bool>("ShowInDiscoveryDocument")
.HasColumnType("INTEGER");
b.Property<DateTime?>("Updated")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("ApiResources");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ApiResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ApiResourceId");
b.ToTable("ApiResourceClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ApiResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Key")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ApiResourceId");
b.ToTable("ApiResourceProperties");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceScope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ApiResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Scope")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ApiResourceId");
b.ToTable("ApiResourceScopes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceSecret", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ApiResourceId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(4000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ApiResourceId");
b.ToTable("ApiResourceSecrets");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<string>("DisplayName")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("Emphasize")
.HasColumnType("INTEGER");
b.Property<bool>("Enabled")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("Required")
.HasColumnType("INTEGER");
b.Property<bool>("ShowInDiscoveryDocument")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("ApiScopes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ScopeId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ScopeId");
b.ToTable("ApiScopeClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeProperty", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Key")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<int>("ScopeId")
.HasColumnType("INTEGER");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ScopeId");
b.ToTable("ApiScopeProperties");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("AbsoluteRefreshTokenLifetime")
.HasColumnType("INTEGER");
b.Property<int>("AccessTokenLifetime")
.HasColumnType("INTEGER");
b.Property<int>("AccessTokenType")
.HasColumnType("INTEGER");
b.Property<bool>("AllowAccessTokensViaBrowser")
.HasColumnType("INTEGER");
b.Property<bool>("AllowOfflineAccess")
.HasColumnType("INTEGER");
b.Property<bool>("AllowPlainTextPkce")
.HasColumnType("INTEGER");
b.Property<bool>("AllowRememberConsent")
.HasColumnType("INTEGER");
b.Property<string>("AllowedIdentityTokenSigningAlgorithms")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<bool>("AlwaysIncludeUserClaimsInIdToken")
.HasColumnType("INTEGER");
b.Property<bool>("AlwaysSendClientClaims")
.HasColumnType("INTEGER");
b.Property<int>("AuthorizationCodeLifetime")
.HasColumnType("INTEGER");
b.Property<bool>("BackChannelLogoutSessionRequired")
.HasColumnType("INTEGER");
b.Property<string>("BackChannelLogoutUri")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<string>("ClientClaimsPrefix")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientId")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientName")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientUri")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<int?>("ConsentLifetime")
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<int>("DeviceCodeLifetime")
.HasColumnType("INTEGER");
b.Property<bool>("EnableLocalLogin")
.HasColumnType("INTEGER");
b.Property<bool>("Enabled")
.HasColumnType("INTEGER");
b.Property<bool>("FrontChannelLogoutSessionRequired")
.HasColumnType("INTEGER");
b.Property<string>("FrontChannelLogoutUri")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<int>("IdentityTokenLifetime")
.HasColumnType("INTEGER");
b.Property<bool>("IncludeJwtId")
.HasColumnType("INTEGER");
b.Property<DateTime?>("LastAccessed")
.HasColumnType("TEXT");
b.Property<string>("LogoUri")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<bool>("NonEditable")
.HasColumnType("INTEGER");
b.Property<string>("PairWiseSubjectSalt")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ProtocolType")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<int>("RefreshTokenExpiration")
.HasColumnType("INTEGER");
b.Property<int>("RefreshTokenUsage")
.HasColumnType("INTEGER");
b.Property<bool>("RequireClientSecret")
.HasColumnType("INTEGER");
b.Property<bool>("RequireConsent")
.HasColumnType("INTEGER");
b.Property<bool>("RequirePkce")
.HasColumnType("INTEGER");
b.Property<bool>("RequireRequestObject")
.HasColumnType("INTEGER");
b.Property<int>("SlidingRefreshTokenLifetime")
.HasColumnType("INTEGER");
b.Property<bool>("UpdateAccessTokenClaimsOnRefresh")
.HasColumnType("INTEGER");
b.Property<DateTime?>("Updated")
.HasColumnType("TEXT");
b.Property<string>("UserCodeType")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<int?>("UserSsoLifetime")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("ClientId")
.IsUnique();
b.ToTable("Clients");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Origin")
.IsRequired()
.HasMaxLength(150)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientCorsOrigins");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("GrantType")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientGrantTypes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Provider")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientIdPRestrictions");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("PostLogoutRedirectUri")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientPostLogoutRedirectUris");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Key")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientProperties");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("RedirectUri")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientRedirectUris");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Scope")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientScopes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(4000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientSecrets");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<string>("DisplayName")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("Emphasize")
.HasColumnType("INTEGER");
b.Property<bool>("Enabled")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("NonEditable")
.HasColumnType("INTEGER");
b.Property<bool>("Required")
.HasColumnType("INTEGER");
b.Property<bool>("ShowInDiscoveryDocument")
.HasColumnType("INTEGER");
b.Property<DateTime?>("Updated")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("IdentityResources");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceClaim", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("IdentityResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("IdentityResourceId");
b.ToTable("IdentityResourceClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("IdentityResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Key")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("IdentityResourceId");
b.ToTable("IdentityResourceProperties");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource")
.WithMany("UserClaims")
.HasForeignKey("ApiResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApiResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource")
.WithMany("Properties")
.HasForeignKey("ApiResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApiResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceScope", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource")
.WithMany("Scopes")
.HasForeignKey("ApiResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApiResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceSecret", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource")
.WithMany("Secrets")
.HasForeignKey("ApiResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApiResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "Scope")
.WithMany("UserClaims")
.HasForeignKey("ScopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Scope");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeProperty", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "Scope")
.WithMany("Properties")
.HasForeignKey("ScopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Scope");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("Claims")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("AllowedCorsOrigins")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("AllowedGrantTypes")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("IdentityProviderRestrictions")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("PostLogoutRedirectUris")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("Properties")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("RedirectUris")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("AllowedScopes")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("ClientSecrets")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceClaim", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource")
.WithMany("UserClaims")
.HasForeignKey("IdentityResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("IdentityResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource")
.WithMany("Properties")
.HasForeignKey("IdentityResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("IdentityResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b =>
{
b.Navigation("Properties");
b.Navigation("Scopes");
b.Navigation("Secrets");
b.Navigation("UserClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b =>
{
b.Navigation("Properties");
b.Navigation("UserClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b =>
{
b.Navigation("AllowedCorsOrigins");
b.Navigation("AllowedGrantTypes");
b.Navigation("AllowedScopes");
b.Navigation("Claims");
b.Navigation("ClientSecrets");
b.Navigation("IdentityProviderRestrictions");
b.Navigation("PostLogoutRedirectUris");
b.Navigation("Properties");
b.Navigation("RedirectUris");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b =>
{
b.Navigation("Properties");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\ConfigurationDbContextModelSnapshot.cs
// <auto-generated />
using System;
using IdentityServer4.EntityFramework.DbContexts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace xIds.Migrations
{
[DbContext(typeof(ConfigurationDbContext))]
partial class ConfigurationDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "5.0.2");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AllowedAccessTokenSigningAlgorithms")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<string>("DisplayName")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("Enabled")
.HasColumnType("INTEGER");
b.Property<DateTime?>("LastAccessed")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("NonEditable")
.HasColumnType("INTEGER");
b.Property<bool>("ShowInDiscoveryDocument")
.HasColumnType("INTEGER");
b.Property<DateTime?>("Updated")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("ApiResources");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ApiResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ApiResourceId");
b.ToTable("ApiResourceClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ApiResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Key")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ApiResourceId");
b.ToTable("ApiResourceProperties");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceScope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ApiResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Scope")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ApiResourceId");
b.ToTable("ApiResourceScopes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceSecret", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ApiResourceId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(4000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ApiResourceId");
b.ToTable("ApiResourceSecrets");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<string>("DisplayName")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("Emphasize")
.HasColumnType("INTEGER");
b.Property<bool>("Enabled")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("Required")
.HasColumnType("INTEGER");
b.Property<bool>("ShowInDiscoveryDocument")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("ApiScopes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ScopeId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ScopeId");
b.ToTable("ApiScopeClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeProperty", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Key")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<int>("ScopeId")
.HasColumnType("INTEGER");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ScopeId");
b.ToTable("ApiScopeProperties");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("AbsoluteRefreshTokenLifetime")
.HasColumnType("INTEGER");
b.Property<int>("AccessTokenLifetime")
.HasColumnType("INTEGER");
b.Property<int>("AccessTokenType")
.HasColumnType("INTEGER");
b.Property<bool>("AllowAccessTokensViaBrowser")
.HasColumnType("INTEGER");
b.Property<bool>("AllowOfflineAccess")
.HasColumnType("INTEGER");
b.Property<bool>("AllowPlainTextPkce")
.HasColumnType("INTEGER");
b.Property<bool>("AllowRememberConsent")
.HasColumnType("INTEGER");
b.Property<string>("AllowedIdentityTokenSigningAlgorithms")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<bool>("AlwaysIncludeUserClaimsInIdToken")
.HasColumnType("INTEGER");
b.Property<bool>("AlwaysSendClientClaims")
.HasColumnType("INTEGER");
b.Property<int>("AuthorizationCodeLifetime")
.HasColumnType("INTEGER");
b.Property<bool>("BackChannelLogoutSessionRequired")
.HasColumnType("INTEGER");
b.Property<string>("BackChannelLogoutUri")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<string>("ClientClaimsPrefix")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientId")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientName")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientUri")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<int?>("ConsentLifetime")
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<int>("DeviceCodeLifetime")
.HasColumnType("INTEGER");
b.Property<bool>("EnableLocalLogin")
.HasColumnType("INTEGER");
b.Property<bool>("Enabled")
.HasColumnType("INTEGER");
b.Property<bool>("FrontChannelLogoutSessionRequired")
.HasColumnType("INTEGER");
b.Property<string>("FrontChannelLogoutUri")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<int>("IdentityTokenLifetime")
.HasColumnType("INTEGER");
b.Property<bool>("IncludeJwtId")
.HasColumnType("INTEGER");
b.Property<DateTime?>("LastAccessed")
.HasColumnType("TEXT");
b.Property<string>("LogoUri")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<bool>("NonEditable")
.HasColumnType("INTEGER");
b.Property<string>("PairWiseSubjectSalt")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ProtocolType")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<int>("RefreshTokenExpiration")
.HasColumnType("INTEGER");
b.Property<int>("RefreshTokenUsage")
.HasColumnType("INTEGER");
b.Property<bool>("RequireClientSecret")
.HasColumnType("INTEGER");
b.Property<bool>("RequireConsent")
.HasColumnType("INTEGER");
b.Property<bool>("RequirePkce")
.HasColumnType("INTEGER");
b.Property<bool>("RequireRequestObject")
.HasColumnType("INTEGER");
b.Property<int>("SlidingRefreshTokenLifetime")
.HasColumnType("INTEGER");
b.Property<bool>("UpdateAccessTokenClaimsOnRefresh")
.HasColumnType("INTEGER");
b.Property<DateTime?>("Updated")
.HasColumnType("TEXT");
b.Property<string>("UserCodeType")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<int?>("UserSsoLifetime")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("ClientId")
.IsUnique();
b.ToTable("Clients");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Origin")
.IsRequired()
.HasMaxLength(150)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientCorsOrigins");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("GrantType")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientGrantTypes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Provider")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientIdPRestrictions");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("PostLogoutRedirectUri")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientPostLogoutRedirectUris");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Key")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientProperties");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("RedirectUri")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientRedirectUris");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Scope")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientScopes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(4000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("ClientSecrets");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("TEXT");
b.Property<string>("DisplayName")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("Emphasize")
.HasColumnType("INTEGER");
b.Property<bool>("Enabled")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<bool>("NonEditable")
.HasColumnType("INTEGER");
b.Property<bool>("Required")
.HasColumnType("INTEGER");
b.Property<bool>("ShowInDiscoveryDocument")
.HasColumnType("INTEGER");
b.Property<DateTime?>("Updated")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("IdentityResources");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceClaim", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("IdentityResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("IdentityResourceId");
b.ToTable("IdentityResourceClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("IdentityResourceId")
.HasColumnType("INTEGER");
b.Property<string>("Key")
.IsRequired()
.HasMaxLength(250)
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("IdentityResourceId");
b.ToTable("IdentityResourceProperties");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource")
.WithMany("UserClaims")
.HasForeignKey("ApiResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApiResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource")
.WithMany("Properties")
.HasForeignKey("ApiResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApiResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceScope", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource")
.WithMany("Scopes")
.HasForeignKey("ApiResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApiResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceSecret", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource")
.WithMany("Secrets")
.HasForeignKey("ApiResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApiResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "Scope")
.WithMany("UserClaims")
.HasForeignKey("ScopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Scope");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeProperty", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "Scope")
.WithMany("Properties")
.HasForeignKey("ScopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Scope");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("Claims")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("AllowedCorsOrigins")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("AllowedGrantTypes")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("IdentityProviderRestrictions")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("PostLogoutRedirectUris")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("Properties")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("RedirectUris")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("AllowedScopes")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client")
.WithMany("ClientSecrets")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceClaim", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource")
.WithMany("UserClaims")
.HasForeignKey("IdentityResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("IdentityResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b =>
{
b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource")
.WithMany("Properties")
.HasForeignKey("IdentityResourceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("IdentityResource");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b =>
{
b.Navigation("Properties");
b.Navigation("Scopes");
b.Navigation("Secrets");
b.Navigation("UserClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b =>
{
b.Navigation("Properties");
b.Navigation("UserClaims");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b =>
{
b.Navigation("AllowedCorsOrigins");
b.Navigation("AllowedGrantTypes");
b.Navigation("AllowedScopes");
b.Navigation("Claims");
b.Navigation("ClientSecrets");
b.Navigation("IdentityProviderRestrictions");
b.Navigation("PostLogoutRedirectUris");
b.Navigation("Properties");
b.Navigation("RedirectUris");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b =>
{
b.Navigation("Properties");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\PersistedGrantDb\20260906032650_InitialPersistedGrantMigration.cs
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace xIds.Migrations.PersistedGrantDb
{
public partial class InitialPersistedGrantMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "DeviceCodes",
columns: table => new
{
UserCode = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
DeviceCode = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
SubjectId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
SessionId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
ClientId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
Description = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
CreationTime = table.Column<DateTime>(type: "TEXT", nullable: false),
Expiration = table.Column<DateTime>(type: "TEXT", nullable: false),
Data = table.Column<string>(type: "TEXT", maxLength: 50000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DeviceCodes", x => x.UserCode);
});
migrationBuilder.CreateTable(
name: "PersistedGrants",
columns: table => new
{
Key = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
Type = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
SubjectId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
SessionId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
ClientId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
Description = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
CreationTime = table.Column<DateTime>(type: "TEXT", nullable: false),
Expiration = table.Column<DateTime>(type: "TEXT", nullable: true),
ConsumedTime = table.Column<DateTime>(type: "TEXT", nullable: true),
Data = table.Column<string>(type: "TEXT", maxLength: 50000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PersistedGrants", x => x.Key);
});
migrationBuilder.CreateIndex(
name: "IX_DeviceCodes_DeviceCode",
table: "DeviceCodes",
column: "DeviceCode",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_DeviceCodes_Expiration",
table: "DeviceCodes",
column: "Expiration");
migrationBuilder.CreateIndex(
name: "IX_PersistedGrants_Expiration",
table: "PersistedGrants",
column: "Expiration");
migrationBuilder.CreateIndex(
name: "IX_PersistedGrants_SubjectId_ClientId_Type",
table: "PersistedGrants",
columns: new[] { "SubjectId", "ClientId", "Type" });
migrationBuilder.CreateIndex(
name: "IX_PersistedGrants_SubjectId_SessionId_Type",
table: "PersistedGrants",
columns: new[] { "SubjectId", "SessionId", "Type" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "DeviceCodes");
migrationBuilder.DropTable(
name: "PersistedGrants");
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\PersistedGrantDb\20260906032650_InitialPersistedGrantMigration.Designer.cs
// <auto-generated />
using System;
using IdentityServer4.EntityFramework.DbContexts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace xIds.Migrations.PersistedGrantDb
{
[DbContext(typeof(PersistedGrantDbContext))]
[Migration("20260906032650_InitialPersistedGrantMigration")]
partial class InitialPersistedGrantMigration
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "5.0.2");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b =>
{
b.Property<string>("UserCode")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientId")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasMaxLength(50000)
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("DeviceCode")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<DateTime?>("Expiration")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SessionId")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("UserCode");
b.HasIndex("DeviceCode")
.IsUnique();
b.HasIndex("Expiration");
b.ToTable("DeviceCodes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b =>
{
b.Property<string>("Key")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientId")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<DateTime?>("ConsumedTime")
.HasColumnType("TEXT");
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasMaxLength(50000)
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("SessionId")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.HasKey("Key");
b.HasIndex("Expiration");
b.HasIndex("SubjectId", "ClientId", "Type");
b.HasIndex("SubjectId", "SessionId", "Type");
b.ToTable("PersistedGrants");
});
#pragma warning restore 612, 618
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\PersistedGrantDb\PersistedGrantDbContextModelSnapshot.cs
// <auto-generated />
using System;
using IdentityServer4.EntityFramework.DbContexts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace xIds.Migrations.PersistedGrantDb
{
[DbContext(typeof(PersistedGrantDbContext))]
partial class PersistedGrantDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "5.0.2");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b =>
{
b.Property<string>("UserCode")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientId")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasMaxLength(50000)
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("DeviceCode")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<DateTime?>("Expiration")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SessionId")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.HasKey("UserCode");
b.HasIndex("DeviceCode")
.IsUnique();
b.HasIndex("Expiration");
b.ToTable("DeviceCodes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b =>
{
b.Property<string>("Key")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("ClientId")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<DateTime?>("ConsumedTime")
.HasColumnType("TEXT");
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasMaxLength(50000)
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("SessionId")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.HasKey("Key");
b.HasIndex("Expiration");
b.HasIndex("SubjectId", "ClientId", "Type");
b.HasIndex("SubjectId", "SessionId", "Type");
b.ToTable("PersistedGrants");
});
#pragma warning restore 612, 618
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\XIdentityDb\20260906032659_InitialIdentityServerDbContext.cs
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace xIds.Migrations.XIdentityDb
{
public partial class InitialIdentityServerDbContext : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(type: "TEXT", nullable: false),
Discriminator = table.Column<string>(type: "TEXT", nullable: false),
FirstName = table.Column<string>(type: "TEXT", maxLength: 50, nullable: true),
LastName = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
IsEnable = table.Column<bool>(type: "INTEGER", nullable: true),
IsBanned = table.Column<bool>(type: "INTEGER", nullable: true),
DateOfBirth = table.Column<DateTime>(type: "TEXT", nullable: true),
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: true),
LastLogin = table.Column<DateTime>(type: "TEXT", nullable: true),
Avatar = table.Column<string>(type: "TEXT", nullable: true),
Gender = table.Column<int>(type: "INTEGER", nullable: true),
Bio = table.Column<string>(type: "TEXT", nullable: true),
CoverImage = table.Column<string>(type: "TEXT", nullable: true),
OpenToSearch = table.Column<bool>(type: "INTEGER", nullable: true),
UserName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
Email = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(type: "INTEGER", nullable: false),
PasswordHash = table.Column<string>(type: "TEXT", nullable: true),
SecurityStamp = table.Column<string>(type: "TEXT", nullable: true),
ConcurrencyStamp = table.Column<string>(type: "TEXT", nullable: true),
PhoneNumber = table.Column<string>(type: "TEXT", nullable: true),
PhoneNumberConfirmed = table.Column<bool>(type: "INTEGER", nullable: false),
TwoFactorEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
LockoutEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
AccessFailedCount = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "BannedDevices",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
BannedOn = table.Column<DateTime>(type: "TEXT", nullable: false),
DeviceStr = table.Column<string>(type: "TEXT", nullable: true),
Deleted = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BannedDevices", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Tokens",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Token = table.Column<string>(type: "TEXT", nullable: true),
Hash = table.Column<string>(type: "TEXT", nullable: true),
UserSelectByParam = table.Column<string>(type: "TEXT", nullable: true),
DeviceStr = table.Column<string>(type: "TEXT", nullable: true),
Type = table.Column<int>(type: "INTEGER", nullable: false),
Deleted = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Tokens", x => x.Id);
});
migrationBuilder.CreateTable(
name: "VerificationRequests",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
VerificationCode = table.Column<string>(type: "TEXT", nullable: false),
NumberOfTries = table.Column<int>(type: "INTEGER", nullable: false),
LastTryOn = table.Column<DateTime>(type: "TEXT", nullable: false),
RequestStr = table.Column<string>(type: "TEXT", nullable: true),
DeviceStr = table.Column<string>(type: "TEXT", nullable: true),
Deleted = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_VerificationRequests", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
RoleId = table.Column<string>(type: "TEXT", nullable: false),
ClaimType = table.Column<string>(type: "TEXT", nullable: true),
ClaimValue = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<string>(type: "TEXT", nullable: false),
ClaimType = table.Column<string>(type: "TEXT", nullable: true),
ClaimValue = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(type: "TEXT", nullable: false),
ProviderKey = table.Column<string>(type: "TEXT", nullable: false),
ProviderDisplayName = table.Column<string>(type: "TEXT", nullable: true),
UserId = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(type: "TEXT", nullable: false),
RoleId = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(type: "TEXT", nullable: false),
LoginProvider = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false),
Value = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Avatars",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<string>(type: "TEXT", nullable: true),
Name = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
Thumb = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
Path = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
ThumbPath = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false),
Deleted = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Avatars", x => x.Id);
table.ForeignKey(
name: "FK_Avatars_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Devices",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Os = table.Column<string>(type: "TEXT", nullable: true),
OsVersion = table.Column<string>(type: "TEXT", nullable: true),
Browser = table.Column<string>(type: "TEXT", nullable: true),
UserAgent = table.Column<string>(type: "TEXT", nullable: true),
DeviceType = table.Column<int>(type: "INTEGER", nullable: false),
UserId = table.Column<string>(type: "TEXT", nullable: true),
Deleted = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Devices", x => x.Id);
table.ForeignKey(
name: "FK_Devices_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Followers",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
State = table.Column<int>(type: "INTEGER", nullable: false),
UserId = table.Column<string>(type: "TEXT", nullable: true),
DestId = table.Column<string>(type: "TEXT", nullable: true),
Deleted = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Followers", x => x.Id);
table.ForeignKey(
name: "FK_Followers_AspNetUsers_DestId",
column: x => x.DestId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Followers_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Followings",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
State = table.Column<int>(type: "INTEGER", nullable: false),
UserId = table.Column<string>(type: "TEXT", nullable: true),
DestId = table.Column<string>(type: "TEXT", nullable: true),
Deleted = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Followings", x => x.Id);
table.ForeignKey(
name: "FK_Followings_AspNetUsers_DestId",
column: x => x.DestId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Followings_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Avatars_UserId",
table: "Avatars",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Devices_UserId",
table: "Devices",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Followers_DestId",
table: "Followers",
column: "DestId");
migrationBuilder.CreateIndex(
name: "IX_Followers_UserId",
table: "Followers",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Followings_DestId",
table: "Followings",
column: "DestId");
migrationBuilder.CreateIndex(
name: "IX_Followings_UserId",
table: "Followings",
column: "UserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "Avatars");
migrationBuilder.DropTable(
name: "BannedDevices");
migrationBuilder.DropTable(
name: "Devices");
migrationBuilder.DropTable(
name: "Followers");
migrationBuilder.DropTable(
name: "Followings");
migrationBuilder.DropTable(
name: "Tokens");
migrationBuilder.DropTable(
name: "VerificationRequests");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\XIdentityDb\20260906032659_InitialIdentityServerDbContext.Designer.cs
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using xIds.DbContext;
namespace xIds.Migrations.XIdentityDb
{
[DbContext(typeof(XIdentityDbContext))]
[Migration("20260906032659_InitialIdentityServerDbContext")]
partial class InitialIdentityServerDbContext
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "5.0.2");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Discriminator")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers");
b.HasDiscriminator<string>("Discriminator").HasValue("IdentityUser");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("ProviderKey")
.HasColumnType("TEXT");
b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.HasColumnType("TEXT");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("xIdentityModels.Models.XBannedDevice", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("BannedOn")
.HasColumnType("TEXT");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DeviceStr")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("BannedDevices");
});
modelBuilder.Entity("xIdentityModels.Models.XToken", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DeviceStr")
.HasColumnType("TEXT");
b.Property<string>("Hash")
.HasColumnType("TEXT");
b.Property<string>("Token")
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<string>("UserSelectByParam")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Tokens");
});
modelBuilder.Entity("xIdentityModels.Models.XVerificationRequest", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DeviceStr")
.HasColumnType("TEXT");
b.Property<DateTime>("LastTryOn")
.HasColumnType("TEXT");
b.Property<int>("NumberOfTries")
.HasColumnType("INTEGER");
b.Property<string>("RequestStr")
.HasColumnType("TEXT");
b.Property<string>("VerificationCode")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("VerificationRequests");
});
modelBuilder.Entity("xIdentityModels.Navigations.XDevice", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Browser")
.HasColumnType("TEXT");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<int>("DeviceType")
.HasColumnType("INTEGER");
b.Property<string>("Os")
.HasColumnType("TEXT");
b.Property<string>("OsVersion")
.HasColumnType("TEXT");
b.Property<string>("UserAgent")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Devices");
});
modelBuilder.Entity("xIdentityModels.Navigations.XFriendshipFollower", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DestId")
.HasColumnType("TEXT");
b.Property<int>("State")
.HasColumnType("INTEGER");
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("DestId");
b.HasIndex("UserId");
b.ToTable("Followers");
});
modelBuilder.Entity("xIdentityModels.Navigations.XFriendshipFollowing", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DestId")
.HasColumnType("TEXT");
b.Property<int>("State")
.HasColumnType("INTEGER");
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("DestId");
b.HasIndex("UserId");
b.ToTable("Followings");
});
modelBuilder.Entity("xIdentityModels.Navigations.XProfileImage", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("Path")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("Thumb")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("ThumbPath")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Avatars");
});
modelBuilder.Entity("xIdentityModels.XUser", b =>
{
b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser");
b.Property<string>("Avatar")
.HasColumnType("TEXT");
b.Property<string>("Bio")
.HasColumnType("TEXT");
b.Property<string>("CoverImage")
.HasColumnType("TEXT");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<DateTime>("DateOfBirth")
.HasColumnType("TEXT");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<int>("Gender")
.HasColumnType("INTEGER");
b.Property<bool>("IsBanned")
.HasColumnType("INTEGER");
b.Property<bool>("IsEnable")
.HasColumnType("INTEGER");
b.Property<DateTime?>("LastLogin")
.HasColumnType("TEXT");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<bool>("OpenToSearch")
.HasColumnType("INTEGER");
b.HasDiscriminator().HasValue("XUser");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("xIdentityModels.XUser", null)
.WithMany("Roles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("xIdentityModels.Navigations.XDevice", b =>
{
b.HasOne("xIdentityModels.XUser", "User")
.WithMany("Devices")
.HasForeignKey("UserId");
b.Navigation("User");
});
modelBuilder.Entity("xIdentityModels.Navigations.XFriendshipFollower", b =>
{
b.HasOne("xIdentityModels.XUser", "Dest")
.WithMany()
.HasForeignKey("DestId");
b.HasOne("xIdentityModels.XUser", "User")
.WithMany("Followers")
.HasForeignKey("UserId");
b.Navigation("Dest");
b.Navigation("User");
});
modelBuilder.Entity("xIdentityModels.Navigations.XFriendshipFollowing", b =>
{
b.HasOne("xIdentityModels.XUser", "Dest")
.WithMany()
.HasForeignKey("DestId");
b.HasOne("xIdentityModels.XUser", "User")
.WithMany("Followings")
.HasForeignKey("UserId");
b.Navigation("Dest");
b.Navigation("User");
});
modelBuilder.Entity("xIdentityModels.Navigations.XProfileImage", b =>
{
b.HasOne("xIdentityModels.XUser", "User")
.WithMany("Avatars")
.HasForeignKey("UserId");
b.Navigation("User");
});
modelBuilder.Entity("xIdentityModels.XUser", b =>
{
b.Navigation("Avatars");
b.Navigation("Devices");
b.Navigation("Followers");
b.Navigation("Followings");
b.Navigation("Roles");
});
#pragma warning restore 612, 618
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Migrations\XIdentityDb\XIdentityDbContextModelSnapshot.cs
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using xIds.DbContext;
namespace xIds.Migrations.XIdentityDb
{
[DbContext(typeof(XIdentityDbContext))]
partial class XIdentityDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "5.0.2");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Discriminator")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers");
b.HasDiscriminator<string>("Discriminator").HasValue("IdentityUser");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("ProviderKey")
.HasColumnType("TEXT");
b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.HasColumnType("TEXT");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("xIdentityModels.Models.XBannedDevice", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("BannedOn")
.HasColumnType("TEXT");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DeviceStr")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("BannedDevices");
});
modelBuilder.Entity("xIdentityModels.Models.XToken", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DeviceStr")
.HasColumnType("TEXT");
b.Property<string>("Hash")
.HasColumnType("TEXT");
b.Property<string>("Token")
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<string>("UserSelectByParam")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Tokens");
});
modelBuilder.Entity("xIdentityModels.Models.XVerificationRequest", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DeviceStr")
.HasColumnType("TEXT");
b.Property<DateTime>("LastTryOn")
.HasColumnType("TEXT");
b.Property<int>("NumberOfTries")
.HasColumnType("INTEGER");
b.Property<string>("RequestStr")
.HasColumnType("TEXT");
b.Property<string>("VerificationCode")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("VerificationRequests");
});
modelBuilder.Entity("xIdentityModels.Navigations.XDevice", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Browser")
.HasColumnType("TEXT");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<int>("DeviceType")
.HasColumnType("INTEGER");
b.Property<string>("Os")
.HasColumnType("TEXT");
b.Property<string>("OsVersion")
.HasColumnType("TEXT");
b.Property<string>("UserAgent")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Devices");
});
modelBuilder.Entity("xIdentityModels.Navigations.XFriendshipFollower", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DestId")
.HasColumnType("TEXT");
b.Property<int>("State")
.HasColumnType("INTEGER");
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("DestId");
b.HasIndex("UserId");
b.ToTable("Followers");
});
modelBuilder.Entity("xIdentityModels.Navigations.XFriendshipFollowing", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("DestId")
.HasColumnType("TEXT");
b.Property<int>("State")
.HasColumnType("INTEGER");
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("DestId");
b.HasIndex("UserId");
b.ToTable("Followings");
});
modelBuilder.Entity("xIdentityModels.Navigations.XProfileImage", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<bool>("Deleted")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("Path")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("Thumb")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("ThumbPath")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Avatars");
});
modelBuilder.Entity("xIdentityModels.XUser", b =>
{
b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser");
b.Property<string>("Avatar")
.HasColumnType("TEXT");
b.Property<string>("Bio")
.HasColumnType("TEXT");
b.Property<string>("CoverImage")
.HasColumnType("TEXT");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<DateTime>("DateOfBirth")
.HasColumnType("TEXT");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<int>("Gender")
.HasColumnType("INTEGER");
b.Property<bool>("IsBanned")
.HasColumnType("INTEGER");
b.Property<bool>("IsEnable")
.HasColumnType("INTEGER");
b.Property<DateTime?>("LastLogin")
.HasColumnType("TEXT");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<bool>("OpenToSearch")
.HasColumnType("INTEGER");
b.HasDiscriminator().HasValue("XUser");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("xIdentityModels.XUser", null)
.WithMany("Roles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("xIdentityModels.Navigations.XDevice", b =>
{
b.HasOne("xIdentityModels.XUser", "User")
.WithMany("Devices")
.HasForeignKey("UserId");
b.Navigation("User");
});
modelBuilder.Entity("xIdentityModels.Navigations.XFriendshipFollower", b =>
{
b.HasOne("xIdentityModels.XUser", "Dest")
.WithMany()
.HasForeignKey("DestId");
b.HasOne("xIdentityModels.XUser", "User")
.WithMany("Followers")
.HasForeignKey("UserId");
b.Navigation("Dest");
b.Navigation("User");
});
modelBuilder.Entity("xIdentityModels.Navigations.XFriendshipFollowing", b =>
{
b.HasOne("xIdentityModels.XUser", "Dest")
.WithMany()
.HasForeignKey("DestId");
b.HasOne("xIdentityModels.XUser", "User")
.WithMany("Followings")
.HasForeignKey("UserId");
b.Navigation("Dest");
b.Navigation("User");
});
modelBuilder.Entity("xIdentityModels.Navigations.XProfileImage", b =>
{
b.HasOne("xIdentityModels.XUser", "User")
.WithMany("Avatars")
.HasForeignKey("UserId");
b.Navigation("User");
});
modelBuilder.Entity("xIdentityModels.XUser", b =>
{
b.Navigation("Avatars");
b.Navigation("Devices");
b.Navigation("Followers");
b.Navigation("Followings");
b.Navigation("Roles");
});
#pragma warning restore 612, 618
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Models\XDbInfo.cs
using System;
using xIds.Constants;
namespace xIds.Models
{
public class XDbInfo
{
private string _migrationAssembly;
public XDbProviders ProviderType { get; set; }
public string MigrationsAssembly
{
get
{
return _migrationAssembly;
}
set
{
//
_migrationAssembly = value;
//
OptionsBuilder = b =>
{
b.MigrationsAssembly(value);
};
}
}
public Action<dynamic> OptionsBuilder { get; set; }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Models\XDbSeedDescriptor.cs
using System.Collections.Generic;
using IdentityServer4.Models;
using xIdentityModels.Descriptors;
namespace xIds.Models
{
/// <summary>
/// the resource Descriptors for Using on DbSeed
/// </summary>
public class XDbSeedDescriptor
{
public bool UpdateExists { get; set; }
public ICollection<ApiScope> ApiScopes { get; set; }
public ICollection<ApiResource> ApiResources { get; set; }
public ICollection<IdentityResource> IdentityResources { get; set; }
public ICollection<Client> Clients { get; set; }
public ICollection<XIdentityUserDescriptor> Users { get; set; }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager.cs
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
using xIdentityModels;
using xIdentityModels.Configurations;
using xIdentityModels.Constants;
using xIdentityModels.Models;
using xMessageService.Interfaces;
using xStorageService.Interfaces;
using xIds.Configurations;
using xIds.DbContext;
using xIds.Interfaces;
namespace xIds.Providers
{
public partial class XIdentityManager : IXIdentityManager
{
//
private JsonSerializerSettings jsonSerializerSettings;
//
public XIdentityDbContext DbContext { get; }
public UserManager<XUser> UserManager { get; }
public IXIdentityHelper IdentityHelper { get; }
public ILogger<IXIdentityManager> Logger { get; }
public IXMessageProvider MessageProvider { get; }
public IXStorageProvider StorageProvider { get; }
public SignInManager<XUser> SignInManager { get; }
public IXSecurityProvider SecurityProvider { get; }
public XIdentityConfiguration Configuration { get; }
public RoleManager<IdentityRole> RoleManager { get; }
public XValidationProvider ValidationProvider { get; }
public XDataServiceConfiguration DataConfiguration { get; }
public IXIdentityMessageProvider IdentityMessageProvider { get; }
public XIdentityResourceConfiguration IdentityResourceConfiguration { get; }
public XIdentityManager(
XIdentityDbContext dbContext,
UserManager<XUser> userManager,
IXIdentityHelper identityHelper,
ILogger<IXIdentityManager> logger,
IXMessageProvider messageProvider,
IXStorageProvider storageProvider,
SignInManager<XUser> signInManager,
IXSecurityProvider securityProvider,
XIdentityConfiguration configuration,
RoleManager<IdentityRole> roleManager,
XValidationProvider validationProvider,
XDataServiceConfiguration dataConfiguration,
IXIdentityMessageProvider identityMessageProvider,
XIdentityResourceConfiguration identityResourceConfiguration
)
{
//
Logger = logger;
DbContext = dbContext;
RoleManager = roleManager;
UserManager = userManager;
SignInManager = signInManager;
SecurityProvider = securityProvider;
Configuration = configuration;
IdentityHelper = identityHelper;
MessageProvider = messageProvider;
StorageProvider = storageProvider;
DataConfiguration = dataConfiguration;
ValidationProvider = validationProvider;
IdentityMessageProvider = identityMessageProvider;
IdentityResourceConfiguration = identityResourceConfiguration;
//
this.jsonSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
}
//
#region Class Getter (s) Methods ...
/// <summary>
/// Retrieve User DB Set
/// </summary>
/// <param name="containDetails">specifies returned object contains all Navigation Properties or not, default is false</param>
/// <returns></returns>
public IQueryable<XUser> GetUsersDbSet(
bool containDetails = false
)
{
//
var dbSet = containDetails ? GetUsersFullDbSet() :
UserManager.Users;
return dbSet;
}
/// <summary>
/// Retrieve User Db Set Full Navigation Properties
/// </summary>
/// <param name="enableTracking"></param>
/// <returns></returns>
public IQueryable<XUser> GetUsersFullDbSet(bool enableTracking = false)
{
//
var dbSet = UserManager.Users
.Include(u => u.Roles)
.Include(u => u.Devices)
.Include(u => u.Followers)
.Include(u => u.Followings)
.Include(u => u.Avatars);
//
return dbSet.AsSplitQuery();
}
#endregion
//
#region Tools ...
/// <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\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityMessageProvider.cs
using System.Linq;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Configurations;
using xIds.Constants;
using xIds.Interfaces;
namespace xIds.Providers
{
public class XIdentityMessageProvider : IXIdentityMessageProvider
{
//
public string InviteMsg { get; set; }
public string RegistrationApproveMsg { get; set; }
public string RegisteredMsg { get; set; }
public string VerificationCodeMsg { get; set; }
public string ChangePasswordMsg { get; set; }
public string PasswordChangedMsg { get; set; }
public string NewDeviceLoggedInMsg { get; set; }
private readonly ILogger<IXIdentityMessageProvider> logger;
private readonly XIdentityConfiguration identityConfiguration;
public XIdentityMessageProvider(
ILogger<IXIdentityMessageProvider> logger,
XIdentityConfiguration identityConfiguration
)
{
this.logger = logger;
this.identityConfiguration = identityConfiguration;
}
/// <summary>
/// Determine All things is Ready or Not
/// </summary>
/// <returns></returns>
public bool IsReady()
{
return !InviteMsg.IsNullOrEmpty() &&
!RegistrationApproveMsg.IsNullOrEmpty() &&
!RegisteredMsg.IsNullOrEmpty() &&
!VerificationCodeMsg.IsNullOrEmpty() &&
!ChangePasswordMsg.IsNullOrEmpty() &&
!PasswordChangedMsg.IsNullOrEmpty() &&
!NewDeviceLoggedInMsg.IsNullOrEmpty();
}
/// <summary>
/// Retrieve a Translated Value Based on Given Lang
/// </summary>
/// <param name="resourceTitle"></param>
/// <param name="lang"></param>
/// <returns></returns>
private string GetStringResource(string resourceTitle, string lang)
{
//
var item = identityConfiguration.IdentityMessages
.FirstOrDefault(sr =>
sr.Language.ToNormalString() == lang.ToNormalString() &&
sr.ResourceTitle.ToNormalString() == resourceTitle.ToNormalString());
//
if (item == null)
{
return null;
}
//
return item.TranslatedValue;
}
/// <summary>
/// Prepare Helper Class and Fill Messages
/// with Specific Language
/// </summary>
/// <param name="lang"></param>
public void PrepareMessages(string lang)
{
//
InviteMsg = GetStringResource(IdentityMessagesKeys.InviteMsg, lang);
RegisteredMsg = GetStringResource(IdentityMessagesKeys.RegisteredMsg, lang);
ChangePasswordMsg = GetStringResource(IdentityMessagesKeys.ChangePasswordMsg, lang);
PasswordChangedMsg = GetStringResource(IdentityMessagesKeys.PasswordChangedMsg, lang);
VerificationCodeMsg = GetStringResource(IdentityMessagesKeys.VerificationCodeMsg, lang);
NewDeviceLoggedInMsg = GetStringResource(IdentityMessagesKeys.NewDeviceLoggedInMsg, lang);
RegistrationApproveMsg = GetStringResource(IdentityMessagesKeys.RegistrationApproveMsg, lang);
//
if (!IsReady())
{
XException.InvalidArgs.Throw();
}
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityProfileService.cs
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Extensions;
using IdentityServer4.Models;
using IdentityServer4.Services;
using Microsoft.AspNetCore.Identity;
using xCommons.Extensions;
using xIdentityModels;
using xIds.Interfaces;
namespace xIds.Providers
{
public class XIdentityProfileService : IProfileService
{
private readonly IXIdentityManager identityManager;
private readonly IUserClaimsPrincipalFactory<XUser> userClaimsPrincipalFacotry;
public XIdentityProfileService(
IXIdentityManager identityManager,
IUserClaimsPrincipalFactory<XUser> userClaimsPrincipalFacotry
)
{
this.identityManager = identityManager;
this.userClaimsPrincipalFacotry = userClaimsPrincipalFacotry;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
//
var sub = context.Subject.GetSubjectId();
var user = await identityManager.GetUserAsync(sub, true);
var principal = await userClaimsPrincipalFacotry.CreateAsync(user);
//
var claims = principal.Claims.ToList();
//
context.IssuedClaims = claims;
}
public async Task IsActiveAsync(IsActiveContext context)
{
//
var sub = context.Subject.GetSubjectId();
var user = await identityManager.GetUserAsync(sub);
//
context.IsActive = !user.IsNull() && user.IsEnable && !user.IsBanned;
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XSecurityProvider.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using xCommons.Extensions;
using xCommons.Providers;
using xIds.Configurations;
using xIds.Interfaces;
namespace xIds.Providers
{
public class XSecurityProvider : IXSecurityProvider
{
//
#region Props ...
private readonly string secretKey;
private readonly byte[] iv;
private readonly byte[] key;
private readonly XValidationProvider validationProvider;
#endregion
//
#region Constructor ...
public XSecurityProvider(
XIdentityResourceConfiguration 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);
}
#endregion
//
#region Actions ...
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;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Admin.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using xCommons.Extensions;
using xIdentityModels.Dtos;
namespace xIds.Providers
{
public partial class XIdentityManager
{
#region Admin Actions ...
/// <summary>
/// Retrieve All UnBanned Users Identifiers
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <returns>a collection of user identifiers</returns>
public async Task<ICollection<string>> GetAllUnbanned(
ICollection<string> userSelectByParam
)
{
//
var result = new List<string>();
if (!userSelectByParam.HasChild())
{
return result;
}
//
foreach (var uParam in userSelectByParam)
{
//
var destUser = await ValidateUserExistsAndRetrieve(uParam, checkIsBanned: false);
if (!destUser.IsBanned)
{
result.Add(uParam);
}
}
//
return result;
}
/// <summary>
/// Get All Banned Users Identifiers
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <returns>a collection of user identifiers</returns>
public async Task<ICollection<string>> GetAllBanned(
ICollection<string> userSelectByParam
)
{
//
var result = new List<string>();
if (!userSelectByParam.HasChild())
{
return result;
}
//
foreach (var uParam in userSelectByParam)
{
//
var destUser = await ValidateUserExistsAndRetrieve(uParam, checkIsBanned: false);
if (destUser.IsBanned)
{
result.Add(uParam);
}
}
//
return result;
}
/// <summary>
/// Ban a Collection of Users
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
/// <returns>a collection of user identifiers</returns>
public async Task<ICollection<string>> Ban(
string userSelectByParam,
XUserNameIdRequest model
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
ValidationProvider.NotNull(model);
ValidationProvider.NotZeroChilds(model.Ids);
//
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: true,
checkIsBanned: true,
containDetails: false,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
var result = new List<string>();
foreach (var uParam in model.Ids)
{
//
var destUser = await ValidateUserExistsAndRetrieve(uParam, checkIsBanned: false);
//
var isBanned = destUser.IsBanned;
if (!isBanned)
{
//
destUser.IsBanned = true;
//
await UpdateUserAsync(
user,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
result.Add(destUser.Id);
}
}
//
return result;
}
/// <summary>
/// UnBan a Collection of Users
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
/// <returns>a collection of user identifiers</returns>
public async Task<ICollection<string>> UnBan(
string userSelectByParam,
XUserNameIdRequest model
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
ValidationProvider.NotNull(model);
ValidationProvider.NotZeroChilds(model.Ids);
//
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: true,
checkIsBanned: true,
containDetails: false,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
var result = new List<string>();
foreach (var uParam in model.Ids)
{
//
var destUser = await ValidateUserExistsAndRetrieve(uParam, checkIsBanned: false);
//
var isBanned = destUser.IsBanned;
if (isBanned)
{
//
destUser.IsBanned = false;
//
await UpdateUserAsync(
user,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
result.Add(destUser.Id);
}
}
//
return result;
}
/// <summary>
/// Detrmines a User is Banned or not
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">destination user identifier which checked is banned or not</param>
/// <returns>a boolean value which represent user banned or not</returns>
public async Task<bool> IsBanned(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: false,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
var destUser = await ValidateUserExistsAndRetrieve(destUserSelectByParam, checkIsBanned: false);
//
var result = destUser.IsBanned;
//
return result;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Device.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
using xIds.Extensions;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Device Actions ...
/// <summary>
/// Check a Device Exists or Not
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>a boolean value</returns>
public async Task<bool> IsDeviceExistsAsync(
XDevice device
)
{
return await DbContext.Devices
.AnyAsync(d => d.IsSameAs(device));
}
/// <summary>
/// Add new Device
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>an instance of <see>XDevice</see></returns>
public async Task<XDevice> AddDeviceAsync(
XDevice device
)
{
//
var isDeviceExists = await IsDeviceExistsAsync(device);
if (isDeviceExists)
{
return null;
}
//
await DbContext.Devices
.AddAsync(device);
await DbContext.SaveChangesAsync();
return device;
}
/// <summary>
/// Get a Device
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>an instance of <see>XDevice</see></returns>
public Task<XDevice> GetDeviceAsync(
XDevice device
)
{
//
return DbContext.Devices
.FirstOrDefaultAsync(d =>
d.IsSameAs(device));
}
/// <summary>
/// Retrieve a List of User Related Devices
/// </summary>
/// <param name="userSelectByParam">user identifier</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
/// <param name="checkIsBanned">check user is banned or not</param>
/// <returns>a collection of <see>XDevice</see> instances which related to user</returns>
public async Task<ICollection<XDevice>> GetUserDevices(
string userSelectByParam,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Validate ARgs ...
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate And Retrieve User ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned
);
//
// Check User Devices ...
if (!user.Devices.HasChild())
{
return new List<XDevice>();
}
//
return user.Devices;
}
/// <summary>
/// Determines a Device is Exists in User's Devices or not
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>a boolean value</returns>
public bool IsDeviceRelateDToUser(
XUser user,
XDevice device
)
{
if (!user.Devices.HasChild())
{
return false;
}
//
var result = user.Devices.Any(d => d.IsSameAs(device));
//
return result;
}
/// <summary>
/// Determines a Device is Exists in User's Devices or not
/// </summary>
/// <param name="userSelectByParam">user identifier</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
/// <param name="checkIsBanned">check user is banned or not</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsDeviceRelateDToUser(
string userSelectByParam,
XDevice device,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
ValidationProvider.NotNull(device);
//
var userDevices = await GetUserDevices(
userSelectByParam,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned
);
if (!userDevices.HasChild())
{
return false;
}
//
var result = userDevices.Any(d => d.IsSameAs(device));
//
return result;
}
/// <summary>
/// Add a Device to a User Related Devices
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>a boolean value</returns>
public async Task<bool> AddUserRelatedDevice(
XUser user,
XDevice device
)
{
//
var isExists = user.Devices.Any(d =>
d.IsSameAs(device));
if (isExists)
{
return true;
}
//
user.Devices.Add(device);
try
{
var result = await UpdateUserAsync(user);
return result.Succeeded;
}
catch
{
throw XException.ActionFailed.ToException();
}
}
/// <summary>
/// Add a Device to a User
/// </summary>
/// <param name="userSelectByParam">user identifier</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
/// <param name="checkIsBanned">check user is banned or not</param>
/// <returns>a boolean value</returns>
public async Task<bool> AddUserRelatedDevice(
string userSelectByParam,
XDevice device,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
ValidationProvider.NotNull(device);
//
// Check Device Related ...
var isDeviceRelatedToUser = await IsDeviceRelateDToUser(
userSelectByParam,
device,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned);
if (isDeviceRelatedToUser)
{
return true;
}
//
// Retrieve User ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned
);
//
// Add User Device ...
user.Devices.Add(device);
//
var result = await UpdateUserAsync(
user,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
return result.Succeeded;
}
/// <summary>
/// Remove a Device from a User Related Devices List
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>a boolean value</returns>
public async Task<bool> RemoveUserRelatedDevice(
XUser user,
XDevice device
)
{
//
var isRelated = IsDeviceRelateDToUser(user, device);
if (!isRelated)
{
return false;
}
//
var instanse = user.Devices
.FirstOrDefault(d =>
d.IsSameAs(device));
//
user.Devices.Remove(instanse);
//
var result = await UpdateUserAsync(
user,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
return result.Succeeded;
}
/// <summary>
/// Remove a Device from a User Devices
/// </summary>
/// <param name="userSelectByParam">user identifier</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
/// <param name="checkIsBanned">check user is banned or not</param>
/// <returns>a boolean value</returns>
public async Task<bool> RemoveUserRelatedDevice(
string userSelectByParam,
XDevice device,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
ValidationProvider.NotNull(device);
//
// Validate user exists and Retrieve it based on userselectbyparam ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned
);
//
return await RemoveUserRelatedDevice(
user,
device
);
}
#endregion
//
#region Banned Device Actions ...
/// <summary>
/// Check a Device is exists in Banned Devices or not
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>a boolean value</returns>
public async Task<bool> IsBannedDeviceExists(
XDevice device
)
{
//
var result = false;
var bannedDeviceEnumerable = DbContext.BannedDevices.AsAsyncEnumerable();
await
foreach (var bannedDevice in bannedDeviceEnumerable)
{
//
if (bannedDevice.Device.IsSameAs(device))
{
//
result = true;
break;
}
}
//
return result;
}
/// <summary>
/// Find First Banned Device
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>an instance of <see>XDevice</see></returns>
public async Task<XBannedDevice> BannedDeviceFindOne(
XDevice device
)
{
//
var result = await DbContext.BannedDevices
.FirstOrDefaultAsync(bd =>
bd.Device.IsSameAs(device)
);
//
return result;
}
/// <summary>
/// Remove Banned Device
/// </summary>
/// <param name="model">an instance of <see>XBannedDevice</see></param>
/// <returns></returns>
public async Task BannedDeviceRemove(
XBannedDevice model
)
{
//
var isExists = await IsBannedDeviceExists(model.Device);
if (!isExists)
{
return;
}
//
var item = await BannedDeviceFindOne(model.Device);
if (item == null)
{
return;
}
//
DbContext.BannedDevices.Remove(item);
await DbContext.SaveChangesAsync();
}
/// <summary>
/// Check a Device is Banned or not
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>a boolean value</returns>
private async Task<bool> IsDeviceBanned(
XDevice device
)
{
//
var result = await IsBannedDeviceExists(device);
return result;
}
/// <summary>
/// Retrieve Specific Banned Device
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>an instance of <see>XBannedDevice</see></returns>
private async Task<XBannedDevice> GetBannedDevice(
XDevice device
)
{
//
var result = await BannedDeviceFindOne(device);
return result;
}
/// <summary>
/// Is a Banned Device passed Banning Time
/// </summary>
/// <param name="bannedDevice">an instance of <see>XBannedDevice</see></param>
/// <returns>a boolean value</returns>
private bool IsDelayTimePassed(
XBannedDevice bannedDevice
)
{
//
// Validate Args ...
if (bannedDevice == null ||
Configuration == null)
{
XException.InvalidArgs.Throw();
}
//
var isPassed = bannedDevice
.IsDelayTimePassed(Configuration.BannedDeviceTimeout);
//
return isPassed;
}
/// <summary>
/// Retrieve Passed Time from Banning Time of specific Device
/// </summary>
/// <param name="bannedDevice">an instance of <see>XBannedDevice</see></param>
/// <returns>an instance of <see>DateTime</see> which represent Passed Time</returns>
private DateTime GetPassedTime(
XBannedDevice bannedDevice
)
{
//
var result = bannedDevice.BannedOn
.AddSeconds(Configuration.BannedDeviceTimeout);
//
return result;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Friendship.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using xCommons.Extensions;
using xDataService.Extensions;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Navigations;
using xModels.Dtos;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Friendship Actions ...
//
#region Actions ...
/// <summary>
/// Send a Follow Request for userSelectByParam to
/// destUserSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
public async Task<XFriendshipFollowing> Follow(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
XFriendshipFollowing following = null;
XFriendshipFollower follower = null;
var isRequested = IsFollowRequested(xUser, xDestUser);
//
// Check Request Happens Or not ...
if (!isRequested)
{
//
following = new XFriendshipFollowing
{
UserId = xUser.Id,
DestId = xDestUser.Id,
State = XFriendshipState.Pending
};
//
follower = new XFriendshipFollower
{
UserId = xDestUser.Id,
DestId = xUser.Id,
State = XFriendshipState.Pending
};
//
xUser.Followings.Add(following);
xDestUser.Followers.Add(follower);
}
else
{
//
// if Request Done Before Must Check State ...
following = xUser.Followings.FirstOrDefault(f => f.DestId == xDestUser.Id);
follower = xDestUser.Followers.FirstOrDefault(f => f.DestId == xUser.Id);
if (following.IsNull() ||
follower.IsNull())
{
XException.NotFound.Throw();
}
//
switch (following.State)
{
case XFriendshipState.Accepted:
case XFriendshipState.Blocked:
throw XException.NotAllowed.ToException();
case XFriendshipState.Rejected:
following.State = XFriendshipState.Pending;
follower.State = XFriendshipState.Pending;
break;
}
}
//
var canContinue = !following.IsNull() && !follower.IsNull();
if (!canContinue)
{
XException.ActionFailed.Throw();
}
//
await UpdateUserAsync(xUser);
await UpdateUserAsync(xDestUser);
//
var result = following;
//
return result;
}
/// <summary>
/// Cancel Following
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns>a boolean value</returns>
public async Task<bool> Cancel(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
XFriendshipFollowing following = null;
XFriendshipFollower follower = null;
var isRequested = IsFollowRequested(xUser, xDestUser);
//
// Check Request Happens Or not ...
if (!isRequested)
{
return false;
}
//
// if Request Done Before Must Check State ...
following = xUser.Followings.FirstOrDefault(f => f.DestId == xDestUser.Id);
follower = xDestUser.Followers.FirstOrDefault(f => f.DestId == xUser.Id);
if (following.IsNull() ||
follower.IsNull())
{
XException.NotFound.Throw();
}
//
switch (following.State)
{
case XFriendshipState.Accepted:
case XFriendshipState.Blocked:
throw XException.NotAllowed.ToException();
case XFriendshipState.Rejected:
case XFriendshipState.Pending:
DbContext.Followers.Remove(follower);
DbContext.Followings.Remove(following);
break;
}
//
var canContinue = !following.IsNull() && !follower.IsNull();
if (!canContinue)
{
XException.ActionFailed.Throw();
}
//
await DbContext.SaveChangesAsync();
//
return true;
}
/// <summary>
/// userSelectByParam remove friendship by it's Follower
/// destUserSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns></returns>
public async Task UnFollowFollower(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
ValidateIsFollowers(xUser, xDestUser);
//
var follower = xUser.Followers
.FirstOrDefault(f =>
f.DestId == xDestUser.Id &&
f.State == XFriendshipState.Accepted);
var following = xDestUser.Followings
.FirstOrDefault(f =>
f.DestId == xUser.Id &&
f.State == XFriendshipState.Accepted);
if (follower.IsNull() ||
following.IsNull())
{
XException.NotFound.Throw();
}
//
DbContext.Followers.Remove(follower);
DbContext.Followings.Remove(following);
//
await DbContext.SaveChangesAsync();
}
/// <summary>
/// userSelectByParam remove friendship by it's Followings
/// destUserSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns></returns>
public async Task UnFollowFollowing(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
ValidateIsFollowings(xUser, xDestUser);
//
var following = xUser.Followings
.FirstOrDefault(f =>
f.DestId == xDestUser.Id &&
f.State == XFriendshipState.Accepted);
var follower = xDestUser.Followers
.FirstOrDefault(f =>
f.DestId == xUser.Id &&
f.State == XFriendshipState.Accepted);
if (follower.IsNull() ||
following.IsNull())
{
XException.NotAllowed.Throw();
}
//
DbContext.Followers.Remove(follower);
DbContext.Followings.Remove(following);
//
await DbContext.SaveChangesAsync();
}
/// <summary>
/// userSelectByParam Block it's follower destUserSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
public async Task<XFriendshipFollowing> Block(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
// Validate XDestUser is Accepted Follower of XUser ...
ValidateIsFollowers(xUser, xDestUser);
//
// Retrieve FriendShip Models ...
var following = xDestUser.Followings
.FirstOrDefault(f =>
f.DestId == xUser.Id &&
(
f.State == XFriendshipState.Accepted
)
);
var follower = xUser.Followers
.FirstOrDefault(f =>
f.DestId == xDestUser.Id &&
(
f.State == XFriendshipState.Accepted
)
);
if (following.IsNull() ||
follower.IsNull())
{
XException.NotAllowed.Throw();
}
//
follower.State = XFriendshipState.Blocked;
following.State = XFriendshipState.Blocked;
//
DbContext.Followers.Update(follower);
DbContext.Followings.Update(following);
//
await DbContext.SaveChangesAsync();
//
var result = following;
//
return result;
}
/// <summary>
/// userSelectByParam UnBlock it's follower destUserSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
public async Task<XFriendshipFollowing> UnBlock(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
// Validate XDestUser is Accepted Follower of XUser ...
ValidateIsBlock(xUser, xDestUser);
//
// Retrieve FriendShip Models ...
var following = xDestUser.Followings
.FirstOrDefault(f =>
f.DestId == xUser.Id &&
(
f.State == XFriendshipState.Blocked
)
);
var follower = xUser.Followers
.FirstOrDefault(f =>
f.DestId == xDestUser.Id &&
(
f.State == XFriendshipState.Blocked
)
);
if (
following.IsNull() ||
follower.IsNull()
)
{
XException.NotAllowed.Throw();
}
//
follower.State = XFriendshipState.Accepted;
following.State = XFriendshipState.Accepted;
//
DbContext.Followers.Update(follower);
DbContext.Followings.Update(following);
//
await DbContext.SaveChangesAsync();
//
var result = following;
//
return result;
}
#endregion
//
#region Request Handlers ...
/// <summary>
/// userSelectByParam Accept Follow Request of
/// destUserSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
public async Task<XFriendshipFollower> AcceptRequest(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
// Validate Request Sent and in Pending State ...
ValidateFollowingRequestForAccept(xUser, xDestUser);
//
// Retrieve FriendShip Models ...
var following = xDestUser.Followings
.FirstOrDefault(f =>
f.DestId == xUser.Id &&
(
f.State == XFriendshipState.Pending ||
f.State == XFriendshipState.Rejected
)
);
var follower = xUser.Followers
.FirstOrDefault(f =>
f.DestId == xDestUser.Id &&
(
f.State == XFriendshipState.Pending ||
f.State == XFriendshipState.Rejected
)
);
if (following.IsNull() ||
follower.IsNull())
{
XException.NotAllowed.Throw();
}
//
follower.State = XFriendshipState.Accepted;
following.State = XFriendshipState.Accepted;
//
await UpdateUserAsync(xUser);
await UpdateUserAsync(xDestUser);
//
var result = follower;
//
return result;
}
/// <summary>
/// Reject a Follow Request of destUserSelectByParam
/// with userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
public async Task<XFriendshipFollower> RejectRequest(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
// Validate Request Sent and in Pending State ...
ValidateFollowingRequest(xUser, xDestUser);
//
// Retrieve Pending Specified User Request Friendship models ...
var following = xDestUser.Followings
.FirstOrDefault(f =>
f.DestId == xUser.Id &&
f.State == XFriendshipState.Pending);
var follower = xUser.Followers
.FirstOrDefault(f =>
f.DestId == xDestUser.Id &&
f.State == XFriendshipState.Pending);
if (following.IsNull() ||
follower.IsNull())
{
XException.NotFound.Throw();
}
//
follower.State = XFriendshipState.Rejected;
following.State = XFriendshipState.Rejected;
//
DbContext.Followers.Update(follower);
DbContext.Followings.Update(following);
//
await DbContext.SaveChangesAsync();
//
var result = follower;
//
return result;
}
#endregion
//
#region Getters ...
/// <summary>
/// determines destUserSelectByParam is in followers of
/// userSelectByParam or not
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsFollower(
string userSelectByParam,
string destUserSelectByParam,
bool checkIsBanned = true,
bool checkCanLoginPolicies = true
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
var result = IsFollowRequested(xDestUser, xUser, XFriendshipState.Accepted);
//
return result;
}
/// <summary>
/// retrieve Friendship state of destUserSelectByParam
/// in Followers of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <returns>a member of <see>XFriendshipState</see></returns>
public async Task<XFriendshipState> GetFollowerState(
string userSelectByParam,
string destUserSelectByParam,
bool checkIsBanned = true,
bool checkCanLoginPolicies = true
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
var isFollow = IsFollowRequested(xDestUser, xUser);
if (!isFollow)
{
return XFriendshipState.None;
}
//
var follower = xUser.Followers.FirstOrDefault(f => f.DestId == xDestUser.Id);
if (follower.IsNull())
{
XException.NotFound.Throw();
}
//
return follower.State;
}
/// <summary>
/// get follower friendship model of destUserSelectByParam
/// in followers of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
public async Task<XFriendshipFollower> GetFollower(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
var isFollow = IsFollowRequested(xDestUser, xUser);
if (!isFollow)
{
return null;
}
//
var follower = xUser.Followers
.FirstOrDefault(f => f.DestId == xDestUser.Id);
if (follower.IsNull())
{
XException.NotFound.Throw();
}
//
var result = follower;
//
return result;
}
/// <summary>
/// Retrieve Accepted Followers list of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <returns>a collection of <see>XFriendshipFollower</see> instances</returns>
public async Task<IEnumerable<XFriendshipFollower>> GetFollowers(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
var result = xUser.Followers
.Where(f => f.State == XFriendshipState.Accepted);
//
return result;
}
/// <summary>
/// Retrieve all Followers list of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <returns>a collection of <see>XFriendshipFollower</see> instances</returns>
public async Task<IEnumerable<XFriendshipFollower>> GetAllFollowers(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
var result = xUser.Followers;
//
return result;
}
/// <summary>
/// Read Specified User's Follower's List based on Query Model ...
/// </summary>
/// <param name="query"></param>
/// <param name="userSelectByParam"></param>
/// <returns></returns>
public async Task<XQueryResult<XFriendDto>> QueryFollowers(
XQuery query,
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotNull(query);
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: false,
containDetails: false,
ignoreDisabledUser: false,
checkCanLoginPolicies: false
);
//
// Prepare Query ...
//
if (query.PageSize < DataConfiguration
.PagingConfiguration
.MinAvailablePageSize)
{
//
query.PageSize = DataConfiguration
.PagingConfiguration
.DefaultPageSize;
}
//
if (query.PageSize > DataConfiguration
.PagingConfiguration
.MaxAvailablePageSize)
{
//
query.PageSize = DataConfiguration
.PagingConfiguration
.MaxAvailablePageSize;
}
//
// Prepare Enumerator ...
Expression<Func<XFriendshipFollower, bool>> whereClause = x => x.UserId == xUser.Id;
var enumerator = DbContext.Followers.AsAsyncEnumerable();
var resultItems = new List<XFriendDto>();
await foreach (var entity in enumerator)
{
//
var isApproved = whereClause.Compile()(entity);
if (isApproved)
{
//
// Convert Approved Entity to Dto ...
// then Validate it and Add it to Results ...
var dto = await ToDto(entity);
if (!dto.IsNull())
{
resultItems.Add(dto);
}
}
}
//
// Enumerable ...
var result = resultItems.AsEnumerable();
//
// Count Total Items ...
var totalItemsCount = result.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
result = result.ApplyFilter(query.Filter);
}
//
// Count Filtered Items ...
var totalFilteredItemsCount = result.Count();
//
// Apply Paging ...
if (totalItemsCount > 0 &&
totalFilteredItemsCount > 0)
{
//
// Apply Sorting ...
if (!query.SortBy.IsNullOrEmpty())
{
//
// Since Sorting Based on Date is Very Important ...
// we have to do Sorting at first Time then
// try to apply Paging ...
result = result
.ApplySorting(
query.SortBy,
query.IsAscending)
.ToList();
}
//
// Apply Paging ...
result = result
.ApplyPaging(
query.Page,
query.PageSize)
.ToList();
}
//
// Calculating Page Count ...
int pagesCount = totalItemsCount / query.PageSize;
if (totalItemsCount % query.PageSize > 0)
{
pagesCount++;
}
//
// Generate Result Object ...
var queryResult = new XQueryResult<XFriendDto>
{
Page = query.Page,
TotalPages = pagesCount,
PageSize = query.PageSize,
TotalItems = totalItemsCount,
Items = result.AsEnumerable(),
TotalFilteredItems = totalFilteredItemsCount
};
//
return queryResult;
}
/// <summary>
/// determines destUserSelectByParam is in followings of
/// userSelectByParam or not
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsFollowing(
string userSelectByParam,
string destUserSelectByParam,
bool checkIsBanned = true,
bool checkCanLoginPolicies = true
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
var result = IsFollowRequested(xUser, xDestUser, XFriendshipState.Accepted);
//
return result;
}
/// <summary>
/// retrieve Frindship State of destUserSelectByParam
/// in Followings of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <returns>a member of <see>XFriendshipState</see></returns>
public async Task<XFriendshipState> GetFollowingState(
string userSelectByParam,
string destUserSelectByParam,
bool checkIsBanned = true,
bool checkCanLoginPolicies = true
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
var isFollow = IsFollowRequested(xUser, xDestUser);
if (!isFollow)
{
return XFriendshipState.None;
}
//
var following = xUser.Followings.FirstOrDefault(f => f.DestId == xDestUser.Id);
if (following.IsNull())
{
XException.NotFound.Throw();
}
//
return following.State;
}
/// <summary>
/// get following friendship model of destUserSelectByParam
/// in followings of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
public async Task<XFriendshipFollowing> GetFollowing(
string userSelectByParam,
string destUserSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
// Validate Not Same Source and Dest Users ...
ValidateNotSameUsers(xUser, xDestUser);
//
var isFollow = IsFollowRequested(xUser, xDestUser);
if (!isFollow)
{
return null;
}
//
var following = xUser.Followings.FirstOrDefault(f => f.DestId == xDestUser.Id);
if (following.IsNull())
{
XException.NotFound.Throw();
}
//
var result = following;
//
return result;
}
/// <summary>
/// Retrieve accepted Followings List of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <returns>a collection of <see>XFriendshipFollowing</see> instances</returns>
public async Task<IEnumerable<XFriendshipFollowing>> GetFollowings(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
var result = xUser.Followings
.Where(f => f.State == XFriendshipState.Accepted);
//
return result;
}
/// <summary>
/// Retrieve all Followings List of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <returns>a collection of <see>XFriendshipFollowing</see> instances</returns>
public async Task<IEnumerable<XFriendshipFollowing>> GetAllFollowings(string userSelectByParam)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: true,
containDetails: true,
ignoreDisabledUser: false,
checkCanLoginPolicies: true
);
//
var result = xUser.Followings;
//
return result;
}
/// <summary>
/// Read Specified User's Following's List based on Query Model ...
/// </summary>
/// <param name="query"></param>
/// <param name="userSelectByParam"></param>
/// <returns></returns>
public async Task<XQueryResult<XFriendDto>> QueryFollowings(
XQuery query,
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotNull(query);
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate and Retrieve User ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
checkIsBanned: false,
containDetails: false,
ignoreDisabledUser: false,
checkCanLoginPolicies: false
);
//
// Prepare Query ...
//
if (query.PageSize < DataConfiguration
.PagingConfiguration
.MinAvailablePageSize)
{
//
query.PageSize = DataConfiguration
.PagingConfiguration
.DefaultPageSize;
}
//
if (query.PageSize > DataConfiguration
.PagingConfiguration
.MaxAvailablePageSize)
{
//
query.PageSize = DataConfiguration
.PagingConfiguration
.MaxAvailablePageSize;
}
//
// Prepare Enumerator ...
Expression<Func<XFriendshipFollowing, bool>> whereClause = x => x.UserId == xUser.Id;
var enumerator = DbContext.Followings.AsAsyncEnumerable();
var resultItems = new List<XFriendDto>();
await foreach (var entity in enumerator)
{
//
var isApproved = whereClause.Compile()(entity);
if (isApproved)
{
//
// Convert Approved Entity to Dto ...
// then Validate it and Add it to Results ...
var dto = await ToDto(entity);
if (!dto.IsNull())
{
resultItems.Add(dto);
}
}
}
//
// Enumerable ...
var result = resultItems.AsEnumerable();
//
// Count Total Items ...
var totalItemsCount = result.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
result = result.ApplyFilter(query.Filter);
}
//
// Count Filtered Items ...
var totalFilteredItemsCount = result.Count();
//
// Apply Paging ...
if (totalItemsCount > 0 &&
totalFilteredItemsCount > 0)
{
//
// Apply Sorting ...
if (!query.SortBy.IsNullOrEmpty())
{
//
// Since Sorting Based on Date is Very Important ...
// we have to do Sorting at first Time then
// try to apply Paging ...
result = result
.ApplySorting(
query.SortBy,
query.IsAscending)
.ToList();
}
//
// Apply Paging ...
result = result
.ApplyPaging(
query.Page,
query.PageSize)
.ToList();
}
//
// Calculating Page Count ...
int pagesCount = totalItemsCount / query.PageSize;
if (totalItemsCount % query.PageSize > 0)
{
pagesCount++;
}
//
// Generate Result Object ...
var queryResult = new XQueryResult<XFriendDto>
{
Page = query.Page,
TotalPages = pagesCount,
PageSize = query.PageSize,
TotalItems = totalItemsCount,
Items = result.AsEnumerable(),
TotalFilteredItems = totalFilteredItemsCount
};
//
return queryResult;
}
#endregion
//
#region Others ...
/// <summary>
/// Retrieve List Of All Followings User Id's
/// of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <returns>a collection of user identifiers</returns>
public async Task<ICollection<string>> GetFollowingList(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate and Retrieve followings List ...
var followings = await GetFollowings(userSelectByParam);
//
var result = followings.Select(f => f.DestId);
//
return result.ToList();
}
/// <summary>
/// Retrieve List Of All Followers User Id's
/// of userSelectByParam
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <returns>a collection of user identifiers</returns>
public async Task<ICollection<string>> GetFollowersList(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
// Validate and Retrieve followings List ...
var followers = await GetFollowers(userSelectByParam);
//
var result = followers.Select(f => f.DestId);
//
return result.ToList();
}
/// <summary>
/// retrieve Friendship Info Model for Specific User
/// </summary>
/// <param name="userSelectByParam">caller user identifier</param>
/// <param name="destUserSelectByParam">dest user identifier</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <returns>an instance of <see>XFriendshipInfoDto</see></returns>
public async Task<XFriendshipInfoDto> GetFriendshipInfo(
string userSelectByParam,
string destUserSelectByParam,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
destUserSelectByParam
);
//
// Validate and Retrieve Dest User ...
var xSourceUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
// Validate and Retrieve Dest User ...
var xDestUser = await ValidateUserExistsAndRetrieve(
destUserSelectByParam,
forceAdmin: false,
containDetails: true,
ignoreDisabledUser: false,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
var isSame = xSourceUser.Id == xDestUser.Id;
var isFollower = false;
var isFollowing = false;
var followerState = XFriendshipState.None;
var followingState = XFriendshipState.None;
//
if (!isSame)
{
//
isFollower = await IsFollower(
userSelectByParam,
destUserSelectByParam,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
isFollowing = await IsFollowing(
userSelectByParam,
destUserSelectByParam,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
followerState = await GetFollowerState(
userSelectByParam,
destUserSelectByParam,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
followingState = await GetFollowingState(
userSelectByParam,
destUserSelectByParam,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
}
//
var result = new XFriendshipInfoDto
{
UserId = xDestUser.Id,
IsFollower = isFollower,
IsFollowing = isFollowing,
FollowerState = followerState,
FollowingState = followingState,
Followers = xDestUser.Followers
.Count(f => f.State == XFriendshipState.Accepted),
Followings = xDestUser.Followings
.Count(f => f.State == XFriendshipState.Accepted)
};
//
return result;
}
#endregion
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Identity.cs
using System;
using System.Net.Http;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xExceptions.Constants;
using xExceptions.Models;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIds.Extensions;
using static IdentityModel.OidcConstants;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Identity Actions ...
/// <summary>
/// Request for Discovery Document
/// </summary>
/// <returns>an instance of <see>DiscoveryDocumentResponse</see></returns>
public async Task<DiscoveryDocumentResponse> RequestDiscoveryDocument()
{
//
var httpClient = GetHttpClient();
var result = httpClient
.GetDiscoveryDocumentAsync(IdentityResourceConfiguration.Authority)
.ContinueWith(docTask =>
{
//
httpClient.Dispose();
return docTask.Result;
});
//
return await result;
}
/// <summary>
/// Request AccessToken for Specific XApiScope
/// </summary>
/// <param name="scope">a member of <see>XApiScope</see></param>
/// <returns>an instance of <see>TokenResponse</see></returns>
public async Task<IdentityModel.Client.TokenResponse> RequestScopeAccessToken(
string scope
)
{
//
// Validate Args ...
if (scope.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
// Retrieve Disco Doc ...
var discoDoc = await RequestDiscoveryDocument();
if (discoDoc.IsError)
{
XException.ActionFailed.Throw();
}
//
var request = new ClientCredentialsTokenRequest
{
Address = discoDoc.TokenEndpoint,
GrantType = GrantTypes.ClientCredentials,
ClientId = IdentityResourceConfiguration.ClientId,
ClientSecret = IdentityResourceConfiguration.ClientSecret,
Scope = scope
};
//
var httpClient = GetHttpClient();
var result = await httpClient
.RequestClientCredentialsTokenAsync(request)
.ContinueWith(response =>
{
//
httpClient.Dispose();
return response.Result;
});
//
return result;
}
/// <summary>
/// Authenticate a User
/// </summary>
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
/// <returns>an instance of <see>TokenResponse</see></returns>
public async Task<IdentityModel.Client.TokenResponse> Authenticate(
XLoginRequest model
)
{
//
// Validate Args ...
ValidationProvider
.GroupValidationBuilder()
.AddNotNull(model)
.AddNotEmpty(
model.UserSelectBy,
model.Password
)
.ValidateGroup();
//
// Retrieve Disco Doc ...
var discoDoc = await RequestDiscoveryDocument();
if (discoDoc.IsError)
{
XException.ActionFailed.Throw();
}
//
// Create Request ...
var request = new PasswordTokenRequest
{
//
Address = discoDoc.TokenEndpoint,
//
GrantType = GrantTypes.ClientCredentials,
ClientId = IdentityResourceConfiguration.ClientId,
ClientSecret = IdentityResourceConfiguration.ClientSecret,
//
UserName = model.UserSelectBy,
Password = model.Password,
//
// Pass Device to Request ...
Parameters = { { "force", false.ToJSON () }
}
};
//
var httpClient = GetHttpClient();
var result = await httpClient
.RequestPasswordTokenAsync(request)
.ContinueWith(response =>
{
//
httpClient.Dispose();
return response.Result;
});
//
return result;
}
/// <summary>
/// Do Login based on XLoginRequest
/// </summary>
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
/// <returns>an instance of <see>XLoginResponse</see></returns>
public async Task<XLoginResponse> Login(
XLoginRequest model
)
{
//
// Validate Args ...
ValidationProvider
.GroupValidationBuilder()
.AddNotNull(model, model.Device)
.AddNotEmpty(
model.UserSelectBy,
model.Password
)
.ValidateGroup();
//
// Get Token Response ...
//
// Retrieve Disco Doc ...
var discoDoc = await RequestDiscoveryDocument();
Logger.LogInformation($"discoDoc: {discoDoc.ToJSON()}");
if (discoDoc.IsError)
{
XException.ActionFailed.Throw();
}
//
// Create Request ...
var request = new PasswordTokenRequest
{
//
Address = discoDoc.TokenEndpoint,
//
GrantType = GrantTypes.ClientCredentials,
ClientId = IdentityResourceConfiguration.ClientId,
ClientSecret = IdentityResourceConfiguration.ClientSecret,
//
UserName = model.UserSelectBy,
Password = model.Password,
//
// Pass Device to Request ...
Parameters = { { "force", false.ToJSON () },
{ "device", model.Device.ToJSON () },
{ "language", model.Language }
}
};
//
var httpClient = GetHttpClient();
var authResponse = await httpClient
.RequestPasswordTokenAsync(request)
.ContinueWith(response =>
{
//
httpClient.Dispose();
return response.Result;
});
//
// Check If Response Has Error ...
Logger.LogInformation($"AuthResponse: {authResponse.ToJSON()}");
//
if (authResponse.IsError)
{
throw authResponse.GetException();
}
//
// Create XLoginResponse Model ...
var result = authResponse.CreateXLoginResponse();
//
// Get ans Set User Profile ...
result.Profile = await GetUserProfileAsync(model.UserSelectBy, model.UserSelectBy);
//
return result;
}
/// <summary>
/// Refresh Tokens
/// </summary>
/// <param name="model">Authentication Tokens, instance of <see>XTokenResponse</see></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 authResponse = await RequestDiscoveryDocument()
.ContinueWith((discoTask) =>
{
//
var discoDoc = discoTask.Result;
if (discoDoc.IsError)
{
XException.ActionFailed.Throw();
}
//
using (var httpClient = GetHttpClient())
{
return httpClient.RequestRefreshTokenAsync(new RefreshTokenRequest
{
//
Address = discoDoc.TokenEndpoint,
GrantType = GrantTypes.RefreshToken,
ClientId = IdentityResourceConfiguration.ClientId,
ClientSecret = IdentityResourceConfiguration.ClientSecret,
RefreshToken = model.RefreshToken
}).Result;
}
});
//
// Check If Response Has Error ...
if (authResponse.IsError)
{
//
XError error = authResponse.ErrorDescription.FromJSON<XError>();
throw error.ToException();
}
//
// Create XLoginResponse Model ...
var result = authResponse.CreateXTokenResponse();
//
return result;
}
#endregion
//
#region Requirements ...
/// <summary>
/// Get an Instance of Http Client
/// </summary>
/// <returns>an instance of <see>HttpClient</see></returns>
public HttpClient GetHttpClient()
{
//
HttpClient httpClient = null;
httpClient = new HttpClient();
var httpClientHandler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
//
Logger.LogInformation(
$"SSL 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);
//
return httpClient;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+MessageProvider.cs
using System;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Navigations;
using xMessageService.Models;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Message Provider ...
/// <summary>
/// Generate and Prepare an XMessage Instance for
/// User Invite Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="emailAddress">reciever email address</param>
/// <param name="inviteToken">invitation token</param>
/// <param name="returnUrl">return url for invitation user to redirect</param>
/// <returns>an instance of <see>XMessage</see></returns>
private XMessage GetUserInviteMessage(
string lang,
string emailAddress,
string inviteToken,
string returnUrl
)
{
//
ValidationProvider
.NotEmpty(lang, emailAddress, inviteToken, returnUrl);
ValidationProvider
.EmailAddress(emailAddress);
ValidationProvider
.Url(returnUrl);
//
HandleMessageProviderPreperation(lang);
//
var msgStr = IdentityMessageProvider.InviteMsg +
Environment.NewLine +
returnUrl +
"?t=" +
inviteToken;
//
var message = new XMessage
{
Message = msgStr,
};
message.Recievers.Add(emailAddress);
//
return message;
}
/// <summary>
/// Generate and Prepare an XMessage Instance for
/// New Device LoggedIn Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="emailAddress">reciever email address</param>
/// <param name="device">an instance of <see>XDevice</see> which represent user new Device</param>
/// <returns>an instance of <see>XMessage</see></returns>
private XMessage GetUserNewDeviceLoggedInMessage(
string lang,
string emailAddress,
XDevice device
)
{
//
ValidationProvider
.NotEmpty(lang, emailAddress);
ValidationProvider
.EmailAddress(emailAddress);
ValidationProvider
.NotNull(device);
//
HandleMessageProviderPreperation(lang);
//
// Generate Specific Message ...
var msgStr = IdentityMessageProvider.NewDeviceLoggedInMsg +
Environment.NewLine +
nameof(XDevice.Os) + ": " + device.Os +
Environment.NewLine +
nameof(XDevice.OsVersion) + ": " + device.OsVersion +
Environment.NewLine +
nameof(XDevice.Browser) + ": " + device.Browser +
Environment.NewLine +
nameof(XDevice.UserAgent) + ": " + device.UserAgent;
//
// Create XMessage Instance ...
var message = new XMessage
{
Message = msgStr,
};
message.Recievers.Add(emailAddress);
//
return message;
}
/// <summary>
/// Generate and Prepare an XMessage Instance for
/// Verification Code Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="mobileNumberOrEmail">an string which points to a user email address or mobile number</param>
/// <param name="verificationCode">user verification code</param>
/// <returns>an instance of <see>XMessage</see></returns>
private XMessage GetVerificationCodeMessage(
string lang,
string mobileNumberOrEmail,
string verificationCode
)
{
//
ValidationProvider
.NotEmpty(lang, mobileNumberOrEmail, verificationCode);
//
HandleMessageProviderPreperation(lang);
//
mobileNumberOrEmail = mobileNumberOrEmail.ToNormalString();
//
// Validate Mobile or Email ...
var isValidEmail = mobileNumberOrEmail.IsValidEmail();
var isValidMobileNumber = mobileNumberOrEmail.IsValidMobileNumber();
if (!isValidEmail &&
!isValidMobileNumber)
{
XException.InvalidData.Throw();
}
//
// Prepare Message String ...
var msgStr = IdentityMessageProvider.VerificationCodeMsg +
Environment.NewLine +
verificationCode;
//
// Create XMessage Instance ...
var message = new XMessage
{
Message = msgStr,
};
message.Recievers.Add(mobileNumberOrEmail);
//
return message;
}
/// <summary>
/// Generate and Prepare an XMessage Instance for
/// Registration Approve Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="emailAddress">reciever email address</param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="returnUrl">return url for redirect</param>
/// <returns>an instance of <see>XMessage</see></returns>
private XMessage GetRegistrationConfirmMessage(
string lang,
string emailAddress,
string actionToken,
string returnUrl
)
{
//
ValidationProvider
.NotEmpty(lang, emailAddress, actionToken, returnUrl);
ValidationProvider
.EmailAddress(emailAddress);
ValidationProvider
.Url(returnUrl);
//
HandleMessageProviderPreperation(lang);
//
// Prepare Message Str ...
var msgStr = IdentityMessageProvider.RegistrationApproveMsg +
Environment.NewLine +
returnUrl +
"?t=" +
actionToken;
//
var message = new XMessage
{
Message = msgStr,
};
message.Recievers.Add(emailAddress);
//
return message;
}
/// <summary>
/// Generate and Prepare an XMessage Instance for
/// Registration Finished Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="emailAddress">reciever email address</param>
/// <param name="returnUrl">return url for redirect</param>
/// <returns>an instance of <see>XMessage</see></returns>
private XMessage GetRegistrationFinishedMessage(
string lang,
string emailAddress,
string returnUrl
)
{
//
ValidationProvider
.NotEmpty(lang, emailAddress, returnUrl);
ValidationProvider
.EmailAddress(emailAddress);
ValidationProvider
.Url(returnUrl);
//
HandleMessageProviderPreperation(lang);
//
var msgStr = IdentityMessageProvider.RegisteredMsg +
Environment.NewLine +
returnUrl;
//
var message = new XMessage
{
Message = msgStr,
};
message.Recievers.Add(emailAddress);
//
return message;
}
/// <summary>
/// Generate and Prepare an XMessage Instance for
/// Password Changed Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="emailAddress">reciever email address</param>
/// <param name="returnUrl">return url for redirect</param>
/// <param name="throwException">specify throw exceptions on failure or not, default is true</param>
/// <returns>an instance of <see>XMessage</see></returns>
private XMessage GetPasswordChangedMessage(
string lang,
string emailAddress,
string returnUrl,
bool throwException = true
)
{
//
if (throwException)
{
ValidationProvider
.NotEmpty(lang, emailAddress, returnUrl);
ValidationProvider
.EmailAddress(emailAddress);
ValidationProvider
.Url(returnUrl);
}
//
HandleMessageProviderPreperation(lang);
//
var msgStr = IdentityMessageProvider.PasswordChangedMsg +
(returnUrl.IsNullOrEmpty() ?
"" :
Environment.NewLine +
returnUrl);
//
var message = new XMessage
{
Message = msgStr,
};
message.Recievers.Add(emailAddress);
//
return message;
}
/// <summary>
/// Generate and Prepare an XMessage Instance for
/// Reset Password Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="emailAddress">reciever email address</param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="returnUrl">return url for redirect</param>
/// <returns>an instance of <see>XMessage</see></returns>
private XMessage GetResetPasswordMessage(
string lang,
string emailAddress,
string actionToken,
string returnUrl
)
{
//
ValidationProvider
.NotEmpty(lang, emailAddress, actionToken, returnUrl);
ValidationProvider
.EmailAddress(emailAddress);
ValidationProvider
.Url(returnUrl);
//
HandleMessageProviderPreperation(lang);
//
// Prepare Message Str ...
var msgStr = IdentityMessageProvider.ChangePasswordMsg +
Environment.NewLine +
returnUrl +
"?t=" +
actionToken;
//
var message = new XMessage
{
Message = msgStr,
};
message.Recievers.Add(emailAddress);
//
return message;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Open.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Dtos;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region OpenGet ...
public async Task<XOpenActionInnerDto> OpenGet(
XOpenActionInnerDto model
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(model)
.AddNotEmpty(model.Token)
.AddNotEmpty(model.Payload)
.ValidateGroupAsync();
//
return await OpenGet(
token: model.Token,
actionRequest: model.Payload
);
}
//
public async Task<XOpenActionInnerDto> OpenGet(
string token,
string actionRequest
)
{
//
// Validatr Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(token)
.AddNotEmpty(actionRequest)
.ValidateGroupAsync();
//
// Try to Decrypt Request ...
var requestModel = ParseModel(
token: token,
request: actionRequest
);
if (requestModel.IsNull() ||
requestModel.Action.IsNullOrEmpty())
{
XException.BadRequest.Throw();
}
//
var responseJson = string.Empty;
switch (requestModel.Action)
{
//
case XOpenActions.GetUserInfo:
//
ValidationProvider.NotEmpty(requestModel.Payload);
var userInfo = await GetUserInfo(requestModel);
if (userInfo.IsNull())
{
XException.InvalidData.Throw();
}
//
responseJson = userInfo.ToJSON();
break;
//
case XOpenActions.GetUserInfos:
ValidationProvider.NotEmpty(requestModel.Payload);
var userInfos = await GetUserInfos(requestModel);
if (userInfos.IsNull())
{
XException.InvalidData.Throw();
}
//
responseJson = userInfos.ToJSON();
break;
}
//
// Encrypt Json Str ...
var responseStr = SecurityProvider.Encrypt(responseJson);
requestModel.Payload = responseStr;
requestModel.Timestamp = DateTime.UtcNow
.AddMinutes(5)
.ToTimestamp()
.ToString();
//
token = requestModel.ToOpenActionToken();
requestModel.Checksum = token;
var result = new XOpenActionInnerDto
{
Token = token,
Payload = requestModel.ToJSON()
};
//
// Check Result ...
if (result.IsNull())
{
XException.ActionFailed.Throw();
}
//
return result;
}
#endregion
public async Task<XOpenActionUserInfoDto> GetUserInfo(
XOpenActionRequestDto model
)
{
//
// Retrieve User Profile ...
var userProfile = await GetUserProfileAsync(
checkIsBanned: false,
checkCanLoginPolicies: false,
requestedUserSelectByParam: "",
forceCheckRequestedUser: false,
userSelectByParam: model.Payload
);
//
// Generate a Dynamic Object ...
var result = new XOpenActionUserInfoDto
{
Username = userProfile.UserName,
Firstname = userProfile.FirstName,
Lastname = userProfile.LastName,
Avatar = userProfile.Avatar
};
//
return result;
}
public async Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
XOpenActionRequestDto model
)
{
//
var ids = model.Payload.ParseListString<string>().ToList();
var profiles = await GetUserProfilesAsync(
ids: ids,
checkIsBanned: false,
checkCanLoginPolicies: false,
requestedUserSelectByParam: "",
forceCheckRequestedUser: false
);
var result = profiles.Select(x => new XOpenActionUserInfoDto
{
Avatar = x.Avatar,
Username = x.UserName,
Lastname = x.LastName,
Firstname = x.FirstName,
});
//
return result;
}
//
#region Private ...
private XOpenActionRequestDto ParseModel(
string token,
string request
)
{
//
// Decript request to get Json string of request object ...
var result = new XOpenActionRequestDto();
//
var jsonStr = SecurityProvider.Decrypt(request);
result = jsonStr.FromJSON<XOpenActionRequestDto>();
if (result.IsNull() ||
!result.Validate() ||
token != result.Checksum
)
{
//
result = null;
return result;
}
//
var modelChecksum = result.ToOpenActionToken();
result =
token == modelChecksum
? result
: null;
//
return result;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Private.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using xCommons.Extensions;
using xCommons.Helpers;
using xExceptions.Constants;
using xIdentityModels;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Generators ...
/// <summary>
/// Generate a Random Number ...
/// </summary>
/// <returns>a long value</returns>
private long GenerateRandom()
{
return new Random().Next(100000, 999999);
}
#endregion
//
#region UserSelectBy Actions ...
/// <summary>
/// Retrieve UserSelectByType based on Given Info
/// </summary>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="forceUserSelectByParamNotEmpty">a boolean value which specify the identifier
/// must be specific and not empty, default is true</param>
/// <param name="forceUserSelectByTypeMustSpecified">a boolean value which specify the type
/// must be specific, default is false</param>
/// <returns>a member of <see>XUserSelectBy</see></returns>
private XUserSelectBy GetUserSelectByType(
string userSelectByParam,
bool forceUserSelectByParamNotEmpty = true,
bool forceUserSelectByTypeMustSpecified = false
)
{
//
if (forceUserSelectByParamNotEmpty)
{
ValidationProvider.NotEmpty(userSelectByParam);
}
//
var result = XUserSelectBy.NotSpecified;
var normalizedString = userSelectByParam.ToNormalString();
if (userSelectByParam.IsValidEmail())
{
//
// Find User by Email ...
result = XUserSelectBy.Email;
}
else if (userSelectByParam.IsValidMobileNumber())
{
//
// Find User by Mobile Number ...
result = XUserSelectBy.MobileNumber;
}
else if (userSelectByParam.IsGuid())
{
//
// Find User By it's ID ...
result = XUserSelectBy.ID;
}
else
{
//
// UserName ...
result = XUserSelectBy.Username;
}
//
if (forceUserSelectByTypeMustSpecified &&
result == XUserSelectBy.NotSpecified)
{
XException.InvalidData.Throw();
}
//
return result;
}
/// <summary>
/// Retrieve UserSelectByParam based on XUser Object
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
/// and throw exception if it is empty, default is true</param>
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
/// exclude them from result, default is null</param>
/// <returns>a user identifier</returns>
private string GetUserSelectByParam(
XUser user,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(user);
//
var id = user.Id;
var userName = user.UserName;
var email = user.Email;
var phoneNumber = user.PhoneNumber;
//
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>
/// Retrieve UserSelectByParam based on <see>XActionRequestContext</see> instance
/// </summary>
/// <param name="context">an instance of <see>XActionRequestContext</see></param>
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
/// and throw exception if it is empty, default is true</param>
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
/// exclude them from result, default is null</param>
/// <returns>a user identifier</returns>
private string GetUserSelectByParam(
XActionRequestContext context,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(context);
//
// Generate User SelectBy ...
var id = context.UserId;
var userName = context.UserName;
var email = context.Email;
var phoneNumber = context.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 param ...
if (forceNotNull &&
selectByParam.IsNullOrEmpty())
{
XException.InvalidData.Throw();
}
//
return selectByParam;
}
/// <summary>
/// Retrieve UserSelectByParam based on <see>XActionRequestToken</see> instance
/// </summary>
/// <param name="request">an instance of <see>XActionRequestToken</see> which
/// provides required informations</param>
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
/// and throw exception if it is empty, default is true</param>
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
/// exclude them from result, default is null</param>
/// <returns>a user identifier</returns>
private string GetUserSelectByParam(
XActionRequestToken request,
bool forceNotNull = true,
ICollection<XUserSelectBy> excludes = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(request);
//
// Generate User SelectBy ...
return GetUserSelectByParam(
context: request.Context,
forceNotNull: forceNotNull,
excludes: excludes
);
}
/// <summary>
/// Retrieve Available UserSelectByParams from given XUser
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <returns></returns>
private ICollection<string> GenerateUserSelectByParams(
XUser user
)
{
//
if (user == null)
{
return null;
}
//
var result = new List<string> {
user.Id,
user.UserName,
user.PhoneNumber,
user.Email,
};
//
return result;
}
/// <summary>
/// Retrieve Required XUserSelectByTypes
/// </summary>
/// <param name="ignores">a collection of <see>XUserSelectBy</see> members which
/// ignored in result</param>
/// <returns>a collection of available <see>XUserSelectBy</see> members</returns>
private ICollection<XUserSelectBy> GenerateUserSelectByExcludes(
ICollection<XUserSelectBy> ignores
)
{
//
var result = ObjectHelper
.ToEnumerableValues<XUserSelectBy>()
.Except(ignores);
//
return result.ToList();
}
#endregion
//
#region XAction Actions ...
/// <summary>
/// Retrieve Action Result Response based on XToken
/// </summary>
/// <param name="xToken">an instance of <see>XToken</see></param>
/// <returns>an instance of <see>XActionResponse</see></returns>
private XActionResponse GetActionResultResponse(
XToken xToken
)
{
//
ValidationProvider.NotNull(xToken);
ValidationProvider.NotEmpty(xToken.Hash, xToken.Token);
//
ValidateToken(xToken.Token);
//
var expDate = GetTokenExpirationDate(xToken.Token);
ValidationProvider.NotNull(expDate);
//
// Generate Result class ...
var result = new XActionResponse
{
Token = xToken.Hash,
Expiration = expDate
};
//
return result;
}
#endregion
//
#region XIdentityMessage Actions ...
/// <summary>
/// Prepare Message Provider and Check it's State
/// </summary>
/// <param name="lang">specify destination language</param>
private void HandleMessageProviderPreperation(
string lang
)
{
//
ValidationProvider
.NotEmpty(lang);
//
// Prepare Identity Messages ...
// the PrepareMessageMethod check IsReady of Helper automatically ...
IdentityMessageProvider.PrepareMessages(lang);
//
// Check Message Provider ...
var isMessageProviderReady = MessageProvider.IsReady(true);
if (!isMessageProviderReady)
{
XException.MessageServiceInitialFailed.Throw();
}
}
#endregion
//
#region Friendship Actions ...
/// <summary>
/// Check Follow Request Sent Before
/// from dest to source
/// </summary>
/// <param name="source">an instance of <see>XUser</see></param>
/// <param name="dest">an instance of <see>XUser</see></param>
/// <returns>a boolean value</returns>
private bool IsFollowRequested(
XUser source,
XUser dest
)
{
//
// Validate Args ...
ValidationProvider.NotNull(source, dest);
//
var result = source.Followings.Any(f => f.DestId == dest.Id);
//
return result;
}
/// <summary>
/// Check Follow Request Sent Before
/// from dest to source
/// </summary>
/// <param name="source">an instance of <see>XUser</see></param>
/// <param name="dest">an instance of <see>XUser</see></param>
/// <param name="state">a member of <see>XFriendshipState</see></param>
/// <returns>a boolean value</returns>
private bool IsFollowRequested(
XUser source,
XUser dest,
XFriendshipState state
)
{
//
// Validate Args ...
ValidationProvider.NotNull(source, dest);
//
var result = source.Followings
.Any(f =>
f.DestId == dest.Id &&
f.State == state);
//
return result;
}
/// <summary>
/// Converts to XFriendDto ...
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
private async Task<XFriendDto> ToDto(XFriendshipFollower entity)
{
//
XFriendDto result = null;
//
if (entity.IsNull())
{
return result;
}
//
// Reading Dest User Profile ...
var profile = await GetUserProfileAsync(
userSelectByParam: entity.DestId,
requestedUserSelectByParam: entity.UserId,
forceCheckRequestedUser: false,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
// Preparing Result ...
result = new XFriendDto
{
UserId = profile.UserId,
Avatar = profile.Avatar,
Username = profile.UserName,
Lastname = profile.LastName,
Firstname = profile.FirstName,
Type = XFriendshipType.Follower,
State = profile.FriendshipInfo.FollowerState,
};
//
return result;
}
/// <summary>
/// Converts to XFriendDto ...
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
private async Task<XFriendDto> ToDto(XFriendshipFollowing entity)
{
//
XFriendDto result = null;
//
if (entity.IsNull())
{
return result;
}
//
// Reading Dest User Profile ...
var profile = await GetUserProfileAsync(
checkIsBanned: false,
checkCanLoginPolicies: false,
forceCheckRequestedUser: false,
userSelectByParam: entity.DestId,
requestedUserSelectByParam: entity.UserId
);
//
// Preparing Result ...
result = new XFriendDto
{
UserId = profile.UserId,
Avatar = profile.Avatar,
Username = profile.UserName,
Lastname = profile.LastName,
Firstname = profile.FirstName,
Type = XFriendshipType.Following,
State = profile.FriendshipInfo.FollowingState,
};
//
return result;
}
#endregion
//
#region User Profile ...
/// <summary>
/// Count User's Page
/// </summary>
/// <param name="pageSize">an integer value which represent page size</param>
/// <returns>an inetger value which represent pages count</returns>
public async Task<int> UserPagesCount(
int pageSize
)
{
//
int count = await UserManager.Users.CountAsync();
int pagesCount = count / pageSize;
//
if (count % pageSize > 0)
{
pagesCount++;
}
//
return pagesCount;
}
/// <summary>
/// Count Avatar's Page
/// </summary>
/// <param name="pageSize">an integer value which represent page size</param>
/// <returns>an inetger value which represent pages count</returns>
public async Task<int> ProfileImagePagesCount(
int pageSize
)
{
//
int count = await DbContext.Avatars.CountAsync();
int pagesCount = count / pageSize;
//
if (count % pageSize > 0)
{
pagesCount++;
}
//
return pagesCount;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Profile.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
using xModels.Dtos;
using xIds.Extensions;
using xIdentityModels.Extensions;
using xIdentityHelper;
using xIdentityHelper.Extensions;
using xDataService.Extensions;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Retrieve Actions ...
/// <summary>
/// Retrieve User Profile
/// </summary>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
/// <param name="forceCheckRequestedUser">specify check requested user's identifier not empty
/// and throw exception if it is, default true</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> GetUserProfileAsync(
string userSelectByParam,
string requestedUserSelectByParam,
bool forceCheckRequestedUser = true,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Data Validation ...
if (forceCheckRequestedUser)
{
ValidationProvider.NotEmpty(
userSelectByParam,
requestedUserSelectByParam);
}
else
{
ValidationProvider.NotEmpty(userSelectByParam);
}
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
var isAdmin = false;
var isSameUser = false;
if (forceCheckRequestedUser &&
!requestedUserSelectByParam.IsNullOrEmpty())
{
//
var xRequestedUser = await ValidateUserExistsAndRetrieve(
requestedUserSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
isSameUser = xUser.Id == xRequestedUser.Id;
//
var xRequestUserRoleNames = await GetRoleNamesAsync(
userSelectByParam: requestedUserSelectByParam,
checkCanLoginPolicies: false,
checkIsBanned: false
);
isAdmin = xRequestUserRoleNames.Contains(XUserRole.Admin.GetStringValue());
}
//
var roleNames = await GetRoleNamesAsync(
userSelectByParam,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
var xFriendshipInfo =
requestedUserSelectByParam.IsNullOrEmpty()
? null
: await GetFriendshipInfo(
requestedUserSelectByParam,
userSelectByParam,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies
);
//
var result = xUser.ToXProfileDto(
isAdmin: isAdmin,
roles: roleNames,
isSameUser: isSameUser,
friendship: xFriendshipInfo,
profileConfig: Configuration.Policy.Profile
);
//
return result;
}
/// <summary>
/// Retrieve a Collection of User Profiles
/// </summary>
/// <param name="ids">a collection of user identifiers</param>
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
/// <param name="forceCheckRequestedUser">specify check requested user's identifier not empty
/// and throw exception if it is, default true</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <returns>an collection of <see>XUserProfileDto</see> instances</returns>
public async Task<IEnumerable<XUserProfileDto>> GetUserProfilesAsync(
ICollection<string> ids,
string requestedUserSelectByParam,
bool forceCheckRequestedUser = true,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Data Validation ...
if (forceCheckRequestedUser)
{
ValidationProvider.NotEmpty(requestedUserSelectByParam);
}
ValidationProvider.NotZeroChilds(ids);
//
var result = new List<XUserProfileDto>();
foreach (var id in ids)
{
//
var xProfile = await GetUserProfileAsync(
id,
requestedUserSelectByParam,
checkIsBanned: checkIsBanned,
checkCanLoginPolicies: checkCanLoginPolicies,
forceCheckRequestedUser: forceCheckRequestedUser
);
result.Add(xProfile);
}
//
return result;
}
/// <summary>
/// Query User Profiles
/// </summary>
/// <param name="requestedUserSelectByParam">requested user's identifier</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(
string requestedUserSelectByParam,
XQuery query
)
{
//
// Validation ...
if (query.IsNull())
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
//
// Since in Resourceable Entities we have to Search on Locales
// we Must Implement Senario Custom ...
var totalEntities = GetUsersDbSet()
.ToList()
.Where(u => !u.ContainsUserSelectByParam(requestedUserSelectByParam))
.Select(u => u.Id)
.ToList();
//
var items = await GetUserProfilesAsync(
totalEntities,
requestedUserSelectByParam,
checkIsBanned: false,
checkCanLoginPolicies: false,
forceCheckRequestedUser: false
);
//
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter);
}
int filteredItemsCount = items.Count();
//
// Count Pages ...
var totalPagesCount = query.CountPages(totalItemsCount);
var filteredPagesCount = query.CountPages(filteredItemsCount);
//
// Apply Paging and Sorting ...
if (totalItemsCount > 0 &&
filteredItemsCount > 0)
{
//
// Apply Sorting ...
items = items
.ToList()
.ApplySorting(
query.SortBy,
query.IsAscending
);
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
);
}
//
// Generate Result Object ...
// Query = query,
var result = new XQueryResult<XUserProfileDto>
{
Items = items,
Page = query.Page,
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
/// <summary>
/// Query In Roles User Profiles
/// </summary>
/// <param name="requestedUserSelectByParam">requested user's identifier</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, default is false</param>
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
public async Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers(
string requestedUserSelectByParam,
string role,
XQuery query,
bool forceRole = false
)
{
//
// Validation ...
if (query.IsNull() || role.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
// Check Role Exists ...
var isExistsRole = await IsRoleExistsAsync(role);
if (!isExistsRole)
{
XException.NotFound.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
//
#region Select Users Based on Specific Roles ...
var selectedUsers = new List<string>();
var usersEnumerator = GetUsersDbSet(query.ContainsDetail).AsAsyncEnumerable();
await
foreach (var user in usersEnumerator)
{
//
if (user.ContainsUserSelectByParam(requestedUserSelectByParam))
{
continue;
}
//
// Set Default Value is True ...
var isInRole = false;
//
// if Force Role ...
if (forceRole)
{
isInRole = await UserManager.IsInRoleAsync(user, role);
}
else
{
//
// Select User Top Role ...
var userRoles = await GetRoleNamesAsync(
checkIsBanned: false,
userSelectByParam: user.Id,
checkCanLoginPolicies: false
);
isInRole = userRoles.HasRolePermissions(role);
}
//
if (isInRole)
{
selectedUsers.Add(user.Id);
}
}
#endregion
//
var items = await GetUserProfilesAsync(
selectedUsers,
requestedUserSelectByParam,
checkIsBanned: false,
checkCanLoginPolicies: false,
forceCheckRequestedUser: false
);
//
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter);
}
int filteredItemsCount = items.Count();
//
// Count Pages ...
var totalPagesCount = query.CountPages(totalItemsCount);
var filteredPagesCount = query.CountPages(filteredItemsCount);
//
// Apply Paging and Sorting ...
if (totalItemsCount > 0 &&
filteredItemsCount > 0)
{
//
// Apply Sorting ...
items = items
.ToList()
.ApplySorting(
query.SortBy,
query.IsAscending
);
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
);
}
//
// Generate Result Object ...
// Query = query,
var result = new XQueryResult<XUserProfileDto>
{
Items = items,
Page = query.Page,
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
/// <summary>
/// Query Specified User's Profile Images
/// </summary>
/// <param name="userSelectByParam">a user identifier</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(
string userSelectByParam,
XQuery query
)
{
//
// Validation ...
if (query.IsNull())
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: true,
checkIsBanned: true
);
//
var items = query.ContainsDetail ?
DbContext.Avatars
.Include(pf => pf.User)
.AsEnumerable() :
DbContext.Avatars
.AsEnumerable();
items = items
.Where(pfi => pfi.UserId == xUser.Id);
//
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter);
}
int filteredItemsCount = items.Count();
//
// Count Pages ...
var totalPagesCount = query.CountPages(totalItemsCount);
var filteredPagesCount = query.CountPages(filteredItemsCount);
//
// Apply Paging and Sorting ...
if (totalItemsCount > 0 &&
filteredItemsCount > 0)
{
//
// Apply Sorting ...
items = items
.ToList()
.ApplySorting(
query.SortBy,
query.IsAscending
);
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
);
}
//
// Generate Result Object ...
// Query = query,
var result = new XQueryResult<XProfileImage>
{
Items = items,
Page = query.Page,
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
/// <summary>
/// Check specific user Confirmed Email or not
/// </summary>
/// <param name="userSelectByParam">a user identifier</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsConfirmedEmail(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
return xUser.EmailConfirmed;
}
/// <summary>
/// Ceck specific user Confirmed Mobile or not
/// </summary>
/// <param name="userSelectByParam">a user identifier</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsConfirmedMobile(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
return xUser.PhoneNumberConfirmed;
}
#endregion
//
#region Update Actions ...
/// <summary>
/// Update User Profile (FirstName/LastName/DateOfBirth) ...
/// </summary>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="requestedUserSelectByParam">requested user's identifier</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(
string userSelectByParam,
string requestedUserSelectByParam,
XProfileUpdateRequest model
)
{
//
// Data Validation ...
ValidationProvider.NotEmpty(
userSelectByParam,
requestedUserSelectByParam);
ValidationProvider.NotNull(model);
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
var xRequestedUser = await ValidateUserExistsAndRetrieve(
requestedUserSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
await ValidateUserForDangerousAction(xUser, xRequestedUser);
//
// FirstName ...
if (!model.FirstName.IsNullOrEmpty())
{
xUser.FirstName = model.FirstName;
}
//
// Last Name ...
if (!model.LastName.IsNullOrEmpty())
{
xUser.LastName = model.LastName;
}
//
// Date of Birth ...
if (model.DateOfBirth.HasValue)
{
xUser.DateOfBirth = model.DateOfBirth.Value;
}
//
// Bio ...
xUser.Bio = model.Bio;
//
// Cover Image ...
xUser.CoverImage = model.CoverImage;
//
// Open To Search ...
xUser.OpenToSearch = model.OpenToSearch;
//
var updateResult = await UpdateUserAsync(xUser);
if (!updateResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
var result = await GetUserProfileAsync(userSelectByParam, requestedUserSelectByParam);
return result;
}
/// <summary>
/// Update User Profile
/// </summary>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="requestedUserSelectByParam">requested user's identifier</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(
string userSelectByParam,
string requestedUserSelectByParam,
XProfileUpdateRequest model
)
{
//
// Data Validation ...
ValidationProvider.NotEmpty(
userSelectByParam,
requestedUserSelectByParam);
ValidationProvider.NotNull(model);
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
var xRequestedUser = await ValidateUserExistsAndRetrieve(
requestedUserSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
await ValidateUserForDangerousAction(xUser, xRequestedUser);
//
#region Fill User with Models Value ...
//
// FirstName ...
xUser.FirstName = !model.FirstName.IsNullOrEmpty() ?
model.FirstName :
xUser.FirstName;
//
// LastName ...
xUser.LastName = !model.LastName.IsNullOrEmpty() ?
model.LastName :
xUser.LastName;
//
// Email ...
xUser.Email = !model.Email.IsNullOrEmpty() ?
model.Email :
xUser.Email;
//
// EmailConfirmed ...
if (model.EmailConfirmed.HasValue)
{
xUser.EmailConfirmed = model.EmailConfirmed.Value;
}
//
// PhoneNumber ...
xUser.PhoneNumber = !model.PhoneNumber.IsNullOrEmpty() ?
model.PhoneNumber :
xUser.PhoneNumber;
//
// PhoneNumberConfirmed ,,,
if (model.PhoneNumberConfirmed.HasValue)
{
xUser.PhoneNumberConfirmed = model.PhoneNumberConfirmed.Value;
}
//
// DateOfBirth ...
if (model.DateOfBirth.HasValue)
{
xUser.DateOfBirth = model.DateOfBirth.Value;
}
//
// CreationDate ...
if (model.CreationDate.HasValue)
{
xUser.CreationDate = model.CreationDate.Value;
}
//
// LastLogin ...
if (model.LastLogin.HasValue)
{
xUser.LastLogin = model.LastLogin.Value;
}
//
// Avatar ...
xUser.Avatar = !model.Avatar.IsNullOrEmpty() ?
model.Avatar :
xUser.Avatar;
//
// Gender ...
if (model.Gender.HasValue)
{
xUser.Gender = model.Gender.Value;
}
//
// IsEnable ...
if (model.IsEnable.HasValue)
{
xUser.IsEnable = model.IsEnable.Value;
}
//
// IsBanned ...
if (model.IsBanned.HasValue)
{
xUser.IsBanned = model.IsBanned.Value;
}
//
// Bio ...
xUser.Bio = model.Bio;
//
// Cover Image ...
xUser.CoverImage = model.CoverImage;
//
// Open To Search ...
xUser.OpenToSearch = model.OpenToSearch;
#endregion
//
var updateResult = await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
if (!updateResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
// Handle Roles ...
//
// Remove User from All Roles ...
if (xUser.Roles.HasChild())
{
//
var roleNames = await GetRoleNamesAsync(
xUser.Id,
checkIsBanned: false,
checkCanLoginPolicies: false
);
//
foreach (var role in roleNames)
{
//
var isRoleExists = await IsRoleExistsAsync(role);
if (isRoleExists)
{
//
var isInRole = await UserManager.IsInRoleAsync(xUser, role);
if (!isInRole)
{
//
var removeRoleResult = await UserManager.RemoveFromRoleAsync(xUser, role);
if (!removeRoleResult.Succeeded)
{
XException.ActionFailed.Throw();
}
}
}
}
}
//
// Check Roles and Add to Exists ...
if (model.Roles.HasChild())
{
//
// Check Exists Roles for Add ...
foreach (var role in model.Roles)
{
//
var isRoleExists = await IsRoleExistsAsync(role);
if (isRoleExists)
{
//
var isInRole = await UserManager.IsInRoleAsync(xUser, role);
if (!isInRole)
{
//
var addToRoleResult = await UserManager.AddToRoleAsync(xUser, role);
if (!addToRoleResult.Succeeded)
{
XException.ActionFailed.Throw();
}
}
}
}
}
//
var result = await GetUserProfileAsync(
userSelectByParam,
requestedUserSelectByParam,
checkCanLoginPolicies: false,
checkIsBanned: false
);
return result;
}
#endregion
//
#region Request For Actions ...
/// <summary>
/// Request Mobile Confirm
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="password">user's password</param>
/// <param name="mobileNumber">mobile number which need to confirm</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestConfirmMobile(
string lang,
XDevice device,
string userSelectByParam,
string password,
string mobileNumber = null
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
userSelectByParam,
password)
.AddNotNull(device)
.ValidateGroupAsync();
//
await ValidateDeviceForActions(device);
//
// Prepare Request Context ...
var context = new XActionRequestContext
{
Lang = lang,
Device = device,
MobileNumber = mobileNumber
};
//
// Validate and Retrieve User ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false);
//
context.UserName = user.UserName;
//
await ValidateUserAndPassword(
userSelectByParam,
password,
false,
XException.ActionFailed.ToException());
//
ValidationProvider.MobileNumber(user.PhoneNumber);
if (!mobileNumber.IsNullOrEmpty() &&
user.PhoneNumber == mobileNumber &&
user.PhoneNumberConfirmed)
{
XException.MobileInUsed.Throw();
}
//
if (mobileNumber.IsNullOrEmpty())
{
mobileNumber = user.PhoneNumber;
}
//
// Remove All Prevoius Requests ...
await HandleRemoveExistsTokens(user.Id);
//
// Prepare New Token Result ,
// by Requesting an Action ...
var request = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.RequestMobileVerificationCode,
context,
forceRenewToken: true
);
//
Logger.LogInformation($"ActionRequest: {request.ToJSON()}");
//
// Call Confirm Method of Registration ...
var result = await RequestMobileVerificationCode(
lang,
device,
request.Token,
mobileNumber,
checkMobileInUse: false);
//
return result;
}
/// <summary>
/// Request Email Confirma
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="password">user's password</param>
/// <param name="emailAddress">email address which need to confirm</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestConfirmEmail(
string lang,
XDevice device,
string userSelectByParam,
string password,
string emailAddress = null
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
userSelectByParam,
password)
.AddNotNull(device)
.ValidateGroupAsync();
//
await ValidateDeviceForActions(device);
//
// Prepare Request Context ...
var context = new XActionRequestContext
{
Lang = lang,
Device = device,
Email = emailAddress
};
//
// Validate and Retrieve User ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false);
//
context.UserName = user.UserName;
//
// Remove All Prevoius Requests ...
await HandleRemoveExistsTokens(user.Id);
//
await ValidateUserAndPassword(
userSelectByParam,
password,
false,
XException.ActionFailed.ToException());
//
ValidationProvider.EmailAddress(user.Email);
if (!emailAddress.IsNullOrEmpty() &&
user.Email == emailAddress &&
user.EmailConfirmed)
{
XException.EmailInUsed.Throw();
}
//
if (emailAddress.IsNullOrEmpty())
{
emailAddress = user.Email;
context.Email = user.Email;
}
//
// Prepare New Token Result ,
// by Requesting an Action ...
var request = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.RequestEmailVerificationCode,
context,
forceRenewToken: true
);
//
// Call Confirm Method of Registration ...
var result = await RequestEmailVerificationCode(
lang,
device,
request.Token,
emailAddress,
checkEmailInUse: false);
//
return result;
}
/// <summary>
/// Request Reset Password
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="returnUrl">redirection url</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestResetPassword(
string lang,
XDevice device,
string userSelectByParam,
string returnUrl
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
userSelectByParam,
returnUrl)
.AddNotNull(device)
.AddUrl(returnUrl)
.ValidateGroupAsync();
//
await ValidateDeviceForActions(device);
//
// Validate and Retrieve User ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: true,
checkIsBanned: true);
//
// Prepare Request Context ...
var context = new XActionRequestContext
{
Lang = lang,
Device = device,
Email = user.Email,
UserName = user.UserName
};
//
// Remove All Prevoius Requests ...
await HandleCleanUserTokens(user);
//
// Prepare New Token Result ,
// by Requesting an Action ...
var result = await ActionRequest(
lang,
device,
user.Email,
XAction.RequestResetPassword,
context
);
//
// Prepare Message ...
var xMessage = GetResetPasswordMessage(
lang,
user.Email,
result.Token,
returnUrl);
//
try
{
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
//
return result;
}
/// <summary>
/// Request Registration Confrirm
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="password">user's password</param>
/// <param name="returnUrl">redirection url</param>
/// <returns></returns>
public async Task RequestConfirmRegistration(
string lang,
XDevice device,
string userSelectByParam,
string password,
string returnUrl
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
userSelectByParam,
password,
returnUrl)
.AddNotNull(device)
.AddUrl(returnUrl)
.ValidateGroupAsync();
//
// Validate user and Retrieve it ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: true,
ignoreDisabledUser: true);
//
// Prepare Request Context ...
var context = new XActionRequestContext
{
Lang = lang,
Device = device,
Email = user.Email
};
//
await ValidateUserAndPassword(
userSelectByParam,
password,
false,
XException.ActionFailed.ToException());
//
// Remove All Prevoius Requests ...
await HandleRemoveExistsTokens(user.Id);
//
// Prepare New Token Result ,
// by Requesting an Action ...
var result = await ActionRequest(
lang,
device,
user.Email,
XAction.Finish,
context
);
//
// Prepare XMessage Instance ...
var xMessage = GetRegistrationConfirmMessage(
lang,
user.Email,
result.Token,
returnUrl);
//
// Send Message ...
try
{
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
}
#endregion
//
#region Password Actions ...
/// <summary>
/// Change Password
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="password">user's password</param>
/// <param name="newPassword">user's new password</param>
/// <param name="returnUrl">redirection url</param>
/// <returns></returns>
public async Task ChangePassword(
string lang,
XDevice device,
string userSelectByParam,
string password,
string newPassword,
string returnUrl
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
userSelectByParam,
password,
newPassword,
returnUrl)
.AddNotNull(device)
.ValidateGroupAsync();
//
// Password Unique ...
if (password == newPassword)
{
XException.PasswordsSame.Throw();
}
//
// Validate and Retrieve User ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: true,
checkIsBanned: true);
//
await ValidateUserAndPassword(
userSelectByParam,
password);
//
// Check Password Policies ...
await ValidatePasswordPolicies(user, newPassword);
//
// Clean All User Tokens ...
await HandleCleanUserTokens(user);
//
// Try to Change User Password ...
var passwordResetResult = await UserManager
.ChangePasswordAsync(
user,
password,
newPassword);
//
// Check Result ...
if (!passwordResetResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
// Prepare Message ...
var xMessage = GetPasswordChangedMessage(
lang,
user.Email,
returnUrl,
throwException: false
);
//
// Send Message ...
try
{
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
}
/// <summary>
/// Reset User Password
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="newPassword">user's new password</param>
/// <param name="returnUrl">redirection url</param>
/// <returns></returns>
public async Task ResetPassword(
string lang,
XDevice device,
string actionToken,
string newPassword,
string returnUrl
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
actionToken,
newPassword,
returnUrl)
.AddNotNull(device)
.ValidateGroupAsync();
//
// Get Related Token to Registration Hash and Validate it,
// then Parse XActionRequest Instance from Token ...
var request = await ValidateAndParseActionHash(actionToken);
//
// Get User Identifier ...
var userSelectByParam = GetUserSelectByParam(request);
//
// Validate and Retrieve User ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: true,
checkIsBanned: true);
//
// Check Password Policies ...
await ValidatePasswordPolicies(user, newPassword);
//
// Clean All User Tokens ...
await HandleCleanUserTokens(user);
//
// Try to Remove User Password ...
var removePasswordResult = await UserManager.RemovePasswordAsync(user);
if (!removePasswordResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
// try to Add New Password ...
var passwordResetResult = await UserManager.AddPasswordAsync(user, newPassword);
if (!passwordResetResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
// Prepare Message ...
var xMessage = GetPasswordChangedMessage(
lang,
user.Email,
returnUrl);
//
// Send Message ...
try
{
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
}
#endregion
//
#region Profile Image Actions ...
/// <summary>
/// Add Profile Image to a User
/// </summary>
/// <param name="userSelectByParam">a user identifier</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(
string userSelectByParam,
IFormFile file
)
{
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
exception: XException.NotFound.ToException()
);
//
// Handle Saving File and Attach it to User ...
var saveResult = await StorageProvider.HandleProfileImageSave(file);
//
var xProfileImage = new XProfileImage
{
UserId = xUser.Id,
Name = saveResult.FileName,
Path = saveResult.FilePath,
Thumb = saveResult.Thmbnail,
ThumbPath = saveResult.ThmbnailPath,
CreationDate = DateTime.UtcNow
};
//
xUser.Avatars.Add(xProfileImage);
var updateResult = await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
if (!updateResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
xUser.Avatar = xProfileImage.ThumbPath;
updateResult = await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
if (!updateResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
return result;
}
/// <summary>
/// Add a Collection of Profile Images to a User
/// </summary>
/// <param name="userSelectByParam">a user identifier</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(
string userSelectByParam,
IFormFileCollection files
)
{
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
exception: XException.NotFound.ToException()
);
//
foreach (var file in files)
{
//
// Handle Saving File and Attach it to User ...
var saveResult = await StorageProvider.HandleProfileImageSave(file);
//
var xProfileImage = new XProfileImage
{
UserId = xUser.Id,
Name = saveResult.FileName,
Path = saveResult.FilePath,
Thumb = saveResult.Thmbnail,
ThumbPath = saveResult.ThmbnailPath,
CreationDate = DateTime.UtcNow
};
//
xUser.Avatars.Add(xProfileImage);
}
//
var updateResult = await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
if (!updateResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
return result;
}
/// <summary>
/// Set Specific Profie Image as Current Profile Image
/// </summary>
/// <param name="userSelectByParam">a user identifier</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(
string userSelectByParam,
int id
)
{
//
ValidationProvider.NotEmpty(userSelectByParam);
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
exception: XException.NotFound.ToException()
);
//
var xProfileImage = xUser.Avatars.FirstOrDefault(pf => pf.Id == id);
if (xProfileImage.IsNull())
{
XException.NotFound.Throw();
}
//
xUser.Avatar = xProfileImage.ThumbPath;
var updateResult = await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
if (!updateResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
return result;
}
/// <summary>
/// Remove a Collection of User's Profile Images
/// </summary>
/// <param name="userSelectByParam">a user identifier</param>
/// <param name="ids">a comma seperated list of avatarIds to remove</param>
/// <returns>an instance of <see>XUserProfileDto</see></returns>
public async Task<XUserProfileDto> RemoveAvatar(
string userSelectByParam,
ICollection<int> ids
)
{
//
ValidationProvider.NotEmpty(userSelectByParam);
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
exception: XException.NotFound.ToException()
);
//
var xProfileImages = xUser.Avatars
.Where(pf => ids.Contains(pf.Id));
if (xProfileImages.HasChild())
{
//
xUser.Avatars = xUser.Avatars
.Except(xProfileImages)
.ToList();
//
// Creat a List of Physical Files to Remove ...
var xFilePathsForRemove = xProfileImages.Select(pf => pf.Thumb).ToList();
xFilePathsForRemove.AddRange(xProfileImages.Select(pf => pf.Name));
//
StorageProvider.DeleteFiles(
xFilePathsForRemove,
forceFileExists: false);
//
var isCurrentProfileImage = xProfileImages.Any(pfi => pfi.ThumbPath == xUser.Avatar);
if (isCurrentProfileImage)
{
xUser.Avatar = "";
}
//
await UpdateUserAsync(xUser);
}
//
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
return result;
}
#endregion
//
#region Confirmations ...
/// <summary>
/// Confirm Registration
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="returnUrl">redirection url</param>
/// <returns></returns>
public async Task ConfirmRegistration(
string lang,
XDevice device,
string actionToken,
string returnUrl
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
actionToken,
returnUrl)
.AddNotNull(device)
.ValidateGroupAsync();
//
// Check Device Validation ...
await ValidateDeviceForActions(device);
//
// Get Related Token to Registration Hash and Validate it,
// then Parse XActionRequest Instance from Token ...
var request = await ValidateAndParseActionHash(actionToken);
if (request.Action != XAction.Finish)
{
XException.ActionFailed.Throw();
}
//
// Extract UserSelectByParam from XActionRequest ...
var userSelectByParam = GetUserSelectByParam(
request,
forceNotNull: true);
//
// Validate user and Retrieve it ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
ignoreDisabledUser: true,
checkIsBanned: true);
//
// Make User Enabled ...
var xMessage = GetRegistrationFinishedMessage(
lang,
user.Email,
returnUrl);
//
user.IsEnable = true;
user.EmailConfirmed = true;
//
await UpdateUserAsync(
user,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
// Remove Token ...
await RemoveTokenByHash(actionToken);
//
// Remove All Prevoius Requests ...
await HandleRemoveExistsTokens(user.Id);
//
await RemoveVerificationCodeRequestByDevice(device);
//
// Send Mail ...
try
{
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
}
/// <summary>
/// Confirm Mobile Number
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="verificationCode">recieved verification code</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> ConfirmMobileNumber(
string lang,
XDevice device,
string actionToken,
string verificationCode
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(lang, actionToken, verificationCode)
.AddNotNull(device)
.ValidateGroupAsync();
//
// Check Device Validation ...
await ValidateDeviceForActions(device);
//
// Get Related Token to Registration Hash and Validate it,
// then Parse XActionRequest Instance from Token ...
var request = await ValidateAndParseActionHash(actionToken);
ValidationProvider.MobileNumber(request.Context.MobileNumber);
//
// Validate two Device Must Same ...
ValidateRequestAndGiveDevices(device, request.Context.Device);
//
// Check XActionRequest Action Must be Request Mobile Validation ...
if (request.Action != XAction.RequestMobileVerificationCode)
{
XException.InvalidData.Throw();
}
//
// Extract UserSelectByParam from XActionRequest ...
var userSelectByParam = GetUserSelectByParam(request);
//
// since device must Requested before,
// Retrieve XVerification instance by Verification Code from Db
// and Validate it ...
XVerificationRequest xVerificationRequest = await ValidateAndRetrieveVerificationRequest(verificationCode);
//
// Check User Added To Db or Not ...
// var isUserExists = await IsUserExistsAsync(userSelectByParam);
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
if (isAddedUser)
{
//
// Validate User Exists and Retireve User Object ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false);
//
// Update Exists User's Mobile Confirmation ...
user.PhoneNumberConfirmed = true;
//
// Save Changes to Db ...
await UpdateUserAsync(user, checkCanLoginPolicies: false, checkIsBanned: false);
//
request.Context.UserId = user.Id;
}
//
// Update Request Context MobileNumber Verification Code
// and it's Confirmation Status ...
request.Context.MobileVerificationCode = verificationCode;
request.Context.MobileVerified = true;
//
// Prepare New Token Result ,
// by Requesting an Action ...
var result = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.ConfirmMobileNumber,
request.Context,
forceCheckUserExists: isAddedUser
);
//
// Remove Previous Token ...
await RemoveTokenByHash(actionToken);
try
{
//
// Remove XVerificationRequest instance from Db ...
await RemoveVerificationRequest(verificationCode);
}
catch { }
//
// Return Result ...
return result;
}
/// <summary>
/// Confirm Email Address
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="verificationCode">recieved verification code</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> ConfirmEmailAddress(
string lang,
XDevice device,
string actionToken,
string verificationCode
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(lang, actionToken, verificationCode)
.AddNotNull(device)
.ValidateGroupAsync();
//
// Check Device Validation ...
await ValidateDeviceForActions(device);
//
// Get Related Token to Registration Hash and Validate it,
// then Parse XActionRequest Instance from Token ...
var request = await ValidateAndParseActionHash(actionToken);
ValidationProvider.EmailAddress(request.Context.Email);
//
// Validate two Device Must Same ...
ValidateRequestAndGiveDevices(device, request.Context.Device);
//
// Check XActionRequest Action Must be Request Mobile Validation ...
if (request.Action != XAction.RequestEmailVerificationCode)
{
XException.InvalidData.Throw();
}
//
// Extract UserSelectByParam from XActionRequest ...
var userSelectByParam = GetUserSelectByParam(request);
//
// since device must Requested before,
// Retrieve XVerification instance by Verification Code from Db
// and Validate it ...
XVerificationRequest xVerificationRequest = await ValidateAndRetrieveVerificationRequest(verificationCode);
//
// Check User Added To Db or Not ...
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
if (isAddedUser)
{
//
// Validate User Exists and Retireve User Object ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false);
//
// Update Exists User's Email Confirmation ...
user.EmailConfirmed = true;
//
// Save Changes to Db ...
await UpdateUserAsync(user, checkCanLoginPolicies: false, checkIsBanned: false);
//
request.Context.UserId = user.Id;
}
//
// Update Request Context Email Address Verification Code
// and it's Confirmation Status ...
request.Context.EmailVerificationCode = verificationCode;
request.Context.EmailVerified = true;
//
// Prepare New Token Result ,
// by Requesting an Action ...
var result = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.ConfirmEmailAddress,
request.Context,
forceCheckUserExists: isAddedUser
);
//
// Remove Previous Token ...
await RemoveTokenByHash(actionToken);
//
// Remove XVerificationRequest instance from Db ...
await RemoveVerificationRequest(verificationCode);
//
// Return Result ...
return result;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Query.cs
using System.Linq;
using System.Threading.Tasks;
using xCommons.Extensions;
using xDataService.Extensions;
using xExceptions.Constants;
using xIdentityModels.Extensions;
using xIds.Extensions;
using xModels.Dtos;
namespace xIds.Providers
{
public partial class XIdentityManager
{
/// <summary>
/// Retrieve Users as Query Model for Query Service ...
/// </summary>
/// <param name="requestedUserSelectByParam"></param>
/// <param name="query"></param>
/// <param name="role"></param>
/// <param name="forceRole"></param>
/// <returns></returns>
public async Task<XQueryResult<string>> QueryUsers(
string requestedUserSelectByParam,
XQuery query,
string role = null,
bool forceRole = false
)
{
//
// Validation ...
if (query.IsNull())
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
//
// Since in Resourceable Entities we have to Search on Locales
// we Must Implement Senario Custom ...
var items = GetUsersDbSet()
.ToList()
.Where(u => !u.ContainsUserSelectByParam(requestedUserSelectByParam))
.ToList()
.AsEnumerable();
//
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter);
}
int filteredItemsCount = items.Count();
//
// Count Pages ...
var totalPagesCount = query.CountPages(totalItemsCount);
var filteredPagesCount = query.CountPages(filteredItemsCount);
//
// Apply Paging and Sorting ...
if (totalItemsCount > 0 &&
filteredItemsCount > 0)
{
//
// Apply Sorting ...
items = items
.ToList()
.ApplySorting(
query.SortBy,
query.IsAscending
);
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
);
}
//
// Generate Result Object ...
// Query = query,
var result = new XQueryResult<string>
{
Items = items
.Select(u => u.Id),
Page = query.Page,
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return await Task.Run(() => result);
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Registration.cs
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels;
using xIdentityModels.Constants;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Registration Actions ...
/// <summary>
/// Invite a User to Register on Dashboard
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="email">which email address is going to invite</param>
/// <param name="returnUrl">return url for invitation user to redirect</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> InviteUser(
string lang,
XDevice device,
string email,
string returnUrl
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
email,
returnUrl
)
.AddNotNull(device)
.AddEmailAddress(email)
.ValidateGroupAsync();
//
// Check Email is Unique ...
await ValidateUserNotExists(email);
//
// Get Request Result ...
var result = await ActionRequest(
lang,
device,
email,
XAction.Invite,
forceCheckContext: false,
forceCheckUserExists: false);
//
// Prepare Propper Message ...
var xMessage = GetUserInviteMessage(lang, email, result.Token, returnUrl);
//
// Send Message ...
try
{
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
//
// Send Result ...
return result;
}
/// <summary>
/// Recieve some Basic Informations and Start Registration Proccess
/// if they Valid
///
/// Registration Proccess Starts with Invoking this Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="invitationHash">optional, if user invited, this is the invitation token</param>
/// <param name="firstName">user's FirstName</param>
/// <param name="lastName">user's LastName</param>
/// <param name="dateOfBirth">user's dob date</param>
/// <param name="mobileNumber">user's Mobile Number</param>
/// <param name="emailAddress">user's Email address</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestRegistration(
string lang,
XDevice device,
string invitationHash,
string firstName,
string lastName,
DateTime dateOfBirth,
string mobileNumber = null,
string emailAddress = null
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
firstName,
lastName
)
.AddNotNull(
device,
dateOfBirth
)
.ValidateGroupAsync();
//
// Validate Mobile Number if Exists ...
if (!mobileNumber.IsNullOrEmpty())
{
//
ValidationProvider.MobileNumber(mobileNumber);
//
// Check Mobile is Uniqsue ...
await ValidateUserNotExists(mobileNumber);
}
//
// Validate Email Address if Exists ...
if (!emailAddress.IsNullOrEmpty())
{
//
ValidationProvider.EmailAddress(emailAddress);
//
// Check Email is Unique ...
await ValidateUserNotExists(emailAddress);
}
//
// Get Related Token and Validate it and
// Check Related Configurations ...
await ValidateInvitationHash(invitationHash);
//
// Check Device Validation ...
await ValidateDeviceForActions(device);
//
// Validate DateOfBirth ...
ValidateDateOfBirth(dateOfBirth);
//
// Define Empty Objects for Using ...
var userSelectByParam = "";
var context = new XActionRequestContext();
//
context.Lang = lang;
context.Device = device;
context.LastName = lastName;
context.FirstName = firstName;
context.DateOfBirth = dateOfBirth;
context.MobileNumber = mobileNumber ?? "";
context.Email = !emailAddress.IsNullOrEmpty() ? emailAddress.ToNormalString() : "";
//
userSelectByParam = GetUserSelectByParam(context);
//
// Token Data Parsing ...
if (!invitationHash.IsNullOrEmpty())
{
//
// Get Related Token, Validate it and Parse Contains
// XAction Request and Validate the Request itself and
// Return it ...
var inviteRequest = await ValidateAndParseActionHash(invitationHash);
//
// Extract User Select By Param and Type ...
userSelectByParam = GetUserSelectByParam(inviteRequest);
var userSelectBy = GetUserSelectByType(userSelectByParam);
//
// Check Invitation Only done with Email Address ...
if (userSelectBy != XUserSelectBy.Email)
{
XException.InvalidData.Throw();
}
//
// Check Invited Email and Given Email to be Same ...
if (emailAddress.IsNullOrEmpty() ||
(!emailAddress.IsNullOrEmpty() &&
!emailAddress.IsValidEmail()))
{
XException.InvalidEmailAddress.Throw();
}
var isSameEmail = inviteRequest.Context.Email.ToNormalString() == emailAddress.ToNormalString();
if (!isSameEmail)
{
XException.EmailsSame.Throw();
}
//
// Update Context Email for Request Action ...
context.Email = userSelectByParam.ToNormalString();
context.EmailVerified = true;
}
//
var result = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.Registration,
context,
forceCheckUserExists: false
);
//
// Remove Invitation Token ...
if (!invitationHash.IsNullOrEmpty())
{
await RemoveTokenByHash(invitationHash);
}
//
// Return Result ...
return result;
}
/// <summary>
/// Add User Account Info
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="userName">user name</param>
/// <param name="password">assigne password</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> AddAcountInfo(
string lang,
XDevice device,
string actionToken,
string userName,
string password
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(
lang,
actionToken,
userName,
password)
.AddNotNull(device)
.ValidateGroupAsync();
//
// Check Device Validation ...
await ValidateDeviceForActions(device);
//
// Validate a UserSelector is Available or not ...
await ValidateCanRegister(userName);
//
// Check UserName is Unique ...
await ValidateUserNotExists(userName);
//
// Get Related Token to Registration Hash and Validate it,
// then Parse XActionRequest Instance from Token ...
var request = await ValidateAndParseActionHash(actionToken);
//
// Validate Requeired Data for Register User must be in Action Context ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(
request.Context,
request.Context.Device,
request.Context.DateOfBirth)
.AddNotEmpty(
request.Context.Email,
request.Context.MobileNumber,
request.Context.FirstName,
request.Context.LastName)
.AddEmailAddress(request.Context.Email)
.AddMobileNumber(request.Context.MobileNumber)
.ValidateGroupAsync();
//
// Validate two Device Must Same ...
ValidateRequestAndGivenDevices(device, request.Context.Device);
//
// Extract UserSelectByParam from XActionRequest ...
var userSelectByParam = GetUserSelectByParam(request);
//
// Validate Request Pointer User doesn't Exists ...
await ValidateUserNotExists(userSelectByParam);
//
// Create an Empty Instance of XUser ...
var xUser = new XUser();
//
// Start Filling User Fields ...
xUser.UserName = userName;
xUser.Email = request.Context.Email;
xUser.PhoneNumber = request.Context.MobileNumber;
//
xUser.FirstName = request.Context.FirstName;
xUser.LastName = request.Context.LastName;
xUser.DateOfBirth = request.Context.DateOfBirth;
//
xUser.EmailConfirmed = request.Context.EmailVerified;
xUser.PhoneNumberConfirmed = request.Context.MobileVerified;
//
xUser.CreationDate = DateTime.UtcNow;
xUser.LastLogin = null;
//
#region Handling New User IsEnable State ...
//
// By Default New Users will Enables ...
xUser.IsEnable = true;
xUser.IsBanned = false;
//
// Check Auto Enable Users ...
if (Configuration.RequireRegistrationConfirm)
{
xUser.IsEnable = false;
}
//
// Check Auto Confirm Email Users ...
if (Configuration.AutoConfirmNewUsersEmail)
{
xUser.EmailConfirmed = true;
}
#endregion
//
// Check Auto Confirm Phone Number Users ...
if (Configuration.AutoConfirmNewUsersPhoneNumber)
{
xUser.PhoneNumberConfirmed = true;
}
//
// Validating given Password ...
await ValidatePasswordPolicies(xUser, password);
//
// Now add new User to Database ...
var createUserResult = await CreateUserAsync(xUser, password);
if (!createUserResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
// Update Request UserId Value ...
request.Context.UserId = xUser.Id;
request.Context.UserName = xUser.UserName;
//
#region Handling New User Role ...
//
// Now Try to Assign Default User role ...
var isContainsDefaultUserRole = !Configuration.NewUsersRole.IsNullOrEmpty();
if (isContainsDefaultUserRole)
{
//
var newUserRoleName = Configuration.NewUsersRole;
var isNewUserRoleExists = await IsRoleExistsAsync(newUserRoleName);
//
// Make Sure New User role Exists ...
if (!isNewUserRoleExists)
{
//
// Create Default Roles ...
await CreateIdentityRoles();
}
//
// Assign User to Role ...
var assignNewUserToRoleResult = await AddUserToRoleAsync(xUser, newUserRoleName);
if (!assignNewUserToRoleResult.Succeeded)
{
//
// Delete User if Role Assignment Faild ...
await UserManager.DeleteAsync(xUser);
//
// Thrown ActionFailed Error ...
XException.ActionFailed.Throw();
}
}
#endregion
//
#region Handle Profile Image ...
// Save and Attach Profile Image to User if it's Added Before ...
if (!request.Context.UserId.IsNullOrEmpty() &&
!request.Context.Thubmnail.IsNull())
{
//
xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
exception: XException.NotFound.ToException()
);
//
// Handle Saving File and Attach it to User ...
var saveResult = await StorageProvider
.HandleProfileImageSave(request.Context.Thubmnail);
//
var xProfileImage = new XProfileImage
{
UserId = request.Context.UserId,
Name = saveResult.FileName,
Path = saveResult.FilePath,
Thumb = saveResult.Thmbnail,
ThumbPath = saveResult.ThmbnailPath
};
//
xUser.Avatars.Add(xProfileImage);
var updateResult = await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
if (updateResult.Succeeded)
{
//
xUser.Avatar = xProfileImage.ThumbPath;
await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
}
}
#endregion
//
// Handle Attaching User device ...
var xUserDevice = await AddUserRelatedDevice(
userSelectByParam,
device,
checkCanLoginPolicies: false);
//
// Prepare New Token Result Resource,
// by Requesting an Action ...
var result = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.Finish,
request.Context,
forceCheckUserExists: false
);
//
// Remove Previous Token ...
await RemoveTokenByHash(actionToken);
//
// Return Result ...
return result;
}
/// <summary>
/// Attach Profile Image
/// </summary>
/// <param name="actionToken">a token which approved user action</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()
.AddNotEmpty(actionToken)
.AddNotNull(file)
.ValidateGroupAsync();
//
// Get Related Token to Registration Hash and Validate it,
// then Parse XActionRequest Instance from Token ...
var request = await ValidateAndParseActionHash(actionToken);
//
// Extract UserSelectByParam from XActionRequest ...
var userSelectByParam = GetUserSelectByParam(request);
if (userSelectByParam.IsNullOrEmpty())
{
XException.InvalidData.Throw();
}
//
// Validate Given FormFile as Profile Image ...
StorageProvider.ValidateProfileImage(file);
//
request.Context.Thubmnail = file;
//
// Save and Attach Profile Image to User if it's Added Before ...
if (!request.Context.UserId.IsNullOrEmpty())
{
//
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
exception: XException.NotFound.ToException()
);
//
// Handle Saving File and Attach it to User ...
var saveResult = await StorageProvider.HandleProfileImageSave(file);
//
var xProfileImage = new XProfileImage
{
UserId = request.Context.UserId,
Name = saveResult.FileName,
Path = saveResult.FilePath,
Thumb = saveResult.Thmbnail,
ThumbPath = saveResult.ThmbnailPath
};
//
xUser.Avatars.Add(xProfileImage);
var updateResult = await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
//
if (updateResult.Succeeded)
{
//
xUser.Avatar = xProfileImage.ThumbPath;
await UpdateUserAsync(
xUser,
checkCanLoginPolicies: false,
checkIsBanned: false
);
}
}
//
// Remove Invitation Token ...
if (!actionToken.IsNullOrEmpty())
{
await RemoveTokenByHash(actionToken);
}
//
var result = await ActionRequest(
request.Context.Lang,
request.Context.Device,
userSelectByParam,
XAction.ProfileAction,
request.Context,
forceCheckUserExists: false
);
//
// Return Result ...
return result;
}
/// <summary>
/// Finishing Registration
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="userSelectByParam">user identifier</param>
/// <param name="password">assigne password</param>
/// <param name="returnUrl">return url for invitation user to redirect</param>
/// <returns></returns>
public async Task FinishRegistration(
string lang,
XDevice device,
string userSelectByParam,
string password,
string returnUrl
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(lang, userSelectByParam, password, returnUrl)
.AddNotNull(device)
.AddUrl(returnUrl)
.ValidateGroupAsync();
//
// Validate User Exists And Retrieve it ...
var xUser = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false,
ignoreDisabledUser: true,
forceAdmin: false
);
//
#region Handling New User Email Notification Senario ...
//
// Here we Check if User is Enable and Approved Email
// send RegisteredMsg and if User is not Enable and
// Verify Registration value in Configuration is True
// send Verify Registration mail to user and handle it ...
if (Configuration.RequireRegistrationConfirm)
{
//
if (xUser.IsEnable)
{
//
// Send Registration Finished Message ...
// since in this step we need to prevent errors from
// going forward. add this try catch here ...
try
{
//
var xMessage = GetRegistrationFinishedMessage(lang, xUser.Email, returnUrl);
//
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
}
else
{
//
// Send Registration Confirm Message ...
// since in this step we need to prevent errors from
// going forward. add this try catch here ...
try
{
//
var request = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.Finish,
forceCheckContext: false,
forceCheckUserExists: true);
//
var xMessage = GetRegistrationConfirmMessage(lang, xUser.Email, request.Token, returnUrl);
//
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
}
}
// //
// await RemoveTokenByDevice (device);
#endregion
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Request.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Action Handlers ...
/// <summary>
/// Request an Action
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <param name="step">a member of <see>XAction</see> which represent Action Step</param>
/// <param name="context">an instance of <see>XActionRequestContext</see> which provides required informations for specified step</param>
/// <param name="forceCheckContext">specify checking context, default is false</param>
/// <param name="forceCheckUserExists">specify check user exists, default is true</param>
/// <param name="forceCheckUserDevice">specify check user and device relation, default is false</param>
/// <param name="forceRenewToken">specifies force renew Action Token if it's expired, default is false</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
private async Task<XActionResponse> ActionRequest(
string lang,
XDevice device,
string userSelectByParam,
XAction step,
XActionRequestContext context = null,
bool forceCheckContext = false,
bool forceCheckUserExists = true,
bool forceCheckUserDevice = false,
bool forceRenewToken = false
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(lang);
ValidationProvider.NotNull(device);
//
// Check Device not Banned ...
await ValidateDeviceForActions(device);
//
// Check User Exists and Device Relation ...
if (forceCheckUserExists)
{
if (forceCheckUserDevice)
{
//
if (context.Device != null &&
!device.IsSameAs(context.Device))
{
XException.InvalidDevice.Throw();
}
//
await ValidateUserAndDeviceRelation(userSelectByParam, device);
}
else
{
await ValidateUserExistsAsync(userSelectByParam);
}
}
//
XToken xToken = null;
XActionResponse result = null;
XActionRequestToken xRequest = null;
//
var isExists = false;
var forceUserSelectByParamNotEmpty = true;
switch (step)
{
case XAction.Registration:
//
forceUserSelectByParamNotEmpty = false;
isExists = await IsTokenExistsByDeviceAndType(device, step);
//
if (isExists)
{
xToken = await ValidateAndRetieveTokenByDeviceAndType(device, step);
}
break;
default:
//
isExists = await IsTokenExistsByUserAndType(userSelectByParam, step);
//
if (isExists)
{
xToken = await ValidateAndRetieveTokenByUserAndType(userSelectByParam, step);
}
break;
}
//
if (isExists)
{
//
var isValidToken = IsValidToken(xToken.Token);
if (!isValidToken && !forceRenewToken)
{
switch (step)
{
case XAction.Registration:
case XAction.Invite:
forceRenewToken = true;
break;
default:
throw XException.InvalidToken.ToException();
}
}
//
if (!isValidToken && forceRenewToken)
{
await ValidateAndHandleToken(xToken.Token);
return await ActionRequest(
lang,
device,
userSelectByParam,
step,
context,
forceCheckContext,
forceCheckUserExists,
forceCheckUserDevice,
forceRenewToken);
}
//
xRequest = ValidateAndParseActionToken(xToken.Token);
//
// Check Exists Context ...
if (forceCheckContext)
{
//
var isSameContext = xRequest.Context.IsSameAs(context);
if (!isSameContext)
{
XException.InvalidData.Throw();
}
}
}
else
{
//
if (context != null)
{
//
var contextUserSelectByParam = GetUserSelectByParam(
context,
false,
new List<XUserSelectBy> {
XUserSelectBy.ID,
XUserSelectBy.Email,
XUserSelectBy.MobileNumber
});
var contextLang = context.Lang;
var contextDevice = context.Device;
//
// prevent from issues on Registration Request ...
if (forceUserSelectByParamNotEmpty)
{
var userSelectByType = GetUserSelectByType(userSelectByParam);
var contextUserSelectByType = GetUserSelectByType(contextUserSelectByParam);
if (contextUserSelectByType != userSelectByType)
{
//
var excludesList = GenerateUserSelectByExcludes(new List<XUserSelectBy> { userSelectByType });
//
contextUserSelectByParam = GetUserSelectByParam(context, false, excludesList);
}
}
//
// Fix Device Not Same on Invitation and Request
if (step == XAction.Registration)
{
//
context.Device = device;
contextDevice = context.Device;
}
//
// Validate Context Data must be Same as Request Data ...
if ((!contextUserSelectByParam.IsNullOrEmpty() &&
contextUserSelectByParam != userSelectByParam) ||
(!contextLang.IsNullOrEmpty() &&
contextLang != lang) ||
(contextDevice != null &&
!contextDevice.IsSameAs(device)))
{
XException.InvalidData.Throw();
}
}
else
{
//
context = new XActionRequestContext
{
Lang = lang,
Device = device
};
//
// Add Content ...
var userSelectByType = GetUserSelectByType(
userSelectByParam,
forceUserSelectByParamNotEmpty);
switch (userSelectByType)
{
case XUserSelectBy.MobileNumber:
context.MobileNumber = userSelectByParam;
break;
case XUserSelectBy.Email:
context.Email = userSelectByParam;
break;
case XUserSelectBy.Username:
context.UserName = userSelectByParam;
break;
case XUserSelectBy.ID:
context.UserId = userSelectByParam;
break;
case XUserSelectBy.NotSpecified:
default:
if (forceCheckUserExists)
{
XException.InvalidArgs.Throw();
}
break;
}
}
//
// Generate Registration Request ...
xRequest = new XActionRequestToken
{
Action = step,
Context = context
};
//
// Add User Id if Exists to Context ...
var isUserExists = await IsUserExistsAsync(userSelectByParam);
if (isUserExists)
{
//
var user = await GetUserAsync(userSelectByParam);
if (user != null)
{
xRequest.Context.UserId = user.Id;
}
}
//
xRequest.Prepare(Configuration.IdentitySecretKey);
//
xToken = await HashRequest(
xRequest,
forceUserSelectByParamNotEmpty);
}
//
// When XToken Exists Passed XToken ...
result = GetActionResultResponse(xToken);
//
if (result == null)
{
XException.ActionFailed.Throw();
}
//
return result;
}
/// <summary>
/// Request a Mobile Verification Code
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="mobileNumber">the mobile number which is going to request a verification code</param>
/// <param name="checkMobileInUse">check mobile number is in use or not, default is true</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
private async Task<XActionResponse> RequestMobileVerificationCode(
string lang,
XDevice device,
string actionToken,
string mobileNumber,
bool checkMobileInUse = true
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(lang, actionToken, mobileNumber)
.AddMobileNumber(mobileNumber)
.AddNotNull(device)
.ValidateGroupAsync();
//
// Check Device Validation ...
await ValidateDeviceForActions(device);
//
// Check Mobile is Unique ...
if (checkMobileInUse)
{
var isUserExists = await IsUserExistsAsync(mobileNumber);
if (isUserExists)
{
//
var xUser = await GetUserAsync(mobileNumber);
//
if (xUser.PhoneNumberConfirmed)
{
XException.MobileInUsed.Throw();
}
}
}
//
// Get Related Token to Registration Hash and Validate it,
// then Parse XActionRequest Instance from Token ...
var request = await ValidateAndParseActionHash(actionToken);
//
// Validate two Device Must Same ...
ValidateRequestAndGiveDevices(device, request.Context.Device);
//
// Extract UserSelectByParam from XActionRequest ...
var userSelectByParam = GetUserSelectByParam(
request,
forceNotNull: false,
excludes: new List<XUserSelectBy> {
XUserSelectBy.ID,
XUserSelectBy.Email,
XUserSelectBy.MobileNumber
});
//
// if it's null, means user doesn't have Invitation Token
// and there is no User Selector ...
if (userSelectByParam.IsNullOrEmpty())
{
//
// Since Mobile is Unique so it can act as a
// UserSelector ...
userSelectByParam = mobileNumber;
}
//
// Define empty Verification Code
// and Empty Verification Request ...
var verificationCode = "";
XVerificationRequest xVerificationRequest = null;
//
// Check Device Request Verification Code before or Not ...
var isDeviceRequested = await IsDeviceRequestedForVerificationCodeBefor(device);
if (isDeviceRequested)
{
//
// if Requested before, Retrieve XVerification instance by Device from Db
// and Validate it ...
xVerificationRequest = await ValidateAndRetrieveVerificationRequest(device);
//
if (xVerificationRequest.VerificationCode.IsNullOrEmpty())
{
//
verificationCode = GenerateRandom().ToString();
xVerificationRequest.VerificationCode = verificationCode;
//
await RemoveVerificationCodeRequestByDevice(
device,
saveChanges: false
);
await AddVerificationRequest(
xVerificationRequest,
saveChanges: false
);
//
await DbContext.SaveChangesAsync();
}
//
// if XVerificationRequest is Valid, it must Contain an Alive Verification Code
// so retrieve it and assign it ...
verificationCode = xVerificationRequest.VerificationCode;
}
else
{
//
verificationCode = GenerateRandom().ToString();
}
//
// if it's First Verification Request of given Device
// Generate a new Verification Code ...
if (verificationCode.IsNullOrEmpty())
{
verificationCode = GenerateRandom().ToString();
}
//
// Check Context Mobile and given Mobile ...
if (!request.Context.MobileNumber.IsNullOrEmpty() &&
mobileNumber != request.Context.MobileNumber)
{
XException.InvalidMobileNumber.Throw();
}
//
// Check User Added To Db or Not ...
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
if (isAddedUser)
{
//
// Validate User Exists and Retireve User Object ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false);
//
// Check Mobiles Same ...
if (user.PhoneNumber == mobileNumber &&
user.PhoneNumberConfirmed)
{
XException.MobilesSame.Throw();
}
//
// Update User Object's Mobile Number and
// Confirmation Status ...
user.PhoneNumber = mobileNumber;
user.PhoneNumberConfirmed = false;
//
// Save Changes to Db ...
await UpdateUserAsync(user, checkCanLoginPolicies: false, checkIsBanned: false);
}
//
// Prepare Verification Request by Checking Next Tries,
// Device Status, and etc, Update or Add XVerificationRequest to db
// and Retrieve the added Entity ...
xVerificationRequest = await HandleVerificationRequestPreparation(verificationCode, request);
//
// Update Request Context MobileNumber
// and it's Confirmation Status ...
request.Context.MobileNumber = mobileNumber;
request.Context.MobileVerified = false;
//
// Remove Previous Token ...
await RemoveTokenByHash(actionToken);
//
// Prepare New Token Result Resource,
// by Requesting an Action ...
var result = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.RequestMobileVerificationCode,
request.Context,
forceCheckUserExists: isAddedUser
);
//
// Prepare Message ...
var xMessage = GetVerificationCodeMessage(lang, mobileNumber, verificationCode);
//
// Send Verification Code Message to User Using SMS Provider ...
await MessageProvider.SendSmsAsync(xMessage, throwException: false);
//
// Return Result ...
return result;
}
/// <summary>
/// Request a Email Verification Code
/// </summary>
/// <param name="lang">specify destination language</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="actionToken">a token which approved user action</param>
/// <param name="emailAddress">the email address which is going to request a verification code</param>
/// <param name="checkEmailInUse">check email address is in use or not, default is true</param>
/// <returns>an instance of <see>XActionResponse</see></returns>
public async Task<XActionResponse> RequestEmailVerificationCode(
string lang,
XDevice device,
string actionToken,
string emailAddress,
bool checkEmailInUse = true
)
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(lang, actionToken, emailAddress)
.AddEmailAddress(emailAddress)
.AddNotNull(device)
.ValidateGroupAsync();
//
// Check Device Validation ...
await ValidateDeviceForActions(device);
//
// Check Email is Unique ...
if (checkEmailInUse)
{
var isUserExists = await IsUserExistsAsync(emailAddress);
if (isUserExists)
{
//
var xUser = await GetUserAsync(emailAddress);
//
if (xUser.EmailConfirmed)
{
XException.EmailInUsed.Throw();
}
}
}
//
// Get Related Token to Registration Hash and Validate it,
// then Parse XActionRequest Instance from Token ...
var request = await ValidateAndParseActionHash(actionToken);
//
// Validate two Device Must Same ...
ValidateRequestAndGiveDevices(device, request.Context.Device);
//
// Extract UserSelectByParam from XActionRequest ...
var userSelectByParam = GetUserSelectByParam(
request,
forceNotNull: false,
excludes: new List<XUserSelectBy> {
XUserSelectBy.ID,
XUserSelectBy.Email,
XUserSelectBy.MobileNumber
});
//
// if it's null, means user doesn't have Invitation Token
// and there is no User Selector ...
if (userSelectByParam.IsNullOrEmpty())
{
//
// Since Email is Unique so it can act as a
// UserSelector ...
userSelectByParam = emailAddress;
}
//
// Define empty Verification Code
// and Empty Verification Request ...
var verificationCode = "";
XVerificationRequest xVerificationRequest = null;
//
// Check Device Request Verification Code before or Not ...
var isDeviceRequested = await IsDeviceRequestedForVerificationCodeBefor(device);
if (isDeviceRequested)
{
//
// if Requested before, Retrieve XVerification instance by Device from Db
// and Validate it ...
xVerificationRequest = await ValidateAndRetrieveVerificationRequest(device);
//
if (xVerificationRequest.VerificationCode.IsNullOrEmpty())
{
//
verificationCode = GenerateRandom().ToString();
xVerificationRequest.VerificationCode = verificationCode;
//
await RemoveVerificationCodeRequestByDevice(
device,
saveChanges: false
);
await AddVerificationRequest(
xVerificationRequest,
saveChanges: true
);
}
//
// if XVerificationRequest is Valid, it must Contain an Alive Verification Code
// so retrieve it and assign it ...
verificationCode = xVerificationRequest.VerificationCode;
}
else
{
//
verificationCode = GenerateRandom().ToString();
}
//
// Check Context Email and given Email ...
if (!request.Context.Email.IsNullOrEmpty() &&
emailAddress != request.Context.Email)
{
XException.InvalidEmailAddress.Throw();
}
//
// Check User Added To Db or Not ...
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
if (isAddedUser)
{
//
// Validate User Exists and Retireve User Object ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: false,
checkIsBanned: false);
//
// Check Email Same ...
if (user.Email == emailAddress &&
user.EmailConfirmed)
{
XException.MobilesSame.Throw();
}
//
// Update User Object's Email and
// Confirmation Status ...
user.Email = emailAddress;
user.EmailConfirmed = false;
//
// Save Changes to Db ...
await UpdateUserAsync(
user,
checkCanLoginPolicies: false,
checkIsBanned: false
);
}
//
// Prepare Verification Request by Checking Next Tries,
// Device Status, and etc, Update or Add XVerificationRequest to db
// and Retrieve the added Entity ...
xVerificationRequest = await HandleVerificationRequestPreparation(verificationCode, request);
//
// Update Request Context Email
// and it's Confirmation Status ...
request.Context.Email = emailAddress;
request.Context.EmailVerified = false;
//
// Prepare New Token Result Resource,
// by Requesting an Action ...
var result = await ActionRequest(
lang,
device,
userSelectByParam,
XAction.RequestEmailVerificationCode,
request.Context,
forceCheckUserExists: isAddedUser
);
//
// Remove Hash ...
await RemoveTokenByHash(actionToken);
//
// Prepare Message ...
var xMessage = GetVerificationCodeMessage(lang, emailAddress, verificationCode);
//
// Send Verification Code Message to User Using Mail Provider ...
await MessageProvider.SendMailAsync(xMessage, throwException: false);
//
// Return Result ...
return result;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Role.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Role Actions ...
/// <summary>
/// Check a Role exists or not
/// </summary>
/// <param name="roleName">role name</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsRoleExistsAsync(
string roleName
)
{
//
if (roleName.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
return await RoleManager.RoleExistsAsync(roleName);
}
/// <summary>
/// Create a new Role
/// </summary>
/// <param name="roleName">role name</param>
/// <returns>an instance of <see>IdentityResult</see></returns>
public async Task<IdentityResult> CreateRoleAsync(
string roleName
)
{
//
var isExists = await RoleManager
.RoleExistsAsync(roleName);
if (isExists)
{
XException.Duplicate.Throw();
}
//
var result = await RoleManager
.CreateAsync(new IdentityRole(roleName));
//
return result;
}
/// <summary>
/// Get a Role
/// </summary>
/// <param name="roleName">role name</param>
/// <returns>an instance of <see>IdentityRole</see></returns>
public async Task<IdentityRole> GetRoleAsync(
string roleName
)
{
//
var isExists = await IsRoleExistsAsync(roleName);
if (!isExists)
{
XException.NotFound.Throw();
}
//
var result = await RoleManager
.FindByNameAsync(roleName);
//
return result;
}
/// <summary>
/// Remove a User From Role
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="roleName">role name</param>
/// <returns>an instance of <see>IdentityResult</see></returns>
public async Task<IdentityResult> RemoveFromRoleAsync(
XUser user,
string roleName
)
{
return await UserManager.RemoveFromRoleAsync(user, roleName);
}
/// <summary>
/// Remove a User From Roles
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="roleNames">a collection of role names</param>
/// <returns>an instance of <see>IdentityResult</see></returns>
public async Task<IdentityResult> RemoveFromRolesAsync(
XUser user,
IEnumerable<string> roleNames
)
{
return await UserManager.RemoveFromRolesAsync(user, roleNames);
}
/// <summary>
/// Assign a User to Specific Role
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="roleName">role name</param>
/// <returns>an instance of <see>IdentityResult</see></returns>
public async Task<IdentityResult> AddUserToRoleAsync(
XUser user,
string roleName
)
{
//
if (user == null ||
roleName.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
var userSelectByParam = GetUserSelectByParam(user);
var isExistsUser = await IsUserExistsAsync(userSelectByParam);
var isExistsRole = await IsRoleExistsAsync(roleName);
if (!isExistsUser || !isExistsRole)
{
XException.NotFound.Throw();
}
//
var result = await UserManager
.AddToRoleAsync(user, roleName);
//
return result;
}
/// <summary>
/// Retrieve Role Name by it's ID
/// </summary>
/// <param name="roleId">role id</param>
/// <returns>role name as string</returns>
public async Task<string> GetRoleNameAsync(
string roleId
)
{
//
// Validate Args ...
if (roleId.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
var role = await RoleManager
.FindByIdAsync(roleId);
//
return role.Name.ToNormalString();
}
/// <summary>
/// Get a List Of User Roles
/// </summary>
/// <param name="userSelectByParam">user identifier</param>
/// <param name="checkCanLoginPolicies"></param>
/// <param name="checkIsBanned"></param>
/// <returns>a collection of role names</returns>
public async Task<IEnumerable<string>> GetRoleNamesAsync(
string userSelectByParam,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Validate Args ...
if (userSelectByParam.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned
);
//
var result = new List<string>();
foreach (var role in user.Roles)
{
//
var roleName = await GetRoleNameAsync(role.RoleId);
roleName = roleName.ToNormalString();
//
result.Add(roleName);
}
//
return result;
}
/// <summary>
/// Check a User is Adminr not
/// </summary>
/// <param name="userSelectByParam">user identifier</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsAdmin(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true,
checkCanLoginPolicies: true);
//
var result = await IsAdmin(user);
//
return result;
}
/// <summary>
/// Check a User is Adminr not
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <returns>a boolean value</returns>
public async Task<bool> IsAdmin(
XUser user
)
{
//
// Validate Args ...
ValidationProvider.NotNull(user);
ValidationProvider.NotEmpty(user.Id);
//
// Retrieve Admin Role ...
// TODO: Fix this ...
var adminRole = "admin";
// XUserRole.Admin
// .GetStringValue ()
// .ToNormalString ();
//
// Check Admin Role Exists in User Roles or not ...
var userRoleNames = await GetRoleNamesAsync(user.Id);
var isContainsAdminRole = userRoleNames.Contains(adminRole);
//
// Return Result ...
return isContainsAdminRole;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Search.cs
using System.Threading.Tasks;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Dtos;
using xModels.Dtos;
using xDataService.Extensions;
using xIds.Extensions;
using System.Linq;
using xIdentityModels.Extensions;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Actions ...
/// <summary>
/// Query User Profiles
/// </summary>
/// <param name="requestedUserSelectByParam">requested user's identifier</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(
string requestedUserSelectByParam,
XQuery query
)
{
//
// Validation ...
if (query.IsNull())
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
//
// Since in Resourceable Entities we have to Search on Locales
// we Must Implement Senario Custom ...
var totalEntities = GetUsersDbSet()
.Where(u => u.OpenToSearch)
.ToList()
.Where(u => !u.ContainsUserSelectByParam(requestedUserSelectByParam))
.Select(u => u.Id)
.ToList();
//
var items = await GetUserProfilesAsync(
totalEntities,
requestedUserSelectByParam,
checkIsBanned: false,
checkCanLoginPolicies: false,
forceCheckRequestedUser: false
);
//
var totalItemsCount = items.Count();
//
// Apply Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
items = items
.ApplyFilter(query.Filter);
}
int filteredItemsCount = items.Count();
//
// Count Pages ...
var totalPagesCount = query.CountPages(totalItemsCount);
var filteredPagesCount = query.CountPages(filteredItemsCount);
//
// Apply Paging and Sorting ...
if (totalItemsCount > 0 &&
filteredItemsCount > 0)
{
//
// Apply Sorting ...
items = items
.ToList()
.ApplySorting(
query.SortBy,
query.IsAscending
);
//
// Apply Paging ...
items = items
.ToList()
.ApplyPaging(
query.Page,
query.PageSize
);
}
//
// Generate Result Object ...
// Query = query,
var result = new XQueryResult<XUserProfileDto>
{
Items = items,
Page = query.Page,
PageSize = query.PageSize,
TotalPages = totalPagesCount,
TotalItems = totalItemsCount,
TotalFilteredPages = filteredPagesCount,
TotalFilteredItems = filteredItemsCount
};
//
return result;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Seed.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Descriptors;
using xIdentityModels.Extensions;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Default Identity Preparation Actions ...
/// <summary>
/// Create Default Roles based on Identity Configuration
/// </summary>
/// <returns></returns>
public async Task CreateIdentityRoles()
{
//
if (Configuration == null ||
Configuration.IdentityRoles == null ||
Configuration.IdentityRoles.Count == 0)
{
return;
}
//
// Check New Users Role exists in IdentityRole or not ...
if (!Configuration.NewUsersRole.IsNullOrEmpty())
{
//
// Ensure NewUsersRole Exists in IdentityRoles ...
var isNewUserRoleExistsInIdentityRoles = Configuration
.IdentityRoles
.Contains(Configuration.NewUsersRole);
if (!isNewUserRoleExistsInIdentityRoles)
{
XException.InvalidArgs.Throw();
}
}
//
// loop through all roles and create them one by one ...
foreach (var roleName in Configuration.IdentityRoles)
{
//
var isRoleExists = await RoleManager.RoleExistsAsync(roleName);
if (!isRoleExists)
{
//
var result = await RoleManager.CreateAsync(new IdentityRole(roleName));
}
}
}
/// <summary>
/// Create a user Based on User Descriptor
/// </summary>
/// <param name="user">an instance of <see>XIdentityUserDescriptor</see></param>
/// <returns></returns>
public async Task CreateUserAsync(
XIdentityUserDescriptor user
)
{
//
// Validate Args ...
ValidationProvider.NotNull(user);
//
var isExistsRole = await RoleManager.RoleExistsAsync(user.Role);
if (!isExistsRole)
{
//
// Check Assigned role to user exists in app roles ...
if (!Configuration
.IdentityRoles
.Contains(user.Role))
{
XException.InvalidArgs.Throw();
}
//
// Ensure All Roles Created ...
await CreateIdentityRoles();
}
//
// Check User Exists ...
var isExistsUser = await IsUserExistsAsync(user.UserName);
if (!isExistsUser)
{
//
// Create a DashboardUser instance based on Configuration Data ...
var userEntity = user.ToXUser();
//
// Try to Create User ...
var userCreateResult = await CreateUserAsync(
userEntity,
user.Password
);
if (!userCreateResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
// Assign Admin User to it's Role ...
var roleAssignResult = await UserManager.AddToRoleAsync(userEntity, user.Role);
if (!roleAssignResult.Succeeded)
{
XException.ActionFailed.Throw();
}
//
var claims = await ToJwtClaims(
userEntity,
checkCanLoginPolicies: true,
checkIsBanned: true);
//
var addClaimsResult = await UserManager.AddClaimsAsync(userEntity, claims);
if (!addClaimsResult.Succeeded)
{
XException.ActionFailed.Throw();
}
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Token.cs
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using xCommons.Extensions;
using xCommons.Helpers;
using xExceptions.Constants;
using xIdentityModels;
using xIdentityModels.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Token Actions ...
/// <summary>
/// Check a Token Entity Exists or not
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="type">specifies Action Step by a member of <see>XAction</see></param>
/// <returns>a boolean value</returns>
private async Task<bool> IsTokenExistsByDeviceAndType(
XDevice device,
XAction type
)
{
//
ValidationProvider.NotNull(device);
//
var isExists = false;
var enumerator = DbContext.Tokens.AsAsyncEnumerable();
await
foreach (var token in enumerator)
{
//
if (token.Type == type &&
token.Device.IsSameAs(device))
{
isExists = true;
break;
}
}
//
return isExists;
}
/// <summary>
/// Check a Token Entity Exists or not
/// </summary>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <param name="type">specifies Action Step by a member of <see>XAction</see></param>
/// <returns>a boolean value</returns>
private async Task<bool> IsTokenExistsByUserAndType(
string userSelectByParam,
XAction type
)
{
//
ValidationProvider.NotEmpty(userSelectByParam);
//
var isExists = false;
var tokensEnumerator = DbContext.Tokens.AsAsyncEnumerable();
await
foreach (var token in tokensEnumerator)
{
//
if (token.Type == type &&
token.UserSelectByParam
.ToNormalString() == userSelectByParam
.ToNormalString())
{
//
isExists = true;
break;
}
}
//
return isExists;
}
/// <summary>
/// Check a Token Entity Exists or not
/// </summary>
/// <param name="token">represent specified action token</param>
/// <returns>a boolean value</returns>
private async Task<bool> IsTokenExistsByToken(
string token
)
{
//
var result = await DbContext.Tokens
.AnyAsync(xt => xt.Token == token);
//
return result;
}
/// <summary>
/// Check a Token Entity Exists or not
/// </summary>
/// <param name="hash">represent specified action token hash</param>
/// <returns>a boolean value</returns>
private async Task<bool> IsTokenExistsByHash(
string hash
)
{
//
var result = await DbContext.Tokens
.AnyAsync(xt => xt.Hash == hash);
//
return result;
}
/// <summary>
/// Check a Token Entity Exists or not
/// </summary>
/// <param name="item">an instance of <see>XToken</see></param>
/// <returns>a boolean value</returns>
private async Task<bool> IsTokenExistsByToken(
XToken item
)
{
//
var result = false;
var tokenEnumerator = DbContext.Tokens
.AsAsyncEnumerable();
await
foreach (var token in tokenEnumerator)
{
//
if (token.Hash == item.Hash &&
token.Token == item.Token &&
token.Type == item.Type &&
token.UserSelectByParam
.ToNormalString() == item.UserSelectByParam
.ToNormalString() &&
token.Device.IsSameAs(item.Device))
{
//
result = true;
break;
}
}
//
return result;
}
/// <summary>
/// Check a Token Entity Exists or not
/// </summary>
/// <param name="id">specifies token id</param>
/// <returns>a boolean value</returns>
private async Task<bool> IsTokenExistsById(
int id
)
{
return await DbContext.Tokens.AnyAsync(t => t.Id == id);
}
/// <summary>
/// Retrieve Token Entity
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="type">specifies Action Step by a member of <see>XAction</see></param>
/// <returns>an instance of <see>XToken</see></returns>
private async Task<XToken> GetTokenByDeviceAndType(
XDevice device,
XAction type
)
{
//
var isExists = await IsTokenExistsByDeviceAndType(device, type);
if (!isExists)
{
return null;
}
//
XToken item = null;
var enumerator = DbContext.Tokens.AsAsyncEnumerable();
await
foreach (var token in enumerator)
{
//
if (token.Type == type &&
token.Device.IsSameAs(device))
{
//
item = token;
break;
}
}
//
return item;
}
/// <summary>
/// Retrieve Token Entity
/// </summary>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <param name="type">specifies Action Step by a member of <see>XAction</see></param>
/// <returns>an instance of <see>XToken</see></returns>
private async Task<XToken> GetTokenByUserAndType(
string userSelectByParam,
XAction type
)
{
//
var isExists = await IsTokenExistsByUserAndType(userSelectByParam, type);
if (!isExists)
{
return null;
}
//
XToken item = null;
var enumerator = DbContext.Tokens.AsAsyncEnumerable();
await
foreach (var token in enumerator)
{
//
if (token.Type == type &&
token.UserSelectByParam
.ToNormalString() == userSelectByParam
.ToNormalString())
{
//
item = token;
break;
}
}
//
return item;
}
/// <summary>
/// Retrieve a Token Entity
/// </summary>
/// <param name="token">represent specified action token</param>
/// <returns>an instance of <see>XToken</see></returns>
private async Task<XToken> GetTokenByToken(
string token
)
{
//
var isExists = await IsTokenExistsByToken(token);
if (!isExists)
{
return null;
}
//
var result = await DbContext.Tokens
.FirstOrDefaultAsync(xt => xt.Token == token);
//
return result;
}
/// <summary>
/// Retrieve Related Hash to a Token
/// </summary>
/// <param name="token">represent specified action token</param>
/// <returns>hash string</returns>
private async Task<string> GetRelatedHashByToken(
string token
)
{
//
var item = await GetTokenByToken(token);
if (item == null)
{
return null;
}
//
return item.Hash;
}
/// <summary>
/// Retrieve a Token Entity
/// </summary>
/// <param name="hash">represent specified action token hash</param>
/// <returns>an instance of <see>XToken</see></returns>
private async Task<XToken> GetTokenByHash(
string hash
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(hash);
//
var isExists = await IsTokenExistsByHash(hash);
if (!isExists)
{
return null;
}
//
var item = await DbContext.Tokens
.FirstOrDefaultAsync(t => t.Hash == hash);
//
return item;
}
/// <summary>
/// Retrieve Related Token to a Hash string
/// </summary>
/// <param name="hash">represent specified action token hash</param>
/// <returns>token string</returns>
private async Task<string> GetRelatedTokenByHash(
string hash
)
{
//
var item = await GetTokenByHash(hash);
if (item == null)
{
return null;
}
//
return item.Token;
}
/// <summary>
/// Retrieve a Token Expiration Date
/// </summary>
/// <param name="token">represent specified action token</param>
/// <returns>an instance of <see>DateTime</see></returns>
private DateTime GetTokenExpirationDate(
string token
)
{
//
ValidationProvider.NotEmpty(token);
//
var result = IdentityHelper.GetTokenExpirationDate(token);
//
return result;
}
/// <summary>
/// Remove a Token Entity
/// </summary>
/// <param name="token">represent specified action token</param>
/// <returns></returns>
private async Task RemoveTokenByToken(
string token
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(token);
//
var isExists = await IsTokenExistsByToken(token);
if (!isExists)
{
return;
}
//
var item = await GetTokenByToken(token);
if (item == null)
{
return;
}
//
DbContext.Tokens.Remove(item);
await DbContext.SaveChangesAsync();
}
/// <summary>
/// Remove a Token Entity
/// </summary>
/// <param name="hash">represent specified action token hash</param>
/// <returns></returns>
private async Task RemoveTokenByHash(
string hash
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(hash);
//
var isExists = await IsTokenExistsByHash(hash);
if (!isExists)
{
return;
}
//
var item = await GetTokenByHash(hash);
if (item == null)
{
return;
}
//
DbContext.Tokens.Remove(item);
await DbContext.SaveChangesAsync();
}
/// <summary>
/// Remove a Token Entity
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns></returns>
private async Task RemoveTokenByDevice(
XDevice device
)
{
//
// Validate Args ...
ValidationProvider.NotNull(device);
//
XToken items = null;
var enumerator = DbContext.Tokens.AsAsyncEnumerable();
await
foreach (var token in enumerator)
{
//
if (token.Device.IsSameAs(device))
{
//
items = token;
break;
}
}
//
if (!items.IsNull())
{
DbContext.Tokens.RemoveRange(items);
await DbContext.SaveChangesAsync();
}
}
/// <summary>
/// add a token Entity
/// </summary>
/// <param name="item">an instance of <see>XToken</see></param>
/// <returns>an instance of <see>XToken</see></returns>
private async Task<XToken> AddTokenAsync(
XToken item
)
{
//
var isExist = await IsTokenExistsByToken(item);
if (isExist)
{
return await GetTokenByHash(item.Hash);
}
//
var entry = await DbContext.Tokens.AddAsync(item);
await DbContext.SaveChangesAsync();
//
return entry.Entity;
}
/// <summary>
/// Hash a Request Token
/// </summary>
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
/// <param name="forceNotNullUserSelectByParam"></param>
/// <param name="forceDeviceNotNull"></param>
/// <returns>an instance of <see>XToken</see></returns>
private async Task<XToken> HashRequest(
XActionRequestToken request,
bool forceNotNullUserSelectByParam = true,
bool forceDeviceNotNull = true
)
{
//
// Validate Args ...
var secretKey = Configuration.IdentitySecretKey;
ValidationProvider.NotNull(request);
ValidationProvider.NotEmpty(secretKey);
//
ValidateActionRequest(request);
//
var type = request.Action;
var device = request.Context.Device;
var tokenObject = ToSecurityToken(request);
var tokenString = ToTokenString(tokenObject);
var tokenHash = ToHash(tokenString);
var userSelectByParam = GetUserSelectByParam(request, forceNotNullUserSelectByParam);
//
if (forceNotNullUserSelectByParam)
{
ValidationProvider.NotEmpty(userSelectByParam);
}
//
ValidationProvider.NotEmpty(tokenString, tokenHash);
//
if (forceDeviceNotNull)
{
ValidationProvider.NotNull(device);
}
//
ValidationProvider.NotNull(tokenObject);
//
var xToken = new XToken
{
Type = type,
Device = device,
Hash = tokenHash,
Token = tokenString,
UserSelectByParam = userSelectByParam
};
//
var addedToken = await AddTokenAsync(xToken);
//
return addedToken;
}
/// <summary>
/// Generate Token Hash string
/// </summary>
/// <param name="token">represent specified action token</param>
/// <param name="checkValidation">check token validation parameters, default is true</param>
/// <returns>hash string</returns>
private string ToHash(
string token,
bool checkValidation = true
)
{
//
ValidationProvider.NotEmpty(token);
//
if (checkValidation)
{
ValidateToken(token);
}
//
var result = token.ToMd5String().ToNormalString();
//
return result;
}
/// <summary>
/// Generate Token string
/// </summary>
/// <param name="token">represent specified action token</param>
/// <returns>token string</returns>
private string ToTokenString(
SecurityToken token
)
{
//
ValidationProvider.NotNull(token, IdentityHelper);
//
var result = IdentityHelper.ToTokenString(token);
//
return result;
}
/// <summary>
/// Generate Token string
/// </summary>
/// <param name="token">represent specified action token</param>
/// <returns>token string</returns>
private string ToTokenString(
JwtSecurityToken token
)
{
//
ValidationProvider.NotNull(token, IdentityHelper);
//
var result = IdentityHelper.ToTokenString(token);
//
return result;
}
/// <summary>
/// Generate Security Token
/// </summary>
/// <param name="token">represent specified action token</param>
/// <returns>an instance of <see>SecurityToken</see></returns>
private SecurityToken ToSecurityToken(
string token
)
{
//
ValidationProvider.NotEmpty(token);
//
var result = IdentityHelper.ToSecurityToken(token);
//
return result;
}
/// <summary>
/// Generate Security Token
/// </summary>
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
/// <returns>an instance of <see>SecurityToken</see></returns>
private SecurityToken ToSecurityToken(
XActionRequestToken request
)
{
//
ValidationProvider.NotNull(request);
//
ValidateActionRequest(request);
//
var result = IdentityHelper.ToSecurityToken(request);
if (result == null)
{
XException.InvalidToken.Throw();
}
//
return result;
}
/// <summary>
/// Cleanup all exists tokens related to specified User
/// </summary>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <returns></returns>
private async Task HandleRemoveExistsTokens(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
var xTokens = new List<XToken>();
var xTokenEnumerator = DbContext.Tokens.AsAsyncEnumerable();
await
foreach (var xToken in xTokenEnumerator)
{
//
if (xToken.UserSelectByParam == userSelectByParam &&
ObjectHelper.ToEnumerableValues<XAction>().Contains(xToken.Type))
{
xTokens.Add(xToken);
}
}
//
if (xTokens.HasChild())
{
DbContext.Tokens.RemoveRange(xTokens);
await DbContext.SaveChangesAsync();
}
}
/// <summary>
/// Cleanup all tokens related to specified User
/// </summary>
/// <param name="userSelectByParams">a collection of user identifiers</param>
/// <returns></returns>
private async Task HandleCleanUserTokens(
ICollection<string> userSelectByParams
)
{
//
// Validate Args ...
if (!userSelectByParams.HasChild())
{
return;
}
//
foreach (var userSelectByParam in userSelectByParams)
{
await HandleRemoveExistsTokens(userSelectByParam);
}
}
/// <summary>
/// Cleanup all tokens related to specified User
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <returns></returns>
private async Task HandleCleanUserTokens(
XUser user
)
{
//
if (user == null)
{
return;
}
//
var userSelectByParams = GenerateUserSelectByParams(user);
//
await HandleCleanUserTokens(userSelectByParams);
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+User.cs
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using IdentityModel;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using xCommons.Constants;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Extensions;
using xIdentityModels.Navigations;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region User Handlers ...
/// <summary>
/// Check a User Exists or not
/// </summary>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <returns>a boolean value</returns>
public async Task<bool> IsUserExistsAsync(
string userSelectByParam
)
{
//
// Validate Args ...
if (userSelectByParam.IsNullOrEmpty())
{
return false;
}
//
var selectType = GetUserSelectByType(userSelectByParam);
//
var result = false;
XUser user = null;
switch (selectType)
{
case XUserSelectBy.MobileNumber:
user = await GetUsersDbSet()
.Where(ur => ur.PhoneNumber == userSelectByParam)
.FirstOrDefaultAsync();
break;
case XUserSelectBy.Email:
user = await UserManager
.FindByEmailAsync(userSelectByParam);
break;
case XUserSelectBy.Username:
user = await UserManager
.FindByNameAsync(userSelectByParam);
break;
case XUserSelectBy.ID:
default:
user = await UserManager
.FindByIdAsync(userSelectByParam);
break;
}
//
result = user != null;
//
return result;
}
/// <summary>
/// Check a User Selector is Available for Registration or Not
/// </summary>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <returns>a boolean value</returns>
public async Task<bool> CanRegister(
string userSelectByParam
)
{
//
// Validate ARgs ...
ValidationProvider.NotEmpty(userSelectByParam);
//
var selectByType = GetUserSelectByType(userSelectByParam);
//
if (selectByType == XUserSelectBy.Username &&
!ValidateUserName(userSelectByParam))
{
return false;
}
//
var isExists = await IsUserExistsAsync(userSelectByParam);
if (isExists)
{
return false;
}
//
return true;
}
/// <summary>
/// Get a User object
/// </summary>
/// <param name="userSelectByParam">specified user's identifier</param>
/// <param name="containDetails">specifies returned object contains all Navigation Properties or not, default is false</param>
/// <returns>an instance of <see>XUser</see></returns>
public async Task<XUser> GetUserAsync(
string userSelectByParam,
bool containDetails = false
)
{
//
var isExists = await IsUserExistsAsync(userSelectByParam);
if (!isExists)
{
XException.NotFound.Throw();
}
//
// Fill User ...
var selectType = GetUserSelectByType(userSelectByParam);
XUser user = null;
var usersStore = GetUsersDbSet(containDetails);
//
// Select Type ...
switch (selectType)
{
case XUserSelectBy.MobileNumber:
user = await usersStore
.FirstOrDefaultAsync(ur => ur.PhoneNumber ==
userSelectByParam);
break;
case XUserSelectBy.Email:
user = await usersStore
.FirstOrDefaultAsync(ur => ur.Email ==
userSelectByParam);
break;
case XUserSelectBy.Username:
user = await usersStore
.FirstOrDefaultAsync(ur => ur.UserName ==
userSelectByParam);
break;
case XUserSelectBy.ID:
default:
user = await usersStore
.FirstOrDefaultAsync(ur => ur.Id ==
userSelectByParam);
break;
}
//
return user;
}
/// <summary>
/// Retrieve User Names based on UserIds
/// </summary>
/// <param name="userIds">a collection of user identifiers</param>
/// <returns>a collection of Usernames</returns>
public async Task<IEnumerable<string>> GetUserNamesAsync(
IEnumerable<string> userIds
)
{
//
// Validate Args ...
if (userIds == null ||
userIds.Count() == 0)
{
return null;
}
//
var result = await GetUsersDbSet()
.Where(
xu =>
userIds
.Contains(xu.Id))
.Select(xt => xt.UserName)
.ToListAsync();
//
return result;
}
/// <summary>
/// get user ids and retrieve corresponding user names
/// </summary>
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represent required UserIds collection</param>
/// <returns>a collection of <see>XUserNameIdResponse</see> instances</returns>
public async Task<IEnumerable<XUserNameIdResponse>> GetUserNameIdsAsync(
XUserNameIdRequest model
)
{
//
// Validate Args ...
if (model.IsNull() || !model.Ids.HasChild())
{
return null;
}
//
var result = await GetUsersDbSet()
.Where(
xu =>
model.Ids.Contains(xu.Id) ||
model.Ids.Contains(xu.Email) ||
model.Ids.Contains(xu.UserName) ||
model.Ids.Contains(xu.PhoneNumber))
.Select(xt => new XUserNameIdResponse
{
Id = xt.Id,
UserName = xt.UserName,
})
.ToListAsync();
//
return result;
}
/// <summary>
/// Create a User
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="password">user's password</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is false</param>
/// <param name="checkIsBanned">check user is banned or not, default is false</param>
/// <returns>an instance of <see>IdentityResult</see></returns>
public async Task<IdentityResult> CreateUserAsync(
XUser user,
string password,
bool checkCanLoginPolicies = false,
bool checkIsBanned = false
)
{
//
if (user == null ||
password.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
// Get User Select By param
var userSelectByParam = GetUserSelectByParam(user, excludes: new List<XUserSelectBy> { XUserSelectBy.ID });
//
// Check User Created before or not ...
var isExists = await IsUserExistsAsync(userSelectByParam);
if (isExists)
{
XException.Duplicate.Throw();
}
//
var result = await UserManager.CreateAsync(user, password);
if (result.Succeeded)
{
//
var claims = await ToJwtClaims(
user,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned);
//
var addClaimsResult = await UserManager.AddClaimsAsync(user, claims);
//
return addClaimsResult;
}
//
return result;
}
/// <summary>
/// Update a User Information
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <returns>an instance of <see>IdentityResult</see></returns>
public async Task<IdentityResult> UpdateUserAsync(
XUser user,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
var updateResult = await this.UserManager.UpdateAsync(user);
if (updateResult.Succeeded)
{
//
var claims = await ToJwtClaims(
user,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned
);
var existsClaims = await UserManager.GetClaimsAsync(user);
//
await UserManager.RemoveClaimsAsync(user, existsClaims);
var addClaimsResult = await UserManager.AddClaimsAsync(user, claims);
//
return addClaimsResult;
}
//
return updateResult;
}
/// <summary>
/// Generate JWT Claims froma DashboardUser object
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <returns>a collection of <see>Claim</see> instances</returns>
public async Task<Claim[]> ToJwtClaims(
XUser user,
bool checkCanLoginPolicies = true,
bool checkIsBanned = true
)
{
//
// Get New Instance of Claims ...
var claims = new List<Claim> {
//
// Mapping to User.Identity.Name ...
new Claim (JwtClaimTypes.Name, user.UserName),
//
// Mapping to User.Identity.Name ...
new Claim (JwtRegisteredClaimNames.UniqueName, user.UserName),
//
// Other Usefull User Related Data ...
new Claim (JwtClaimTypes.GivenName, user.FirstName),
new Claim (JwtClaimTypes.FamilyName, user.LastName),
//
// User Gendre ...
new Claim (JwtClaimTypes.Gender, user.Gender.ToString (), ClaimValueTypes.Integer),
//
// User Profile Picture ...
new Claim (JwtClaimTypes.Picture, !user.Avatar.IsNullOrEmpty () ?
user.Avatar.ToString () :
""),
//
// The Unique Identifier for Each Token ...
new Claim (JwtRegisteredClaimNames.Jti, Guid.NewGuid ().ToString ()),
//
// Add isEnable and isBanned feature ...
new Claim (
XCustomClaims.IsEnabled,
user.IsEnable.ToString (),
ClaimValueTypes.Boolean
),
new Claim (
XCustomClaims.IsBanned,
user.IsBanned.ToString (),
ClaimValueTypes.Boolean
),
};
//
#region Set Claims based on Profile Policies ...
//
if (Configuration.Policy.Profile.ContainsDateOfBirth)
{
claims.Add(new Claim(JwtRegisteredClaimNames.Birthdate, user.DateOfBirth.ToString()));
}
//
if (Configuration.Policy.Profile.ContainsEmail)
{
claims.Add(new Claim(JwtClaimTypes.Email, user.Email));
claims.Add(new Claim(
JwtClaimTypes.EmailVerified,
user.EmailConfirmed.ToString(),
ClaimValueTypes.Boolean));
}
//
if (Configuration.Policy.Profile.ContainsPhoneNumber)
{
claims.Add(new Claim(JwtClaimTypes.PhoneNumber, user.PhoneNumber));
claims.Add(new Claim(
JwtClaimTypes.PhoneNumberVerified,
user.PhoneNumberConfirmed.ToString(),
ClaimValueTypes.Boolean));
}
//
if (Configuration.Policy.Profile.ContainsRoles)
{
var roleNames = await GetRoleNamesAsync(
user.UserName,
checkCanLoginPolicies: checkCanLoginPolicies,
checkIsBanned: checkIsBanned);
roleNames.ToList()
.ForEach(rn =>
{
claims.Add(new Claim(JwtClaimTypes.Role, rn));
});
}
//
if (Configuration.Policy.Profile.ContainsLastLogin)
{
claims.Add(new Claim(
JwtClaimTypes.AuthenticationTime,
user.LastLogin.ToString(),
ClaimValueTypes.DateTime));
}
#endregion
//
// Return Result ...
return claims.ToArray();
}
/// <summary>
/// Check User and Password relation
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="password">user's password</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="language">specify destination language</param>
/// <param name="lockoutOnFailure">specify account lockout on failure log in</param>
/// <param name="isForced">specify log in force without checking <see>XDevice</see> and lang relation</param>
/// <returns>an instance of <see>SignInResult</see></returns>
public async Task<SignInResult> CheckPasswordSignInAsync(
XUser user,
string password,
XDevice device,
string language,
bool lockoutOnFailure,
bool isForced = true
)
{
//
var result = await SignInManager.CheckPasswordSignInAsync(
user, password, lockoutOnFailure
);
//
if (result.Succeeded && isForced)
{
//
var isExistsDevice = user.Devices.Any(d => d.IsSameAs(device));
if (!isExistsDevice && !user.Email.IsNullOrEmpty() && user.EmailConfirmed)
{
//
user.Devices.Add(device);
//
var updateUserResult = await UpdateUserAsync(user);
if (updateUserResult.Succeeded)
{
//
try
{
//
var xMessage = GetUserNewDeviceLoggedInMessage(
language,
user.Email,
device
);
//
await MessageProvider.SendMailAsync(xMessage);
}
catch { }
}
}
}
//
return result;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Validators.cs
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels;
using xIdentityModels.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region User Validators ...
/// <summary>
/// Validate User Name for Registration based on Policies
/// </summary>
/// <param name="userName">provided user name</param>
/// <returns>a boolean value</returns>
private bool ValidateUserName(
string userName
)
{
//
// Check min/max Length ...
if (userName.IsNullOrEmpty() ||
userName.Length < Configuration.Policy.User.MinLength ||
userName.Length > Configuration.Policy.User.MaxLength)
{
return false;
}
//
// Check Allowed UserName Characters ...
if (!UserManager.Options.User.AllowedUserNameCharacters.IsNullOrEmpty() &&
userName.Any(c => !UserManager.Options.User.AllowedUserNameCharacters.Contains(c)))
{
return false;
}
//
// Check invalid UserNames ...
if (Configuration.Policy.User.InvalidUserNames
.HasChild() && Configuration.Policy.User.InvalidUserNames
.Any(u => userName
.ToNormalString()
.Contains(u.ToNormalString())))
{
return false;
}
//
return true;
}
/// <summary>
/// Validate a User Exists
/// </summary>
/// <param name="userSelectByParam">specifies user identifier</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateUserExistsAsync(
string userSelectByParam,
Exception exception = null
)
{
//
ValidationProvider
.NotEmpty(userSelectByParam);
//
if (exception == null)
{
exception = XException.NotFound.ToException();
}
//
// Check User Exists ...
var isExists = await IsUserExistsAsync(userSelectByParam);
if (!isExists)
{
throw exception;
}
}
/// <summary>
/// Validate a User Not Exists
/// </summary>
/// <param name="userSelectByParam">specifies user identifier</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateUserNotExists(
string userSelectByParam,
Exception exception = null
)
{
//
ValidationProvider
.NotEmpty(userSelectByParam);
//
if (exception == null)
{
exception = XException.UserRegisteredBefore.ToException();
}
//
// Check User Exists ...
var isExists = await IsUserExistsAsync(userSelectByParam);
if (isExists)
{
throw exception;
}
}
/// <summary>
/// Validate User Exists and Some Usefull Checks
/// </summary>
/// <param name="userSelectByParam">specifies user identifier</param>
/// <param name="containDetails">specifies returned object contains all Navigation Properties or not, default is false</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is false</param>
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
/// <param name="ignoreDisabledUser">specify do not thrown <see>Exception</see> if user is Disabled, default is false</param>
/// <param name="forceAdmin">specify requested person is Admin role, default is false</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>an instance of <see>XUser</see></returns>
public async Task<XUser> ValidateUserExistsAndRetrieve(
string userSelectByParam,
bool containDetails = false,
bool checkCanLoginPolicies = false,
bool checkIsBanned = true,
bool ignoreDisabledUser = false,
bool forceAdmin = false,
Exception exception = null
)
{
//
ValidationProvider
.NotEmpty(userSelectByParam);
ValidationProvider.NotNull(
Configuration,
Configuration.Policy,
Configuration.Policy.SignIn);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidData.ToException();
}
//
// Check User Exists ...
await ValidateUserExistsAsync(userSelectByParam);
//
// Retrieve User ...
var result = await GetUserAsync(userSelectByParam, containDetails);
if (result == null)
{
throw exception;
}
//
// Check Force Admin ...
if (forceAdmin)
{
//
var isAdmin = await IsAdmin(result);
if (!isAdmin)
{
XException.NotAuthorized.Throw();
}
}
//
// Check User not Bann ...
if (checkIsBanned &&
result.IsBanned)
{
XException.UserBanned.Throw();
}
//
var requireConfirmedEmail = Configuration.Policy.SignIn.RequireConfirmedEmail;
var requireConfirmedPhoneNumber = Configuration.Policy.SignIn.RequireConfirmedPhoneNumber;
var requireEnabled = Configuration.Policy.SignIn.RequiredEnabled;
//
var isEnabled = result.IsEnable;
var isMobileConfirmed = result.PhoneNumberConfirmed;
var isEmailConfirmed = result.EmailConfirmed;
//
if (checkCanLoginPolicies)
{
//
// Check IsEnabled ...
if (!ignoreDisabledUser &&
requireEnabled &&
!isEnabled)
{
XException.UserDisabled.Throw();
}
//
// Check Email Confirmed ...
if (requireConfirmedEmail &&
!isEmailConfirmed)
{
XException.EmailNotConfirmed.Throw();
}
//
// Check Mobile Confirmed ...
if (requireConfirmedPhoneNumber &&
!isMobileConfirmed)
{
XException.MobileNotConfirmed.Throw();
}
}
//
// Return Result ...
return result;
}
/// <summary>
/// Validate a Device for User Actions
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns></returns>
private async Task ValidateDeviceForActions(
XDevice device
)
{
//
ValidationProvider
.NotNull(device);
//
// Check is Device Banned or not ...
var isDeviceBanned = await IsDeviceBanned(device);
if (isDeviceBanned)
{
//
// Retrieve Banned Device ...
var xBannedDevice = await GetBannedDevice(device);
if (xBannedDevice == null)
{
XException.InvalidArgs.Throw();
}
//
// Check Banned Device Time out Passed or not ...
var isDelayTimePassed = IsDelayTimePassed(xBannedDevice);
if (!isDelayTimePassed)
{
//
var passedTime = GetPassedTime(xBannedDevice);
//
XException.DeviceBanned
.AddContentToException(passedTime.ToString());
}
//
// if Delay Passed of Banned Device
// the device must Removed ...
await BannedDeviceRemove(xBannedDevice);
}
}
/// <summary>
/// Validate a DateOfBirth for Registration
/// </summary>
/// <param name="dateOfBirth">users dob date, an instance of <see>DateTime</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private void ValidateDateOfBirth(
DateTime dateOfBirth,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(dateOfBirth);
//
if (exception.IsNull())
{
exception = XException.InvalidDate.ToException();
}
//
var currentDate = DateTime.UtcNow;
if (dateOfBirth >= currentDate)
{
throw exception;
}
//
var zeroDate = (new DateTime(1, 1, 1)).ToUniversalTime();
var minAge = Configuration.Policy.User.MinAgeForRegistration;
var maxAge = Configuration.Policy.User.MaxAgeForRegistration;
//
var timeSpan = currentDate - dateOfBirth;
var age = (zeroDate + timeSpan).Year - 1;
//
if (age > maxAge || age < minAge)
{
throw exception;
}
}
/// <summary>
/// Validate a Given User Can Registere
/// </summary>
/// <param name="userSelectByParam">specifies user identifier</param>
/// <returns></returns>
private async Task ValidateCanRegister(
string userSelectByParam
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(userSelectByParam);
//
var canRegister = await CanRegister(userSelectByParam);
if (!canRegister)
{
XException.Unavailable.Throw();
}
}
/// <summary>
/// Validate Password by Gicen Policies
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="password">user's password</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidatePasswordPolicies(
XUser user,
string password,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(user);
ValidationProvider.NotEmpty(password);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidPassword.ToException();
}
//
// Check new Password Validation ...
var passwordValidator = new PasswordValidator<XUser>();
var checkPasswordResult = await passwordValidator.ValidateAsync(UserManager, user, password);
if (!checkPasswordResult.Succeeded)
{
throw exception;
}
}
/// <summary>
/// Validate a User for Dangerous Actions
/// </summary>
/// <param name="user">an instance of <see>XUser</see></param>
/// <param name="requester">specified which user request Action by an instance of <see>XUser</see></param>
/// <returns></returns>
private async Task ValidateUserForDangerousAction(
XUser user,
XUser requester
)
{
//
// Validate ARgs ...
ValidationProvider.NotNull(user, requester);
//
var requesterRoleNames = await GetRoleNamesAsync(requester.Id);
//
var isSame = user.Id == requester.Id;
var isRequesterAdmin = requesterRoleNames.Any(r => r.ToNormalString() == "admin");
if (!isSame && !isRequesterAdmin)
{
XException.NotAllowed.Throw();
}
}
#endregion
//
#region Device Validators ...
/// <summary>
/// Validate a Device for Specified User
/// </summary>
/// <param name="userSelectByParam">specifies user identifier</param>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateUserAndDeviceRelation(
string userSelectByParam,
XDevice device,
Exception exception = null
)
{
//
ValidationProvider.NotEmpty(userSelectByParam);
ValidationProvider.NotNull(device);
//
if (exception == null)
{
exception = XException.InvalidDevice.ToException();
}
//
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: true);
//
var result = await IsDeviceRelateDToUser(
userSelectByParam,
device
);
if (!result)
{
throw exception;
}
}
#endregion
//
#region Token Validators ...
/// <summary>
/// Validate a Token
/// </summary>
/// <param name="token">token string</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
private void ValidateToken(
string token,
Exception exception = null
)
{
//
ValidationProvider.NotEmpty(token);
//
if (exception == null)
{
exception = XException.InvalidToken.ToException();
}
//
var result = IdentityHelper.ValidateToken(token);
if (!result)
{
throw exception;
}
}
/// <summary>
/// Validate a Token is Specified to a Device and User
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="type">specifies Action type by a member of <see>XAction</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>an instance of <see>XToken</see></returns>
private async Task<XToken> ValidateAndRetieveTokenByDeviceAndType(
XDevice device,
XAction type,
Exception exception = null
)
{
//
ValidationProvider.NotNull(device);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.NotFound.ToException();
}
//
var isExists = await IsTokenExistsByDeviceAndType(device, type);
if (!isExists)
{
throw exception;
}
//
var item = await GetTokenByDeviceAndType(device, type);
if (item == null)
{
throw exception;
}
//
return item;
}
/// <summary>
/// Validate a Token By User and Specified Type
/// </summary>
/// <param name="userSelectByParam">specifies user identifier</param>
/// <param name="type">specifies Action type by a member of <see>XAction</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>an instance of <see>XToken</see></returns>
private async Task<XToken> ValidateAndRetieveTokenByUserAndType(
string userSelectByParam,
XAction type,
Exception exception = null
)
{
//
ValidationProvider.NotEmpty(userSelectByParam);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidData.ToException();
}
//
var isExists = await IsTokenExistsByUserAndType(userSelectByParam, type);
if (!isExists)
{
throw exception;
}
//
var item = await GetTokenByUserAndType(userSelectByParam, type);
if (item == null)
{
throw exception;
}
//
return item;
}
/// <summary>
/// Check Token Validation
/// </summary>
/// <param name="token">token string</param>
/// <returns>a boolean value</returns>
private bool IsValidToken(
string token
)
{
//
ValidationProvider.NotEmpty(token);
//
var result = IdentityHelper.ValidateToken(token);
//
return result;
}
/// <summary>
/// Retrieve Action Request Based on Action Token
/// </summary>
/// <param name="token">token string</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>an instance of <see>XActionRequestToken</see></returns>
private XActionRequestToken ValidateAndParseActionToken(
string token,
Exception exception = null
)
{
//
ValidationProvider.NotEmpty(token);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidToken.ToException();
}
//
ValidateToken(token);
//
var result = IdentityHelper.ParseActionRequestToken(token);
if (result == null)
{
throw exception;
}
//
ValidateActionRequest(result);
//
return result;
}
/// <summary>
/// Parse Action Request from Token
/// </summary>
/// <param name="token">token string</param>
/// <returns>an instance of <see>XActionRequestToken</see></returns>
private XActionRequestToken ParseActionRequest(
string token
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(token);
//
var result = IdentityHelper
.ParseActionRequestToken(token);
//
return result;
}
/// <summary>
/// Parse Action Hash by Corresponding Token
/// </summary>
/// <param name="hash">token hash string</param>
/// <returns>an instance of <see>XActionRequestToken</see></returns>
private async Task<XActionRequestToken> ParseActionHash(
string hash
)
{
//
ValidationProvider.NotEmpty(hash);
//
var isHashExists = await IsTokenExistsByHash(hash);
if (!isHashExists)
{
return null;
}
//
var xToken = await GetTokenByHash(hash);
if (xToken == null)
{
return null;
}
//
var isValidToken = IsValidToken(xToken.Token);
if (!isValidToken)
{
return null;
}
//
var result = ParseActionRequest(xToken.Token);
//
return result;
}
/// <summary>
/// Validate and Parse Action Hash
/// </summary>
/// <param name="hash">token hash string</param>
/// <param name="forceTokenValidation">specifies chack token Validation Parameter, default is true</param>
/// <param name="forceActionValidation">specifies check action Validations, default is true</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>an instance of <see>XActionRequestToken</see></returns>
private async Task<XActionRequestToken> ValidateAndParseActionHash(
string hash,
bool forceTokenValidation = true,
bool forceActionValidation = true,
Exception exception = null
)
{
//
ValidationProvider.NotEmpty(hash);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidToken.ToException();
}
//
var token = await ValidateAndRetrieveRelatedToken(hash, forceTokenValidation);
//
var result = await ParseActionHash(hash);
if (result == null)
{
throw exception;
}
//
if (forceActionValidation)
{
ValidateActionRequest(result);
}
//
return result;
}
/// <summary>
/// Validate Action Request
/// </summary>
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
private void ValidateActionRequest(
XActionRequestToken request,
Exception exception = null
)
{
//
ValidationProvider
.NotNull(request);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidData.ToException();
}
//
var isValid = IsValidActionRequest(request);
if (!isValid)
{
throw exception;
}
}
/// <summary>
/// Check Action Request Validation
/// </summary>
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
/// <returns>a boolean value</returns>
private bool IsValidActionRequest(
XActionRequestToken request
)
{
//
// Validate Args ...
if (request == null ||
Configuration.IdentitySecretKey.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
var result = request.Validate(Configuration.IdentitySecretKey);
//
return result;
}
/// <summary>
/// Check Token and Act Based on it
/// </summary>
/// <param name="token">token string</param>
/// <param name="issueExcepion">specify <see>Excetion</see> to thrown on Issue failure</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateAndHandleToken(
string token,
bool issueExcepion = false,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(token);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidToken.ToException();
}
//
var isValidToken = IsValidToken(token);
//
if (!isValidToken)
{
//
await RemoveTokenByToken(token);
//
if (issueExcepion)
{
throw exception;
}
}
}
/// <summary>
/// Validate a Hash Exists or not
/// </summary>
/// <param name="hash">token hash string</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateHashExists(
string hash,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(hash);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidToken.ToException();
}
//
var isExists = await IsTokenExistsByHash(hash);
if (!isExists)
{
throw exception;
}
}
/// <summary>
/// Validate a Token Exists
/// </summary>
/// <param name="token">token string</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateTokenExists(
string token,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(token);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidToken.ToException();
}
//
var isExists = await IsTokenExistsByToken(token);
if (!isExists)
{
throw exception;
}
}
/// <summary>
/// Validate a Hash and Retrieve it's Corresponding Token
/// </summary>
/// <param name="hash">token hash string</param>
/// <param name="forceTokenValidation">specifies chack token Validation Parameter, default is true</param>
/// <param name="issueExcepion">specify <see>Excetion</see> to thrown on Issue failure</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>token string</returns>
private async Task<string> ValidateAndRetrieveRelatedToken(
string hash,
bool forceTokenValidation = true,
bool issueExcepion = false,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(hash);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidToken.ToException();
}
//
await ValidateHashExists(hash);
//
var token = await GetRelatedTokenByHash(hash);
if (token.IsNullOrEmpty())
{
throw exception;
}
//
if (forceTokenValidation)
{
await ValidateAndHandleToken(token, issueExcepion);
}
//
return token;
}
/// <summary>
/// Validate a Token and Retrieve it's Corresponding Hash
/// </summary>
/// <param name="token">token string</param>
/// <param name="forceTokenValidation">specifies chack token Validation Parameter, default is true</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>hash string</returns>
private async Task<string> ValidateAndRetrieveRelatedHash(
string token,
bool forceTokenValidation = true,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(token);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidToken.ToException();
}
//
if (forceTokenValidation)
{
await ValidateAndHandleToken(token);
}
//
await ValidateTokenExists(token);
//
var hash = await GetRelatedHashByToken(token);
if (hash.IsNullOrEmpty())
{
throw exception;
}
//
return hash;
}
/// <summary>
/// Validate Invitation Hash
/// </summary>
/// <param name="invitationHash">registration invitation hash string</param>
/// <param name="forceUserExists">thrown <see>Exception</see> if user Exists, default is true</param>
/// <returns></returns>
private async Task ValidateInvitationHash(
string invitationHash,
bool forceUserExists = true
)
{
//
// Validate Args ...
ValidationProvider.NotNull(Configuration);
//
if (Configuration.RegistrationJustWithInvite &&
invitationHash.IsNullOrEmpty())
{
XException.NotAllowed.Throw();
}
//
// Validate Invitation Token if it isn't null ...
if (!invitationHash.IsNullOrEmpty())
{
//
await ValidateHashExists(invitationHash);
//
// Token Validation also done in this task ...
var relatedToken = await ValidateAndRetrieveRelatedToken(invitationHash);
//
var inviteAction = ValidateAndParseActionToken(relatedToken);
ValidationProvider.NotNull(inviteAction);
//
var inviteUerSelectByParam = GetUserSelectByParam(inviteAction);
var inviteUserSelectBy = GetUserSelectByType(inviteUerSelectByParam);
if (inviteUserSelectBy != XUserSelectBy.Email)
{
XException.InvalidToken.Throw();
}
//
if (forceUserExists)
{
//
await ValidateUserNotExists(
inviteUerSelectByParam,
XException.EmailInUsed.ToException());
}
}
}
#endregion
//
#region Profile Validators ...
/// <summary>
/// Validate a Request is Corresponding to Specific Device
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="requestDevice">specify requested device by an instance of <see>XDevice</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
private void ValidateRequestAndGiveDevices(
XDevice device,
XDevice requestDevice,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(device, requestDevice);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidDevice.ToException();
}
//
var isDevicesSame = device.IsSameAs(requestDevice);
//
if (!isDevicesSame)
{
throw exception;
}
}
/// <summary>
/// Check Validation of a User SelectBy Param and Password
/// </summary>
/// <param name="userSelectByParam">specifies user identifier</param>
/// <param name="password">user's password</param>
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateUserAndPassword(
string userSelectByParam,
string password,
bool checkCanLoginPolicies = true,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotEmpty(
userSelectByParam,
password
);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.LoginFailed.ToException();
}
//
// Retrieve User and Validate User Exists ...
var user = await ValidateUserExistsAndRetrieve(
userSelectByParam,
containDetails: false,
checkCanLoginPolicies: checkCanLoginPolicies,
ignoreDisabledUser: false,
checkIsBanned: true,
exception: exception);
//
// Check Given Password Follows Policies ...
await ValidatePasswordPolicies(user, password, exception);
//
// Check Password for User ...
var checkPasswordResult = await UserManager.CheckPasswordAsync(user, password);
if (!checkPasswordResult)
{
throw exception;
}
}
#endregion
//
#region Friendship Validators ...
/// <summary>
/// Validate Friendship Requested Before or not
/// </summary>
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
private void ValidateRequestBefore(
XUser source,
XUser dest
)
{
//
// Validate Args ...
ValidationProvider.NotNull(source, dest);
//
var isRequested = IsFollowRequested(source, dest);
if (!isRequested)
{
XException.NotFound.Throw();
}
}
/// <summary>
/// Validate a Friendship Not Requested Before
/// </summary>
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
private void ValidateNotRequestBefore(
XUser source,
XUser dest
)
{
//
// Validate Args ...
ValidationProvider.NotNull(source, dest);
//
var isRequested = IsFollowRequested(source, dest);
if (isRequested)
{
XException.Duplicate.Throw();
}
}
/// <summary>
/// Validate User Can Send Following Request to Dest User
/// </summary>
/// <param name="accepterUser">specifies a user to check as dest by an instance of <see>XUser</see></param>
/// <param name="requesterUser">specifies a user to check as source by an instance of <see>XUser</see></param>
private void ValidateFollowingRequest(
XUser accepterUser,
XUser requesterUser
)
{
//
// Validate Args ...
ValidationProvider.NotNull(accepterUser, requesterUser);
//
var isRequest = IsFollowRequested(requesterUser, accepterUser, XFriendshipState.Pending);
if (!isRequest)
{
XException.NotFound.Throw();
}
}
/// <summary>
/// Validate a User can Accept a Following Request or Not
/// </summary>
/// <param name="accepterUser">specifies a user to check as dest by an instance of <see>XUser</see></param>
/// <param name="requesterUser">specifies a user to check as source by an instance of <see>XUser</see></param>
private void ValidateFollowingRequestForAccept(
XUser accepterUser,
XUser requesterUser
)
{
//
// Validate Args ...
ValidationProvider.NotNull(accepterUser, requesterUser);
//
var isRequestPending = IsFollowRequested(requesterUser, accepterUser, XFriendshipState.Pending);
var isRequestRejected = IsFollowRequested(requesterUser, accepterUser, XFriendshipState.Rejected);
if (!isRequestPending &&
!isRequestRejected)
{
XException.NotFound.Throw();
}
}
/// <summary>
/// Validate a Request is not Passed for Same Users
/// </summary>
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
private void ValidateNotSameUsers(
XUser source,
XUser dest
)
{
//
// Validate ARgs ...
ValidationProvider.NotNull(source, dest);
//
var isSame = source.Id == dest.Id;
if (isSame)
{
XException.ActionFailed.Throw();
}
}
/// <summary>
/// Check a user is in Followers of another
/// </summary>
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
private void ValidateIsFollowers(
XUser source,
XUser dest
)
{
//
// Validate Args ...
ValidationProvider.NotNull(source, dest);
//
ValidateNotSameUsers(source, dest);
ValidateRequestBefore(dest, source);
//
var isFollower = IsFollowRequested(dest, source, XFriendshipState.Accepted) ||
IsFollowRequested(dest, source, XFriendshipState.Blocked);
if (!isFollower)
{
XException.NotFound.Throw();
}
}
/// <summary>
/// Check a user is in Followings of another
/// </summary>
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
private void ValidateIsFollowings(
XUser source,
XUser dest
)
{
//
// Validate Args ...
ValidationProvider.NotNull(source, dest);
//
ValidateNotSameUsers(source, dest);
ValidateRequestBefore(source, dest);
//
var isFollowing = IsFollowRequested(source, dest, XFriendshipState.Accepted);
if (!isFollowing)
{
XException.NotFound.Throw();
}
}
/// <summary>
/// Validate a User Blocked another
/// </summary>
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
private void ValidateIsBlock(
XUser source,
XUser dest
)
{
//
// Validate Args ...
ValidationProvider.NotNull(source, dest);
//
ValidateNotSameUsers(source, dest);
ValidateRequestBefore(dest, source);
//
var isFollower = IsFollowRequested(dest, source, XFriendshipState.Blocked);
if (!isFollower)
{
XException.NotFound.Throw();
}
}
#endregion
//
#region XActionRequest Validators ...
/// <summary>
/// Validate a Device for Request
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="requestDevice">specify requested device by an instance of <see>XDevice</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
private void ValidateRequestAndGivenDevices(
XDevice device,
XDevice requestDevice,
Exception exception = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(device, requestDevice);
//
// Prepare Default Exception ...
if (exception == null)
{
exception = XException.InvalidDevice.ToException();
}
//
var isDevicesSame = device.IsSameAs(requestDevice);
//
if (!isDevicesSame)
{
throw exception;
}
}
#endregion
//
#region XVerification Request ...
/// <summary>
/// Validate Verification Request Exists by Device
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateVerificationRequestExists(
XDevice device,
Exception exception = null
)
{
//
ValidationProvider.NotNull(device);
//
if (exception == null)
{
exception = XException.InvalidDevice.ToException();
}
//
var isExists = await IsDeviceRequestedForVerificationCodeBefor(device);
if (!isExists)
{
throw exception;
}
}
/// <summary>
/// Validate Verification Request Exists by VerificationCode
/// </summary>
/// <param name="verificationCode">Confirm Verification Code</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns></returns>
private async Task ValidateVerificationRequestExists(
string verificationCode,
Exception exception = null
)
{
//
ValidationProvider.NotEmpty(verificationCode);
//
if (exception == null)
{
exception = XException.InvalidVerificationCode.ToException();
}
//
var isExists = await IsVerificationCodeRequested(verificationCode);
if (!isExists)
{
throw exception;
}
}
/// <summary>
/// Validate and Retrive Verification Request for Given Device
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>an instance of <see>XVerificationRequest</see></returns>
private async Task<XVerificationRequest> ValidateAndRetrieveVerificationRequest(
XDevice device,
Exception exception = null
)
{
//
ValidationProvider.NotNull(device);
//
if (exception == null)
{
exception = XException.InvalidDevice.ToException();
}
//
await ValidateVerificationRequestExists(device);
//
var result = await GetVerificationRequest(device);
if (result == null)
{
throw exception;
}
//
return result;
}
/// <summary>
/// Validate and Retrieve Verification Request for Given VerificationCode
/// </summary>
/// <param name="verificationCode">Confirm Verification Code</param>
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
/// <returns>an instance of <see>XVerificationRequest</see></returns>
private async Task<XVerificationRequest> ValidateAndRetrieveVerificationRequest(
string verificationCode,
Exception exception = null
)
{
//
ValidationProvider.NotEmpty(verificationCode);
//
if (exception == null)
{
exception = XException.InvalidVerificationCode.ToException();
}
//
await ValidateVerificationRequestExists(verificationCode);
//
var result = await GetVerificationRequest(verificationCode);
if (result == null)
{
throw exception;
}
//
return result;
}
/// <summary>
/// Handle Prepare Verification Request
/// </summary>
/// <param name="verificationCode">Confirm Verification Code</param>
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
/// <returns>an instance of <see>XVerificationRequest</see></returns>
private async Task<XVerificationRequest> HandleVerificationRequestPreparation(
string verificationCode,
XActionRequestToken request
)
{
//
ValidationProvider
.NotEmpty(verificationCode);
//
// Check Action Request Validation ...
ValidateActionRequest(request);
//
var device = request.Context.Device;
//
// Check is Device Requested Before or not ...
XVerificationRequest xVerificationRequest = null;
var isDeviceRequested = await IsDeviceRequestedForVerificationCodeBefor(device);
if (!isDeviceRequested)
{
//
xVerificationRequest = new XVerificationRequest
{
VerificationCode = verificationCode,
NumberOfTries = 1,
LastTryOn = DateTime.UtcNow,
Device = device,
Request = request
};
//
await AddVerificationRequest(xVerificationRequest);
}
else
{
//
// Get Verification Request ...
xVerificationRequest = await ValidateAndRetrieveVerificationRequest(device);
}
//
return xVerificationRequest;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+VerificationCode.cs
using System.Threading.Tasks;
using xCommons.Extensions;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
namespace xIds.Providers
{
public partial class XIdentityManager
{
//
#region Verification Code Actions ...
/// <summary>
/// Check a Device Requeste for Verification Code before or not
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>a boolean value</returns>
private async Task<bool> IsDeviceRequestedForVerificationCodeBefor(
XDevice device
)
{
//
var result = false;
var enumerator = DbContext.VerificationRequests
.AsAsyncEnumerable();
await
foreach (var entity in enumerator)
{
//
if (entity.Device.IsSameAs(device))
{
//
result = true;
break;
}
}
//
return result;
}
/// <summary>
/// Check a Verification Code Requested before or not
/// </summary>
/// <param name="verificationCode">Confirm Verification Code</param>
/// <returns>a boolean value</returns>
private async Task<bool> IsVerificationCodeRequested(
string verificationCode
)
{
//
// Validate Args ...
if (verificationCode.IsNullOrEmpty())
{
return false;
}
//
var result = false;
var enumerator = DbContext.VerificationRequests
.AsAsyncEnumerable();
await
foreach (var entity in enumerator)
{
//
if (entity.VerificationCode == verificationCode)
{
//
result = true;
break;
}
}
//
return result;
}
/// <summary>
/// Retrieve Verification Request
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <returns>an instance of <see>XVerificationRequest</see></returns>
private async Task<XVerificationRequest> GetVerificationRequest(
XDevice device
)
{
//
XVerificationRequest result = null;
var enumerator = DbContext.VerificationRequests
.AsAsyncEnumerable();
await
foreach (var entity in enumerator)
{
//
if (entity.Device.IsSameAs(device))
{
//
result = entity;
break;
}
}
//
return result;
}
/// <summary>
/// Retrieve Verification Request
/// </summary>
/// <param name="verificationCode">Confirm Verification Code</param>
/// <returns>an instance of <see>XVerificationRequest</see></returns>
private async Task<XVerificationRequest> GetVerificationRequest(
string verificationCode
)
{
//
XVerificationRequest result = null;
var enumerator = DbContext.VerificationRequests
.AsAsyncEnumerable();
await
foreach (var entity in enumerator)
{
//
if (entity.VerificationCode == verificationCode)
{
//
result = entity;
break;
}
}
//
return result;
}
/// <summary>
/// Remove Exists Verification Code Request
/// </summary>
/// <param name="device">an instance of <see>XDevice</see></param>
/// <param name="saveChanges">save changes on DbContext, default is true</param>
/// <returns></returns>
private async Task RemoveVerificationCodeRequestByDevice(
XDevice device,
bool saveChanges = true
)
{
//
if (!await IsDeviceRequestedForVerificationCodeBefor(device))
{
return;
}
//
var xvr = await GetVerificationRequest(device);
DbContext.VerificationRequests.Remove(xvr);
//
if (saveChanges)
{
await DbContext.SaveChangesAsync();
}
}
/// <summary>
/// Remove Exists Verification Code Request
/// </summary>
/// <param name="verificationCode">Confirm Verification Code</param>
/// <param name="saveChanges">save changes on DbContext, default is true</param>
/// <returns></returns>
private async Task RemoveVerificationRequest(
string verificationCode,
bool saveChanges = true
)
{
//
ValidationProvider.NotEmpty(verificationCode);
//
var request = await GetVerificationRequest(verificationCode);
DbContext.VerificationRequests.Remove(request);
//
if (saveChanges)
{
await DbContext.SaveChangesAsync();
}
}
/// <summary>
/// Add Verification Code Request
/// </summary>
/// <param name="request">an instance of <see>XVerificationRequest</see></param>
/// <param name="saveChanges">save changes on DbContext, default is true</param>
/// <returns>an instance of <see>XVerificationRequest</see></returns>
private async Task<XVerificationRequest> AddVerificationRequest(
XVerificationRequest request,
bool saveChanges = true
)
{
//
if (await IsDeviceRequestedForVerificationCodeBefor(request.Device))
{
await RemoveVerificationCodeRequestByDevice(request.Device);
}
//
var entry = await DbContext.VerificationRequests.AddAsync(request);
//
if (saveChanges)
{
await DbContext.SaveChangesAsync();
}
//
return entry.Entity;
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Stores\XPersistedGrantStore.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Mappers;
using IdentityServer4.Models;
using IdentityServer4.Stores;
using Microsoft.EntityFrameworkCore;
namespace xIds.Stores
{
public class XPersistedGrantStore : IPersistedGrantStore
{
private readonly PersistedGrantDbContext dbContext;
public XPersistedGrantStore(PersistedGrantDbContext dbContext)
{
this.dbContext = dbContext;
}
public async Task<IEnumerable<PersistedGrant>> GetAllAsync(string subjectId)
{
//
var result = (await dbContext.PersistedGrants
.Where(g => g.SubjectId == subjectId)
.AsNoTracking()
.Select(res => res.ToModel())
.ToListAsync()).AsEnumerable();
//
return result;
}
public async Task<PersistedGrant> GetAsync(string key)
{
//
var result = await dbContext.PersistedGrants
.FirstOrDefaultAsync(g => g.Key == key);
//
return result.ToModel();
}
public async Task RemoveAllAsync(string subjectId, string clientId)
{
//
var items = await dbContext.PersistedGrants
.Where(g =>
g.SubjectId == subjectId &&
g.ClientId == clientId)
.ToListAsync();
//
dbContext.PersistedGrants.RemoveRange(items);
//
await dbContext.SaveChangesAsync();
}
public async Task RemoveAllAsync(string subjectId, string clientId, string type)
{
//
var items = await dbContext.PersistedGrants
.Where(g =>
g.SubjectId == subjectId &&
g.ClientId == clientId &&
g.Type == type)
.ToListAsync();
//
dbContext.PersistedGrants.RemoveRange(items);
//
await dbContext.SaveChangesAsync();
}
public async Task RemoveAsync(string key)
{
//
var items = await dbContext.PersistedGrants
.Where(g => g.Key == key)
.ToListAsync();
//
dbContext.PersistedGrants.RemoveRange(items);
//
await dbContext.SaveChangesAsync();
}
public async Task<bool> IsExistsAsync(string key)
{
return await this.dbContext.PersistedGrants.AnyAsync(g => g.Key == key);
}
public async Task<bool> IsExistsAsync(PersistedGrant grant)
{
return await IsExistsAsync(grant.Key);
}
public async Task AddOrUpdateAsync(PersistedGrant grant)
{
//
var isExists = await IsExistsAsync(grant);
if (isExists)
{
await UpdateAsync(grant);
}
else
{
await AddAsync(grant);
}
}
public async Task AddAsync(PersistedGrant grant)
{
//
var item = grant.ToEntity();
await dbContext.PersistedGrants.AddAsync(item);
await dbContext.SaveChangesAsync();
}
public async Task UpdateAsync(PersistedGrant grant)
{
//
var item = grant.ToEntity();
var entity = dbContext.Attach(item);
entity.State = EntityState.Modified;
await dbContext.SaveChangesAsync();
}
public async Task StoreAsync(PersistedGrant grant)
{
await AddOrUpdateAsync(grant);
}
//
// TODO: Complete this ...
public Task<IEnumerable<PersistedGrant>> GetAllAsync(PersistedGrantFilter filter)
{
throw new System.NotImplementedException();
}
//
// TODO: Complete this ...
public Task RemoveAllAsync(PersistedGrantFilter filter)
{
throw new System.NotImplementedException();
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xIds\Validators\XResourceOwnerPasswordValidator.cs
using System;
using System.Threading.Tasks;
using IdentityServer4.Events;
using IdentityServer4.Models;
using IdentityServer4.Services;
using IdentityServer4.Validation;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Navigations;
using xIds.Interfaces;
using static IdentityModel.OidcConstants;
namespace xIds.Validators
{
public class XResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
private readonly IXIdentityManager identityManager;
private readonly IEventService events;
private readonly ILogger<XResourceOwnerPasswordValidator> logger;
public XResourceOwnerPasswordValidator(
IXIdentityManager identityProvider,
IEventService events,
ILogger<XResourceOwnerPasswordValidator> logger
)
{
this.identityManager = identityProvider;
this.events = events;
this.logger = logger;
}
/// <summary>
/// Validates the resource owner password credential
/// by providing UserName/Email or PhoneNumber
/// </summary>
/// <param name="context">The context.</param>
/// <returns></returns>
public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
//
var clientId = context.Request?.Client?.ClientId;
var xUser = await identityManager.GetUserAsync(context.UserName, true);
//
// Check Force Data ...
var isForced = true;
var isForcedStr = context.Request?.Raw["force"];
if (!isForcedStr.IsNullOrEmpty())
{
isForced = isForcedStr.FromJSON<bool>();
}
//
XDevice device = null;
var language = context.Request?.Raw["language"];
var deviceStr = context.Request?.Raw["device"];
if (deviceStr.IsNullOrEmpty() && isForced)
{
//
logger.LogError($"Device not Found ...");
//
await events
.RaiseAsync(
new UserLoginFailureEvent(
xUser.UserName,
XException.InvalidDevice.ToXError().Message,
false,
clientId
));
return;
}
device = isForced ? deviceStr.FromJSON<XDevice>() : null;
//
XException exception;
if (!xUser.IsNull())
{
//
var result = await identityManager
.CheckPasswordSignInAsync(
xUser,
context.Password,
device,
language,
true,
isForced
);
if (result.Succeeded)
{
//
logger.LogInformation("Credentials validated for username: {username}", xUser.UserName);
//
// Update User Last Login ...
xUser.LastLogin = DateTime.UtcNow;
await identityManager.UpdateUserAsync(xUser);
//
await events.RaiseAsync(
new UserLoginSuccessEvent(
xUser.UserName, xUser.Id, xUser.UserName, false, clientId
));
//
context.Result = new GrantValidationResult(xUser.Id, AuthenticationMethods.Password);
return;
}
else if (result.IsLockedOut)
{
//
logger.LogInformation("Authentication failed for username: {username}, reason: locked out", xUser.UserName);
//
exception = XException.AccountLockedOut;
await events
.RaiseAsync(
new UserLoginFailureEvent(
xUser.UserName,
exception.ToXError().Message,
false,
clientId
));
}
else if (result.IsNotAllowed)
{
//
logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", xUser.UserName);
//
exception = XException.NotAllowed;
await events
.RaiseAsync(
new UserLoginFailureEvent(
xUser.UserName,
exception.ToXError().Message,
false,
clientId
));
}
else
{
//
logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", xUser.UserName);
//
exception = XException.LoginFailed;
await events
.RaiseAsync(
new UserLoginFailureEvent(
xUser.UserName,
exception.ToXError().Message,
false,
clientId
));
//
}
}
else
{
//
logger.LogInformation("No user found matching username: {username}", xUser.UserName);
//
exception = XException.InvalidUserName;
await events
.RaiseAsync(
new UserLoginFailureEvent(
xUser.UserName,
exception.ToXError().Message,
false,
clientId
));
}
//
Exception ecs = exception.ToException();
if (exception == XException.AccountLockedOut && xUser.LockoutEnd.HasValue)
{
//
var passedTime = xUser.LockoutEnd.Value.UtcDateTime;
ecs = XException.AccountLockedOut
.AddContentToException(passedTime.ToString());
}
//
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, ecs.Message);
}
}
}