Skip to content

Commit

Permalink
Merge pull request #2 from sj-distributor/initialize-project
Browse files Browse the repository at this point in the history
Initialize project
  • Loading branch information
xieyangp authored Aug 8, 2024
2 parents 32786b0 + b90e22f commit b6fdb00
Show file tree
Hide file tree
Showing 113 changed files with 4,645 additions and 0 deletions.
501 changes: 501 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

53 changes: 53 additions & 0 deletions FClub.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Facade", "Facade", "{FF0D55EE-1020-4407-ACB7-03B27F96A5C5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FClub.Api", "src\FClub.Api\FClub.Api.csproj", "{07899078-62EE-4F64-AB32-07A4B7249BC5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{82ECFFE5-A8A0-4BC4-A6F0-A5BC8B1BF953}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D6877F67-0966-4B69-B101-0A0CE2DE3685}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FClub.Core", "src\FClub.Core\FClub.Core.csproj", "{67A09F71-41F1-4A16-96DB-88DCAE613D38}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FClub.Messages", "src\FClub.Messages\FClub.Messages.csproj", "{476E730D-DB3E-4A89-B482-AB2C54B903BC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FClub.IntegrationTests", "src\FClub.IntegrationTests\FClub.IntegrationTests.csproj", "{F3ED8E08-0EE6-49F4-8900-A16B4105357A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FClub.UnitTests", "src\FClub.UnitTests\FClub.UnitTests.csproj", "{F17F4770-974F-4CC6-BFFE-1115477504FB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{07899078-62EE-4F64-AB32-07A4B7249BC5} = {FF0D55EE-1020-4407-ACB7-03B27F96A5C5}
{67A09F71-41F1-4A16-96DB-88DCAE613D38} = {82ECFFE5-A8A0-4BC4-A6F0-A5BC8B1BF953}
{476E730D-DB3E-4A89-B482-AB2C54B903BC} = {82ECFFE5-A8A0-4BC4-A6F0-A5BC8B1BF953}
{F3ED8E08-0EE6-49F4-8900-A16B4105357A} = {D6877F67-0966-4B69-B101-0A0CE2DE3685}
{F17F4770-974F-4CC6-BFFE-1115477504FB} = {D6877F67-0966-4B69-B101-0A0CE2DE3685}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{07899078-62EE-4F64-AB32-07A4B7249BC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07899078-62EE-4F64-AB32-07A4B7249BC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07899078-62EE-4F64-AB32-07A4B7249BC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07899078-62EE-4F64-AB32-07A4B7249BC5}.Release|Any CPU.Build.0 = Release|Any CPU
{67A09F71-41F1-4A16-96DB-88DCAE613D38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67A09F71-41F1-4A16-96DB-88DCAE613D38}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67A09F71-41F1-4A16-96DB-88DCAE613D38}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67A09F71-41F1-4A16-96DB-88DCAE613D38}.Release|Any CPU.Build.0 = Release|Any CPU
{476E730D-DB3E-4A89-B482-AB2C54B903BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{476E730D-DB3E-4A89-B482-AB2C54B903BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{476E730D-DB3E-4A89-B482-AB2C54B903BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{476E730D-DB3E-4A89-B482-AB2C54B903BC}.Release|Any CPU.Build.0 = Release|Any CPU
{F3ED8E08-0EE6-49F4-8900-A16B4105357A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3ED8E08-0EE6-49F4-8900-A16B4105357A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3ED8E08-0EE6-49F4-8900-A16B4105357A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3ED8E08-0EE6-49F4-8900-A16B4105357A}.Release|Any CPU.Build.0 = Release|Any CPU
{F17F4770-974F-4CC6-BFFE-1115477504FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F17F4770-974F-4CC6-BFFE-1115477504FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F17F4770-974F-4CC6-BFFE-1115477504FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F17F4770-974F-4CC6-BFFE-1115477504FB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
14 changes: 14 additions & 0 deletions NuGet.Config
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="SJ.Nuget" value="https://nuget.sjfood.us/nuget" />
<add key="NuGet.org v3" value="https://api.nuget.org/v3/index.json" />
<add key="HangfirePro" value="https://nuget.hangfire.io/nuget/hangfire-pro/v3/index.json" />
</packageSources>
<packageSourceCredentials>
<HangfirePro>
<add key="Username" value="ProtonTechnology" />
<add key="ClearTextPassword" value="YM2Nx2m285Sfy5xv" />
</HangfirePro>
</packageSourceCredentials>
</configuration>
28 changes: 28 additions & 0 deletions WebApiDockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env

WORKDIR /app
EXPOSE 80
EXPOSE 443

COPY ./src/FClub.Api ./build/FClub.Api
COPY ./src/FClub.Core ./build/FClub.Core
COPY ./src/FClub.Messages ./build/FClub.Messages
COPY ./NuGet.Config ./build

RUN dotnet publish build/FClub.Api -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:7.0

# ffmpeg
RUN apt-get update && apt-get install -y bzip2 make gcc yasm libopencore-amrnb-dev libopencore-amrwb-dev wget xz-utils

RUN wget https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \
tar -jxvf ffmpeg-snapshot.tar.bz2 && \
cd ffmpeg && \
./configure --enable-gpl --enable-libopencore-amrnb --enable-libopencore-amrwb --prefix=/usr/local/ffmpeg --enable-version3 && \
make -j8 && make install && \
ln -s /usr/local/ffmpeg/bin/ffmpeg /usr/local/bin/

WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "FClub.Api.dll"]
56 changes: 56 additions & 0 deletions src/FClub.Api/Authentication/ApiKey/ApiKeyAuthenticationHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using FClub.Core.Constants;
using System.Security.Claims;
using System.Text.Encodings.Web;
using FClub.Core.Services.Account;
using FClub.Core.Services.Caching;
using FClub.Messages.Enums.Caching;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authentication;

namespace FClub.Api.Authentication.ApiKey;

public class ApiKeyAuthenticationHandler : AuthenticationHandler<ApiKeyAuthenticationOptions>
{
private readonly ICacheManager _cacheManager;
private readonly IAccountDataProvider _accountDataProvider;

public ApiKeyAuthenticationHandler(IOptionsMonitor<ApiKeyAuthenticationOptions> options, ILoggerFactory logger,
UrlEncoder encoder, ISystemClock clock, ICacheManager cacheManager, IAccountDataProvider accountDataProvider) : base(options, logger, encoder, clock)
{
_cacheManager = cacheManager;
_accountDataProvider = accountDataProvider;
}

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!Request.Headers.ContainsKey("X-API-KEY"))
return AuthenticateResult.NoResult();

var apiKey = Context.Request.Headers["X-API-KEY"].ToString();

if (string.IsNullOrWhiteSpace(apiKey))
return AuthenticateResult.NoResult();

var userInfo = await _cacheManager.GetOrAddAsync(apiKey,
async _ => await _accountDataProvider.GetUserAccountByApiKeyAsync(apiKey).ConfigureAwait(false),
CachingType.RedisCache, TimeSpan.FromHours(24), CancellationToken.None);

if (userInfo == null)
return AuthenticateResult.NoResult();

var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, userInfo.UserName),
new Claim(ClaimTypes.NameIdentifier, userInfo.Id.ToString()),
}, AuthenticationSchemeConstants.ApiKeyAuthenticationScheme);

var claimsPrincipal = new ClaimsPrincipal(identity);

var authenticationTicket = new AuthenticationTicket(claimsPrincipal,
new AuthenticationProperties { IsPersistent = false }, Scheme.Name);

Request.HttpContext.User = claimsPrincipal;

return AuthenticateResult.Success(authenticationTicket);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Microsoft.AspNetCore.Authentication;

namespace FClub.Api.Authentication.ApiKey;

public class ApiKeyAuthenticationOptions : AuthenticationSchemeOptions
{
}
48 changes: 48 additions & 0 deletions src/FClub.Api/Controllers/CombineController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Mediator.Net;
using FClub.Messages.Commands;
using FClub.Messages.Requests;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;

namespace FClub.Api.Controllers;

[Authorize]
[ApiController]
[Route("[controller]")]
public class CombineController : ControllerBase
{
private readonly IMediator _mediator;

public CombineController(IMediator mediator)
{
_mediator = mediator;
}

[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(CombineMp4VideosResponse))]
public async Task<IActionResult> CombineMp4VideosAsync([FromBody] CombineMp4VideosCommand command)
{
var response = await _mediator.SendAsync<CombineMp4VideosCommand, CombineMp4VideosResponse>(command);

return Ok(response);
}

[Route("task"), HttpPost]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(CombineMp4VideosTaskResponse))]
public async Task<IActionResult> CombineMp4VideosTaskAsync([FromBody] CombineMp4VideosTaskCommand command)
{
var response = await _mediator.SendAsync<CombineMp4VideosTaskCommand, CombineMp4VideosTaskResponse>(command).ConfigureAwait(false);

return Ok(response);
}

