Compare commits
5 Commits
b82fbc491f
...
55562a9f00
Author | SHA1 | Date | |
---|---|---|---|
55562a9f00 | |||
57b9819d13 | |||
78254ed23d | |||
202d20bb25 | |||
3e05863aea |
@ -1,4 +1,4 @@
|
|||||||
name: Build and Deploy Docker Container
|
name: Build and Deploy Docker Container
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -52,6 +52,12 @@ jobs:
|
|||||||
SECURITY_HASH_SIZE: ${{ secrets.SECURITY_HASH_SIZE }}
|
SECURITY_HASH_SIZE: ${{ secrets.SECURITY_HASH_SIZE }}
|
||||||
SECURITY_HASH_TOKEN: ${{ secrets.SECURITY_HASH_TOKEN }}
|
SECURITY_HASH_TOKEN: ${{ secrets.SECURITY_HASH_TOKEN }}
|
||||||
SECURITY_SALT_SIZE: ${{ secrets.SECURITY_SALT_SIZE }}
|
SECURITY_SALT_SIZE: ${{ secrets.SECURITY_SALT_SIZE }}
|
||||||
|
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
|
||||||
|
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
|
||||||
|
YANDEX_CLIENT_ID: ${{ secrets.YANDEX_CLIENT_ID }}
|
||||||
|
YANDEX_CLIENT_SECRET: ${{ secrets.YANDEX_CLIENT_SECRET }}
|
||||||
|
MAILRU_CLIENT_ID: ${{ secrets.MAILRU_CLIENT_ID }}
|
||||||
|
MAILRU_CLIENT_SECRET: ${{ secrets.MAILRU_CLIENT_SECRET }}
|
||||||
run: |
|
run: |
|
||||||
ssh-keyscan $SSH_HOST >> ~/.ssh/known_hosts
|
ssh-keyscan $SSH_HOST >> ~/.ssh/known_hosts
|
||||||
ssh $SSH_USER@$SSH_HOST "
|
ssh $SSH_USER@$SSH_HOST "
|
||||||
@ -78,6 +84,12 @@ jobs:
|
|||||||
-e ACTUAL_SUB_PATH=api \
|
-e ACTUAL_SUB_PATH=api \
|
||||||
-e SWAGGER_SUB_PATH=swagger \
|
-e SWAGGER_SUB_PATH=swagger \
|
||||||
-e TZ=Europe/Moscow \
|
-e TZ=Europe/Moscow \
|
||||||
|
-e GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID \
|
||||||
|
-e GOOGLE_CLIENT_SECRET=GOOGLE_CLIENT_SECRET \
|
||||||
|
-e YANDEX_CLIENT_ID=YANDEX_CLIENT_ID \
|
||||||
|
-e YANDEX_CLIENT_SECRET=YANDEX_CLIENT_SECRET \
|
||||||
|
-e MAILRU_CLIENT_ID=MAILRU_CLIENT_ID \
|
||||||
|
-e MAILRU_CLIENT_SECRET=MAILRU_CLIENT_SECRET \
|
||||||
$DOCKER_IMAGE
|
$DOCKER_IMAGE
|
||||||
"
|
"
|
||||||
|
|
||||||
|
@ -302,19 +302,19 @@ public class SetupController(
|
|||||||
[HttpPost("CreateAdmin")]
|
[HttpPost("CreateAdmin")]
|
||||||
[TokenAuthentication]
|
[TokenAuthentication]
|
||||||
[BadRequestResponse]
|
[BadRequestResponse]
|
||||||
public ActionResult<string> CreateAdmin([FromBody] CreateUserRequest user)
|
public ActionResult<string> CreateAdmin([FromBody] CreateUserRequest userRequest)
|
||||||
{
|
{
|
||||||
new PasswordPolicyService(GeneralConfig.PasswordPolicy).ValidatePasswordOrThrow(user.Password);
|
new PasswordPolicyService(GeneralConfig.PasswordPolicy).ValidatePasswordOrThrow(userRequest.Password);
|
||||||
|
|
||||||
if (!MailAddress.TryCreate(user.Email, out _))
|
if (!MailAddress.TryCreate(userRequest.Email, out _))
|
||||||
throw new ControllerArgumentException("The email address is incorrect.");
|
throw new ControllerArgumentException("The email address is incorrect.");
|
||||||
|
|
||||||
var (salt, hash) = passwordHashService.HashPassword(user.Password);
|
var (salt, hash) = passwordHashService.HashPassword(userRequest.Password);
|
||||||
|
|
||||||
var admin = new Admin
|
var admin = new Admin
|
||||||
{
|
{
|
||||||
Username = user.Username,
|
Username = userRequest.Username,
|
||||||
Email = user.Email,
|
Email = userRequest.Email,
|
||||||
PasswordHash = hash,
|
PasswordHash = hash,
|
||||||
Salt = salt
|
Salt = salt
|
||||||
};
|
};
|
||||||
|
@ -75,7 +75,7 @@ public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<Gener
|
|||||||
|
|
||||||
if (userId != null)
|
if (userId != null)
|
||||||
{
|
{
|
||||||
userEntity.OAuthProviders ??= new Dictionary<OAuthProvider, OAuthUser>();
|
userEntity.OAuthProviders ??= [];
|
||||||
|
|
||||||
if (!userEntity.OAuthProviders.TryAdd(provider, oAuthUser))
|
if (!userEntity.OAuthProviders.TryAdd(provider, oAuthUser))
|
||||||
{
|
{
|
||||||
@ -105,7 +105,7 @@ public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<Gener
|
|||||||
TwoFactorAuthenticator = userEntity.TwoFactorAuthenticator,
|
TwoFactorAuthenticator = userEntity.TwoFactorAuthenticator,
|
||||||
SecondFactorToken = userEntity.Secret,
|
SecondFactorToken = userEntity.Secret,
|
||||||
OAuthProviders = userEntity.OAuthProviders
|
OAuthProviders = userEntity.OAuthProviders
|
||||||
}, provider);
|
});
|
||||||
|
|
||||||
title = "Успешный вход в аккаунт.";
|
title = "Успешный вход в аккаунт.";
|
||||||
message = "Вы успешно вошли в свою учетную запись. Добро пожаловать!";
|
message = "Вы успешно вошли в свою учетную запись. Добро пожаловать!";
|
||||||
@ -152,7 +152,7 @@ public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<Gener
|
|||||||
[MaintenanceModeIgnore]
|
[MaintenanceModeIgnore]
|
||||||
public ActionResult<List<AvailableOAuthProvidersResponse>> AvailableProviders() =>
|
public ActionResult<List<AvailableOAuthProvidersResponse>> AvailableProviders() =>
|
||||||
Ok(oAuthService
|
Ok(oAuthService
|
||||||
.GetAvailableProviders(HttpContext, HttpContext.GetApiUrl(Url.Action("AuthorizeOAuth2")!))
|
.GetAvailableProviders(HttpContext.GetApiUrl(Url.Action("AuthorizeOAuth2")!))
|
||||||
.ConvertToDto());
|
.ConvertToDto());
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -80,6 +80,7 @@ public class SecurityController(IOptionsSnapshot<GeneralConfig> generalConfig) :
|
|||||||
/// The current password policy
|
/// The current password policy
|
||||||
/// </returns>
|
/// </returns>
|
||||||
[HttpGet("PasswordPolicy")]
|
[HttpGet("PasswordPolicy")]
|
||||||
|
[MaintenanceModeIgnore]
|
||||||
public ActionResult<PasswordPolicy> PasswordPolicy() =>
|
public ActionResult<PasswordPolicy> PasswordPolicy() =>
|
||||||
Ok(generalConfig.Value.PasswordPolicy.ConvertToDto());
|
Ok(generalConfig.Value.PasswordPolicy.ConvertToDto());
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@ -58,7 +59,10 @@ public class Program
|
|||||||
builder.Host.AddCustomSerilog();
|
builder.Host.AddCustomSerilog();
|
||||||
AddDatabase(builder.Services, builder.Configuration, healthCheckBuilder);
|
AddDatabase(builder.Services, builder.Configuration, healthCheckBuilder);
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers(options =>
|
||||||
|
{
|
||||||
|
options.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status500InternalServerError));
|
||||||
|
});
|
||||||
|
|
||||||
builder.Services.AddSingleton<IMaintenanceModeNotConfigureService, MaintenanceModeNotConfigureService>();
|
builder.Services.AddSingleton<IMaintenanceModeNotConfigureService, MaintenanceModeNotConfigureService>();
|
||||||
builder.Services.AddSingleton<IMaintenanceModeService, MaintenanceModeService>();
|
builder.Services.AddSingleton<IMaintenanceModeService, MaintenanceModeService>();
|
||||||
|
@ -84,7 +84,7 @@ To set up the `redirect URL` when registering and logging in using OAuth 2, use
|
|||||||
"{schema}://{domain}{portString}{ACTUAL_SUB_PATH}/api/v1/Auth/OAuth2"
|
"{schema}://{domain}{portString}{ACTUAL_SUB_PATH}/api/v1/Auth/OAuth2"
|
||||||
```
|
```
|
||||||
|
|
||||||
** Where:**
|
**Where:**
|
||||||
|
|
||||||
- `{schema}` is the protocol you are using (`http` or `https').
|
- `{schema}` is the protocol you are using (`http` or `https').
|
||||||
- `{domain}` is your domain (for example, `mydomain.com ` or IP address).
|
- `{domain}` is your domain (for example, `mydomain.com ` or IP address).
|
||||||
|
@ -107,7 +107,7 @@ public class AuthService(ICacheService cache, IAccessToken accessTokenService, I
|
|||||||
authToken.Fingerprint);
|
authToken.Fingerprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TwoFactorAuthenticator> LoginOAuthAsync(CookieOptionsParameters cookieOptions, HttpContext context, User user, OAuthProvider provider, CancellationToken cancellation = default)
|
public async Task<TwoFactorAuthenticator> LoginOAuthAsync(CookieOptionsParameters cookieOptions, HttpContext context, User user, CancellationToken cancellation = default)
|
||||||
{
|
{
|
||||||
var requestContext = new RequestContextInfo(context, cookieOptions);
|
var requestContext = new RequestContextInfo(context, cookieOptions);
|
||||||
|
|
||||||
|
@ -108,9 +108,9 @@ public class OAuthService(ILogger<OAuthService> logger, Dictionary<OAuthProvider
|
|||||||
|
|
||||||
public Uri GetProviderRedirect(HttpContext context, CookieOptionsParameters cookieOptions, string redirectUri, OAuthProvider provider)
|
public Uri GetProviderRedirect(HttpContext context, CookieOptionsParameters cookieOptions, string redirectUri, OAuthProvider provider)
|
||||||
{
|
{
|
||||||
var providerData = providers[provider];
|
var (clientId, _) = providers[provider];
|
||||||
|
|
||||||
var redirectUrl = $"?client_id={providerData.ClientId}" +
|
var redirectUrl = $"?client_id={clientId}" +
|
||||||
"&response_type=code" +
|
"&response_type=code" +
|
||||||
$"&redirect_uri={redirectUri}" +
|
$"&redirect_uri={redirectUri}" +
|
||||||
$"&scope={ProviderData[provider].Scope}" +
|
$"&scope={ProviderData[provider].Scope}" +
|
||||||
@ -121,10 +121,9 @@ public class OAuthService(ILogger<OAuthService> logger, Dictionary<OAuthProvider
|
|||||||
return new Uri(ProviderData[provider].RedirectUrl + redirectUrl);
|
return new Uri(ProviderData[provider].RedirectUrl + redirectUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public (OAuthProvider Provider, Uri Redirect)[] GetAvailableProviders(HttpContext context, string redirectUri)
|
public (OAuthProvider Provider, Uri Redirect)[] GetAvailableProviders(string redirectUri)
|
||||||
{
|
{
|
||||||
return providers.Select(x => (x.Key, new Uri(redirectUri.TrimEnd('/') + "/?provider=" + (int)x.Key)))
|
return [.. providers.Select(x => (x.Key, new Uri(redirectUri.TrimEnd('/') + "/?provider=" + (int)x.Key)))];
|
||||||
.ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(OAuthProvider provider, OAuthUser User)> LoginOAuth(HttpContext context, CookieOptionsParameters cookieOptions, string redirectUrl, string code, string state, CancellationToken cancellation = default)
|
public async Task<(OAuthProvider provider, OAuthUser User)> LoginOAuth(HttpContext context, CookieOptionsParameters cookieOptions, string redirectUrl, string code, string state, CancellationToken cancellation = default)
|
||||||
|
Reference in New Issue
Block a user