refactor: add .editorconfig and refactor code
This commit is contained in:
parent
2a33ecbf07
commit
408a95e4b3
278
.editorconfig
Normal file
278
.editorconfig
Normal file
@ -0,0 +1,278 @@
|
||||
# Удалите строку ниже, если вы хотите наследовать параметры .editorconfig из каталогов, расположенных выше в иерархии
|
||||
root = true
|
||||
|
||||
# Файлы C#
|
||||
[*.cs]
|
||||
|
||||
#### Основные параметры EditorConfig ####
|
||||
|
||||
# Отступы и интервалы
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
tab_width = 4
|
||||
|
||||
# Предпочтения для новых строк
|
||||
end_of_line = crlf
|
||||
insert_final_newline = false
|
||||
|
||||
#### Действия кода .NET ####
|
||||
|
||||
# Члены типа
|
||||
dotnet_hide_advanced_members = false
|
||||
dotnet_member_insertion_location = with_other_members_of_the_same_kind
|
||||
dotnet_property_generation_behavior = prefer_throwing_properties
|
||||
|
||||
# Поиск символов
|
||||
dotnet_search_reference_assemblies = true
|
||||
|
||||
#### Рекомендации по написанию кода .NET ####
|
||||
|
||||
# Упорядочение Using
|
||||
dotnet_separate_import_directive_groups = false
|
||||
dotnet_sort_system_directives_first = false
|
||||
file_header_template = unset
|
||||
|
||||
# Предпочтения для this. и Me.
|
||||
dotnet_style_qualification_for_event = false
|
||||
dotnet_style_qualification_for_field = false
|
||||
dotnet_style_qualification_for_method = false
|
||||
dotnet_style_qualification_for_property = false
|
||||
|
||||
# Параметры использования ключевых слов языка и типов BCL
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true
|
||||
dotnet_style_predefined_type_for_member_access = true
|
||||
|
||||
# Предпочтения для скобок
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
|
||||
|
||||
# Предпочтения модификатора
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members
|
||||
|
||||
# Выражения уровень предпочтения
|
||||
dotnet_prefer_system_hash_code = true
|
||||
dotnet_style_coalesce_expression = true
|
||||
dotnet_style_collection_initializer = true
|
||||
dotnet_style_explicit_tuple_names = true
|
||||
dotnet_style_namespace_match_folder = true
|
||||
dotnet_style_null_propagation = true
|
||||
dotnet_style_object_initializer = true
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
dotnet_style_prefer_auto_properties = true
|
||||
dotnet_style_prefer_collection_expression = when_types_loosely_match
|
||||
dotnet_style_prefer_compound_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_return = true
|
||||
dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true
|
||||
dotnet_style_prefer_inferred_tuple_names = true
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true
|
||||
dotnet_style_prefer_simplified_interpolation = true
|
||||
|
||||
# Предпочтения для полей
|
||||
dotnet_style_readonly_field = true
|
||||
|
||||
# Настройки параметров
|
||||
dotnet_code_quality_unused_parameters = non_public
|
||||
|
||||
# Параметры подавления
|
||||
dotnet_remove_unnecessary_suppression_exclusions = none
|
||||
|
||||
# Предпочтения для новых строк
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = true
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = false
|
||||
|
||||
#### Рекомендации по написанию кода C# ####
|
||||
|
||||
# Предпочтения var
|
||||
csharp_style_var_elsewhere = true:suggestion
|
||||
csharp_style_var_for_built_in_types = true:silent
|
||||
csharp_style_var_when_type_is_apparent = true:silent
|
||||
|
||||
# Члены, заданные выражениями
|
||||
csharp_style_expression_bodied_accessors = true:silent
|
||||
csharp_style_expression_bodied_constructors = true:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_lambdas = true:silent
|
||||
csharp_style_expression_bodied_local_functions = true:silent
|
||||
csharp_style_expression_bodied_methods = true:silent
|
||||
csharp_style_expression_bodied_operators = true:silent
|
||||
csharp_style_expression_bodied_properties = true:silent
|
||||
|
||||
# Настройки соответствия шаблонов
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_prefer_extended_property_pattern = true:suggestion
|
||||
csharp_style_prefer_not_pattern = true:suggestion
|
||||
csharp_style_prefer_pattern_matching = true:silent
|
||||
csharp_style_prefer_switch_expression = true:suggestion
|
||||
|
||||
# Настройки проверки на null
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
|
||||
# Предпочтения модификатора
|
||||
csharp_prefer_static_anonymous_function = true:suggestion
|
||||
csharp_prefer_static_local_function = true:suggestion
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
|
||||
csharp_style_prefer_readonly_struct = true:suggestion
|
||||
csharp_style_prefer_readonly_struct_member = true:suggestion
|
||||
|
||||
# Предпочтения для блоков кода
|
||||
csharp_prefer_braces = when_multiline:silent
|
||||
csharp_prefer_simple_using_statement = true:suggestion
|
||||
csharp_prefer_system_threading_lock = true:suggestion
|
||||
csharp_style_namespace_declarations = file_scoped:silent
|
||||
csharp_style_prefer_method_group_conversion = true:silent
|
||||
csharp_style_prefer_primary_constructors = true:suggestion
|
||||
csharp_style_prefer_top_level_statements = false:silent
|
||||
|
||||
# Выражения уровень предпочтения
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_prefer_index_operator = true:suggestion
|
||||
csharp_style_prefer_local_over_anonymous_function = true:suggestion
|
||||
csharp_style_prefer_null_check_over_type_check = true:suggestion
|
||||
csharp_style_prefer_range_operator = true:suggestion
|
||||
csharp_style_prefer_tuple_swap = true:suggestion
|
||||
csharp_style_prefer_unbound_generic_type_in_nameof = true:suggestion
|
||||
csharp_style_prefer_utf8_string_literals = true:suggestion
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||
|
||||
# предпочтения для директивы using
|
||||
csharp_using_directive_placement = outside_namespace:silent
|
||||
|
||||
# Предпочтения для новых строк
|
||||
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
|
||||
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
|
||||
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
|
||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:silent
|
||||
csharp_style_allow_embedded_statements_on_same_line_experimental = false:silent
|
||||
|
||||
#### Правила форматирования C# ####
|
||||
|
||||
# Предпочтения для новых строк
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# Предпочтения для отступов
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
# Предпочтения для интервалов
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# Предпочтения переноса
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = true
|
||||
|
||||
#### Стили именования ####
|
||||
|
||||
# Правила именования
|
||||
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.severity = error
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = error
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
|
||||
# Спецификации символов
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
# Стили именования
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||
|
||||
[*.{cs,vb}]
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
end_of_line = crlf
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true:silent
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
|
||||
dotnet_style_namespace_match_folder = true:suggestion
|
||||
dotnet_code_quality_unused_parameters = non_public:suggestion
|
||||
dotnet_style_predefined_type_for_member_access = true:silent
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||
dotnet_style_qualification_for_field = false:silent
|
||||
dotnet_style_qualification_for_property = false:silent
|
||||
dotnet_style_qualification_for_method = false:silent
|
||||
dotnet_style_qualification_for_event = false:silent
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = false:silent
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
@ -8,6 +8,7 @@ EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Elements of the solution", "Elements of the solution", "{3E087889-A4A0-4A55-A07D-7D149A5BC928}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.dockerignore = .dockerignore
|
||||
.editorconfig = .editorconfig
|
||||
.env = .env
|
||||
.gitattributes = .gitattributes
|
||||
.gitignore = .gitignore
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Mirea.Api.Endpoint.Common.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = false)]
|
||||
public class CacheMaxAgeAttribute : Attribute
|
||||
{
|
||||
public int MaxAge { get; }
|
||||
|
@ -13,7 +13,7 @@ public class TokenAuthenticationAttribute : Attribute, IActionFilter
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
var setupToken = context.HttpContext.RequestServices.GetRequiredService<ISetupToken>();
|
||||
if (!context.HttpContext.Request.Cookies.TryGetValue(AuthToken, out string? tokenFromCookie))
|
||||
if (!context.HttpContext.Request.Cookies.TryGetValue(AuthToken, out var tokenFromCookie))
|
||||
{
|
||||
context.Result = new UnauthorizedResult();
|
||||
return;
|
||||
|
@ -3,6 +3,5 @@
|
||||
public interface IMaintenanceModeNotConfigureService
|
||||
{
|
||||
bool IsMaintenanceMode { get; }
|
||||
|
||||
void DisableMaintenanceMode();
|
||||
}
|
@ -3,8 +3,6 @@
|
||||
public interface IMaintenanceModeService
|
||||
{
|
||||
bool IsMaintenanceMode { get; }
|
||||
|
||||
void EnableMaintenanceMode();
|
||||
|
||||
void DisableMaintenanceMode();
|
||||
}
|
@ -9,5 +9,6 @@ public static class PairPeriodTimeConverter
|
||||
public static Dictionary<int, Dto.Common.PairPeriodTime> ConvertToDto(this IDictionary<int, ScheduleSettings.PairPeriodTime> pairPeriod) =>
|
||||
pairPeriod.ToDictionary(kvp => kvp.Key, kvp => new Dto.Common.PairPeriodTime { Start = kvp.Value.Start, End = kvp.Value.End });
|
||||
|
||||
public static Dictionary<int, ScheduleSettings.PairPeriodTime> ConvertFromDto(this IDictionary<int, Dto.Common.PairPeriodTime> pairPeriod) => pairPeriod.ToDictionary(kvp => kvp.Key, kvp => new ScheduleSettings.PairPeriodTime(kvp.Value.Start, kvp.Value.End));
|
||||
public static Dictionary<int, ScheduleSettings.PairPeriodTime> ConvertFromDto(this IDictionary<int, Dto.Common.PairPeriodTime> pairPeriod) =>
|
||||
pairPeriod.ToDictionary(kvp => kvp.Key, kvp => new ScheduleSettings.PairPeriodTime(kvp.Value.Start, kvp.Value.End));
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ namespace Mirea.Api.Endpoint.Common.Services.Security;
|
||||
|
||||
public class DistributedCacheService(IDistributedCache cache) : ICacheService
|
||||
{
|
||||
public async Task SetAsync<T>(string key, T value, TimeSpan? absoluteExpirationRelativeToNow = null, TimeSpan? slidingExpiration = null, CancellationToken cancellationToken = default)
|
||||
public async Task SetAsync<T>(string key, T value, TimeSpan? absoluteExpirationRelativeToNow = null, TimeSpan? slidingExpiration = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var options = new DistributedCacheEntryOptions
|
||||
{
|
||||
|
@ -9,7 +9,8 @@ namespace Mirea.Api.Endpoint.Common.Services.Security;
|
||||
|
||||
public class MemoryCacheService(IMemoryCache cache) : ICacheService
|
||||
{
|
||||
public Task SetAsync<T>(string key, T value, TimeSpan? absoluteExpirationRelativeToNow = null, TimeSpan? slidingExpiration = null, CancellationToken cancellationToken = default)
|
||||
public Task SetAsync<T>(string key, T value, TimeSpan? absoluteExpirationRelativeToNow = null, TimeSpan? slidingExpiration = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var options = new MemoryCacheEntryOptions
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ public class ScheduleSyncService : IHostedService, IDisposable
|
||||
|
||||
private void OnForceSyncRequested()
|
||||
{
|
||||
StopAsync(default).ContinueWith(_ =>
|
||||
StopAsync(CancellationToken.None).ContinueWith(_ =>
|
||||
{
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
ExecuteTask(null);
|
||||
@ -41,9 +41,9 @@ public class ScheduleSyncService : IHostedService, IDisposable
|
||||
|
||||
private void OnUpdateIntervalRequested()
|
||||
{
|
||||
StopAsync(default).ContinueWith(_ =>
|
||||
StopAsync(CancellationToken.None).ContinueWith(_ =>
|
||||
{
|
||||
StartAsync(default);
|
||||
StartAsync(CancellationToken.None);
|
||||
});
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ public class ScheduleSyncService : IHostedService, IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
StopAsync(default).GetAwaiter().GetResult();
|
||||
StopAsync(CancellationToken.None).GetAwaiter().GetResult();
|
||||
_timer?.Dispose();
|
||||
ScheduleSyncManager.OnForceSyncRequested -= OnForceSyncRequested;
|
||||
ScheduleSyncManager.OnUpdateIntervalRequested -= OnUpdateIntervalRequested;
|
||||
|
@ -21,7 +21,7 @@ public static class EnvironmentConfiguration
|
||||
|
||||
var commentIndex = line.IndexOf('#', StringComparison.Ordinal);
|
||||
|
||||
string arg = line;
|
||||
var arg = line;
|
||||
|
||||
if (commentIndex != -1)
|
||||
arg = arg.Remove(commentIndex, arg.Length - commentIndex);
|
||||
|
@ -19,12 +19,14 @@ public static class JwtConfiguration
|
||||
var jwtDecrypt = Encoding.UTF8.GetBytes(configuration["SECURITY_ENCRYPTION_TOKEN"] ?? string.Empty);
|
||||
|
||||
if (jwtDecrypt.Length != 32)
|
||||
throw new InvalidOperationException("The secret token \"SECURITY_ENCRYPTION_TOKEN\" cannot be less than 32 characters long. Now the size is equal is " + jwtDecrypt.Length);
|
||||
throw new InvalidOperationException("The secret token \"SECURITY_ENCRYPTION_TOKEN\" cannot be less than 32 characters long. " +
|
||||
"Now the size is equal is " + jwtDecrypt.Length);
|
||||
|
||||
var jwtKey = Encoding.UTF8.GetBytes(configuration["SECURITY_SIGNING_TOKEN"] ?? string.Empty);
|
||||
|
||||
if (jwtKey.Length != 64)
|
||||
throw new InvalidOperationException("The signature token \"SECURITY_SIGNING_TOKEN\" cannot be less than 64 characters. Now the size is " + jwtKey.Length);
|
||||
throw new InvalidOperationException("The signature token \"SECURITY_SIGNING_TOKEN\" cannot be less than 64 characters. " +
|
||||
"Now the size is " + jwtKey.Length);
|
||||
|
||||
var jwtIssuer = configuration["SECURITY_JWT_ISSUER"];
|
||||
var jwtAudience = configuration["SECURITY_JWT_AUDIENCE"];
|
||||
|
@ -23,7 +23,8 @@ public class ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) :
|
||||
{
|
||||
Title = "MIREA Schedule Web API",
|
||||
Version = description.ApiVersion.ToString(),
|
||||
Description = "This API provides a convenient interface for retrieving data stored in the database. Special attention was paid to the lightweight and easy transfer of all necessary data. Made by the Winsomnia team.",
|
||||
Description = "This API provides a convenient interface for retrieving data stored in the database. " +
|
||||
"Special attention was paid to the lightweight and easy transfer of all necessary data. Made by the Winsomnia team.",
|
||||
Contact = new OpenApiContact { Name = "Author name", Email = "support@winsomnia.net" },
|
||||
License = new OpenApiLicense { Name = "MIT", Url = new Uri("https://opensource.org/licenses/MIT") }
|
||||
};
|
||||
|
@ -14,8 +14,8 @@ public class SetupTokenService : ISetupToken
|
||||
|
||||
var token2 = Token.Value.Span;
|
||||
|
||||
int result = 0;
|
||||
for (int i = 0; i < Token.Value.Length; i++)
|
||||
var result = 0;
|
||||
for (var i = 0; i < Token.Value.Length; i++)
|
||||
result |= token2[i] ^ token[i];
|
||||
|
||||
return result == 0;
|
||||
|
@ -144,7 +144,7 @@ public class SetupController(
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetPsql([FromBody] DatabaseRequest request)
|
||||
{
|
||||
string connectionString = $"Host={request.Server}:{request.Port};Username={request.User};Database={request.Database}";
|
||||
var connectionString = $"Host={request.Server}:{request.Port};Username={request.User};Database={request.Database}";
|
||||
if (request.Password != null)
|
||||
connectionString += $";Password={request.Password}";
|
||||
if (request.Ssl)
|
||||
@ -171,7 +171,7 @@ public class SetupController(
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetMysql([FromBody] DatabaseRequest request)
|
||||
{
|
||||
string connectionString = $"Server={request.Server}:{request.Port};Uid={request.User};Database={request.Database};";
|
||||
var connectionString = $"Server={request.Server}:{request.Port};Uid={request.User};Database={request.Database};";
|
||||
if (request.Password != null)
|
||||
connectionString += $"Pwd={request.Password};";
|
||||
if (request.Ssl)
|
||||
@ -241,7 +241,7 @@ public class SetupController(
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetRedis([FromBody] CacheRequest request)
|
||||
{
|
||||
string connectionString = $"{request.Server}:{request.Port},ssl=false";
|
||||
var connectionString = $"{request.Server}:{request.Port},ssl=false";
|
||||
if (request.Password != null)
|
||||
connectionString += $",password={request.Password}";
|
||||
|
||||
|
@ -23,7 +23,8 @@ using OAuthProvider = Mirea.Api.Security.Common.Domain.OAuthProvider;
|
||||
namespace Mirea.Api.Endpoint.Controllers.V1;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<GeneralConfig> generalConfig, AuthService auth, PasswordHashService passwordService, OAuthService oAuthService) : BaseController
|
||||
public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<GeneralConfig> generalConfig, AuthService auth,
|
||||
PasswordHashService passwordService, OAuthService oAuthService) : BaseController
|
||||
{
|
||||
private CookieOptionsParameters GetCookieParams() =>
|
||||
new()
|
||||
@ -34,8 +35,8 @@ public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<Gener
|
||||
|
||||
private static string GenerateHtmlResponse(string title, string message, OAuthProvider? provider, bool isError = false, string? traceId = null)
|
||||
{
|
||||
string messageColor = isError ? "red" : "white";
|
||||
string script = "<script>setTimeout(()=>{if(window.opener){window.opener.postMessage(" +
|
||||
var messageColor = isError ? "red" : "white";
|
||||
var script = "<script>setTimeout(()=>{if(window.opener){window.opener.postMessage(" +
|
||||
"{success:" + (!isError).ToString().ToLower() +
|
||||
",provider:'" + (provider == null ? "null" : (int)provider) +
|
||||
"',providerName:'" + (provider == null ? "null" : Enum.GetName(provider.Value)) +
|
||||
@ -80,7 +81,8 @@ public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<Gener
|
||||
if (!userEntity.OAuthProviders.TryAdd(provider, oAuthUser))
|
||||
{
|
||||
title = "Ошибка связи аккаунта!";
|
||||
message = "Этот OAuth провайдер уже связан с вашей учетной записью. Пожалуйста, используйте другого провайдера или удалите связь с аккаунтом.";
|
||||
message = "Этот OAuth провайдер уже связан с вашей учетной записью. " +
|
||||
"Пожалуйста, используйте другого провайдера или удалите связь с аккаунтом.";
|
||||
return Content(GenerateHtmlResponse(title, message, provider, true, traceId), "text/html");
|
||||
}
|
||||
|
||||
@ -138,7 +140,8 @@ public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<Gener
|
||||
if (!Enum.IsDefined(typeof(OAuthProvider), provider))
|
||||
throw new ControllerArgumentException("There is no selected provider");
|
||||
|
||||
return Redirect(oAuthService.GetProviderRedirect(HttpContext, GetCookieParams(), HttpContext.GetApiUrl(Url.Action("OAuth2")!), (OAuthProvider)provider).AbsoluteUri);
|
||||
return Redirect(oAuthService.GetProviderRedirect(HttpContext, GetCookieParams(), HttpContext.GetApiUrl(Url.Action("OAuth2")!),
|
||||
(OAuthProvider)provider).AbsoluteUri);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -24,7 +24,8 @@ public class DisciplineController(IMediator mediator) : BaseController
|
||||
/// <returns>Paginated list of disciplines.</returns>
|
||||
[HttpGet]
|
||||
[BadRequestResponse]
|
||||
public async Task<ActionResult<List<DisciplineResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page, [FromQuery][Range(1, int.MaxValue)] int? pageSize)
|
||||
public async Task<ActionResult<List<DisciplineResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page,
|
||||
[FromQuery][Range(1, int.MaxValue)] int? pageSize)
|
||||
{
|
||||
var result = await mediator.Send(new GetDisciplineListQuery()
|
||||
{
|
||||
|
@ -23,7 +23,8 @@ public class FacultyController(IMediator mediator) : BaseController
|
||||
/// <returns>Paginated list of faculties.</returns>
|
||||
[HttpGet]
|
||||
[BadRequestResponse]
|
||||
public async Task<ActionResult<List<FacultyResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page, [FromQuery][Range(1, int.MaxValue)] int? pageSize)
|
||||
public async Task<ActionResult<List<FacultyResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page,
|
||||
[FromQuery][Range(1, int.MaxValue)] int? pageSize)
|
||||
{
|
||||
var result = await mediator.Send(new GetFacultyListQuery()
|
||||
{
|
||||
|
@ -38,7 +38,8 @@ public class GroupController(IMediator mediator) : BaseController
|
||||
/// <returns>A list of groups.</returns>
|
||||
[HttpGet]
|
||||
[BadRequestResponse]
|
||||
public async Task<ActionResult<List<GroupResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page, [FromQuery][Range(1, int.MaxValue)] int? pageSize)
|
||||
public async Task<ActionResult<List<GroupResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page,
|
||||
[FromQuery][Range(1, int.MaxValue)] int? pageSize)
|
||||
{
|
||||
var result = await mediator.Send(new GetGroupListQuery()
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ public class ImportController(IMediator mediator, IOptionsSnapshot<GeneralConfig
|
||||
GroupIds = request.Groups,
|
||||
LectureHallIds = request.LectureHalls,
|
||||
ProfessorIds = request.Professors
|
||||
})).Schedules;
|
||||
})).Schedules.ToList();
|
||||
|
||||
if (result.Count == 0)
|
||||
return NoContent();
|
||||
@ -58,8 +58,8 @@ public class ImportController(IMediator mediator, IOptionsSnapshot<GeneralConfig
|
||||
using var package = new ExcelPackage();
|
||||
var worksheet = package.Workbook.Worksheets.Add("Расписание");
|
||||
|
||||
int row = 1;
|
||||
int col = 1;
|
||||
var row = 1;
|
||||
var col = 1;
|
||||
|
||||
worksheet.Cells[row, col++].Value = "День";
|
||||
worksheet.Cells[row, col++].Value = "Пара";
|
||||
|
@ -26,7 +26,8 @@ public class ProfessorController(IMediator mediator) : BaseController
|
||||
/// <returns>A list of professors.</returns>
|
||||
[HttpGet]
|
||||
[BadRequestResponse]
|
||||
public async Task<ActionResult<List<ProfessorResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page, [FromQuery][Range(1, int.MaxValue)] int? pageSize)
|
||||
public async Task<ActionResult<List<ProfessorResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page,
|
||||
[FromQuery][Range(1, int.MaxValue)] int? pageSize)
|
||||
{
|
||||
var result = await mediator.Send(new GetProfessorListQuery()
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConf
|
||||
GroupIds = request.Groups,
|
||||
LectureHallIds = request.LectureHalls,
|
||||
ProfessorIds = request.Professors
|
||||
})).Schedules;
|
||||
})).Schedules.ToList();
|
||||
|
||||
if (result.Count == 0)
|
||||
NoContent();
|
||||
|
@ -19,7 +19,8 @@ using Group = Mirea.Api.DataAccess.Domain.Schedule.Group;
|
||||
|
||||
namespace Mirea.Api.Endpoint.Sync;
|
||||
|
||||
internal partial class ScheduleSynchronizer(UberDbContext dbContext, IOptionsSnapshot<GeneralConfig> config, ILogger<ScheduleSynchronizer> logger, IMaintenanceModeService maintenanceMode)
|
||||
internal partial class ScheduleSynchronizer(UberDbContext dbContext, IOptionsSnapshot<GeneralConfig> config, ILogger<ScheduleSynchronizer> logger,
|
||||
IMaintenanceModeService maintenanceMode)
|
||||
{
|
||||
private readonly DataRepository<Campus> _campuses = new([.. dbContext.Campuses]);
|
||||
private readonly DataRepository<Discipline> _disciplines = new([.. dbContext.Disciplines]);
|
||||
@ -120,7 +121,7 @@ internal partial class ScheduleSynchronizer(UberDbContext dbContext, IOptionsSna
|
||||
{
|
||||
hall = [];
|
||||
campuses = [];
|
||||
for (int i = 0; i < groupInfo.Campuses.Length; i++)
|
||||
for (var i = 0; i < groupInfo.Campuses.Length; i++)
|
||||
{
|
||||
var campus = groupInfo.Campuses[i];
|
||||
campuses.Add(_campuses.GetOrCreate(
|
||||
@ -151,7 +152,7 @@ internal partial class ScheduleSynchronizer(UberDbContext dbContext, IOptionsSna
|
||||
Name = groupInfo.Discipline
|
||||
});
|
||||
|
||||
var lesson = _lessons.GetOrCreate(l =>
|
||||
Lesson lesson = _lessons.GetOrCreate(l =>
|
||||
l.IsEven == groupInfo.IsEven &&
|
||||
l.DayOfWeek == groupInfo.Day &&
|
||||
l.PairNumber == groupInfo.Pair &&
|
||||
@ -182,9 +183,9 @@ internal partial class ScheduleSynchronizer(UberDbContext dbContext, IOptionsSna
|
||||
return lesson;
|
||||
});
|
||||
|
||||
int maxValue = int.Max(int.Max(professor?.Count ?? -1, hall?.Count ?? -1), 1);
|
||||
var maxValue = int.Max(int.Max(professor?.Count ?? -1, hall?.Count ?? -1), 1);
|
||||
|
||||
for (int i = 0; i < maxValue; i++)
|
||||
for (var i = 0; i < maxValue; i++)
|
||||
{
|
||||
var prof = professor?.ElementAtOrDefault(i);
|
||||
var lectureHall = hall?.ElementAtOrDefault(i);
|
||||
@ -226,7 +227,9 @@ internal partial class ScheduleSynchronizer(UberDbContext dbContext, IOptionsSna
|
||||
|
||||
if (pairPeriods == null || startTerm == null)
|
||||
{
|
||||
logger.LogWarning("It is not possible to synchronize the schedule due to the fact that the {Arg1} or {Arg2} variable is not initialized.", nameof(pairPeriods), nameof(startTerm));
|
||||
logger.LogWarning("It is not possible to synchronize the schedule due to the fact that the {Arg1} or {Arg2} variable is not initialized.",
|
||||
nameof(pairPeriods),
|
||||
nameof(startTerm));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Mirea.Api.Security.Common.Domain.OAuth2;
|
||||
|
||||
internal struct OAuthProviderUrisData
|
||||
internal readonly struct OAuthProviderUrisData
|
||||
{
|
||||
public string RedirectUrl { get; init; }
|
||||
public string TokenUrl { get; init; }
|
||||
|
@ -61,7 +61,8 @@ public static class DependencyInjection
|
||||
providers.Add(provider, (clientId, secret));
|
||||
}
|
||||
|
||||
services.AddSingleton(provider => new OAuthService(provider.GetRequiredService<ILogger<OAuthService>>(), providers, configuration["SECURITY_ENCRYPTION_TOKEN"]!));
|
||||
services.AddSingleton(provider => new OAuthService(provider.GetRequiredService<ILogger<OAuthService>>(), providers,
|
||||
configuration["SECURITY_ENCRYPTION_TOKEN"]!));
|
||||
|
||||
return services;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ public static class GeneratorKey
|
||||
var random = new Random();
|
||||
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
string charsForGenerate = excludes?
|
||||
var charsForGenerate = excludes?
|
||||
.Aggregate(chars, (current, ex) => current.Replace(ex.ToString(), string.Empty)) ?? chars;
|
||||
|
||||
if (!string.IsNullOrEmpty(includes))
|
||||
|
@ -51,7 +51,8 @@ public class OAuthService(ILogger<OAuthService> logger, Dictionary<OAuthProvider
|
||||
}
|
||||
};
|
||||
|
||||
private static async Task<OAuthTokenResponse?> ExchangeCodeForTokensAsync(string requestUri, string redirectUrl, string code, string clientId, string secret, CancellationToken cancellation)
|
||||
private static async Task<OAuthTokenResponse?> ExchangeCodeForTokensAsync(string requestUri, string redirectUrl, string code,
|
||||
string clientId, string secret, CancellationToken cancellation)
|
||||
{
|
||||
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, requestUri)
|
||||
{
|
||||
@ -77,7 +78,8 @@ public class OAuthService(ILogger<OAuthService> logger, Dictionary<OAuthProvider
|
||||
return JsonSerializer.Deserialize<OAuthTokenResponse>(data);
|
||||
}
|
||||
|
||||
private static async Task<OAuthUser?> GetUserProfileAsync(string requestUri, string authHeader, string accessToken, OAuthProvider provider, CancellationToken cancellation)
|
||||
private static async Task<OAuthUser?> GetUserProfileAsync(string requestUri, string authHeader, string accessToken, OAuthProvider provider,
|
||||
CancellationToken cancellation)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
|
||||
|
||||
@ -130,7 +132,8 @@ public class OAuthService(ILogger<OAuthService> logger, Dictionary<OAuthProvider
|
||||
public (OAuthProvider Provider, Uri Redirect)[] GetAvailableProviders(string redirectUri) =>
|
||||
[.. providers.Select(x => (x.Key, new Uri(redirectUri.TrimEnd('/') + "/?provider=" + (int)x.Key)))];
|
||||
|
||||
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)
|
||||
{
|
||||
var partsState = state.Split('_');
|
||||
|
||||
@ -160,11 +163,14 @@ public class OAuthService(ILogger<OAuthService> logger, Dictionary<OAuthProvider
|
||||
OAuthTokenResponse? accessToken = null;
|
||||
try
|
||||
{
|
||||
accessToken = await ExchangeCodeForTokensAsync(currentProviderStruct.TokenUrl, redirectUrl, code, providerInfo.ClientId, providerInfo.Secret, cancellation);
|
||||
accessToken = await ExchangeCodeForTokensAsync(currentProviderStruct.TokenUrl, redirectUrl, code, providerInfo.ClientId,
|
||||
providerInfo.Secret, cancellation);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogWarning(ex, "Failed to exchange code for access token with provider {Provider}. State: {State}", provider, state);
|
||||
logger.LogWarning(ex, "Failed to exchange code for access token with provider {Provider}. State: {State}",
|
||||
provider,
|
||||
secretStateData);
|
||||
}
|
||||
|
||||
if (accessToken == null)
|
||||
@ -173,7 +179,8 @@ public class OAuthService(ILogger<OAuthService> logger, Dictionary<OAuthProvider
|
||||
OAuthUser? result = null;
|
||||
try
|
||||
{
|
||||
result = await GetUserProfileAsync(currentProviderStruct.UserInfoUrl, currentProviderStruct.AuthHeader, accessToken.AccessToken, provider, cancellation);
|
||||
result = await GetUserProfileAsync(currentProviderStruct.UserInfoUrl, currentProviderStruct.AuthHeader, accessToken.AccessToken,
|
||||
provider, cancellation);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -34,8 +34,8 @@ public class PasswordHashService
|
||||
if (a.Length != b.Length)
|
||||
return false;
|
||||
|
||||
int result = 0;
|
||||
for (int i = 0; i < a.Length; i++)
|
||||
var result = 0;
|
||||
for (var i = 0; i < a.Length; i++)
|
||||
result |= a[i] ^ b[i];
|
||||
return result == 0;
|
||||
}
|
||||
|
@ -10,5 +10,5 @@ public class CampusBasicInfoVm
|
||||
/// <summary>
|
||||
/// The list of campus basic information.
|
||||
/// </summary>
|
||||
public IList<CampusBasicInfoDto> Campuses { get; set; } = new List<CampusBasicInfoDto>();
|
||||
public IEnumerable<CampusBasicInfoDto> Campuses { get; set; } = [];
|
||||
}
|
@ -11,7 +11,8 @@ public class GetCampusDetailsQueryHandler(ICampusDbContext dbContext) : IRequest
|
||||
{
|
||||
public async Task<CampusDetailsVm> Handle(GetCampusDetailsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var campus = await dbContext.Campuses.FirstOrDefaultAsync(c => c.Id == request.Id, cancellationToken) ?? throw new NotFoundException(typeof(Domain.Schedule.Campus), request.Id);
|
||||
var campus = await dbContext.Campuses.FirstOrDefaultAsync(c => c.Id == request.Id, cancellationToken) ??
|
||||
throw new NotFoundException(typeof(Domain.Schedule.Campus), request.Id);
|
||||
|
||||
return new CampusDetailsVm()
|
||||
{
|
||||
|
@ -11,7 +11,8 @@ public class GetDisciplineInfoQueryHandler(IDisciplineDbContext dbContext) : IRe
|
||||
{
|
||||
public async Task<DisciplineInfoVm> Handle(GetDisciplineInfoQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var discipline = await dbContext.Disciplines.FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken) ?? throw new NotFoundException(typeof(Domain.Schedule.Discipline), request.Id);
|
||||
var discipline = await dbContext.Disciplines.FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken) ??
|
||||
throw new NotFoundException(typeof(Domain.Schedule.Discipline), request.Id);
|
||||
|
||||
return new DisciplineInfoVm()
|
||||
{
|
||||
|
@ -10,5 +10,5 @@ public class DisciplineListVm
|
||||
/// <summary>
|
||||
/// The list of disciplines.
|
||||
/// </summary>
|
||||
public IList<DisciplineLookupDto> Disciplines { get; set; } = new List<DisciplineLookupDto>();
|
||||
public IEnumerable<DisciplineLookupDto> Disciplines { get; set; } = [];
|
||||
}
|
@ -10,5 +10,5 @@ public class FacultyListVm
|
||||
/// <summary>
|
||||
/// The list of faculties.
|
||||
/// </summary>
|
||||
public IList<FacultyLookupDto> Faculties { get; set; } = new List<FacultyLookupDto>();
|
||||
public IEnumerable<FacultyLookupDto> Faculties { get; set; } = [];
|
||||
}
|
@ -14,9 +14,4 @@ public class FacultyLookupDto
|
||||
/// The name of the faculty.
|
||||
/// </summary>
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID indicating the faculty's affiliation to the campus.
|
||||
/// </summary>
|
||||
public int? CampusId { get; set; }
|
||||
}
|
@ -10,5 +10,5 @@ public class GroupListVm
|
||||
/// <summary>
|
||||
/// The list of groups.
|
||||
/// </summary>
|
||||
public IList<GroupLookupDto> Groups { get; set; } = new List<GroupLookupDto>();
|
||||
public IEnumerable<GroupLookupDto> Groups { get; set; } = [];
|
||||
}
|
@ -10,5 +10,5 @@ public class LectureHallListVm
|
||||
/// <summary>
|
||||
/// The list of lecture hall.
|
||||
/// </summary>
|
||||
public IList<LectureHallLookupDto> LectureHalls { get; set; } = new List<LectureHallLookupDto>();
|
||||
public IEnumerable<LectureHallLookupDto> LectureHalls { get; set; } = [];
|
||||
}
|
@ -11,7 +11,8 @@ public class GetProfessorInfoQueryHandler(IProfessorDbContext dbContext) : IRequ
|
||||
{
|
||||
public async Task<ProfessorInfoVm> Handle(GetProfessorInfoQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var professor = await dbContext.Professors.FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken) ?? throw new NotFoundException(typeof(Domain.Schedule.Professor), request.Id);
|
||||
var professor = await dbContext.Professors.FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken) ??
|
||||
throw new NotFoundException(typeof(Domain.Schedule.Professor), request.Id);
|
||||
|
||||
return new ProfessorInfoVm()
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ public class GetProfessorInfoSearchQueryHandler(IProfessorDbContext dbContext) :
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
AltName = x.AltName
|
||||
}).ToList()
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
@ -11,5 +11,5 @@ public class ProfessorInfoListVm
|
||||
/// <summary>
|
||||
/// List of <see cref="ProfessorInfoVm"/>
|
||||
/// </summary>
|
||||
public required IList<ProfessorInfoVm> Details { get; set; }
|
||||
public IEnumerable<ProfessorInfoVm> Details { get; set; } = [];
|
||||
}
|
@ -10,5 +10,5 @@ public class ProfessorListVm
|
||||
/// <summary>
|
||||
/// The list of professors.
|
||||
/// </summary>
|
||||
public IList<ProfessorLookupDto> Professors { get; set; } = new List<ProfessorLookupDto>();
|
||||
public IEnumerable<ProfessorLookupDto> Professors { get; set; } = [];
|
||||
}
|
@ -83,7 +83,7 @@ public class GetScheduleListQueryHandler(ILessonDbContext dbContext) : IRequestH
|
||||
.Select(la => la.ProfessorId),
|
||||
|
||||
LinkToMeet = l.LessonAssociations!.Select(la => la.LinkToMeet)
|
||||
}).ToList();
|
||||
});
|
||||
|
||||
return new ScheduleListVm
|
||||
{
|
||||
|
@ -10,5 +10,5 @@ public class ScheduleListVm
|
||||
/// <summary>
|
||||
/// Gets or sets the list of schedules.
|
||||
/// </summary>
|
||||
public IList<ScheduleLookupDto> Schedules { get; set; } = new List<ScheduleLookupDto>();
|
||||
public IEnumerable<ScheduleLookupDto> Schedules { get; set; } = [];
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using FluentValidation;
|
||||
using FluentValidation;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Mirea.Api.DataAccess.Application.Common.Behaviors;
|
||||
@ -11,7 +11,7 @@ public static class DependencyInjection
|
||||
public static IServiceCollection AddApplication(this IServiceCollection services)
|
||||
{
|
||||
services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
|
||||
services.AddValidatorsFromAssemblies(new[] { Assembly.GetExecutingAssembly() });
|
||||
services.AddValidatorsFromAssemblies([Assembly.GetExecutingAssembly()]);
|
||||
services.AddTransient(typeof(IPipelineBehavior<,>),
|
||||
typeof(ValidationBehavior<,>));
|
||||
return services;
|
||||
|
@ -9,7 +9,7 @@ public static class ModelBuilderExtensions
|
||||
{
|
||||
var applyGenericMethod = typeof(ModelBuilder)
|
||||
.GetMethods()
|
||||
.First(m => m.Name == "ApplyConfiguration" &&
|
||||
.First(m => m.Name == nameof(ApplyConfiguration) &&
|
||||
m.GetParameters().Any(p => p.ParameterType.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>)));
|
||||
|
||||
var entityType = configuration.GetType().GetInterfaces()
|
||||
|
@ -4,8 +4,6 @@ namespace Mirea.Api.DataAccess.Persistence;
|
||||
|
||||
public static class DbInitializer
|
||||
{
|
||||
public static void Initialize(DbContext dbContext)
|
||||
{
|
||||
public static void Initialize(DbContext dbContext) =>
|
||||
dbContext.Database.Migrate();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user