[Route("task/{taskId:guid}"), HttpGet]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetCombineMp4VideosTaskResponse))]
public async Task<IActionResult> GetCombineMp4VideosTaskAsync(Guid taskId)
{
var response = await _mediator.RequestAsync<GetCombineMp4VideosTaskRequest, GetCombineMp4VideosTaskResponse>(
new GetCombineMp4VideosTaskRequest {TaskId = taskId}).ConfigureAwait(false);

return Ok(response);
}
}
25 changes: 25 additions & 0 deletions src/FClub.Api/Extensions/AuthenticationExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using FClub.Core.Constants;
using FClub.Api.Authentication.ApiKey;
using Microsoft.AspNetCore.Authorization;

namespace FClub.Api.Extensions;

public static class AuthenticationExtension
{
public static void AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AuthenticationSchemeConstants.ApiKeyAuthenticationScheme;
options.DefaultChallengeScheme = AuthenticationSchemeConstants.ApiKeyAuthenticationScheme;
})
.AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(
AuthenticationSchemeConstants.ApiKeyAuthenticationScheme, _ => { });

services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder(
AuthenticationSchemeConstants.ApiKeyAuthenticationScheme).RequireAuthenticatedUser().Build();
});
}
}
23 changes: 23 additions & 0 deletions src/FClub.Api/Extensions/CorsPolicyExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using FClub.Core.Settings.CorsPolicy;

