last ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,394 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fa" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>مستندات فنی پیادهسازی احراز هویت XApiKey در xIds</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700;800&display=swap');
|
||||
:root {
|
||||
--primary: #1a365d;
|
||||
--primary-light: #2c5282;
|
||||
--accent: #c9a961;
|
||||
--accent-dark: #a8893f;
|
||||
--bg: #faf9f6;
|
||||
--card-bg: #ffffff;
|
||||
--text: #1a202c;
|
||||
--text-muted: #4a5568;
|
||||
--border: #e2e8f0;
|
||||
--success: #38a169;
|
||||
--danger: #e53e3e;
|
||||
--warning: #dd6b20;
|
||||
--shadow: 0 4px 6px rgba(0,0,0,0.05), 0 10px 30px rgba(26,54,93,0.08);
|
||||
--code-bg: #f7fafc;
|
||||
}
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Vazirmatn', Tahoma, sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
line-height: 1.8;
|
||||
font-size: 15px;
|
||||
padding: 30px 15px;
|
||||
}
|
||||
.document-container {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
background: var(--card-bg);
|
||||
box-shadow: var(--shadow);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.document-header {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
|
||||
color: white;
|
||||
padding: 40px;
|
||||
position: relative;
|
||||
border-bottom: 4px solid var(--accent);
|
||||
}
|
||||
.header-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.doc-meta {
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.doc-meta div { margin-bottom: 4px; }
|
||||
.document-title h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.document-title h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.document-body {
|
||||
padding: 40px;
|
||||
}
|
||||
.section {
|
||||
margin-bottom: 40px;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 2px solid var(--border);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.section-number {
|
||||
width: 40px; height: 40px;
|
||||
background: linear-gradient(135deg, var(--primary), var(--primary-light));
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 800;
|
||||
font-size: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.section-title h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--primary);
|
||||
}
|
||||
.section-content p {
|
||||
margin-bottom: 15px;
|
||||
text-align: justify;
|
||||
}
|
||||
.code-block {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-right: 4px solid var(--accent);
|
||||
border-radius: 6px;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
font-family: 'Consolas', 'Monaco', monospace;
|
||||
font-size: 13px;
|
||||
overflow-x: auto;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
.highlight-box {
|
||||
background: #fffaf0;
|
||||
border: 1px solid #f6e05e;
|
||||
border-right: 4px solid var(--accent);
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.success-box {
|
||||
background: #f0fff4;
|
||||
border: 1px solid #9ae6b4;
|
||||
border-right: 4px solid var(--success);
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.warning-box {
|
||||
background: #fff5f5;
|
||||
border: 1px solid #feb2b2;
|
||||
border-right: 4px solid var(--danger);
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
}
|
||||
th, td {
|
||||
padding: 12px;
|
||||
border: 1px solid var(--border);
|
||||
text-align: right;
|
||||
}
|
||||
th {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
}
|
||||
tr:nth-child(even) { background: #f8fafc; }
|
||||
.document-footer {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
.footer-brand {
|
||||
font-weight: 700;
|
||||
color: var(--accent);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document-container">
|
||||
<header class="document-header">
|
||||
<div class="header-top">
|
||||
<div class="doc-meta">
|
||||
<div>شماره مستند: TECH-XIDS-APIKEY-001</div>
|
||||
<div>نسخه: ۱.۰</div>
|
||||
<div>تاریخ تهیه: ۲۰ مهر ۱۴۰۵</div>
|
||||
<div>طبقهبندی: داخلی - فنی</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="document-title">
|
||||
<h1>راهنمای جامع پیادهسازی و عیبیابی احراز هویت XApiKey</h1>
|
||||
<h2>پروژه xIds (Identity Server) | ماژول مدیریت Application و API Key</h2>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="document-body">
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="section-number">۱</div>
|
||||
<div class="section-title">
|
||||
<h3>مقدمه و بررسی وضعیت فعلی</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p>
|
||||
در پروژه <strong>xIds</strong>، زیرساخت کاملی برای مدیریت <code>XApplication</code> و <code>XApiKey</code> پیادهسازی شده است.
|
||||
کلاسهای <code>XApplicationProvider</code> و <code>XApiKeyHelper</code> وظیفه تولید، هش کردن و اعتبارسنجی کلیدها را بر عهده دارند.
|
||||
با این حال، چالش اصلی در لایه <strong>Authentication Middleware</strong> و نحوه اتصال آن به Policyهای موجود بود.
|
||||
</p>
|
||||
<div class="highlight-box">
|
||||
<strong>مشکل شناسایی شده:</strong> درخواستهای ارسالی با هدر <code>X-Api-Key</code> توسط ASP.NET Core نادیده گرفته میشدند، زیرا Scheme پیشفرض روی JWT Bearer تنظیم شده بود و Handler مخصوص ApiKey فراخوانی نمیشد.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="section-number">۲</div>
|
||||
<div class="section-title">
|
||||
<h3>راهحل فنی: اصلاح زنجیره احراز هویت</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p>برای رفع مشکل، دو تغییر اساسی در فایل <code>xIds/DI/XDIHelperExtension.cs</code> اعمال شد:</p>
|
||||
|
||||
<h4>الف) ثبت Scheme اختصاصی برای XApiKey</h4>
|
||||
<p>قبل از ثبت JwtBearer، Scheme مربوط به ApiKey ثبت میشود تا در لیست Authentication Schemes وجود داشته باشد.</p>
|
||||
|
||||
<h4>ب) استفاده از ForwardDefaultSelector هوشمند</h4>
|
||||
<p>به جای استفاده ثابت از <code>ForwardDefault</code>، از یک Delegate استفاده میکنیم که Header درخواست را بررسی میکند.</p>
|
||||
|
||||
<div class="code-block">
|
||||
// xIds/DI/XDIHelperExtension.cs
|
||||
|
||||
public static void AddXIdentityServerAuthentication(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration,
|
||||
bool addApiKeyAuthentication = false)
|
||||
{
|
||||
services.AddXIdentityResourceConfiguration(configuration);
|
||||
var authBuilder = services.AddAuthentication();
|
||||
|
||||
// 1. ثبت Scheme برای XApiKey (اولویت اول)
|
||||
if (addApiKeyAuthentication)
|
||||
{
|
||||
authBuilder.AddScheme<AuthenticationSchemeOptions, XApiKeyAuthenticationHandler>(
|
||||
XAuthenticationScheme.XApiKey.GetStringValue(), // "XApiKey"
|
||||
options => { });
|
||||
}
|
||||
|
||||
// 2. ثبت JwtBearer با Selector هوشمند
|
||||
authBuilder.AddJwtBearer(options =>
|
||||
{
|
||||
options.SaveToken = true;
|
||||
options.RequireHttpsMetadata = false;
|
||||
|
||||
// انتخاب دینامیک Scheme بر اساس هدر درخواست
|
||||
options.ForwardDefaultSelector = context =>
|
||||
{
|
||||
var apiKeyHeader = XHeader.ApiKey.GetStringValue(); // "X-Api-Key"
|
||||
if (context.Request.Headers.ContainsKey(apiKeyHeader))
|
||||
{
|
||||
return XAuthenticationScheme.XApiKey.GetStringValue();
|
||||
}
|
||||
// در غیر این صورت، از احراز هویت استاندارد IdentityServer استفاده کن
|
||||
return XAuthentication.IDENTITY_SERVER_LOCAL_API;
|
||||
};
|
||||
})
|
||||
.AddLocalApi();
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="section-number">۳</div>
|
||||
<div class="section-title">
|
||||
<h3>اصلاح Claims تولید شده در Handler</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p>
|
||||
در فایل <code>xIds/Providers/XApiKeyAuthenticationHandler.cs</code>، متد <code>HandleAuthenticateAsync</code> باید Claimهای صحیح را تولید کند تا با Policyهای تعریف شده در <code>XAuthorizationHelper</code> همخوانی داشته باشد.
|
||||
</p>
|
||||
<div class="warning-box">
|
||||
<strong>نکته مهم:</strong> Policyهای ApiKey بر اساس Scope (مانند read, write, admin) کار میکنند، نه Role. بنابراین Claim از نوع <code>JwtClaimTypes.Scope</code> ضروری است.
|
||||
</div>
|
||||
<div class="code-block">
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
// ... استخراج و اعتبارسنجی ApiKey ...
|
||||
|
||||
var validationResult = await applicationProvider.ValidateApiKey(apiKey, clientIP);
|
||||
|
||||
if (validationResult.Errors.HasChild())
|
||||
return AuthenticateResult.Fail(string.Join(", ", validationResult.Errors));
|
||||
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.Name, validationResult.OwnerId),
|
||||
new Claim(JwtClaimTypes.Subject, validationResult.OwnerId),
|
||||
new Claim("application_id", validationResult.ApplicationId.ToString()),
|
||||
new Claim("auth_type", "apikey"),
|
||||
};
|
||||
|
||||
// افزودن Scopeهای مجاز به Claims
|
||||
if (validationResult.Scopes != null)
|
||||
{
|
||||
foreach (var scope in validationResult.Scopes)
|
||||
{
|
||||
claims.Add(new Claim(JwtClaimTypes.Scope, scope));
|
||||
}
|
||||
}
|
||||
|
||||
var identity = new ClaimsIdentity(claims, Scheme.Name);
|
||||
var principal = new ClaimsPrincipal(identity);
|
||||
var ticket = new AuthenticationTicket(principal, Scheme.Name);
|
||||
|
||||
return AuthenticateResult.Success(ticket);
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="section-number">۴</div>
|
||||
<div class="section-title">
|
||||
<h3>نحوه استفاده در Controllerها</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p>برای محافظت از Endpointها با ApiKey، از Attributeهای زیر استفاده کنید:</p>
|
||||
<div class="code-block">
|
||||
[RequireXPowered]
|
||||
[Authorize(Policy = XPolicies.ApiKeyAccess)] // دسترسی کلی
|
||||
public async Task<ActionResult> MySecureAction() { ... }
|
||||
|
||||
[Authorize(Policy = XPolicies.ApiKeyReadAccess)] // فقط خواندن
|
||||
public async Task<ActionResult> GetItems() { ... }
|
||||
</div>
|
||||
<div class="success-box">
|
||||
<strong>تست موفقیتآمیز:</strong> اکنون با ارسال هدر <code>X-Api-Key: xapp_...</code> به Endpointهای فوق، احراز هویت انجام شده و دسترسی اعطا میشود.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="section-number">۵</div>
|
||||
<div class="section-title">
|
||||
<h3>چکلیست نهایی استقرار</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ردیف</th>
|
||||
<th>اقدام</th>
|
||||
<th>وضعیت</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>۱</td>
|
||||
<td>بررسی ثبت <code>AddXIdentityServerAuthentication</code> در Startup با پارامتر <code>true</code></td>
|
||||
<td>✅ انجام شد</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>۲</td>
|
||||
<td>اطمینان از وجود Policyهای <code>ApiKeyAccess</code> در <code>XAuthorizationHelper</code></td>
|
||||
<td>✅ موجود است</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>۳</td>
|
||||
<td>تست ایجاد ApiKey جدید از طریق <code>/Applications/{id}/ApiKeys/Create</code></td>
|
||||
<td>✅ تست شد</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>۴</td>
|
||||
<td>تست دسترسی به <code>/Account/Test/HiApiKeyAccess</code> با کلید معتبر</td>
|
||||
<td>✅ پاس شد</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="document-footer">
|
||||
<div class="footer-brand">تهیه شده توسط: هادی خزاعی اصل | شرکت فن آوران ساحر علم</div>
|
||||
<div>تاریخ انتشار: ۲۰ مهر ۱۴۰۵</div>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,173 +0,0 @@
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\Constants\ConfigurationNodeNames.cs
|
||||
|
||||
namespace xAiService.Constants
|
||||
{
|
||||
public partial struct ConfigurationNodeNames
|
||||
{
|
||||
public const string AI_SERVICE_NODE = "AIServiceConfiguration";
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\Constants\XAiServiceConstants.cs
|
||||
|
||||
namespace xAiService.Constants
|
||||
{
|
||||
public struct XAiServiceConstants
|
||||
{
|
||||
//
|
||||
// Service Extensions Log Tag ...
|
||||
public const string XAiServiceDILogTag = "XAiService";
|
||||
|
||||
//
|
||||
// File Provider Identifiers ...
|
||||
public const string XAiProjectFilesIdentifier = "AiPrjF";
|
||||
public const string XAiMessageFilesIdentifier = "AiMsgF";
|
||||
public const string XMetaDataFileIdsIdentifier = "FileIds";
|
||||
public const string XAiConversationFilesIdentifier = "AiCnvrF";
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\DI\XDIHelperExtension.cs
|
||||
|
||||
namespace xAiService.DI
|
||||
{
|
||||
public static partial class XDIHelperExtension
|
||||
{ }
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\Extensions\XAiServiceExtensions.cs
|
||||
|
||||
using xCommons.Extensions;
|
||||
using xExceptions.Constants;
|
||||
using xIdentityModels.Models;
|
||||
|
||||
namespace xAiService.Extensions
|
||||
{
|
||||
public static class XAiServiceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Validate User Info ...
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValid(this XUserClaimsInfoDto source)
|
||||
{
|
||||
//
|
||||
var result =
|
||||
!source.IsNullOrDefault() &&
|
||||
!source.UserId.IsNullOrEmpty() &&
|
||||
!source.AccessToken.IsNullOrEmpty();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate User Info ...
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="invalidException"></param>
|
||||
public static void Validate(
|
||||
this XUserClaimsInfoDto source,
|
||||
XException invalidException = XException.InvalidArgs
|
||||
)
|
||||
{
|
||||
//
|
||||
var isValid = source.IsValid();
|
||||
if (!isValid)
|
||||
{
|
||||
invalidException.Throw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\Helpers\VectorHelper.cs
|
||||
|
||||
using System;
|
||||
using xCommons.Extensions;
|
||||
|
||||
namespace xAiService.Helpers
|
||||
{
|
||||
public static class VectorHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Normalize a Vector ...
|
||||
/// </summary>
|
||||
/// <param name="vector"></param>
|
||||
public static void Normalize(float[] vector)
|
||||
{
|
||||
//
|
||||
// Validate ...
|
||||
if (vector.IsNull() || !vector.HasChild())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
float sum = 0f;
|
||||
foreach (var value in vector)
|
||||
{
|
||||
sum += value * value;
|
||||
}
|
||||
|
||||
//
|
||||
float norm = MathF.Sqrt(sum);
|
||||
if (norm <= 1e-9f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < vector.Length; i++)
|
||||
{
|
||||
vector[i] /= norm;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Similarity Check ...
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns></returns>
|
||||
public static float CosineSimilarity(float[] a, float[] b)
|
||||
{
|
||||
//
|
||||
if (a.IsNull() || b.IsNull())
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
//
|
||||
if (a.Length != b.Length)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
//
|
||||
float dot = 0f;
|
||||
float normA = 0f;
|
||||
float normB = 0f;
|
||||
for (int i = 0; i < a.Length; i++)
|
||||
{
|
||||
//
|
||||
dot += a[i] * b[i];
|
||||
normA += a[i] * a[i];
|
||||
normB += b[i] * b[i];
|
||||
}
|
||||
|
||||
//
|
||||
float denominator = MathF.Sqrt(normA) * MathF.Sqrt(normB);
|
||||
if (denominator <= 1e-9f)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
//
|
||||
var result = dot / denominator;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,253 +0,0 @@
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xExceptions\Attributes\StringValueAttribute.cs
|
||||
|
||||
using System;
|
||||
|
||||
namespace xExceptions.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// an attribute which attached to enums to carry propper string
|
||||
/// </summary>
|
||||
public partial class StringValueAttribute : Attribute {
|
||||
public string StringValue { get; set; }
|
||||
|
||||
public StringValueAttribute (string value) {
|
||||
this.StringValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xExceptions\Constants\XException.cs
|
||||
|
||||
using xExceptions.Attributes;
|
||||
|
||||
namespace xExceptions.Constants
|
||||
{
|
||||
public enum XException {
|
||||
//
|
||||
#region Invalid Exceptions 1xx ...
|
||||
[StringValue ("Invalid Data ...")]
|
||||
InvalidData = 100,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Date ...")]
|
||||
InvalidDate = 101,
|
||||
|
||||
//
|
||||
[StringValue ("Bad Request ...")]
|
||||
BadRequest = 102,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Args ...")]
|
||||
InvalidArgs = 103,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Message ...")]
|
||||
InvalidMessage = 104,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Token ...")]
|
||||
InvalidToken = 105,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Verification Code ...")]
|
||||
InvalidVerificationCode = 106,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Email Address ...")]
|
||||
InvalidEmailAddress = 107,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Mobile Number ...")]
|
||||
InvalidMobileNumber = 108,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Password ...")]
|
||||
InvalidPassword = 109,
|
||||
|
||||
//
|
||||
[StringValue ("Inavlid Url ...")]
|
||||
InavlidUrl = 110,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Device ...")]
|
||||
InvalidDevice = 111,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Profile Image ...")]
|
||||
InvalidProfileImage = 112,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid File ...")]
|
||||
InavlidFile = 113,
|
||||
|
||||
//
|
||||
[StringValue ("Invalid Username ...")]
|
||||
InvalidUserName = 114,
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Not (...) Exceptions 2xx ...
|
||||
//
|
||||
[StringValue ("Not Found ...")]
|
||||
NotFound = 200,
|
||||
|
||||
//
|
||||
[StringValue ("Not Allowed ...")]
|
||||
NotAllowed = 201,
|
||||
|
||||
//
|
||||
[StringValue ("Not Authorized ...")]
|
||||
NotAuthorized = 202,
|
||||
|
||||
//
|
||||
[StringValue ("Not Visible ...")]
|
||||
NotVisible = 203,
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region User/Registration/Account/Bann Exceptions 3xx ...
|
||||
//
|
||||
[StringValue ("Account Locked out Until:{0}")]
|
||||
AccountLockedOut = 300,
|
||||
|
||||
//
|
||||
[StringValue ("Login Failed ...")]
|
||||
LoginFailed = 301,
|
||||
|
||||
//
|
||||
[StringValue ("User Registered Before ...")]
|
||||
UserRegisteredBefore = 302,
|
||||
|
||||
//
|
||||
[StringValue ("User Disabled ...")]
|
||||
UserDisabled = 303,
|
||||
//
|
||||
[StringValue ("Device Banned Until:{0}")]
|
||||
DeviceBanned = 304,
|
||||
|
||||
//
|
||||
[StringValue ("You can't Request Verification code Until:{0}")]
|
||||
VerificationCodeResendNotAllowed = 305,
|
||||
|
||||
//
|
||||
[StringValue ("Passwords Same ...")]
|
||||
PasswordsSame = 306,
|
||||
|
||||
//
|
||||
[StringValue ("Mobiles Same ...")]
|
||||
MobilesSame = 307,
|
||||
|
||||
//
|
||||
[StringValue ("Emails Same ...")]
|
||||
EmailsSame = 308,
|
||||
|
||||
//
|
||||
[StringValue ("Mobile In Used ...")]
|
||||
MobileInUsed = 309,
|
||||
|
||||
//
|
||||
[StringValue ("Email In Used ...")]
|
||||
EmailInUsed = 310,
|
||||
|
||||
//
|
||||
[StringValue ("Mobile Not Confirmed ...")]
|
||||
MobileNotConfirmed = 311,
|
||||
|
||||
//
|
||||
[StringValue ("Email Not Confirmed ...")]
|
||||
EmailNotConfirmed = 312,
|
||||
|
||||
//
|
||||
[StringValue ("Post Banned ...")]
|
||||
PostBanned = 313,
|
||||
|
||||
//
|
||||
[StringValue ("User Banned ...")]
|
||||
UserBanned = 314,
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region General Exceptions 4xx ...
|
||||
//
|
||||
[StringValue ("Unknown Error ...")]
|
||||
Unknown = 400,
|
||||
|
||||
//
|
||||
[StringValue ("Duplicate ...")]
|
||||
Duplicate = 401,
|
||||
|
||||
//
|
||||
[StringValue ("Action Failed ...")]
|
||||
ActionFailed = 402,
|
||||
|
||||
//
|
||||
[StringValue ("Expired Date ...")]
|
||||
ExpiredDate = 403,
|
||||
|
||||
//
|
||||
[StringValue ("Unavailable ...")]
|
||||
Unavailable = 404,
|
||||
|
||||
//
|
||||
[StringValue ("Max Allowed Tag Exceeded ...")]
|
||||
MaxAllowedTagExceeded = 405,
|
||||
|
||||
//
|
||||
[StringValue ("Timed out ...")]
|
||||
Timeout = 406,
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region File Exceptions 5xx ...
|
||||
//
|
||||
[StringValue ("Empty File ...")]
|
||||
EmptyFile = 500,
|
||||
|
||||
//
|
||||
[StringValue ("max File size exceeded ...")]
|
||||
MaxFileSizeExceeded = 501,
|
||||
|
||||
//
|
||||
[StringValue ("Unsupported File Type ...")]
|
||||
UnsupportedFileType = 502,
|
||||
|
||||
//
|
||||
[StringValue ("Max Allowed Media Exceeded ...")]
|
||||
MaxAllowedMediaExceeded = 503,
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Configuration Exceptions 6xx ...
|
||||
//
|
||||
[StringValue ("Invalid Configuration ...")]
|
||||
InvalidConfiguration = 600,
|
||||
|
||||
//
|
||||
[StringValue ("Storage Service Initiallization Failed ...")]
|
||||
StorageServiceInitialFailed = 601,
|
||||
|
||||
//
|
||||
[StringValue ("Message Service Initialization Failed ...")]
|
||||
MessageServiceInitialFailed = 602,
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xExceptions\Models\XError.cs
|
||||
|
||||
namespace xExceptions.Models {
|
||||
public partial class XError {
|
||||
/// <summary>
|
||||
/// th ID of Error
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the String Value of Error
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,607 +0,0 @@
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Configurations\XHttpServiceConfiguration.cs
|
||||
|
||||
namespace xHttpService.Configurations {
|
||||
public partial class XHttpServiceConfiguration {
|
||||
/// <summary>
|
||||
/// Determines Http Handler Check SSL or not ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public bool DisableSSLCheck { get; set; }
|
||||
public int DefaultClientTimeout { get; set; } = 360;
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Constants\ConfigurationNodeNames.cs
|
||||
|
||||
namespace xHttpService.Constants {
|
||||
public partial struct ConfigurationNodeNames {
|
||||
public const string HTTP_SERVICE_NODE_NAME = "HttpServiceConfiguration";
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Constants\XHttpMethod.cs
|
||||
|
||||
using xExceptions.Attributes;
|
||||
|
||||
namespace xHttpService.Constants {
|
||||
public enum XHttpMethod {
|
||||
[StringValue ("GET")]
|
||||
GET,
|
||||
|
||||
[StringValue ("POST")]
|
||||
POST,
|
||||
|
||||
[StringValue ("PUT")]
|
||||
PUT,
|
||||
|
||||
[StringValue ("DELETE")]
|
||||
DELETE
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\DI\XDIHelperExtension.cs
|
||||
|
||||
using System;
|
||||
using xCommons.Extensions;
|
||||
using xHttpService.Constants;
|
||||
using xHttpService.Providers;
|
||||
using xHttpService.Interfaces;
|
||||
using xHttpService.Configurations;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace xHttpService.DI {
|
||||
public static partial class XDIHelperExtension {
|
||||
/// <summary>
|
||||
/// Retrieve XHttpService Configuration from AppSettings
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <returns></returns>
|
||||
public static XHttpServiceConfiguration GetXHttpServiceConfiguration (this IConfiguration configuration) {
|
||||
//
|
||||
var xHttpSection = configuration.GetSection (ConfigurationNodeNames.HTTP_SERVICE_NODE_NAME);
|
||||
return xHttpSection.Get<XHttpServiceConfiguration> ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register XHttpService Configuration
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXHttpServiceConfiguration (
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration
|
||||
) {
|
||||
//
|
||||
var httpServiceConfiguration = configuration.GetXHttpServiceConfiguration ();
|
||||
services.AddXHttpServiceConfiguration(httpServiceConfiguration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register XHttpService Configuration
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXHttpServiceConfiguration (
|
||||
this IServiceCollection services,
|
||||
XHttpServiceConfiguration configuration
|
||||
) {
|
||||
//
|
||||
if (configuration.IsNull ()) {
|
||||
Console.WriteLine($"xHttpService: there is no provided configurations, using default ...");
|
||||
configuration = new XHttpServiceConfiguration ();
|
||||
}
|
||||
|
||||
//
|
||||
services.AddSingleton<XHttpServiceConfiguration> (configuration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register XHttpService on DI ...
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXHttpService (
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration
|
||||
) {
|
||||
//
|
||||
// Register Service Configuration ...
|
||||
if (services.GetRegisteredService<XHttpServiceConfiguration> ().IsNull ()) {
|
||||
services.AddXHttpServiceConfiguration (configuration);
|
||||
}
|
||||
|
||||
//
|
||||
// Register Service ...
|
||||
services.AddSingleton<IXHttpProvider, XHttpProvider> ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register XHttpService on DI ...
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXHttpService (
|
||||
this IServiceCollection services,
|
||||
XHttpServiceConfiguration configuration
|
||||
) {
|
||||
//
|
||||
// Register Service Configuration ...
|
||||
if (services.GetRegisteredService<XHttpServiceConfiguration> ().IsNull ()) {
|
||||
services.AddXHttpServiceConfiguration (configuration);
|
||||
}
|
||||
|
||||
//
|
||||
// Register Service ...
|
||||
services.AddSingleton<IXHttpProvider, XHttpProvider> ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Extensions\RestSharpExtensions.cs
|
||||
|
||||
using RestSharp;
|
||||
using xModels.Dtos;
|
||||
using xCommons.Constants;
|
||||
using xCommons.Extensions;
|
||||
|
||||
namespace xHttpService.Extensions
|
||||
{
|
||||
public static partial class RestSharpExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Attach an instance of XQuery to a RestRequest object
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="query"></param>
|
||||
/// <returns></returns>
|
||||
public static RestRequest AttachXQuery(
|
||||
this RestRequest source,
|
||||
XQuery query
|
||||
)
|
||||
{
|
||||
//
|
||||
if (query.IsNull())
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
//
|
||||
// ContainsDetail ...
|
||||
//
|
||||
var containsDetailKey = System.Uri.EscapeDataString(nameof(query.ContainsDetail));
|
||||
var containsDetailValue = query.ContainsDetail.AsHttpParamString();
|
||||
source.AddQueryParameter(containsDetailKey, containsDetailValue);
|
||||
|
||||
//
|
||||
// IsAscending ...
|
||||
var isAscendingKey = System.Uri.EscapeDataString(nameof(query.IsAscending));
|
||||
var isAscendingValue = query.IsAscending.AsHttpParamString();
|
||||
source.AddQueryParameter(isAscendingKey, isAscendingValue);
|
||||
|
||||
//
|
||||
// Filter ...
|
||||
if (!query.Filter.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
var key = System.Uri.EscapeDataString(nameof(query.Filter));
|
||||
var value = query.Filter.AsHttpParamString();
|
||||
source.AddQueryParameter(key, value);
|
||||
}
|
||||
|
||||
//
|
||||
// SortBy ...
|
||||
if (!query.SortBy.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
var key = System.Uri.EscapeDataString(nameof(query.SortBy));
|
||||
var value = query.SortBy.AsHttpParamString();
|
||||
source.AddQueryParameter(key, value);
|
||||
}
|
||||
|
||||
//
|
||||
// Page ...
|
||||
if (query.Page > 0)
|
||||
{
|
||||
//
|
||||
var key = System.Uri.EscapeDataString(nameof(query.Page));
|
||||
var value = query.Page.AsHttpParamString();
|
||||
source.AddQueryParameter(key, value);
|
||||
}
|
||||
|
||||
//
|
||||
// PageSize ...
|
||||
if (query.PageSize > 0)
|
||||
{
|
||||
//
|
||||
var key = System.Uri.EscapeDataString(nameof(query.PageSize));
|
||||
var value = query.PageSize.AsHttpParamString();
|
||||
source.AddQueryParameter(key, value);
|
||||
}
|
||||
|
||||
//
|
||||
return source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Dest User to Query Strings ...
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="destUser"></param>
|
||||
/// <returns></returns>
|
||||
public static RestRequest AttachDestUser(
|
||||
this RestRequest source,
|
||||
string destUser
|
||||
)
|
||||
{
|
||||
//
|
||||
if (destUser.IsNullOrEmpty())
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
//
|
||||
var destUserKey = System.Uri.EscapeDataString(nameof(destUser));
|
||||
var destUserValue = destUser.AsHttpParamString();
|
||||
source.AddQueryParameter(destUserKey, destUserValue);
|
||||
|
||||
//
|
||||
return source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add XPoweredBy Header to specific RestRequest Headers ...
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="poweredByValue"></param>
|
||||
/// <returns></returns>
|
||||
public static RestRequest AddXPoweredBy(
|
||||
this RestRequest source,
|
||||
string poweredByValue
|
||||
)
|
||||
{
|
||||
//
|
||||
source.AddHeader(
|
||||
XAuthorization.XPoweredBy,
|
||||
poweredByValue
|
||||
);
|
||||
|
||||
//
|
||||
return source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add XAccessToken Header to specific RestRequest Headers ...
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="poweredByValue"></param>
|
||||
/// <returns></returns>
|
||||
public static RestRequest AddXAccessToken(
|
||||
this RestRequest source,
|
||||
string token
|
||||
)
|
||||
{
|
||||
//
|
||||
token = $"{XAuthentication.BEARER} {token}";
|
||||
|
||||
//
|
||||
source.AddHeader(
|
||||
XAuthorization.Header,
|
||||
token
|
||||
);
|
||||
|
||||
//
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Interfaces\IXHttpProvider.cs
|
||||
|
||||
using RestSharp;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using xHttpService.Constants;
|
||||
using xIdentityModels.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace xHttpService.Interfaces {
|
||||
public partial interface IXHttpProvider {
|
||||
HttpClient GetHttpClient ();
|
||||
RestClient GetRestClient (
|
||||
string baseUrl = null,
|
||||
string poweredByValue = null,
|
||||
XTokenResponse tokens = null
|
||||
);
|
||||
RestRequest GetRestRequet (
|
||||
string endpoint,
|
||||
IDictionary<string, string> @params = null,
|
||||
IDictionary<string, string> headers = null,
|
||||
IDictionary<string, string> queryStrings = null
|
||||
);
|
||||
Task<T> RunRestRequest<T> (
|
||||
RestClient client,
|
||||
RestRequest request,
|
||||
XHttpMethod method
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Providers\XHttpProvider.cs
|
||||
|
||||
using System;
|
||||
using RestSharp;
|
||||
using xModels.Base;
|
||||
using System.Net.Http;
|
||||
using xCommons.Constants;
|
||||
using xCommons.Extensions;
|
||||
using xExceptions.Constants;
|
||||
using System.Threading.Tasks;
|
||||
using xHttpService.Constants;
|
||||
using xIdentityModels.Models;
|
||||
using xHttpService.Interfaces;
|
||||
using RestSharp.Authenticators;
|
||||
using System.Collections.Generic;
|
||||
using xHttpService.Configurations;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace xHttpService.Providers {
|
||||
public partial class XHttpProvider : XBaseClass, IXHttpProvider {
|
||||
|
||||
private readonly XHttpServiceConfiguration configuration;
|
||||
|
||||
public XHttpProvider (
|
||||
ILoggerFactory loggerFactory,
|
||||
XHttpServiceConfiguration configuration
|
||||
) : base (loggerFactory) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
//
|
||||
#region Actions ...
|
||||
/// <summary>
|
||||
/// Get an Instance of Http Client
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public HttpClient GetHttpClient () {
|
||||
//
|
||||
HttpClient httpClient = null;
|
||||
httpClient = new HttpClient ();
|
||||
|
||||
//
|
||||
if (configuration.DisableSSLCheck) {
|
||||
//
|
||||
var httpHandler = new HttpClientHandler ();
|
||||
httpHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
|
||||
|
||||
//
|
||||
httpClient = new HttpClient (httpHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Timeout ...
|
||||
httpClient.Timeout = TimeSpan
|
||||
.FromSeconds (configuration.DefaultClientTimeout);
|
||||
|
||||
//
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an Instance of RestClient
|
||||
/// </summary>
|
||||
/// <param name="baseUrl"></param>
|
||||
/// <param name="poweredByValue"></param>
|
||||
/// <param name="tokens"></param>
|
||||
/// <returns></returns>
|
||||
public RestClient GetRestClient (
|
||||
string baseUrl = null,
|
||||
string poweredByValue = null,
|
||||
XTokenResponse tokens = null
|
||||
) {
|
||||
//
|
||||
var client = new RestClient (baseUrl);
|
||||
|
||||
//
|
||||
// Add XPowered By to Default Headers ...
|
||||
if (!poweredByValue.IsNullOrEmpty ()) {
|
||||
client.AddDefaultHeader (XAuthorization.XPoweredBy, poweredByValue);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Authenticator ...
|
||||
if (!tokens.IsNull () &&
|
||||
!tokens.AccessToken.IsNullOrEmpty ()) {
|
||||
client.Authenticator = new JwtAuthenticator (tokens.AccessToken);
|
||||
}
|
||||
|
||||
//
|
||||
// Refresh Token ...
|
||||
if (!tokens.IsNull () &&
|
||||
!tokens.RefreshToken.IsNullOrEmpty ()) {
|
||||
client.AddDefaultHeader (XAuthorization.RefreshToken, tokens.RefreshToken);
|
||||
}
|
||||
|
||||
//
|
||||
// ExpiresAt ...
|
||||
if (!tokens.IsNull () &&
|
||||
tokens.ExpiresAt > 0) {
|
||||
client.AddDefaultHeader (XAuthorization.ExpiresAt, tokens.ExpiresAt.AsHttpParamString ());
|
||||
}
|
||||
|
||||
//
|
||||
// Set Default Timeout ...
|
||||
client.Timeout = configuration.DefaultClientTimeout;
|
||||
|
||||
//
|
||||
// SSL Validation Handler ...
|
||||
if (configuration.DisableSSLCheck) {
|
||||
client.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
|
||||
}
|
||||
|
||||
//
|
||||
return client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an Instance of RestRequest
|
||||
/// </summary>
|
||||
/// <param name="endpoint"></param>
|
||||
/// <param name="params"></param>
|
||||
/// <param name="headers"></param>
|
||||
/// <param name="queryStrings"></param>
|
||||
/// <returns></returns>
|
||||
public RestRequest GetRestRequet (
|
||||
string endpoint,
|
||||
IDictionary<string, string> @params = null,
|
||||
IDictionary<string, string> headers = null,
|
||||
IDictionary<string, string> queryStrings = null
|
||||
) {
|
||||
//
|
||||
var url = endpoint.ToString ();
|
||||
|
||||
//
|
||||
// Add Route Payloads ...
|
||||
if (!@params.IsNull () && @params.Count > 0) {
|
||||
//
|
||||
var enumerator = @params.GetEnumerator ();
|
||||
while (enumerator.MoveNext ()) {
|
||||
//
|
||||
var item = enumerator.Current;
|
||||
|
||||
//
|
||||
url = url.Replace (item.Key, item.Value.ToUrlEncoded ());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add Query Strings ...
|
||||
if (!queryStrings.IsNull () && queryStrings.Count > 0) {
|
||||
//
|
||||
url = $"{url}?";
|
||||
var enumerator = queryStrings.GetEnumerator ();
|
||||
while (enumerator.MoveNext ()) {
|
||||
//
|
||||
var item = enumerator.Current;
|
||||
|
||||
//
|
||||
url += $"{item.Key}={item.Value.ToUrlEncoded ()}&";
|
||||
}
|
||||
|
||||
//
|
||||
// remove lates & ...
|
||||
if (url.EndsWith ("&")) {
|
||||
url = url.Substring (0, url.Length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Create request ...
|
||||
var request = new RestRequest (url, DataFormat.Json);
|
||||
|
||||
//
|
||||
// Add Headers to request ...
|
||||
if (!headers.IsNull () && headers.Count > 0) {
|
||||
//
|
||||
var enumerator = headers.GetEnumerator ();
|
||||
while (enumerator.MoveNext ()) {
|
||||
//
|
||||
var item = enumerator.Current;
|
||||
request.AddHeader (item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle Call Specific Request and retrieve Response
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public async Task<T> RunRestRequest<T> (
|
||||
RestClient client,
|
||||
RestRequest request,
|
||||
XHttpMethod method
|
||||
) {
|
||||
//
|
||||
var response = await Task.Run (() => {
|
||||
//
|
||||
IRestResponse resp = null;
|
||||
|
||||
//
|
||||
// Call Endpoint Service using Specified Method ...
|
||||
switch (method) {
|
||||
//
|
||||
// Get ...
|
||||
case XHttpMethod.GET:
|
||||
resp = client.Get (request);
|
||||
break;
|
||||
|
||||
//
|
||||
// Put ...
|
||||
case XHttpMethod.PUT:
|
||||
resp = client.Put (request);
|
||||
break;
|
||||
|
||||
//
|
||||
// Post ...
|
||||
case XHttpMethod.POST:
|
||||
resp = client.Post (request);
|
||||
break;
|
||||
|
||||
//
|
||||
// Delete ...
|
||||
case XHttpMethod.DELETE:
|
||||
resp = client.Delete (request);
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (!resp.IsSuccessful) {
|
||||
//
|
||||
// UnAuthorized ...
|
||||
if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
|
||||
XException.NotAuthorized.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
// NotFound ...
|
||||
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound) {
|
||||
XException.NotFound.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
// Timeout ...
|
||||
if (!resp.ErrorMessage.IsNullOrEmpty () &&
|
||||
resp.ErrorMessage.Contains ("timed out")) {
|
||||
XException.Timeout.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
// ErrorMessage ...
|
||||
if (!resp.ErrorMessage.IsNullOrEmpty ()) {
|
||||
throw new Exception (resp.ErrorMessage);
|
||||
}
|
||||
|
||||
//
|
||||
// Default Exception ...
|
||||
XException.BadRequest.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
var result = resp.Content.FromJSON<T> ();
|
||||
return result;
|
||||
});
|
||||
|
||||
//
|
||||
return response;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,727 +0,0 @@
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Constants\ConfigurationNodeNames.cs
|
||||
|
||||
namespace xMessageService.Constants {
|
||||
public partial struct ConfigurationNodeNames {
|
||||
public const string MESSAGE_NODE_NAME = "MessageConfiguration";
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Constants\xMessageServiceConstants.cs
|
||||
|
||||
namespace xMessageService.Constants {
|
||||
public struct xMessageServiceConstants {
|
||||
public const string DEFAULT_EMPTY_PROVIDER = "EMPTY";
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\DI\XDIHelperExtension.cs
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using xCommons.Extensions;
|
||||
using xMessageService.Models;
|
||||
using xMessageService.Constants;
|
||||
using xMessageService.Providers;
|
||||
using System.Collections.Generic;
|
||||
using xMessageService.Interfaces;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace xMessageService.DI {
|
||||
public static partial class XDIHelperExtension {
|
||||
/// <summary>
|
||||
/// Retrieve XMessage Configuration from App Settings
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
public static XMessageConfiguration GetXMessageConfiguration (this IConfiguration config) {
|
||||
//
|
||||
var xMessageConfigSection = config.GetSection (ConfigurationNodeNames.MESSAGE_NODE_NAME);
|
||||
var xMessageConfiguration = xMessageConfigSection.Get<XMessageConfiguration> ();
|
||||
|
||||
//
|
||||
var defaultMailConfiguration = new Dictionary<string, XMailConfiguration> {
|
||||
["EMPTY"] =
|
||||
new XMailConfiguration {
|
||||
Title = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
|
||||
Host = "",
|
||||
Port = 25,
|
||||
EnableSsl = false,
|
||||
Username = "",
|
||||
Password = ""
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
var defaultSmsConfiguration = new Dictionary<string, XSmsConfiguration> {
|
||||
["EMPTY"] =
|
||||
new XSmsConfiguration {
|
||||
ServiceUrl = "",
|
||||
Username = "",
|
||||
Password = "",
|
||||
LineNumber = "",
|
||||
UserApiKey = "",
|
||||
SecretKey = "",
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
if (xMessageConfiguration.IsNull ()) {
|
||||
//
|
||||
xMessageConfiguration = new XMessageConfiguration {
|
||||
DefaultSMSProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
|
||||
DefaultMailProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
|
||||
MailConfigurations = defaultMailConfiguration,
|
||||
SmsConfigurations = defaultSmsConfiguration
|
||||
};
|
||||
|
||||
//
|
||||
// Warn Message is Default Configuration ...
|
||||
Console.WriteLine ($"IMPORTANT: xMessageService Configuration is Default, so the Service can't works properly ...");
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Default Mail Provider ...
|
||||
if (xMessageConfiguration.DefaultMailProvider.IsNullOrEmpty ()) {
|
||||
//
|
||||
if (xMessageConfiguration.IsNull () ||
|
||||
//
|
||||
xMessageConfiguration.MailConfigurations.IsNull () ||
|
||||
xMessageConfiguration.MailConfigurations.Count == 0) {
|
||||
//
|
||||
Console.WriteLine ("There is no defined Mail Provider Configurations ...");
|
||||
xMessageConfiguration.DefaultMailProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER;
|
||||
}
|
||||
|
||||
//
|
||||
if (xMessageConfiguration.DefaultMailProvider == xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER) {
|
||||
xMessageConfiguration.MailConfigurations = defaultMailConfiguration;
|
||||
} else {
|
||||
xMessageConfiguration.DefaultMailProvider = xMessageConfiguration.MailConfigurations.Keys.First ();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Default SMS Provider ...
|
||||
if (xMessageConfiguration.DefaultSMSProvider.IsNullOrEmpty ()) {
|
||||
//
|
||||
if (xMessageConfiguration.IsNull () ||
|
||||
xMessageConfiguration.SmsConfigurations.IsNull () ||
|
||||
xMessageConfiguration.SmsConfigurations.Count == 0) {
|
||||
//
|
||||
Console.WriteLine ("There is no defined SMS Provider Configurations ...");
|
||||
xMessageConfiguration.DefaultSMSProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER;
|
||||
}
|
||||
|
||||
//
|
||||
if (xMessageConfiguration.DefaultSMSProvider == xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER) {
|
||||
xMessageConfiguration.SmsConfigurations = defaultSmsConfiguration;
|
||||
} else {
|
||||
xMessageConfiguration.DefaultSMSProvider = xMessageConfiguration.SmsConfigurations.Keys.First ();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return xMessageConfiguration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register XMessage Service
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="config"></param>
|
||||
public static void AddXMessageService (this IServiceCollection services, IConfiguration config) {
|
||||
//
|
||||
var xMessageConfiguration = config.GetXMessageConfiguration ();
|
||||
services.AddSingleton<XMessageConfiguration> (xMessageConfiguration);
|
||||
|
||||
//
|
||||
// Register SMS Service ...
|
||||
var xSmsService = new XSmsService (
|
||||
xMessageConfiguration.DefaultSMSProvider,
|
||||
xMessageConfiguration.SmsConfigurations
|
||||
);
|
||||
services.AddSingleton<IXSmsService> (xSmsService);
|
||||
|
||||
//
|
||||
// Register Mail Service ...
|
||||
var xMailService = new XMailService (
|
||||
xMessageConfiguration.DefaultMailProvider,
|
||||
xMessageConfiguration.MailConfigurations
|
||||
);
|
||||
services.AddSingleton<IXMailService> (xMailService);
|
||||
|
||||
//
|
||||
// Register MEssage Provider ...
|
||||
services.AddSingleton<IXMessageProvider, XMessageProvider> ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXMailService.cs
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using xMessageService.Models;
|
||||
|
||||
namespace xMessageService.Interfaces {
|
||||
public partial interface IXMailService {
|
||||
Task SendMailAsync (
|
||||
XMessage message,
|
||||
string provider = null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXMessageProvider.cs
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using xMessageService.Models;
|
||||
|
||||
namespace xMessageService.Interfaces {
|
||||
public partial interface IXMessageProvider {
|
||||
bool IsReady (
|
||||
bool? checkMailService = false,
|
||||
bool? checkSmsService = false
|
||||
);
|
||||
|
||||
Task SendMailAsync (
|
||||
XMessage message,
|
||||
string provider = null,
|
||||
bool throwException = true,
|
||||
Exception exception = null
|
||||
);
|
||||
|
||||
Task SendSmsAsync (
|
||||
XMessage message,
|
||||
string provider = null,
|
||||
bool throwException = true,
|
||||
Exception exception = null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXSmsService.cs
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using xMessageService.Models;
|
||||
|
||||
namespace xMessageService.Interfaces {
|
||||
public partial interface IXSmsService {
|
||||
Task SendSmsAsync (
|
||||
XMessage message,
|
||||
string provider = null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Models\XMailConfiguration.cs
|
||||
|
||||
namespace xMessageService.Models {
|
||||
public partial class XMailConfiguration {
|
||||
public string Title { get; set; }
|
||||
public string Host { get; set; }
|
||||
public int Port { get; set; }
|
||||
public bool EnableSsl { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Models\XMessage.cs
|
||||
|
||||
using xModels.Base;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace xMessageService.Models {
|
||||
public partial class XMessage : XBaseDto {
|
||||
public HashSet<string> Recievers { get; set; } = new HashSet<string> ();
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Models\XMessageConfiguration.cs
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace xMessageService.Models {
|
||||
public partial class XMessageConfiguration {
|
||||
public string DefaultSMSProvider { get; set; }
|
||||
public string DefaultMailProvider { get; set; }
|
||||
public IDictionary<string, XMailConfiguration> MailConfigurations { get; set; }
|
||||
public IDictionary<string, XSmsConfiguration> SmsConfigurations { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Models\XSmsConfiguration.cs
|
||||
|
||||
namespace xMessageService.Models {
|
||||
public partial class XSmsConfiguration {
|
||||
public string ServiceUrl { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string LineNumber { get; set; }
|
||||
public string UserApiKey { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Providers\XMailService.cs
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
using xCommons.Extensions;
|
||||
using xExceptions.Constants;
|
||||
using System.Threading.Tasks;
|
||||
using xMessageService.Models;
|
||||
using System.Collections.Generic;
|
||||
using xMessageService.Interfaces;
|
||||
|
||||
namespace xMessageService.Providers {
|
||||
public partial class XMailService : IXMailService {
|
||||
private SmtpClient smtpClient;
|
||||
private readonly string defaultProvider;
|
||||
private readonly IDictionary<string, XMailConfiguration> configurations;
|
||||
|
||||
public XMailService (
|
||||
string defaultProvider,
|
||||
IDictionary<string, XMailConfiguration> configurations
|
||||
) {
|
||||
this.defaultProvider = defaultProvider;
|
||||
this.configurations = configurations;
|
||||
|
||||
//
|
||||
// Get instance of SMTP Client ...
|
||||
PrepareSmtpClient ();
|
||||
}
|
||||
|
||||
public Task SendMailAsync (
|
||||
XMessage message,
|
||||
string provider = null
|
||||
) {
|
||||
//
|
||||
// Run Send Mail Asynchronous ...
|
||||
return Task.Run (() => {
|
||||
SendMail (message, provider);
|
||||
});
|
||||
}
|
||||
|
||||
#region Private ...
|
||||
/// <summary>
|
||||
/// Validate and Retrieve Provider Configuration for Service
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
/// <returns></returns>
|
||||
private XMailConfiguration GetConfiguration (string provider = null) {
|
||||
//
|
||||
if (provider.IsNullOrEmpty ()) {
|
||||
provider = defaultProvider;
|
||||
}
|
||||
|
||||
//
|
||||
if (!configurations.Keys.Contains (provider)) {
|
||||
XException.MessageServiceInitialFailed.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
return configurations[provider];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepare SMTP Client by Using Specified/Default Provider
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
private void PrepareSmtpClient (string provider = null) {
|
||||
//
|
||||
var config = GetConfiguration (provider);
|
||||
if (config.IsNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
smtpClient = new SmtpClient () {
|
||||
Host = config.Host,
|
||||
Port = config.Port,
|
||||
EnableSsl = config.EnableSsl,
|
||||
UseDefaultCredentials = false,
|
||||
Credentials = new NetworkCredential (
|
||||
config.Username,
|
||||
config.Password)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepare Mail Message With Specified/Default Provider
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="provider"></param>
|
||||
/// <returns></returns>
|
||||
private MailMessage PrepareMailMessage (
|
||||
XMessage message,
|
||||
string provider = null
|
||||
) {
|
||||
//
|
||||
if (message == null ||
|
||||
message.Message.IsNullOrEmpty () ||
|
||||
message.Recievers.Count == 0) {
|
||||
XException.InvalidMessage.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
var config = GetConfiguration (provider);
|
||||
var mailMessage = new MailMessage () {
|
||||
From = new MailAddress (config.Username),
|
||||
Subject = config.Title,
|
||||
Body = message.Message
|
||||
};
|
||||
|
||||
//
|
||||
foreach (var reciever in message.Recievers) {
|
||||
mailMessage.To.Add (reciever);
|
||||
}
|
||||
|
||||
//
|
||||
return mailMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Mail Using Specified/Default Provider
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="provider"></param>
|
||||
private void SendMail (
|
||||
XMessage message,
|
||||
string provider = null
|
||||
) {
|
||||
//
|
||||
if (smtpClient.IsNull()) {
|
||||
//
|
||||
Console.WriteLine ($"SMTP Error: MessageServiceInitialFailed ...");
|
||||
XException.MessageServiceInitialFailed.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
var mailMessage = PrepareMailMessage (message, provider);
|
||||
|
||||
//
|
||||
try {
|
||||
smtpClient.Send (mailMessage);
|
||||
} catch (Exception ex) {
|
||||
//
|
||||
Console.WriteLine ($"SMTP Error: {ex.Message}");
|
||||
XException.MessageServiceInitialFailed.Throw ();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Providers\XMessageProvider.cs
|
||||
|
||||
using System;
|
||||
using xCommons.Extensions;
|
||||
using xExceptions.Constants;
|
||||
using System.Threading.Tasks;
|
||||
using xMessageService.Models;
|
||||
using xMessageService.Interfaces;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace xMessageService.Providers {
|
||||
public partial class XMessageProvider : IXMessageProvider {
|
||||
private readonly XMessageConfiguration configuration;
|
||||
private readonly ILogger<XMessageProvider> logger;
|
||||
private readonly IXSmsService smsService;
|
||||
private readonly IXMailService mailService;
|
||||
|
||||
public XMessageProvider (
|
||||
XMessageConfiguration configuration,
|
||||
ILogger<XMessageProvider> logger,
|
||||
IXSmsService smsService,
|
||||
IXMailService mailService
|
||||
) {
|
||||
this.configuration = configuration;
|
||||
this.logger = logger;
|
||||
this.smsService = smsService;
|
||||
this.mailService = mailService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a Mail Message
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="provider"></param>
|
||||
/// <param name="throwException"></param>
|
||||
/// <param name="exception"></param>
|
||||
/// <returns></returns>
|
||||
public async Task SendMailAsync (
|
||||
XMessage message,
|
||||
string provider = null,
|
||||
bool throwException = true,
|
||||
Exception exception = null
|
||||
) {
|
||||
//
|
||||
if (exception.IsNull ()) {
|
||||
exception = XException.ActionFailed.ToException ();
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
await mailService.SendMailAsync (message, provider);
|
||||
} catch (Exception ex) {
|
||||
//
|
||||
logger.LogError ($"Exeption: {ex.Message}");
|
||||
|
||||
//
|
||||
if (throwException) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send SMS Message
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="provider"></param>
|
||||
/// <param name="throwException"></param>
|
||||
/// <param name="exception"></param>
|
||||
/// <returns></returns>
|
||||
public async Task SendSmsAsync (
|
||||
XMessage message,
|
||||
string provider = null,
|
||||
bool throwException = true,
|
||||
Exception exception = null
|
||||
) {
|
||||
//
|
||||
if (exception.IsNull ()) {
|
||||
exception = XException.ActionFailed.ToException ();
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
await smsService.SendSmsAsync (message, provider);
|
||||
} catch {
|
||||
if (throwException) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check Message Provider is Ready or not
|
||||
/// </summary>
|
||||
/// <param name="checkMailService"></param>
|
||||
/// <param name="checkSmsService"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsReady (
|
||||
bool? checkMailService = false,
|
||||
bool? checkSmsService = false
|
||||
) {
|
||||
//
|
||||
var result = true;
|
||||
|
||||
//
|
||||
// Check Mail Service ...
|
||||
if (checkMailService.HasValue &&
|
||||
checkMailService.GetValueOrDefault ()) {
|
||||
result = result && mailService != null;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Sms Service ...
|
||||
if (checkSmsService.HasValue &&
|
||||
checkSmsService.GetValueOrDefault ()) {
|
||||
result = result && smsService != null;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Providers\XSmsService.cs
|
||||
|
||||
using System;
|
||||
using RestSharp;
|
||||
using PhoneNumbers;
|
||||
using xCommons.Extensions;
|
||||
using xExceptions.Constants;
|
||||
using System.Threading.Tasks;
|
||||
using xMessageService.Models;
|
||||
using System.Collections.Generic;
|
||||
using xMessageService.Interfaces;
|
||||
|
||||
namespace xMessageService.Providers {
|
||||
public partial class XSmsService : IXSmsService {
|
||||
private string serviceUrl;
|
||||
private readonly string defaultProvider;
|
||||
private readonly IDictionary<string, XSmsConfiguration> configurations;
|
||||
|
||||
public XSmsService (
|
||||
string defaultProvider,
|
||||
IDictionary<string, XSmsConfiguration> configurations
|
||||
) {
|
||||
this.defaultProvider = defaultProvider;
|
||||
this.configurations = configurations;
|
||||
|
||||
//
|
||||
PrepareServiceUrl ();
|
||||
}
|
||||
|
||||
public Task SendSmsAsync (
|
||||
XMessage message,
|
||||
string provider = null
|
||||
) {
|
||||
//
|
||||
// Run Send SMS Asynchronous ...
|
||||
return Task.Run (() => {
|
||||
SendSMS (message, provider);
|
||||
});
|
||||
}
|
||||
|
||||
#region Private ...
|
||||
/// <summary>
|
||||
/// Prepare Service Url for Specified/Default Provider
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
private void PrepareServiceUrl (string provider = null) {
|
||||
//
|
||||
if (provider.IsNullOrEmpty ()) {
|
||||
provider = defaultProvider;
|
||||
}
|
||||
|
||||
//
|
||||
var config = GetConfiguration (provider);
|
||||
if (config.IsNull ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
serviceUrl = config.ServiceUrl;
|
||||
serviceUrl += "&username=" + config.Username + "&password=" + config.Password + "&";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepare Service url for Integrating XMessage by
|
||||
/// using Specified/Default Provider Configurations
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="provider"></param>
|
||||
private void PrepareSmsMessage (
|
||||
XMessage message,
|
||||
string provider = null
|
||||
) {
|
||||
//
|
||||
if (message == null ||
|
||||
message.Message.IsNullOrEmpty () ||
|
||||
message.Recievers.Count == 0) {
|
||||
XException.InvalidMessage.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
// Validating Mobile Numbers ...
|
||||
var phoneNumberUtil = PhoneNumbers.PhoneNumberUtil.GetInstance ();
|
||||
var recieversList = "";
|
||||
|
||||
//
|
||||
PrepareServiceUrl (provider);
|
||||
|
||||
//
|
||||
foreach (var reciever in message.Recievers) {
|
||||
try {
|
||||
//
|
||||
var mPhoneNumber = phoneNumberUtil.Parse (reciever, null);
|
||||
if (phoneNumberUtil.IsValidNumber (mPhoneNumber)) {
|
||||
//
|
||||
// Format Phone Numbers to the '+989120000000' pattern ...
|
||||
var recieverPhone = phoneNumberUtil.Format (mPhoneNumber, PhoneNumberFormat.E164);
|
||||
if (recieversList.Length > 0) {
|
||||
recieversList += ",";
|
||||
}
|
||||
recieversList += reciever;
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
//
|
||||
var config = GetConfiguration ();
|
||||
|
||||
//
|
||||
// Preparing All Content and Configurations for Sending Messages ...
|
||||
serviceUrl += "to=" +
|
||||
recieversList +
|
||||
"&message=" +
|
||||
message.Message +
|
||||
"&from=" +
|
||||
config.LineNumber +
|
||||
"&flash=" +
|
||||
false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a Message as SMS by Specified/Default Provider
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="provider"></param>
|
||||
private void SendSMS (
|
||||
XMessage message,
|
||||
string provider = null
|
||||
) {
|
||||
//
|
||||
if (serviceUrl.IsNullOrEmpty ()) {
|
||||
//
|
||||
Console.WriteLine ($"SMS Error: MessageServiceInitialFailed ...");
|
||||
XException.MessageServiceInitialFailed.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
//
|
||||
// preparing Service Url based on message data ...
|
||||
PrepareSmsMessage (message, provider);
|
||||
|
||||
//
|
||||
// Implementing Service Calling Using RestSharp Library ...
|
||||
// We Select RestSharp because it supports Sync/Async Calls ...
|
||||
var client = new RestClient (serviceUrl);
|
||||
var request = new RestRequest (Method.POST);
|
||||
|
||||
//
|
||||
// Send Request ...
|
||||
var response = client.Execute (request);
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine ($"SMS Error: {ex.Message}");
|
||||
XException.MessageServiceInitialFailed.Throw ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate and Retrieve Provider Configuration for Service
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
/// <returns></returns>
|
||||
private XSmsConfiguration GetConfiguration (string provider = null) {
|
||||
//
|
||||
if (
|
||||
provider.IsNullOrEmpty () ||
|
||||
provider.ToNormalString () == "empty"
|
||||
) {
|
||||
//
|
||||
provider = defaultProvider;
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
if (!configurations.Keys.Contains (provider)) {
|
||||
XException.MessageServiceInitialFailed.Throw ();
|
||||
}
|
||||
|
||||
//
|
||||
return configurations[provider];
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,574 +0,0 @@
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Configurations\XTermsAndConditionsServiceConfiguration.cs
|
||||
|
||||
using xDataService.Constants;
|
||||
using System.Collections.Generic;
|
||||
using xStringService.Models.Dtos;
|
||||
|
||||
namespace xTermsAndConditionsService.Configurations
|
||||
{
|
||||
/// <summary>
|
||||
/// Terms and Conditions Configuration ...
|
||||
/// </summary>
|
||||
public class XTermsAndConditionsServiceConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Terms And Conditions Resource Title in XString Table ...
|
||||
/// </summary>
|
||||
public string ResourceTitle { get; set; } = "terms_and_conditions";
|
||||
|
||||
/// <summary>
|
||||
/// Seeding Mode for Terms and Conditions ...
|
||||
/// </summary>
|
||||
public XDbSeedingMode SeedingMode { get; set; } = XDbSeedingMode.AddIfNotExists;
|
||||
|
||||
/// <summary>
|
||||
/// Default Terms and Conditions for Add to Databse on App Startup ...
|
||||
/// </summary>
|
||||
public List<XStringDto> TermsAndConditions { get; set; } = null;
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Constants\ConfigurationNodeNames.cs
|
||||
|
||||
namespace xTermsAndConditionsService.Constants
|
||||
{
|
||||
public partial struct ConfigurationNodeNames
|
||||
{
|
||||
public const string TERMS_AND_CONDITIONS_SERVICE_NODE = "TermsAndConditionsService";
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Constants\XTermsAndConditionsServiceConstants.cs
|
||||
|
||||
namespace xTermsAndConditionsService.Constants
|
||||
{
|
||||
public struct XTermsAndConditionsServiceConstants
|
||||
{
|
||||
//
|
||||
// Service Extensions Log Tag ...
|
||||
public const string XTermsAndConditionsServiceDILogTag = "XTermsAndConditionsService";
|
||||
|
||||
//
|
||||
// Table Mapping Identifiers ...
|
||||
|
||||
//
|
||||
// GraphQL Collection Mappings ...
|
||||
|
||||
//
|
||||
// Hubs ...
|
||||
|
||||
//
|
||||
// Custome Constants ...
|
||||
|
||||
//
|
||||
// EF Repositories Helper Extensions ...
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Controllers\XTermsAndConditionsControllerBase.cs
|
||||
|
||||
using xCommons.Providers;
|
||||
using xCommons.Configurations;
|
||||
using xStringService.Controllers;
|
||||
using xIdentityService.Interfaces;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using xTermsAndConditionsService.Interfaces;
|
||||
|
||||
namespace xTermsAndConditionsService.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// a Base Controller Implementation for Providing Base Actions of
|
||||
/// Terms and Conditions Provided Actions ...
|
||||
/// </summary>
|
||||
[AllowAnonymous]
|
||||
public abstract class XTermsAndConditionsControllerBase : XBaseResourceProviderControllerBase<IXTermsAndConditionsProvider>, IXTermsAndConditionsController
|
||||
{
|
||||
protected XTermsAndConditionsControllerBase(
|
||||
ILogger<XTermsAndConditionsControllerBase> logger,
|
||||
XAppConfiguration appConfiguration,
|
||||
IXIdentityProvider identityProvider,
|
||||
XValidationProvider validationProvider,
|
||||
IXTermsAndConditionsProvider provider
|
||||
) : base(
|
||||
logger,
|
||||
appConfiguration,
|
||||
identityProvider,
|
||||
validationProvider,
|
||||
provider
|
||||
)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\DI\XDIHelperExtension.cs
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using xPushService.DI;
|
||||
using xCommons.Extensions;
|
||||
using xPushService.Helpers;
|
||||
using xExceptions.Constants;
|
||||
using xCommons.Configurations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using xStringService.Interfaces.Dtos;
|
||||
using xTermsAndConditionsService.Hubs;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using xTermsAndConditionsService.Constants;
|
||||
using xTermsAndConditionsService.Providers;
|
||||
using xTermsAndConditionsService.Interfaces;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using xTermsAndConditionsService.Configurations;
|
||||
|
||||
namespace xTermsAndConditionsService.DI
|
||||
{
|
||||
public static class XDIHelperExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve xTermsAndConditionsService Configuration from AppSettings ...
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <returns></returns>
|
||||
public static XTermsAndConditionsServiceConfiguration GetXTermsAndConditionsServiceConfiguration(
|
||||
this IConfiguration configuration
|
||||
)
|
||||
{
|
||||
//
|
||||
var section = configuration.GetSection(ConfigurationNodeNames.TERMS_AND_CONDITIONS_SERVICE_NODE);
|
||||
var result = section.Get<XTermsAndConditionsServiceConfiguration>();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract xTermsAndConditionsService Configurations from AppSettings
|
||||
/// and Register it in DI ...
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXTermsAndConditionsConfiguration(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration
|
||||
)
|
||||
{
|
||||
//
|
||||
var serviceConfiguration = configuration.GetXTermsAndConditionsServiceConfiguration();
|
||||
services.AddXTermsAndConditionsConfiguration(serviceConfiguration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register xTermsAndConditionsService Configurations in DI ...
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXTermsAndConditionsConfiguration(
|
||||
this IServiceCollection services,
|
||||
XTermsAndConditionsServiceConfiguration configuration
|
||||
)
|
||||
{
|
||||
//
|
||||
if (configuration.IsNull())
|
||||
{
|
||||
Log($"there is no provided configurations, using default ...");
|
||||
configuration = new XTermsAndConditionsServiceConfiguration();
|
||||
}
|
||||
|
||||
//
|
||||
services.AddSingleton(configuration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register TermsConditions Provider ...
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration">provided AppSettings Configuration</param>
|
||||
/// <param name="lifeTime"></param>
|
||||
public static void AddXTermsConditionsService(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration,
|
||||
ServiceLifetime lifeTime = ServiceLifetime.Transient
|
||||
)
|
||||
{
|
||||
//
|
||||
AddTermsAndConditionsService(
|
||||
services: services,
|
||||
lifeTime: lifeTime,
|
||||
configuration: configuration
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register TermsConditions Provider ...
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration">provided xTermsAndConditionsService Configuration</param>
|
||||
/// <param name="lifeTime"></param>
|
||||
public static void AddXTermsConditionsService(
|
||||
this IServiceCollection services,
|
||||
XTermsAndConditionsServiceConfiguration configuration,
|
||||
ServiceLifetime lifeTime = ServiceLifetime.Transient
|
||||
)
|
||||
{
|
||||
//
|
||||
AddTermsAndConditionsService(
|
||||
services: services,
|
||||
lifeTime: lifeTime,
|
||||
serviceConfiguration: configuration
|
||||
);
|
||||
}
|
||||
|
||||
public static void UseXTermsAndConditionsService(
|
||||
this IApplicationBuilder app
|
||||
)
|
||||
{
|
||||
//
|
||||
// Create an Scope for Services Acess ...
|
||||
using (var scope = app.ApplicationServices.CreateScope())
|
||||
{
|
||||
//
|
||||
// Inject Requirements ...
|
||||
var stringProvider = scope.ServiceProvider.GetService<IXStringServiceProvider>();
|
||||
var serviceConfiguration = scope.ServiceProvider.GetService<XTermsAndConditionsServiceConfiguration>();
|
||||
|
||||
//
|
||||
// Using XTerms Hub ...
|
||||
var pushHelper = new XPushServiceHelper();
|
||||
pushHelper.AddHub<XTermsHub>("terms");
|
||||
app.UseXPushService(pushHelper);
|
||||
|
||||
//
|
||||
// Validate Requirements Exists ...
|
||||
var isValid =
|
||||
!stringProvider.IsNull() &&
|
||||
!serviceConfiguration.IsNull() &&
|
||||
!serviceConfiguration.TermsAndConditions.IsNull() &&
|
||||
serviceConfiguration.TermsAndConditions.HasChild() &&
|
||||
serviceConfiguration.SeedingMode != xDataService.Constants.XDbSeedingMode.None;
|
||||
if (isValid)
|
||||
{
|
||||
//
|
||||
// Prepare Default Terms ...
|
||||
serviceConfiguration
|
||||
.TermsAndConditions
|
||||
.ToList()
|
||||
.ForEach(t => t.ResourceTitle = serviceConfiguration.ResourceTitle);
|
||||
|
||||
//
|
||||
// Loop through Terms and Conditions for Seeding ...
|
||||
foreach (var item in serviceConfiguration.TermsAndConditions)
|
||||
{
|
||||
//
|
||||
// Detect Exists Item ...
|
||||
var exists = stringProvider.FindOneAsync(
|
||||
predicate: x =>
|
||||
x.Language == item.Language &&
|
||||
x.ResourceTitle == item.ResourceTitle
|
||||
)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
|
||||
//
|
||||
var isExists = !exists.IsNullOrDefault();
|
||||
|
||||
//
|
||||
switch (serviceConfiguration.SeedingMode)
|
||||
{
|
||||
//
|
||||
case xDataService.Constants.XDbSeedingMode.AddOrUpdate:
|
||||
//
|
||||
// Update Exists by new Provided ...
|
||||
exists.TranslatedValue = item.TranslatedValue;
|
||||
exists = stringProvider.UpdateAsync(
|
||||
id: exists.Id,
|
||||
item: exists,
|
||||
saveChanges: true
|
||||
)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
|
||||
//
|
||||
Log($"Refresh Terms and Conditions of {exists.Language}");
|
||||
break;
|
||||
|
||||
//
|
||||
case xDataService.Constants.XDbSeedingMode.AddIfNotExists:
|
||||
//
|
||||
if (!isExists)
|
||||
{
|
||||
//
|
||||
exists = stringProvider.AddAsync(
|
||||
item: item,
|
||||
saveChanges: true
|
||||
)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
|
||||
//
|
||||
Log($"Add Terms and Conditions for {exists.Language}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
#region Private ...
|
||||
/// <summary>
|
||||
/// a LogTag for Service ...
|
||||
/// </summary>
|
||||
private static string XLogTag = XTermsAndConditionsServiceConstants.XTermsAndConditionsServiceDILogTag;
|
||||
|
||||
/// <summary>
|
||||
/// print a log in Console ...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
private static void Log(string message)
|
||||
{
|
||||
Console.WriteLine($"{XLogTag} => {message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Terms and Conditions Provider Service ...
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="lifeTime"></param>
|
||||
private static void AddTermsAndConditionsService(
|
||||
IServiceCollection services,
|
||||
IConfiguration configuration = null,
|
||||
XTermsAndConditionsServiceConfiguration serviceConfiguration = null,
|
||||
ServiceLifetime lifeTime = ServiceLifetime.Transient
|
||||
)
|
||||
{
|
||||
//
|
||||
var exception = XException.InvalidArgs.ToException(); ;
|
||||
|
||||
//
|
||||
// Services ...
|
||||
var isServicesExists = !services.IsNull();
|
||||
if (!isServicesExists)
|
||||
{
|
||||
//
|
||||
Log("AddTermsAndConditions failed, services not provided ...");
|
||||
throw exception;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Configuration ...
|
||||
var isConfigValid = !configuration.IsNull() || !serviceConfiguration.IsNull();
|
||||
if (!isConfigValid)
|
||||
{
|
||||
//
|
||||
Log("AddTermsAndConditions failed, configuration not provided ...");
|
||||
throw exception;
|
||||
}
|
||||
|
||||
//
|
||||
// Lifetime ...
|
||||
var isLifetimeExists = !lifeTime.IsNull();
|
||||
if (!isLifetimeExists)
|
||||
{
|
||||
//
|
||||
Log("AddTermsAndConditions failed, lifetime not provided ...");
|
||||
throw exception;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Dependencies Exists ...
|
||||
var isDependenciesPassed = !services
|
||||
.GetRegisteredService<XAppConfiguration>()
|
||||
.IsNull() &&
|
||||
!services.GetRegisteredService<IXStringServiceProvider>()
|
||||
.IsNull();
|
||||
if (!isDependenciesPassed)
|
||||
{
|
||||
//
|
||||
Log("AddTermsAndConditions failed due Dependencies Issues, IXStringServiceProvider or XAppConfiguration not provided ...");
|
||||
throw exception;
|
||||
}
|
||||
|
||||
//
|
||||
// Service Configuration Handler ...
|
||||
if (serviceConfiguration.IsNull())
|
||||
{
|
||||
serviceConfiguration = configuration.GetXTermsAndConditionsServiceConfiguration();
|
||||
}
|
||||
services.AddXTermsAndConditionsConfiguration(serviceConfiguration);
|
||||
|
||||
//
|
||||
// Register Resource Providers ...
|
||||
services.Add(new ServiceDescriptor(typeof(IXTermsAndConditionsProvider), typeof(XTermsAndConditionsProvider), lifeTime));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Hubs\XTermsHub.cs
|
||||
|
||||
using System.Threading;
|
||||
using xPushService.Base;
|
||||
using xCommons.Extensions;
|
||||
using System.Threading.Tasks;
|
||||
using xPushService.Constants;
|
||||
using xStringService.Models.Dtos;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace xTermsAndConditionsService.Hubs
|
||||
{
|
||||
/// <summary>
|
||||
/// a Hub for Notifing Terms and Conditions Events to Connected Clients ...
|
||||
/// </summary>
|
||||
public class XTermsHub : XBaseHub
|
||||
{
|
||||
public XTermsHub(
|
||||
ILogger<XTermsHub> logger
|
||||
) : base(logger)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
#region Hub Actions ...
|
||||
/// <summary>
|
||||
/// Add Specified Terms and Conditions ...
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task Add(
|
||||
XStringDto entity,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var connectionId = Context.ConnectionId;
|
||||
if (!connectionId.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
await Clients
|
||||
.AllExcept(connectionId)
|
||||
.SendAsync(
|
||||
XBaseEntityHubAction.Add.GetStringValue(),
|
||||
entity.ToJSON(camelCase: true),
|
||||
connectionId,
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deleted Specified Terms and Conditions ...
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task Delete(
|
||||
XStringDto entity,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var connectionId = Context.ConnectionId;
|
||||
if (!connectionId.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
await Clients
|
||||
.AllExcept(connectionId)
|
||||
.SendAsync(
|
||||
XBaseEntityHubAction.Delete.GetStringValue(),
|
||||
entity.ToJSON(camelCase: true),
|
||||
connectionId,
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notify an Entity Updated ...
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task Update(
|
||||
XStringDto entity,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var connectionId = Context.ConnectionId;
|
||||
if (!connectionId.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
await Clients
|
||||
.AllExcept(connectionId)
|
||||
.SendAsync(
|
||||
XBaseEntityHubAction.Update.GetStringValue(),
|
||||
entity.ToJSON(camelCase: true),
|
||||
connectionId,
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Interfaces\IXTermsAndConditionsController.cs
|
||||
|
||||
using xStringService.Interfaces;
|
||||
|
||||
namespace xTermsAndConditionsService.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// an Interface for Describing Terms and Conditions Management Controller Actions ...
|
||||
/// </summary>
|
||||
public interface IXTermsAndConditionsController : IXBaseResourceProviderController
|
||||
{ }
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Interfaces\IXTermsAndConditionsProvider.cs
|
||||
|
||||
using xStringService.Interfaces;
|
||||
|
||||
namespace xTermsAndConditionsService.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// an Interface for Describing Terms and Conditions Management Provided Actions ...
|
||||
/// </summary>
|
||||
public interface IXTermsAndConditionsProvider : IXResourceProvider
|
||||
{ }
|
||||
}
|
||||
|
||||
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Providers\XTermsAndConditionsProvider.cs
|
||||
|
||||
using xStringService.Providers;
|
||||
using xStringService.Interfaces.Dtos;
|
||||
using xTermsAndConditionsService.Interfaces;
|
||||
using xTermsAndConditionsService.Configurations;
|
||||
|
||||
namespace xTermsAndConditionsService.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// an Implementation of Terms and Conditions Management Provided Actions ...
|
||||
/// </summary>
|
||||
public class XTermsAndConditionsProvider : XBaseResourceProvider, IXTermsAndConditionsProvider
|
||||
{
|
||||
public XTermsAndConditionsProvider(
|
||||
IXStringServiceProvider provider,
|
||||
XTermsAndConditionsServiceConfiguration configuration
|
||||
) : base(
|
||||
resource: "NULL",
|
||||
provider
|
||||
)
|
||||
{
|
||||
//
|
||||
// Since we nee to Set Resource Title of Terms and Conditions
|
||||
// during instancing using Provided Configurations ...
|
||||
// set this value here ...
|
||||
resource = configuration.ResourceTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,94 @@
|
||||
# Script: Merge-TextFiles.ps1
|
||||
# Description: ادغام تمام فایلهای متنی در یک پوشه به یک فایل با نام حاوی تاریخ
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$SourceDirectory,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$OutputFileName = "MergedContent",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string[]]$Extensions = @("*.txt", "*.md", "*.csv", "*.json", "*.xml")
|
||||
)
|
||||
|
||||
# بررسی وجود پوشه منبع
|
||||
if (-not (Test-Path $SourceDirectory)) {
|
||||
Write-Error "Specified Source Path doesn't Exists: $SourceDirectory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# تولید نام فایل خروجی با تاریخ و زمان
|
||||
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$outputFile = Join-Path $SourceDirectory "$OutputFileName`_$timestamp.txt"
|
||||
|
||||
Write-Host "Starting processing..." -ForegroundColor Cyan
|
||||
Write-Host "Source directory: $SourceDirectory" -ForegroundColor Yellow
|
||||
Write-Host "Output file: $outputFile" -ForegroundColor Yellow
|
||||
|
||||
# جمعآوری تمام فایلهای متنی
|
||||
$allFiles = @()
|
||||
foreach ($ext in $Extensions) {
|
||||
$files = Get-ChildItem -Path $SourceDirectory -Filter $ext -File -Recurse
|
||||
$allFiles += $files
|
||||
}
|
||||
|
||||
if ($allFiles.Count -eq 0) {
|
||||
Write-Warning "هیچ فایل متنی یافت نشد!"
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Host "تعداد فایلهای یافت شده: $($allFiles.Count)" -ForegroundColor Green
|
||||
|
||||
# ایجاد فایل خروجی و نوشتن محتوا
|
||||
try {
|
||||
# هدر فایل
|
||||
$header = @"
|
||||
==================================================
|
||||
فایل ادغام شده از پوشه: $SourceDirectory
|
||||
تاریخ ایجاد: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
|
||||
تعداد فایلها: $($allFiles.Count)
|
||||
==================================================
|
||||
|
||||
"@
|
||||
|
||||
Set-Content -Path $outputFile -Value $header -Encoding UTF8
|
||||
|
||||
# پردازش هر فایل
|
||||
$counter = 1
|
||||
foreach ($file in $allFiles) {
|
||||
Write-Progress -Activity "در حال پردازش فایلها" -Status "فایل $counter از $($allFiles.Count): $($file.Name)" -PercentComplete (($counter / $allFiles.Count) * 100)
|
||||
|
||||
# افزودن جداکننده و نام فایل
|
||||
$separator = "`n`n--------------------------------------------------`n"
|
||||
$fileHeader = "فایل: $($file.FullName)`nمسیر نسبی: $($file.FullName.Replace($SourceDirectory, '').TrimStart('\'))`nحجم: $($file.Length) بایت`n--------------------------------------------------`n`n"
|
||||
|
||||
Add-Content -Path $outputFile -Value $separator -Encoding UTF8
|
||||
Add-Content -Path $outputFile -Value $fileHeader -Encoding UTF8
|
||||
|
||||
# خواندن و نوشتن محتوای فایل
|
||||
try {
|
||||
$content = Get-Content -Path $file.FullName -Raw -Encoding UTF8
|
||||
Add-Content -Path $outputFile -Value $content -Encoding UTF8
|
||||
}
|
||||
catch {
|
||||
Write-Warning "خطا در خواندن فایل: $($file.Name) - $_"
|
||||
Add-Content -Path $outputFile -Value "[خطا در خواندن این فایل]" -Encoding UTF8
|
||||
}
|
||||
|
||||
$counter++
|
||||
}
|
||||
|
||||
Write-Progress -Activity "در حال پردازش فایلها" -Completed
|
||||
|
||||
# نمایش اطلاعات نهایی
|
||||
$outputFileInfo = Get-Item $outputFile
|
||||
Write-Host "`nعملیات با موفقیت انجام شد!" -ForegroundColor Green
|
||||
Write-Host "فایل خروجی: $($outputFileInfo.FullName)" -ForegroundColor Cyan
|
||||
Write-Host "حجم فایل: $([math]::Round($outputFileInfo.Length / 1KB, 2)) کیلوبایت" -ForegroundColor Cyan
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Error "خطا در ایجاد فایل خروجی: $_"
|
||||
exit 1
|
||||
}
|
||||
+1
-1
Submodule Modules/xCommons updated: 69f238f5b1...8e2d2e0a4b
+1
-1
Submodule xIds updated: 5085fc54a4...bfd60e9bb3
Reference in New Issue
Block a user