Initial ...

This commit is contained in:
2026-03-23 19:13:06 +03:30
commit f863f49af7
14 changed files with 795 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
#
bin
obj
#
Db/*
!Db/.gitkeep
#
Migrations/*
#
wwwroot/*
+33
View File
@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Attributes;
using xCommons.Configurations;
using xCommons.Providers;
using xIdentityService.Controllers;
using xIdentityService.Interfaces;
namespace xAiApi.Base
{
[ApiController]
[ApiVersion("1.0")]
[RequireXPowered(true)]
[Route("api/v{version:apiVersion}/[controller]")]
public abstract class XIBaseV1Controller : XIBaseController
{
//
#region Constructor ...
protected XIBaseV1Controller(
ILogger<XIBaseV1Controller> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{ }
#endregion
}
}
+45
View File
@@ -0,0 +1,45 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Controllers;
using xCommons.Providers;
namespace xAiApi.Controllers
{
/// <summary>
/// Runing when application start ...
/// </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></returns>
[HttpGet("")]
[AllowAnonymous]
public virtual ActionResult<string> Index()
{
//
var controllerName = GetControllerName();
var message = $"{AppConfiguration.WelcomeMessage}";
//
return Ok(message);
}
}
}
+193
View File
@@ -0,0 +1,193 @@
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Attributes;
using xCommons.Configurations;
using xCommons.Providers;
using xIdentityHelper;
using xIdentityService.Controllers;
using xIdentityService.Interfaces;
namespace xAiApi.Controllers
{
/// <summary>
/// Test all Authentication Policies ...
/// </summary>
[RequireXPowered(false)]
public class TestIdentity : XIBaseController
{
public TestIdentity(
ILogger<TestIdentity> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{ }
//
#region Test Actions ...
/// <summary>
/// API Read Scope
/// </summary>
/// <returns>string message</returns>
[HttpGet("PassReadAccess")]
[Authorize(Policy = XPolicies.ReadAccess)]
public ActionResult<string> PassReadAccess()
{
return Ok("Read Access Passed ...");
}
/// <summary>
/// API Write Scope
/// </summary>
/// <returns>string message</returns>
[HttpGet("PassWriteAccess")]
[Authorize(Policy = XPolicies.WriteAccess)]
public ActionResult<string> PassWriteAccess()
{
return Ok("Write Access Passed ...");
}
/// <summary>
/// API Admin Scope
/// </summary>
/// <returns>string message</returns>
[HttpGet("PassAdminAccess")]
[Authorize(Policy = XPolicies.AdminAccess)]
public ActionResult<string> PassAdminAccess()
{
return Ok("Admin Access Passed ...");
}
/// <summary>
/// API Manage Scop
/// </summary>
/// <returns>string message</returns>
[HttpGet("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>
[HttpGet("HiClaims")]
[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>
[HttpGet("HiUser")]
[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>
[HttpGet("HiEnabledUser")]
[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>
[HttpGet("HiAgent")]
[Authorize(Policy = XPolicies.Agent)]
public ActionResult<string> HiAgent()
{
//
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>
[HttpGet("HiEnabledAgent")]
[Authorize(Policy = XPolicies.EnabledAgent)]
public ActionResult<string> HiEnabledAgent()
{
//
var result = $"Hi Admin: {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>
[HttpGet("HiAdmin")]
[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>
[HttpGet("HiEnabledAdmin")]
[Authorize(Policy = XPolicies.EnabledAdmin)]
public ActionResult<string> HiEnabledAdmin()
{
//
var result = $"Hi Admin: {User.Identity.Name} is Enabled ...";
//
return Ok(result);
}
#endregion
}
}
View File
+32
View File
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
namespace xAiApi.DI
{
public static class XPushDIExtensions
{
/// <summary>
/// Register XPushProvider Services
/// </summary>
/// <param name="services"></param>
public static void AddXPushHubProvider(
this IServiceCollection services,
ServiceLifetime lifeTime = ServiceLifetime.Transient
)
{
AddPushHubProvider(services, lifeTime);
}
//
#region Private ...
private static void AddPushHubProvider(
this IServiceCollection services,
ServiceLifetime lifeTime = ServiceLifetime.Transient
)
{ }
#endregion
}
}
+86
View File
@@ -0,0 +1,86 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Authorization;
using xCommons.Extensions;
using xIdentityHelper;
namespace xAiApi.Extensions
{
public static class XStartupExtensions
{
/// <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);
}
}
}
});
//
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);
}
}
}
+20
View File
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace xAiApi
{
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>();
});
}
}
+23
View File
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5129",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:6001;http://localhost:6000;https://0.0.0.0:6001;",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
+194
View File
@@ -0,0 +1,194 @@
using System;
using System.IO;
using System.Net.Http;
using System.Reflection;
using IdentityModel.AspNetCore.OAuth2Introspection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using xCommons.Configurations;
using xCommons.Extensions;
using xHttpService.DI;
using xIdentityService.DI;
using xPushService.DI;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Hosting;
using xDataService.Configuration;
using xDataService.Constants;
using xDataService.DI;
using xDataService.Interfaces;
using xPushService.Helpers;
using xAiApi.Extensions;
using xAiApi.DI;
// using xApi.Extensions;
// using xDataHelper;
// using xDataHelper.DbSeeder;
// using xDataHelper.Helpers;
// using xFileService.Hubs;
// using xPushHelper.DI;
// using xServices.DI;
// using xServices.TermsConditions.Push;
// using xStringService.Hubs;
// using xTagService.Hubs;
namespace xAiApi
{
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 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 HttpService ...
services.AddXHttpService(Configuration);
//
// Register Api Versioning ...
services.AddApiVersioning(opt =>
{
//
// Set Default Api Version ...
opt.DefaultApiVersion = new ApiVersion(1, 0);
//
// Set Routing to Default API Version, if Version unspecified ...
opt.AssumeDefaultVersionWhenUnspecified = true;
//
// Report All Available Api Versions on Response ...
opt.ReportApiVersions = true;
});
//
var lifeTime = ServiceLifetime.Scoped;
//
// OAuthIntrospectin Http Client Handler ...
// this is for handling SSLErrors ...
services.AddHttpClient(OAuth2IntrospectionDefaults.BackChannelHttpClientName)
.ConfigurePrimaryHttpMessageHandler(() =>
{
return new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true
};
});
//
// Register Authorizations ...
services.AddXAuthorization();
//
services.AddControllers()
.AddNewtonsoftJson(x =>
{
x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
x.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
//
// Register XPushService ...
services.AddXPushService(Configuration);
services.AddXPushHubProvider(lifeTime);
//
// Register XIdentityService ...
services.AddXIdentityService(Configuration, lifeTime);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//
var withPlayground = false;
if (env.IsDevelopment())
{
//
withPlayground = true;
app.UseDeveloperExceptionPage();
}
//
// Use Swagger Middleware ...
app.UseXSwagger();
//
app.UseHttpsRedirection();
//
// Using Cors ...
app.UseXCors();
//
app.UseRouting();
//
// Use xIdentityService ...
app.UseXIdentityService();
//
app.UseAuthorization();
//
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//
#region XPushService ...
//
var helper = new XPushServiceHelper();
//
// helper.AddHub<XTermsHub>("termsHub");
// helper.AddHub<XTagEntityHub>("tagEntityHub");
// helper.AddHub<XFileEntityHub>("fileEntityHub");
// helper.AddHub<XStringEntityHub>("stringEntityHub");
//
app.UseXPushService(helper);
#endregion
//
// Use xDataService Middleware ...
app.UseXDataService();
// //
// // Using Services ...
// app.UseXServices();
//
// Use xGraphQL Middleware ...
app.UseXGraphQL(withPlayground: withPlayground);
}
}
}
+28
View File
@@ -0,0 +1,28 @@
{
"AllowedOrigins": [
"http://localhost:5000",
"https://localhost:5001",
"http://api.saherelm.ir",
"https://api.saherelm.ir",
"http://api.saherelmhub.ir",
"https://api.saherelmhub.ir"
],
"IdentityServiceConfiguration": {
"Authority": "https://localhost:4001",
"ApiName": "xSaherElmAPI",
"ApiSecret": "s@H@1694056",
"ClientId": "xSaherElmAPIClient",
"ClientSecret": "s@H@1694056",
"XPoweredValue": "SaherElmITCenter",
"XRevisionSecretKey": "SaherElmITCenter@1694056",
"DefaultClientTimeout": -1
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
+69
View File
@@ -0,0 +1,69 @@
{
"Version": "0.1",
"Name": "xAiApi",
"DefaultLanguage": "fa-IR",
"XPoweredValue": "SaherElmITCenter",
"WelcomeMessage": "Welcome to xSaherElm Project's AI API",
"AllowedOrigins": [
"http://api.saherelm.ir",
"https://api.saherelm.ir",
"http://api.saherelmhub.ir",
"https://api.saherelmhub.ir"
],
"SwaggerConfiguration": {
"Version": "v1.0",
"Title": "xSaherElm AI API",
"Description": "Complete API Documentation",
"Contact": {
"Name": "Hadi Khazaee Asl",
"Email": "hadi_khazaee_asl@yahoo.com",
"Url": "https://www.saherelm.ir"
}
},
"XDbProvider": "SQLITE",
"ConnectionStrings": {
"DataConnection": "Filename=./Db/XAiApi.db"
},
"DataServiceConfiguration": {
"EnableTracking": true,
"EnableSoftDelete": false,
"EnableDetailedErrors": false,
"EnableSensitiveDataLogging": true,
"PagingConfiguration": {
"DefaultPageSize": 20,
"MaxAvailablePageSize": 400,
"MinAvailablePageSize": 5
},
"GraphQLBasePath": "/graphs"
},
"DbSeeder": {
"UpdateExists": false,
"Strings": []
},
"HttpServiceConfiguration": {
"DisableSSLCheck": true,
"DefaultClientTimeout": -1
},
"IdentityServiceConfiguration": {
"Authority": "https://172.18.0.151",
"ApiName": "xSaherElmAPI",
"ApiSecret": "s@H@1694056",
"ClientId": "xSaherElmAPIClient",
"ClientSecret": "s@H@1694056",
"XPoweredValue": "SaherElmITCenter",
"XRevisionSecretKey": "SaherElmITCenter@1694056",
"DefaultClientTimeout": -1
},
"PushServiceConfiguration": {
"BaseRoute": "hubs",
"AddSupportMessageProtocol": true
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="baget" value="https://nuget.saherelmhub.ir/v3/index.json" protocolVersion="3" />
<add key="RunFlare" value="https://mirror-nuget.runflare.com/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
+51
View File
@@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<!-- Runtime Definition -->
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PackageId>xSaherElm.xAiApi</PackageId>
<Version>1.0.0</Version>
<Authors>Hadi Khazaee Asl</Authors>
<Company>SaherElm IT Center</Company>
<Description>
a WebAPI Project which contains all Business Logic of xSaherElm Project's AI.
</Description>
<!-- Fix Duplicate TargetFramework Issue -->
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<!-- Local Projects -->
<ItemGroup>
<ProjectReference Include="..\Modules\xIdentityHelper\xIdentityHelper.csproj" />
</ItemGroup>
<!-- Local Modules -->
<ItemGroup>
<PackageReference Include="xDashboard.xCommons" Version="1.0.0" />
<PackageReference Include="xDashboard.xDataService" Version="1.0.0" />
<PackageReference Include="xDashboard.xPushService" Version="1.0.0" />
</ItemGroup>
<!-- Dependencies -->
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.11" />
<PackageReference Include="IdentityModel.AspNetCore.OAuth2Introspection" Version="5.0.0" />
</ItemGroup>
<!-- For XML Documentation Support -->
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
<!-- Ef Core -->
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>