namespace FClub.Api.Extensions;

public static class CorsPolicyExtension
{
public static IServiceCollection AddCorsPolicy(this IServiceCollection services, IConfiguration configuration)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
policy =>
{
policy.WithOrigins(new AllowableCorsOriginsSetting(configuration).Value)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});

return services;
}
}
68 changes: 68 additions & 0 deletions src/FClub.Api/Extensions/HangfireExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Serilog;
using Hangfire;
using Newtonsoft.Json;
using FClub.Core.Jobs;
using Hangfire.Correlate;
using FClub.Core.Constants;
using FClub.Core.Services.Jobs;
using FClub.Core.Settings.Caching;

namespace FClub.Api.Extensions;

public static class HangfireExtension
{
public static void AddHangfireInternal(this IServiceCollection services, IConfiguration configuration)
{
services.AddHangfire((sp, c) =>
{
c.UseCorrelate(sp);
c.UseMaxArgumentSizeToRender(int.MaxValue);
c.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
c.UseRedisStorage(new RedisCacheConnectionStringSetting(configuration).Value);
c.UseSerializerSettings(new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
});

services.AddHangfireServer(opt =>
{
opt.ServerTimeout = TimeSpan.FromHours(2);
opt.Queues = new[]
{
HangfireConstants.DefaultQueue,
HangfireConstants.MeetingSummaryQueue
};
});
}

public static void UseHangfireInternal(this IApplicationBuilder app)
{
app.UseHangfireDashboard(options: new DashboardOptions
{
IgnoreAntiforgeryToken = true
});

app.ScanHangfireRecurringJobs();
}

public static void ScanHangfireRecurringJobs(this IApplicationBuilder app)
{
var backgroundJobClient = app.ApplicationServices.GetRequiredService<IFClubBackgroundJobClient>();

var recurringJobTypes = typeof(IRecurringJob).Assembly.GetTypes().Where(type => type.IsClass && typeof(IRecurringJob).IsAssignableFrom(type)).ToList();

foreach (var type in recurringJobTypes)
{
var job = (IRecurringJob) app.ApplicationServices.GetRequiredService(type);

if (string.IsNullOrEmpty(job.CronExpression))
{
Log.Error("Recurring Job Cron Expression Empty, {Job}", job.GetType().FullName);
continue;
}

backgroundJobClient.AddOrUpdateRecurringJob<IJobSafeRunner>(job.JobId, r => r.Run(job.JobId, type), job.CronExpression, job.TimeZone);
}
}
}
22 changes: 22 additions & 0 deletions src/FClub.Api/Extensions/HttpClientExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Correlate;
using FClub.Messages;

namespace FClub.Api.Extensions;

public static class HttpClientExtension
{
public static void AddHttpClientInternal(this IServiceCollection services)
{
services.AddHttpClient(string.Empty, (sp, c) =>
{
var correlationContextAccessor = sp.GetRequiredService<ICorrelationContextAccessor>();
if (correlationContextAccessor.CorrelationContext == null) return;
foreach (var correlationIdHeader in FClubConstants.CorrelationIdHeaders)
{
c.DefaultRequestHeaders.Add(correlationIdHeader, correlationContextAccessor.CorrelationContext.CorrelationId);
}
});
}
}
Loading

0 comments on commit b6fdb00

Please sign in to comment.