From eb0d26a1d9d4ba9c14eae1e4c9250c4922a65324 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 04:10:08 -0600 Subject: [PATCH 01/15] Updates nuget packages. --- src/Tests.Application/Tests.Application.csproj | 12 ++++++------ src/Tests.Cli/Tests.Cli.csproj | 8 ++++---- .../UserRights.Application.csproj | 2 +- src/UserRights.Cli/UserRights.Cli.csproj | 2 +- src/UserRights/UserRights.csproj | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Tests.Application/Tests.Application.csproj b/src/Tests.Application/Tests.Application.csproj index 17f8195..3eb8b24 100644 --- a/src/Tests.Application/Tests.Application.csproj +++ b/src/Tests.Application/Tests.Application.csproj @@ -15,11 +15,11 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + all @@ -27,7 +27,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/Tests.Cli/Tests.Cli.csproj b/src/Tests.Cli/Tests.Cli.csproj index 72239e2..acb160e 100644 --- a/src/Tests.Cli/Tests.Cli.csproj +++ b/src/Tests.Cli/Tests.Cli.csproj @@ -15,9 +15,9 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all @@ -26,7 +26,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/UserRights.Application/UserRights.Application.csproj b/src/UserRights.Application/UserRights.Application.csproj index 42ff85f..ad64632 100644 --- a/src/UserRights.Application/UserRights.Application.csproj +++ b/src/UserRights.Application/UserRights.Application.csproj @@ -12,7 +12,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all diff --git a/src/UserRights.Cli/UserRights.Cli.csproj b/src/UserRights.Cli/UserRights.Cli.csproj index c31dbcd..3160068 100644 --- a/src/UserRights.Cli/UserRights.Cli.csproj +++ b/src/UserRights.Cli/UserRights.Cli.csproj @@ -12,7 +12,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/UserRights/UserRights.csproj b/src/UserRights/UserRights.csproj index 7424761..bc9f7d9 100644 --- a/src/UserRights/UserRights.csproj +++ b/src/UserRights/UserRights.csproj @@ -13,7 +13,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + From 08c4b86a27da6fee07b1c33d4e72e40a4f616dd0 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 04:10:21 -0600 Subject: [PATCH 02/15] Updates dotnet SDK. --- src/global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global.json b/src/global.json index 7b27722..918e756 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.300", + "version": "9.0.305", "rollForward": "latestFeature" } } \ No newline at end of file From 9dff25e8860c0d94bc200de43b6a8fc17998b5af Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:26:17 -0600 Subject: [PATCH 03/15] Updates analyzer configuration. --- src/.editorconfig | 171 ++++++++++-------- src/Directory.Build.props | 17 +- src/StyleCop.ruleset | 34 ---- .../Tests.Application.csproj | 8 - src/Tests.Cli/Tests.Cli.csproj | 8 - src/Tests/Tests.csproj | 8 - .../UserRights.Application.csproj | 8 - src/UserRights.Cli/UserRights.Cli.csproj | 8 - .../UserRights.Extensions.csproj | 8 - src/UserRights.sln | 1 - src/UserRights/UserRights.csproj | 8 - 11 files changed, 111 insertions(+), 168 deletions(-) delete mode 100644 src/StyleCop.ruleset diff --git a/src/.editorconfig b/src/.editorconfig index cdcef13..1b9cc02 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -2,6 +2,7 @@ root = true # All files [*] +charset = utf-8 indent_style = space # Xml files @@ -30,35 +31,38 @@ dotnet_sort_system_directives_first = true file_header_template = unset # this. and Me. preferences -dotnet_style_qualification_for_event = true:suggestion -dotnet_style_qualification_for_field = true:suggestion -dotnet_style_qualification_for_method = true:suggestion -dotnet_style_qualification_for_property = true:suggestion +dotnet_style_qualification_for_event = false:warning +dotnet_style_qualification_for_field = false:warning +dotnet_style_qualification_for_method = false:warning +dotnet_style_qualification_for_property = false:warning # Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion # Parentheses preferences -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_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion # Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion # Expression-level preferences dotnet_style_coalesce_expression = true:suggestion dotnet_style_collection_initializer = true:suggestion dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_namespace_match_folder = true:suggestion dotnet_style_null_propagation = true:suggestion dotnet_style_object_initializer = true:suggestion dotnet_style_operator_placement_when_wrapping = beginning_of_line dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion dotnet_style_prefer_compound_assignment = true:suggestion dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion -dotnet_style_prefer_conditional_expression_over_return = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = none +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed:suggestion dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion dotnet_style_prefer_inferred_tuple_names = true:suggestion dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion @@ -74,9 +78,41 @@ dotnet_code_quality_unused_parameters = all:suggestion # Suppression preferences dotnet_remove_unnecessary_suppression_exclusions = none +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = false:suggestion +dotnet_style_allow_statement_immediately_after_block_experimental = false:suggestion + # ReSharper inspection severities +resharper_access_to_disposed_closure_highlighting = none +resharper_arrange_object_creation_when_type_not_evident_highlighting = suggestion +resharper_convert_if_statement_to_return_statement_highlighting = none +resharper_invert_if_highlighting = none +resharper_loop_can_be_converted_to_query_highlighting = none +resharper_object_creation_when_type_not_evident = target_typed resharper_redundant_name_qualifier_highlighting = none +# Analyzer inspection severities +dotnet_diagnostic.IDE0001.severity = none +dotnet_diagnostic.IDE0003.severity = none # https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0003-ide0009 +dotnet_diagnostic.IDE0039.severity = none +dotnet_diagnostic.IDE0046.severity = none +dotnet_diagnostic.IDE0058.severity = none + +dotnet_diagnostic.CA1822.severity = none + +dotnet_diagnostic.MA0003.severity = none +dotnet_diagnostic.MA0007.severity = none +dotnet_diagnostic.MA0038.severity = none +dotnet_diagnostic.MA0041.severity = none +dotnet_diagnostic.MA0051.severity = none + +dotnet_diagnostic.SA1101.severity = none +dotnet_diagnostic.SA1118.severity = none +dotnet_diagnostic.SA1309.severity = none +dotnet_diagnostic.SA1312.severity = none +dotnet_diagnostic.SA1413.severity = none +dotnet_diagnostic.SA1633.severity = none + #### C# Coding Conventions #### [*.cs] @@ -90,7 +126,7 @@ csharp_style_expression_bodied_accessors = true:suggestion csharp_style_expression_bodied_constructors = true:suggestion csharp_style_expression_bodied_indexers = true:suggestion csharp_style_expression_bodied_lambdas = true:suggestion -csharp_style_expression_bodied_local_functions = true:suggestion +csharp_style_expression_bodied_local_functions = false:silent csharp_style_expression_bodied_methods = true:suggestion csharp_style_expression_bodied_operators = true:suggestion csharp_style_expression_bodied_properties = true:suggestion @@ -98,6 +134,7 @@ csharp_style_expression_bodied_properties = true:suggestion # Pattern matching preferences 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:suggestion csharp_style_prefer_switch_expression = true:suggestion @@ -106,20 +143,31 @@ csharp_style_prefer_switch_expression = true:suggestion csharp_style_conditional_delegate_call = true:suggestion # Modifier preferences +csharp_prefer_static_anonymous_function = true:suggestion csharp_prefer_static_local_function = true:warning -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent +csharp_preferred_modifier_order = public,private,protected,internal,file,const,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion +csharp_style_prefer_readonly_struct = true:suggestion +csharp_style_prefer_readonly_struct_member = true:suggestion # Code-block preferences csharp_prefer_braces = true:suggestion csharp_prefer_simple_using_statement = true:suggestion +csharp_style_namespace_declarations = file_scoped:suggestion +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_primary_constructors = false:silent +csharp_style_prefer_top_level_statements = true:silent # Expression-level preferences 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_pattern_local_over_anonymous_function = 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_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 @@ -175,20 +223,6 @@ csharp_space_between_square_brackets = false csharp_preserve_single_line_blocks = true csharp_preserve_single_line_statements = true -csharp_style_namespace_declarations = file_scoped:suggestion -csharp_style_prefer_method_group_conversion = true:suggestion -csharp_style_prefer_top_level_statements = false:silent -csharp_style_prefer_null_check_over_type_check = true:suggestion -csharp_style_prefer_local_over_anonymous_function = true:suggestion -csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion -csharp_style_prefer_tuple_swap = true:suggestion -csharp_style_prefer_utf8_string_literals = true:suggestion -csharp_style_prefer_readonly_struct = true:suggestion -csharp_style_allow_embedded_statements_on_same_line_experimental = false:suggestion -csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:suggestion -csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false:suggestion -csharp_style_prefer_extended_property_pattern = true:suggestion - #### Naming styles #### [*.{cs,vb}] @@ -236,11 +270,11 @@ dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields -dotnet_naming_rule.private_fields_should_be__camelcase.style = camelcase +dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields -dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = camelcase +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields @@ -274,31 +308,31 @@ dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase dotnet_naming_symbols.interfaces.applicable_kinds = interface dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.interfaces.required_modifiers = +dotnet_naming_symbols.interfaces.required_modifiers = dotnet_naming_symbols.enums.applicable_kinds = enum dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.enums.required_modifiers = +dotnet_naming_symbols.enums.required_modifiers = dotnet_naming_symbols.events.applicable_kinds = event dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.events.required_modifiers = +dotnet_naming_symbols.events.required_modifiers = dotnet_naming_symbols.methods.applicable_kinds = method dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.methods.required_modifiers = +dotnet_naming_symbols.methods.required_modifiers = dotnet_naming_symbols.properties.applicable_kinds = property dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.properties.required_modifiers = +dotnet_naming_symbols.properties.required_modifiers = dotnet_naming_symbols.public_fields.applicable_kinds = field dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal -dotnet_naming_symbols.public_fields.required_modifiers = +dotnet_naming_symbols.public_fields.required_modifiers = dotnet_naming_symbols.private_fields.applicable_kinds = field dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected -dotnet_naming_symbols.private_fields.required_modifiers = +dotnet_naming_symbols.private_fields.required_modifiers = dotnet_naming_symbols.private_static_fields.applicable_kinds = field dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected @@ -306,15 +340,15 @@ dotnet_naming_symbols.private_static_fields.required_modifiers = static dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.types_and_namespaces.required_modifiers = +dotnet_naming_symbols.types_and_namespaces.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_symbols.non_field_members.required_modifiers = dotnet_naming_symbols.type_parameters.applicable_kinds = namespace dotnet_naming_symbols.type_parameters.applicable_accessibilities = * -dotnet_naming_symbols.type_parameters.required_modifiers = +dotnet_naming_symbols.type_parameters.required_modifiers = dotnet_naming_symbols.private_constant_fields.applicable_kinds = field dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected @@ -322,7 +356,7 @@ dotnet_naming_symbols.private_constant_fields.required_modifiers = const dotnet_naming_symbols.local_variables.applicable_kinds = local dotnet_naming_symbols.local_variables.applicable_accessibilities = local -dotnet_naming_symbols.local_variables.required_modifiers = +dotnet_naming_symbols.local_variables.required_modifiers = dotnet_naming_symbols.local_constants.applicable_kinds = local dotnet_naming_symbols.local_constants.applicable_accessibilities = local @@ -330,7 +364,7 @@ dotnet_naming_symbols.local_constants.required_modifiers = const dotnet_naming_symbols.parameters.applicable_kinds = parameter dotnet_naming_symbols.parameters.applicable_accessibilities = * -dotnet_naming_symbols.parameters.required_modifiers = +dotnet_naming_symbols.parameters.required_modifiers = dotnet_naming_symbols.public_constant_fields.applicable_kinds = field dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal @@ -346,57 +380,50 @@ dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readon dotnet_naming_symbols.local_functions.applicable_kinds = local_function dotnet_naming_symbols.local_functions.applicable_accessibilities = * -dotnet_naming_symbols.local_functions.required_modifiers = +dotnet_naming_symbols.local_functions.required_modifiers = # Naming styles -dotnet_naming_style.pascalcase.required_prefix = -dotnet_naming_style.pascalcase.required_suffix = -dotnet_naming_style.pascalcase.word_separator = +dotnet_naming_style.pascalcase.required_prefix = +dotnet_naming_style.pascalcase.required_suffix = +dotnet_naming_style.pascalcase.word_separator = dotnet_naming_style.pascalcase.capitalization = pascal_case dotnet_naming_style.ipascalcase.required_prefix = I -dotnet_naming_style.ipascalcase.required_suffix = -dotnet_naming_style.ipascalcase.word_separator = +dotnet_naming_style.ipascalcase.required_suffix = +dotnet_naming_style.ipascalcase.word_separator = dotnet_naming_style.ipascalcase.capitalization = pascal_case dotnet_naming_style.tpascalcase.required_prefix = T -dotnet_naming_style.tpascalcase.required_suffix = -dotnet_naming_style.tpascalcase.word_separator = +dotnet_naming_style.tpascalcase.required_suffix = +dotnet_naming_style.tpascalcase.word_separator = dotnet_naming_style.tpascalcase.capitalization = pascal_case dotnet_naming_style._camelcase.required_prefix = _ -dotnet_naming_style._camelcase.required_suffix = -dotnet_naming_style._camelcase.word_separator = +dotnet_naming_style._camelcase.required_suffix = +dotnet_naming_style._camelcase.word_separator = dotnet_naming_style._camelcase.capitalization = camel_case -dotnet_naming_style.camelcase.required_prefix = -dotnet_naming_style.camelcase.required_suffix = -dotnet_naming_style.camelcase.word_separator = +dotnet_naming_style.camelcase.required_prefix = +dotnet_naming_style.camelcase.required_suffix = +dotnet_naming_style.camelcase.word_separator = dotnet_naming_style.camelcase.capitalization = camel_case dotnet_naming_style.s_camelcase.required_prefix = s_ -dotnet_naming_style.s_camelcase.required_suffix = -dotnet_naming_style.s_camelcase.word_separator = +dotnet_naming_style.s_camelcase.required_suffix = +dotnet_naming_style.s_camelcase.word_separator = dotnet_naming_style.s_camelcase.capitalization = camel_case -tab_width = 4 -indent_size = 4 -end_of_line = crlf -dotnet_style_namespace_match_folder = true:suggestion -dotnet_style_allow_multiple_blank_lines_experimental = false:suggestion -dotnet_style_allow_statement_immediately_after_block_experimental = false:suggestion - -[*.{csproj,props}] -indent_size = 2 [**.json] indent_size = 2 +tab_width = 2 -[*.ruleset] -indent_size = 2 - -[*.mjml] +# XML project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] indent_size = 2 +tab_width = 2 -[*.cshtml] +# XML config files +[*.{props,targets,ruleset,config,nuspec,resx,transform,vsixmanifest,vsct}] indent_size = 2 +tab_width = 2 diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 23b05e2..2b9f876 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -4,15 +4,22 @@ Windows User Rights Assignment Utility Utility for managing user right assignments. Copyright © Joseph L. Casale 2022 - - - - $(MSBuildThisFileDirectory)StyleCop.ruleset true + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + - + diff --git a/src/StyleCop.ruleset b/src/StyleCop.ruleset deleted file mode 100644 index 3466bed..0000000 --- a/src/StyleCop.ruleset +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Tests.Application/Tests.Application.csproj b/src/Tests.Application/Tests.Application.csproj index 3eb8b24..e96f27f 100644 --- a/src/Tests.Application/Tests.Application.csproj +++ b/src/Tests.Application/Tests.Application.csproj @@ -11,20 +11,12 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/src/Tests.Cli/Tests.Cli.csproj b/src/Tests.Cli/Tests.Cli.csproj index acb160e..a2858a5 100644 --- a/src/Tests.Cli/Tests.Cli.csproj +++ b/src/Tests.Cli/Tests.Cli.csproj @@ -11,18 +11,10 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 36db85e..e16c39f 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -8,14 +8,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/src/UserRights.Application/UserRights.Application.csproj b/src/UserRights.Application/UserRights.Application.csproj index ad64632..d6fb065 100644 --- a/src/UserRights.Application/UserRights.Application.csproj +++ b/src/UserRights.Application/UserRights.Application.csproj @@ -8,18 +8,10 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/src/UserRights.Cli/UserRights.Cli.csproj b/src/UserRights.Cli/UserRights.Cli.csproj index 3160068..f092145 100644 --- a/src/UserRights.Cli/UserRights.Cli.csproj +++ b/src/UserRights.Cli/UserRights.Cli.csproj @@ -8,15 +8,7 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/src/UserRights.Extensions/UserRights.Extensions.csproj b/src/UserRights.Extensions/UserRights.Extensions.csproj index 03d44c8..c13be21 100644 --- a/src/UserRights.Extensions/UserRights.Extensions.csproj +++ b/src/UserRights.Extensions/UserRights.Extensions.csproj @@ -9,14 +9,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - \ No newline at end of file diff --git a/src/UserRights.sln b/src/UserRights.sln index c941be8..e88fee3 100644 --- a/src/UserRights.sln +++ b/src/UserRights.sln @@ -21,7 +21,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig global.json = global.json - StyleCop.ruleset = StyleCop.ruleset EndProjectSection EndProject Global diff --git a/src/UserRights/UserRights.csproj b/src/UserRights/UserRights.csproj index bc9f7d9..60f8e7c 100644 --- a/src/UserRights/UserRights.csproj +++ b/src/UserRights/UserRights.csproj @@ -9,10 +9,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - @@ -22,10 +18,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - From 1cb992238817defc101f9ebcf2ab85508880822e Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:31:10 -0600 Subject: [PATCH 04/15] Fixes IDE0003: Remove this or Me qualification. --- .../AdminOnlyFactAttribute.cs | 2 +- .../LsaUserRightsGetPrincipalsTests.cs | 2 +- .../LsaUserRightsGrantPrivilegeTests.cs | 4 +- .../LsaUserRightsRevokePrivilegeTests.cs | 4 +- .../LsaUserRightsTestBase.cs | 26 ++++---- .../UserRightsManagerListTests.cs | 6 +- .../UserRightsManagerPrincipalTests.cs | 12 ++-- .../UserRightsManagerPrivilegeTests.cs | 16 ++--- .../UserRightsManagerTestBase.cs | 22 +++---- src/Tests.Cli/CliTestBase.cs | 20 +++---- src/Tests.Cli/ListCommandTests.cs | 16 ++--- src/Tests.Cli/ListSyntaxTests.cs | 20 +++---- src/Tests.Cli/PrincipalCommandTests.cs | 40 ++++++------- src/Tests.Cli/PrincipalSyntaxTests.cs | 44 +++++++------- src/Tests.Cli/PrivilegeCommandTests.cs | 56 ++++++++--------- src/Tests.Cli/PrivilegeSyntaxTests.cs | 60 +++++++++---------- src/Tests/MockLsaUserRights.cs | 38 ++++++------ src/UserRights.Application/LsaUserRights.cs | 42 ++++++------- src/UserRights.Application/UserRightEntry.cs | 6 +- .../UserRightsManager.cs | 32 +++++----- src/UserRights.Cli/CliBuilder.cs | 38 ++++++------ src/UserRights.Cli/HelpExamplesAction.cs | 4 +- 22 files changed, 255 insertions(+), 255 deletions(-) diff --git a/src/Tests.Application/AdminOnlyFactAttribute.cs b/src/Tests.Application/AdminOnlyFactAttribute.cs index 18f5466..fc1924c 100644 --- a/src/Tests.Application/AdminOnlyFactAttribute.cs +++ b/src/Tests.Application/AdminOnlyFactAttribute.cs @@ -20,6 +20,6 @@ public AdminOnlyFactAttribute() return; } - this.Skip = "Current user is not an administrator."; + Skip = "Current user is not an administrator."; } } \ No newline at end of file diff --git a/src/Tests.Application/LsaUserRightsGetPrincipalsTests.cs b/src/Tests.Application/LsaUserRightsGetPrincipalsTests.cs index d390f78..6db92cc 100644 --- a/src/Tests.Application/LsaUserRightsGetPrincipalsTests.cs +++ b/src/Tests.Application/LsaUserRightsGetPrincipalsTests.cs @@ -22,7 +22,7 @@ public sealed class LsaUserRightsGetPrincipalsTests : LsaUserRightsTestBase [AdminOnlyFact] public void GetPrincipalsShouldWork() { - var expected = this.InitialState.Values + var expected = InitialState.Values .SelectMany(p => p) .Distinct() .Order() diff --git a/src/Tests.Application/LsaUserRightsGrantPrivilegeTests.cs b/src/Tests.Application/LsaUserRightsGrantPrivilegeTests.cs index 578c451..4392c17 100644 --- a/src/Tests.Application/LsaUserRightsGrantPrivilegeTests.cs +++ b/src/Tests.Application/LsaUserRightsGrantPrivilegeTests.cs @@ -26,7 +26,7 @@ public void GrantPrivilegeShouldWork() { var securityIdentifier = new SecurityIdentifier(Users); - if (this.InitialState.TryGetValue(SeMachineAccountPrivilege, out var initial)) + if (InitialState.TryGetValue(SeMachineAccountPrivilege, out var initial)) { Assert.DoesNotContain(securityIdentifier, initial); } @@ -35,7 +35,7 @@ public void GrantPrivilegeShouldWork() policy.Connect(); policy.LsaAddAccountRights(securityIdentifier, SeMachineAccountPrivilege); - var current = this.GetCurrentState(); + var current = GetCurrentState(); current.TryGetValue(SeMachineAccountPrivilege, out var collection); diff --git a/src/Tests.Application/LsaUserRightsRevokePrivilegeTests.cs b/src/Tests.Application/LsaUserRightsRevokePrivilegeTests.cs index f656dd0..f6fa5a0 100644 --- a/src/Tests.Application/LsaUserRightsRevokePrivilegeTests.cs +++ b/src/Tests.Application/LsaUserRightsRevokePrivilegeTests.cs @@ -26,7 +26,7 @@ public void RevokePrivilegeShouldWork() { var securityIdentifier = new SecurityIdentifier(BackupOperators); - this.InitialState.TryGetValue(SeBackupPrivilege, out var initial); + InitialState.TryGetValue(SeBackupPrivilege, out var initial); Assert.NotNull(initial); Assert.Contains(securityIdentifier, initial); @@ -35,7 +35,7 @@ public void RevokePrivilegeShouldWork() policy.Connect(); policy.LsaRemoveAccountRights(securityIdentifier, SeBackupPrivilege); - var current = this.GetCurrentState(); + var current = GetCurrentState(); if (current.TryGetValue(SeBackupPrivilege, out var collection)) { diff --git a/src/Tests.Application/LsaUserRightsTestBase.cs b/src/Tests.Application/LsaUserRightsTestBase.cs index ee0256b..f4f80ad 100644 --- a/src/Tests.Application/LsaUserRightsTestBase.cs +++ b/src/Tests.Application/LsaUserRightsTestBase.cs @@ -39,17 +39,17 @@ protected LsaUserRightsTestBase() try { // Create a backup to restore during disposal. - CreateSecurityDatabaseBackup(this.directory.FullName); + CreateSecurityDatabaseBackup(directory.FullName); // Load the contents of the backup for use as initial state. - this.initialState = ReadSecurityDatabaseBackup(this.directory.FullName); + initialState = ReadSecurityDatabaseBackup(directory.FullName); // Create the updated configuration file to remove assignments for any privileges that were originally empty. - CreateRestoreTemplate(this.directory.FullName, this.initialState); + CreateRestoreTemplate(directory.FullName, initialState); } catch { - this.directory = null; + directory = null; throw; } @@ -62,16 +62,16 @@ protected IReadOnlyDictionary> I { get { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - return this.initialState; + return initialState; } } /// public void Dispose() { - this.Dispose(true); + Dispose(true); GC.SuppressFinalize(this); } @@ -81,21 +81,21 @@ public void Dispose() /// A value indicating whether the method call comes from a dispose method (its value is ) or from a finalizer (its value is ). protected virtual void Dispose(bool disposing) { - if (this.disposed) + if (disposed) { return; } if (disposing) { - if (this.directory is not null) + if (directory is not null) { - RestoreSecurityDatabaseBackup(this.directory.FullName); + RestoreSecurityDatabaseBackup(directory.FullName); - this.directory.Delete(true); + directory.Delete(true); } - this.disposed = true; + disposed = true; } } @@ -105,7 +105,7 @@ protected virtual void Dispose(bool disposing) /// A map of privilege to security identifiers. protected IReadOnlyDictionary> GetCurrentState() { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); var directoryInfo = CreateTempDirectory(); diff --git a/src/Tests.Application/UserRightsManagerListTests.cs b/src/Tests.Application/UserRightsManagerListTests.cs index 8714daf..4c64d85 100644 --- a/src/Tests.Application/UserRightsManagerListTests.cs +++ b/src/Tests.Application/UserRightsManagerListTests.cs @@ -31,7 +31,7 @@ public sealed class UserRightsManagerListTests : UserRightsManagerTestBase [Fact] public void InvalidArgumentsThrowsException() { - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); Assert.ThrowsAny(() => manager.GetUserRights(null!)); } @@ -74,7 +74,7 @@ public async Task SerializingToCsvShouldWork() Assert.Equal([Privilege1, Privilege2], policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal([Privilege1, Privilege2], policy.LsaEnumerateAccountRights(PrincipalSid2)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); var userRights = manager.GetUserRights(policy).ToArray(); Assert.Equal(expected, userRights, new UserRightEntryEqualityComparer()); @@ -141,7 +141,7 @@ public async Task SerializingToJsonShouldWork() Assert.Equal(new[] { Privilege1, Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege1, Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); var userRights = manager.GetUserRights(policy).ToArray(); Assert.Equal(expected, userRights, new UserRightEntryEqualityComparer()); diff --git a/src/Tests.Application/UserRightsManagerPrincipalTests.cs b/src/Tests.Application/UserRightsManagerPrincipalTests.cs index 58db2ff..38ebc4d 100644 --- a/src/Tests.Application/UserRightsManagerPrincipalTests.cs +++ b/src/Tests.Application/UserRightsManagerPrincipalTests.cs @@ -92,7 +92,7 @@ public void GrantAndRevokeOthersShouldWork() Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrincipal(policy, PrincipalName1, [Privilege2], [], false, true, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight().Order()); @@ -130,7 +130,7 @@ public void GrantAndRevokeShouldWork() Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrincipal(policy, PrincipalName1, [Privilege2], [Privilege1], false, false, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); @@ -168,7 +168,7 @@ public void GrantShouldWork() Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrincipal(policy, PrincipalName1, [Privilege2], [], false, false, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); @@ -190,7 +190,7 @@ public void GrantShouldWork() [MemberData(nameof(InvalidArguments))] public void InvalidArgumentsThrowsException(IUserRightsSerializable policy, string principal, string[] grants, string[] revocations, bool revokeAll, bool revokeOthers, bool dryRun) { - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); Assert.ThrowsAny(() => manager.ModifyPrincipal(policy, principal, grants, revocations, revokeAll, revokeOthers, dryRun)); } @@ -226,7 +226,7 @@ public void RevokeAllShouldWork() Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid1).Order(StringComparer.OrdinalIgnoreCase)); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrincipal(policy, PrincipalName1, [], [], true, false, false); Assert.Empty(policy.LsaEnumerateAccountRights(PrincipalSid1)); @@ -264,7 +264,7 @@ public void RevokeShouldWork() Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrincipal(policy, PrincipalName2, [], [Privilege2], false, false, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); diff --git a/src/Tests.Application/UserRightsManagerPrivilegeTests.cs b/src/Tests.Application/UserRightsManagerPrivilegeTests.cs index 9d07c9b..c442648 100644 --- a/src/Tests.Application/UserRightsManagerPrivilegeTests.cs +++ b/src/Tests.Application/UserRightsManagerPrivilegeTests.cs @@ -102,7 +102,7 @@ public void GrantAndRevokeOthersShouldWork() Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight(Privilege1).Order()); Assert.Equal([PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight(Privilege2)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrivilege(policy, Privilege2, [PrincipalName1], [], false, true, null!, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); @@ -142,7 +142,7 @@ public void GrantAndRevokeShouldWork() Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid1).Order(StringComparer.OrdinalIgnoreCase)); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrivilege(policy, Privilege1, [PrincipalName2], [PrincipalName1], false, false, null!, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); @@ -185,7 +185,7 @@ public void GrantAndRevokePatternShouldWork() Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid3).Order(StringComparer.OrdinalIgnoreCase)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); var pattern = new Regex("^S-1-5-21", RegexOptions.None, TimeSpan.FromSeconds(1)); manager.ModifyPrivilege(policy, Privilege1, [PrincipalName1], [], false, false, pattern, false); @@ -224,7 +224,7 @@ public void GrantShouldWork() Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrivilege(policy, Privilege2, [PrincipalName1], [], false, false, null!, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); @@ -247,7 +247,7 @@ public void GrantShouldWork() [MemberData(nameof(InvalidArguments))] public void InvalidArgumentsThrowsException(IUserRightsSerializable policy, string privilege, string[] grants, string[] revocations, bool revokeAll, bool revokeOthers, string revokePattern, bool dryRun) { - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); var regex = string.IsNullOrWhiteSpace(revokePattern) ? null : new Regex(revokePattern, RegexOptions.None, TimeSpan.FromSeconds(1)); Assert.ThrowsAny(() => manager.ModifyPrivilege(policy, privilege, grants, revocations, revokeAll, revokeOthers, regex, dryRun)); @@ -286,7 +286,7 @@ public void RevokeAllShouldWork() Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight(Privilege1).Order()); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight(Privilege2).Order()); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrivilege(policy, Privilege1, [], [], true, false, null!, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); @@ -326,7 +326,7 @@ public void RevokeShouldWork() Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrivilege(policy, Privilege1, [], [PrincipalName2], false, false, null!, false); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); @@ -369,7 +369,7 @@ public void RevokePatternForAllButBuiltinAndVirtualShouldWork() Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid3).Order(StringComparer.OrdinalIgnoreCase)); - var manager = this.ServiceProvider.GetRequiredService(); + var manager = ServiceProvider.GetRequiredService(); var pattern = new Regex("^S-1-5-21", RegexOptions.None, TimeSpan.FromSeconds(1)); manager.ModifyPrivilege(policy, Privilege1, [], [], false, false, pattern, false); diff --git a/src/Tests.Application/UserRightsManagerTestBase.cs b/src/Tests.Application/UserRightsManagerTestBase.cs index d393c0d..394faa4 100644 --- a/src/Tests.Application/UserRightsManagerTestBase.cs +++ b/src/Tests.Application/UserRightsManagerTestBase.cs @@ -21,7 +21,7 @@ public abstract class UserRightsManagerTestBase : IDisposable /// protected UserRightsManagerTestBase() { - this.serviceCollection = new ServiceCollection() + serviceCollection = new ServiceCollection() .AddSingleton() .AddLogging(builder => builder .ClearProviders() @@ -29,7 +29,7 @@ protected UserRightsManagerTestBase() .AddDebug()); // Defer the creation until the instance is accessed to allow inheritors to modify the service collection. - this.serviceProvider = new Lazy(this.serviceCollection.BuildServiceProvider); + serviceProvider = new Lazy(serviceCollection.BuildServiceProvider); } /// @@ -39,9 +39,9 @@ protected IServiceCollection ServiceCollection { get { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - return this.serviceCollection; + return serviceCollection; } } @@ -52,16 +52,16 @@ protected ServiceProvider ServiceProvider { get { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - return this.serviceProvider.Value; + return serviceProvider.Value; } } /// public void Dispose() { - this.Dispose(true); + Dispose(true); GC.SuppressFinalize(this); } @@ -71,19 +71,19 @@ public void Dispose() /// A value indicating whether the method call comes from a dispose method (its value is ) or from a finalizer (its value is ). protected virtual void Dispose(bool disposing) { - if (this.disposed) + if (disposed) { return; } if (disposing) { - if (this.serviceProvider.IsValueCreated) + if (serviceProvider.IsValueCreated) { - this.serviceProvider.Value.Dispose(); + serviceProvider.Value.Dispose(); } - this.disposed = true; + disposed = true; } } } \ No newline at end of file diff --git a/src/Tests.Cli/CliTestBase.cs b/src/Tests.Cli/CliTestBase.cs index c918cf8..8d66301 100644 --- a/src/Tests.Cli/CliTestBase.cs +++ b/src/Tests.Cli/CliTestBase.cs @@ -20,13 +20,13 @@ public abstract class CliTestBase : IDisposable /// protected CliTestBase() { - this.serviceCollection = new ServiceCollection() + serviceCollection = new ServiceCollection() .AddLogging(builder => builder .ClearProviders() .SetMinimumLevel(LogLevel.Trace) .AddDebug()); - this.serviceProvider = new Lazy(this.serviceCollection.BuildServiceProvider); + serviceProvider = new Lazy(serviceCollection.BuildServiceProvider); } /// @@ -36,9 +36,9 @@ protected IServiceCollection ServiceCollection { get { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - return this.serviceCollection; + return serviceCollection; } } @@ -49,16 +49,16 @@ protected ServiceProvider ServiceProvider { get { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - return this.serviceProvider.Value; + return serviceProvider.Value; } } /// public void Dispose() { - this.Dispose(true); + Dispose(true); GC.SuppressFinalize(this); } @@ -68,15 +68,15 @@ public void Dispose() /// A value indicating whether the method call comes from a dispose method (its value is ) or from a finalizer (its value is ). protected virtual void Dispose(bool disposing) { - if (this.disposed) + if (disposed) { return; } if (disposing) { - this.serviceProvider.Value.Dispose(); - this.disposed = true; + serviceProvider.Value.Dispose(); + disposed = true; } } } \ No newline at end of file diff --git a/src/Tests.Cli/ListCommandTests.cs b/src/Tests.Cli/ListCommandTests.cs index c6ced4b..d909e6d 100644 --- a/src/Tests.Cli/ListCommandTests.cs +++ b/src/Tests.Cli/ListCommandTests.cs @@ -57,11 +57,11 @@ public async Task PathAndJsonShouldWork() var policy = new MockLsaUserRights(database); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -129,11 +129,11 @@ public async Task PathShouldWork() .ThenBy(p => p.SecurityId, StringComparer.OrdinalIgnoreCase) .ToArray(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); diff --git a/src/Tests.Cli/ListSyntaxTests.cs b/src/Tests.Cli/ListSyntaxTests.cs index 61a7940..cfb9601 100644 --- a/src/Tests.Cli/ListSyntaxTests.cs +++ b/src/Tests.Cli/ListSyntaxTests.cs @@ -17,11 +17,11 @@ public sealed class ListSyntaxTests : CliTestBase /// public ListSyntaxTests() { - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - this.builder = this.ServiceProvider.GetRequiredService(); + builder = ServiceProvider.GetRequiredService(); } /// @@ -31,7 +31,7 @@ public ListSyntaxTests() public void CsvToStdoutShouldWork() { var args = new[] { "list" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -45,7 +45,7 @@ public void CsvToStdoutShouldWork() public void CsvToPathShouldWork() { var args = new[] { "list", "--path", "file.csv" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -60,7 +60,7 @@ public void CsvToPathShouldWork() [InlineData("list", "--path", "")] [InlineData("list", "--path", " ")] public void PathWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace system name is rejected. @@ -70,7 +70,7 @@ public void PathWithInvalidStringThrowsException(params string[] args) [InlineData("list", "--system-name", "")] [InlineData("list", "--system-name", " ")] public void SystemNameWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Verifies list mode with JSON formatted output sent to STDOUT is parsed successfully. @@ -79,7 +79,7 @@ public void SystemNameWithInvalidStringThrowsException(params string[] args) public void JsonToStdoutShouldWork() { var args = new[] { "list", "--json" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -93,7 +93,7 @@ public void JsonToStdoutShouldWork() public void JsonToPathShouldWork() { var args = new[] { "list", "--json", "--path", "file.csv" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); diff --git a/src/Tests.Cli/PrincipalCommandTests.cs b/src/Tests.Cli/PrincipalCommandTests.cs index 73491a0..1bb953b 100644 --- a/src/Tests.Cli/PrincipalCommandTests.cs +++ b/src/Tests.Cli/PrincipalCommandTests.cs @@ -48,11 +48,11 @@ public void GrantAndRevokeOthersShouldWork() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -105,11 +105,11 @@ public void GrantAndRevokeShouldWork() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -163,11 +163,11 @@ public void GrantShouldWork() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -220,11 +220,11 @@ public void RevokeAllShouldWork() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -275,11 +275,11 @@ public void RevokeShouldWork() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); diff --git a/src/Tests.Cli/PrincipalSyntaxTests.cs b/src/Tests.Cli/PrincipalSyntaxTests.cs index a76bec1..e017432 100644 --- a/src/Tests.Cli/PrincipalSyntaxTests.cs +++ b/src/Tests.Cli/PrincipalSyntaxTests.cs @@ -17,11 +17,11 @@ public sealed class PrincipalSyntaxTests : CliTestBase /// public PrincipalSyntaxTests() { - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - this.builder = this.ServiceProvider.GetRequiredService(); + builder = ServiceProvider.GetRequiredService(); } /// @@ -31,7 +31,7 @@ public PrincipalSyntaxTests() public void GrantAndRevokeShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--revoke", "SeBatchLogonRight" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -45,7 +45,7 @@ public void GrantAndRevokeShouldWork() public void GrantMultipleShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--grant", "SeBatchLogonRight" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -59,7 +59,7 @@ public void GrantMultipleShouldWork() public void GrantShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -74,7 +74,7 @@ public void GrantShouldWork() [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", "")] [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", " ")] public void GrantWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures granting a privilege and revoking all other privileges is rejected. @@ -83,7 +83,7 @@ public void GrantWithInvalidStringThrowsException(params string[] args) public void GrantWithRevokeAllThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--revoke-all" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -95,7 +95,7 @@ public void GrantWithRevokeAllThrowsException() public void NoOptionsThrowsException() { var args = new[] { "principal" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -109,7 +109,7 @@ public void NoOptionsThrowsException() [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--grant", "SeServiceLogonRight")] [InlineData("principal", "DOMAIN\\UserOrGroup", "--revoke", "SeServiceLogonRight", "--revoke", "SeServiceLogonRight")] public void OverlappingGrantsAndRevokesThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace principal is rejected. @@ -119,7 +119,7 @@ public void OverlappingGrantsAndRevokesThrowsException(params string[] args) [InlineData("principal", "", "--grant", "SeServiceLogonRight")] [InlineData("principal", " ", "--grant", "SeServiceLogonRight")] public void PrincipalWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures revoking all privileges is accepted. @@ -128,7 +128,7 @@ public void PrincipalWithInvalidStringThrowsException(params string[] args) public void RevokeAllShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-all" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -142,7 +142,7 @@ public void RevokeAllShouldWork() public void RevokeAllWithGrantsThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-all", "--grant", "SeServiceLogonRight" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -154,7 +154,7 @@ public void RevokeAllWithGrantsThrowsException() public void RevokeAllWithRevocationsThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-all", "--revoke", "SeServiceLogonRight" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -166,7 +166,7 @@ public void RevokeAllWithRevocationsThrowsException() public void RevokeAllWithRevokeOthersThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-all", "--revoke-others" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -178,7 +178,7 @@ public void RevokeAllWithRevokeOthersThrowsException() public void RevokeMultipleShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke", "SeServiceLogonRight", "--revoke", "SeBatchLogonRight" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -193,7 +193,7 @@ public void RevokeOthersWithOutGrantsThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-others" }; - Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); } /// @@ -203,7 +203,7 @@ public void RevokeOthersWithOutGrantsThrowsException() public void RevokeOthersWithRevocationsThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-others", "--revoke", "SeServiceLogonRight" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -215,7 +215,7 @@ public void RevokeOthersWithRevocationsThrowsException() public void RevokeShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke", "SeServiceLogonRight" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -230,7 +230,7 @@ public void RevokeShouldWork() [InlineData("principal", "DOMAIN\\UserOrGroup", "--revoke", "")] [InlineData("principal", "DOMAIN\\UserOrGroup", "--revoke", " ")] public void RevokeWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace system name is rejected. @@ -240,5 +240,5 @@ public void RevokeWithInvalidStringThrowsException(params string[] args) [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--system-name", "")] [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--system-name", " ")] public void SystemNameWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); } \ No newline at end of file diff --git a/src/Tests.Cli/PrivilegeCommandTests.cs b/src/Tests.Cli/PrivilegeCommandTests.cs index 95a9c79..2ac2ed9 100644 --- a/src/Tests.Cli/PrivilegeCommandTests.cs +++ b/src/Tests.Cli/PrivilegeCommandTests.cs @@ -51,11 +51,11 @@ public void GrantAndRevokeOthersShouldWork() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -110,11 +110,11 @@ public void GrantAndRevokePasses() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -173,11 +173,11 @@ public void GrantAndRevokePatternPasses() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -231,11 +231,11 @@ public void GrantPasses() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -290,11 +290,11 @@ public void RevokeAllPasses() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -347,11 +347,11 @@ public void RevokePasses() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); @@ -408,11 +408,11 @@ public void RevokePatternForAllButBuiltinAndVirtualPasses() policy.ResetConnection(); - this.ServiceCollection.AddSingleton(policy); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(policy); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - var builder = this.ServiceProvider.GetRequiredService(); + var builder = ServiceProvider.GetRequiredService(); var configuration = builder.Build(); diff --git a/src/Tests.Cli/PrivilegeSyntaxTests.cs b/src/Tests.Cli/PrivilegeSyntaxTests.cs index 30cb1f3..d9e130e 100644 --- a/src/Tests.Cli/PrivilegeSyntaxTests.cs +++ b/src/Tests.Cli/PrivilegeSyntaxTests.cs @@ -17,11 +17,11 @@ public sealed class PrivilegeSyntaxTests : CliTestBase /// public PrivilegeSyntaxTests() { - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); - this.ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); + ServiceCollection.AddSingleton(); - this.builder = this.ServiceProvider.GetRequiredService(); + builder = ServiceProvider.GetRequiredService(); } /// @@ -31,7 +31,7 @@ public PrivilegeSyntaxTests() public void GrantAndRevokeShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\User", "--revoke", "DOMAIN\\Group" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -45,7 +45,7 @@ public void GrantAndRevokeShouldWork() public void GrantMultipleShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\User", "--grant", "DOMAIN\\Group" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -59,7 +59,7 @@ public void GrantMultipleShouldWork() public void GrantShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\User" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -74,7 +74,7 @@ public void GrantShouldWork() [InlineData("privilege", "SeServiceLogonRight", "--grant", "")] [InlineData("privilege", "SeServiceLogonRight", "--grant", " ")] public void GrantWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures granting a context and revoking all contexts is rejected. @@ -83,7 +83,7 @@ public void GrantWithInvalidStringThrowsException(params string[] args) public void GrantWithRevokeAllThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\User", "--revoke-all" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -95,7 +95,7 @@ public void GrantWithRevokeAllThrowsException() public void NoOptionsThrowsException() { var args = new[] { "privilege" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -109,7 +109,7 @@ public void NoOptionsThrowsException() [InlineData("privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\UserOrGroup", "--grant", "DOMAIN\\UserOrGroup")] [InlineData("privilege", "SeServiceLogonRight", "--revoke", "DOMAIN\\UserOrGroup", "--revoke", "DOMAIN\\UserOrGroup")] public void OverlappingGrantsAndRevokesThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace principal is rejected. @@ -119,7 +119,7 @@ public void OverlappingGrantsAndRevokesThrowsException(params string[] args) [InlineData("privilege", "", "--grant", "DOMAIN\\UserOrGroup")] [InlineData("privilege", " ", "--grant", "DOMAIN\\UserOrGroup")] public void PrivilegeWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures revoking all contexts is accepted. @@ -128,7 +128,7 @@ public void PrivilegeWithInvalidStringThrowsException(params string[] args) public void RevokeAllShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-all" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); int? rc = null; var exception = Record.Exception(() => rc = configuration.Parse(args).Validate().Invoke()); @@ -144,7 +144,7 @@ public void RevokeAllShouldWork() public void RevokeAllWithGrantsThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-all", "--grant", "DOMAIN\\UserOrGroup" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -156,7 +156,7 @@ public void RevokeAllWithGrantsThrowsException() public void RevokeAllWithRevocationsThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-all", "--revoke", "DOMAIN\\UserOrGroup" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -168,7 +168,7 @@ public void RevokeAllWithRevocationsThrowsException() public void RevokeAllWithRevokeOthersThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-all", "--revoke-others" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -180,7 +180,7 @@ public void RevokeAllWithRevokeOthersThrowsException() public void RevokeMultipleShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke", "DOMAIN\\User", "--revoke", "DOMAIN\\Group" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -194,7 +194,7 @@ public void RevokeMultipleShouldWork() public void RevokeOthersWithOutGrantsThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-others" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -206,7 +206,7 @@ public void RevokeOthersWithOutGrantsThrowsException() public void RevokeOthersWithRevocationsThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-others", "--revoke", "DOMAIN\\UserOrGroup" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -218,7 +218,7 @@ public void RevokeOthersWithRevocationsThrowsException() public void RevokePatternShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-pattern", "^S-1-5-21-" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -232,7 +232,7 @@ public void RevokePatternShouldWork() public void RevokePatternWithGrantShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\UserOrGroup", "--revoke-pattern", "^S-1-5-21-" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -249,7 +249,7 @@ public void RevokePatternWithGrantShouldWork() [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", "(?i)^[A-Z]+")] public void RevokePatternWithValidRegexShouldWork(params string[] args) { - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -263,7 +263,7 @@ public void RevokePatternWithValidRegexShouldWork(params string[] args) public void RevokePatternWithRevokeAllThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-pattern", "^S-1-5-21-", "--revoke-all" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -275,7 +275,7 @@ public void RevokePatternWithRevokeAllThrowsException() public void RevokePatternWithRevokeOthersThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-pattern", "^S-1-5-21-", "--revoke-others" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -287,7 +287,7 @@ public void RevokePatternWithRevokeOthersThrowsException() public void RevokePatternWithRevokeThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-pattern", "^S-1-5-21-", "--revoke", "DOMAIN\\UserOrGroup" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -300,7 +300,7 @@ public void RevokePatternWithRevokeThrowsException() [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", "[0-9]{3,1}")] [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", "^[S-1-5-21-")] public void RevokePatternWithInvalidRegexThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace revocation pattern is rejected. @@ -310,7 +310,7 @@ public void RevokePatternWithInvalidRegexThrowsException(params string[] args) [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", "")] [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", " ")] public void RevokePatternWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures revoking a context is accepted. @@ -319,7 +319,7 @@ public void RevokePatternWithInvalidStringThrowsException(params string[] args) public void RevokeShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke", "DOMAIN\\UserOrGroup" }; - var configuration = this.builder.Build(); + var configuration = builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -334,7 +334,7 @@ public void RevokeShouldWork() [InlineData("privilege", "SeServiceLogonRight", "--revoke", "")] [InlineData("privilege", "SeServiceLogonRight", "--revoke", " ")] public void RevokeWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace system name is rejected. @@ -344,5 +344,5 @@ public void RevokeWithInvalidStringThrowsException(params string[] args) [InlineData("privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\UserOrGroup", "--system-name", "")] [InlineData("privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\UserOrGroup", "--system-name", " ")] public void SystemNameWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => this.builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); } \ No newline at end of file diff --git a/src/Tests/MockLsaUserRights.cs b/src/Tests/MockLsaUserRights.cs index d72f032..6190c6b 100644 --- a/src/Tests/MockLsaUserRights.cs +++ b/src/Tests/MockLsaUserRights.cs @@ -34,19 +34,19 @@ public MockLsaUserRights(IDictionary> da foreach (var kvp in database) { - this.database.Add(kvp.Key, kvp.Value); + database.Add(kvp.Key, kvp.Value); } } /// public void Connect(string? systemName = default) { - if (this.connected) + if (connected) { throw new InvalidOperationException("A connection to the policy database already exists."); } - this.connected = true; + connected = true; } /// @@ -60,14 +60,14 @@ public void LsaAddAccountRights(SecurityIdentifier accountSid, params string[] u throw new ArgumentException("Value cannot be an empty collection.", nameof(userRights)); } - if (!this.connected) + if (!connected) { throw new InvalidOperationException("A connection to the policy database is required."); } foreach (var userRight in userRights) { - if (this.database.TryGetValue(userRight, out var accountSids)) + if (database.TryGetValue(userRight, out var accountSids)) { if (!accountSids.Contains(accountSid)) { @@ -78,7 +78,7 @@ public void LsaAddAccountRights(SecurityIdentifier accountSid, params string[] u { accountSids = [accountSid]; - this.database.Add(userRight, accountSids); + database.Add(userRight, accountSids); } } } @@ -88,12 +88,12 @@ public string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) { ArgumentNullException.ThrowIfNull(accountSid); - if (!this.connected) + if (!connected) { throw new InvalidOperationException("A connection to the policy database is required."); } - return this.database + return database .Where(p => p.Value.Contains(accountSid)) .Select(p => p.Key) .ToArray(); @@ -102,17 +102,17 @@ public string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) /// public SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = default) { - if (!this.connected) + if (!connected) { throw new InvalidOperationException("A connection to the policy database is required."); } if (string.IsNullOrWhiteSpace(userRight)) { - return this.database.Values.SelectMany(p => p).Distinct().ToArray(); + return database.Values.SelectMany(p => p).Distinct().ToArray(); } - if (this.database.TryGetValue(userRight, out var accountSids)) + if (database.TryGetValue(userRight, out var accountSids)) { return [.. accountSids]; } @@ -131,14 +131,14 @@ public void LsaRemoveAccountRights(SecurityIdentifier accountSid, params string[ throw new ArgumentException("Value cannot be an empty collection.", nameof(userRights)); } - if (!this.connected) + if (!connected) { throw new InvalidOperationException("A connection to the policy database is required."); } foreach (var userRight in userRights) { - if (this.database.TryGetValue(userRight, out var principals) && principals.Contains(accountSid)) + if (database.TryGetValue(userRight, out var principals) && principals.Contains(accountSid)) { principals.Remove(accountSid); } @@ -148,17 +148,17 @@ public void LsaRemoveAccountRights(SecurityIdentifier accountSid, params string[ /// /// Allow a test to assert the policy database before manipulating it. /// - public void ResetConnection() => this.connected = false; + public void ResetConnection() => connected = false; /// public void Deserialize(IXunitSerializationInfo info) { ArgumentNullException.ThrowIfNull(info); - var items = info.GetValue(nameof(this.database)); + var items = info.GetValue(nameof(database)); foreach (var item in items) { - this.database.Add(item[0], item[1..].Select(p => new SecurityIdentifier(p)).ToArray()); + database.Add(item[0], item[1..].Select(p => new SecurityIdentifier(p)).ToArray()); } } @@ -168,15 +168,15 @@ public void Serialize(IXunitSerializationInfo info) ArgumentNullException.ThrowIfNull(info); // Flatten the map into an array of arrays composed of the principal and their security ids. - var data = this.database.Select(p => + var data = database.Select(p => { string[] items = [p.Key, ..p.Value.Select(x => x.Value)]; return items; }).ToArray(); - info.AddValue(nameof(this.database), data); + info.AddValue(nameof(database), data); } /// - public override string ToString() => $"{string.Join(" | ", this.database.Select(p => $"{p.Key}: {string.Join(',', p.Value)}"))}"; + public override string ToString() => $"{string.Join(" | ", database.Select(p => $"{p.Key}: {string.Join(',', p.Value)}"))}"; } \ No newline at end of file diff --git a/src/UserRights.Application/LsaUserRights.cs b/src/UserRights.Application/LsaUserRights.cs index 0db5ca8..adb8285 100644 --- a/src/UserRights.Application/LsaUserRights.cs +++ b/src/UserRights.Application/LsaUserRights.cs @@ -21,9 +21,9 @@ public class LsaUserRights : ILsaUserRights, IDisposable /// public void Connect(string? systemName = default) { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - if (this.handle is not null) + if (handle is not null) { throw new InvalidOperationException("A connection to the policy database already exists."); } @@ -34,22 +34,22 @@ public void Connect(string? systemName = default) PInvoke.POLICY_LOOKUP_NAMES | PInvoke.POLICY_VIEW_LOCAL_INFORMATION; - this.handle = this.LsaOpenPolicy(ref objectAttributes, desiredAccess, systemName); + handle = LsaOpenPolicy(ref objectAttributes, desiredAccess, systemName); } /// public void Dispose() { - this.Dispose(true); + Dispose(true); GC.SuppressFinalize(this); } /// public unsafe void LsaAddAccountRights(SecurityIdentifier accountSid, params string[] userRights) { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - if (this.handle is null) + if (handle is null) { throw new InvalidOperationException("A connection to the policy database is required."); } @@ -87,7 +87,7 @@ public unsafe void LsaAddAccountRights(SecurityIdentifier accountSid, params str } } - var status = PInvoke.LsaAddAccountRights(this.handle, ssid, rights); + var status = PInvoke.LsaAddAccountRights(handle, ssid, rights); var error = PInvoke.LsaNtStatusToWinError(status); if ((WIN32_ERROR)error != WIN32_ERROR.ERROR_SUCCESS) @@ -100,9 +100,9 @@ public unsafe void LsaAddAccountRights(SecurityIdentifier accountSid, params str /// public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - if (this.handle is null) + if (handle is null) { throw new InvalidOperationException("A connection to the policy database is required."); } @@ -119,7 +119,7 @@ public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) LSA_UNICODE_STRING* userRights = default; try { - var status = PInvoke.LsaEnumerateAccountRights(this.handle, ssid, out userRights, out var count); + var status = PInvoke.LsaEnumerateAccountRights(handle, ssid, out userRights, out var count); var error = (WIN32_ERROR)PInvoke.LsaNtStatusToWinError(status); if (error != WIN32_ERROR.ERROR_SUCCESS) @@ -153,9 +153,9 @@ public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) /// public unsafe SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = default) { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - if (this.handle is null) + if (handle is null) { throw new InvalidOperationException("A connection to the policy database is required."); } @@ -183,7 +183,7 @@ SecurityIdentifier[] Method(LSA_UNICODE_STRING right) void* buffer = default; try { - var status = PInvoke.LsaEnumerateAccountsWithUserRight(this.handle, right, out buffer, out var count); + var status = PInvoke.LsaEnumerateAccountsWithUserRight(handle, right, out buffer, out var count); var error = (WIN32_ERROR)PInvoke.LsaNtStatusToWinError(status); if (error == WIN32_ERROR.ERROR_NO_MORE_ITEMS) @@ -222,9 +222,9 @@ SecurityIdentifier[] Method(LSA_UNICODE_STRING right) /// public unsafe void LsaRemoveAccountRights(SecurityIdentifier accountSid, params string[] userRights) { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - if (this.handle is null) + if (handle is null) { throw new InvalidOperationException("A connection to the policy database is required."); } @@ -262,7 +262,7 @@ public unsafe void LsaRemoveAccountRights(SecurityIdentifier accountSid, params } } - var status = PInvoke.LsaRemoveAccountRights(this.handle, ssid, false, rights); + var status = PInvoke.LsaRemoveAccountRights(handle, ssid, false, rights); var error = PInvoke.LsaNtStatusToWinError(status); if ((WIN32_ERROR)error != WIN32_ERROR.ERROR_SUCCESS) @@ -278,15 +278,15 @@ public unsafe void LsaRemoveAccountRights(SecurityIdentifier accountSid, params /// A value indicating whether the method call comes from a dispose method (its value is ) or from a finalizer (its value is ). protected virtual void Dispose(bool disposing) { - if (this.disposed) + if (disposed) { return; } if (disposing) { - this.handle?.Dispose(); - this.disposed = true; + handle?.Dispose(); + disposed = true; } } @@ -299,9 +299,9 @@ protected virtual void Dispose(bool disposing) /// A handle to the Policy object. private unsafe LsaCloseSafeHandle LsaOpenPolicy(ref LSA_OBJECT_ATTRIBUTES objectAttributes, uint desiredAccess, string? systemName = default) { - ObjectDisposedException.ThrowIf(this.disposed, this); + ObjectDisposedException.ThrowIf(disposed, this); - if (this.handle is not null) + if (handle is not null) { throw new InvalidOperationException("A connection to the policy database already exists."); } diff --git a/src/UserRights.Application/UserRightEntry.cs b/src/UserRights.Application/UserRightEntry.cs index 0163d0a..6ea5c0b 100644 --- a/src/UserRights.Application/UserRightEntry.cs +++ b/src/UserRights.Application/UserRightEntry.cs @@ -18,9 +18,9 @@ public UserRightEntry(string privilege, string securityId, string? accountName) ArgumentException.ThrowIfNullOrEmpty(privilege); ArgumentException.ThrowIfNullOrEmpty(securityId); - this.Privilege = privilege; - this.SecurityId = securityId; - this.AccountName = string.IsNullOrWhiteSpace(accountName) ? null : accountName; + Privilege = privilege; + SecurityId = securityId; + AccountName = string.IsNullOrWhiteSpace(accountName) ? null : accountName; } /// diff --git a/src/UserRights.Application/UserRightsManager.cs b/src/UserRights.Application/UserRightsManager.cs index df0552a..44d5763 100644 --- a/src/UserRights.Application/UserRightsManager.cs +++ b/src/UserRights.Application/UserRightsManager.cs @@ -20,7 +20,7 @@ public class UserRightsManager : IUserRightsManager /// Initializes a new instance of the class. /// /// The logging instance. - public UserRightsManager(ILogger logger) => this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); + public UserRightsManager(ILogger logger) => logger = logger ?? throw new ArgumentNullException(nameof(logger)); /// public IEnumerable GetUserRights(IUserRights policy) @@ -116,7 +116,7 @@ public void ModifyPrincipal(IUserRights policy, string principal, string[] grant { foreach (var privilege in privileges) { - this.RevokePrivilege(policy, securityIdentifier, privilege, dryRun); + RevokePrivilege(policy, securityIdentifier, privilege, dryRun); } // Ignore any further processing. @@ -135,20 +135,20 @@ public void ModifyPrincipal(IUserRights policy, string principal, string[] grant var others = privileges.Where(p => !grantSet.Contains(p)); foreach (var privilege in others) { - this.RevokePrivilege(policy, securityIdentifier, privilege, dryRun); + RevokePrivilege(policy, securityIdentifier, privilege, dryRun); } } // Grant any deficit privileges. foreach (var privilege in deficit) { - this.GrantPrivilege(policy, securityIdentifier, privilege, dryRun); + GrantPrivilege(policy, securityIdentifier, privilege, dryRun); } // Revoke any surplus privileges. foreach (var privilege in surplus) { - this.RevokePrivilege(policy, securityIdentifier, privilege, dryRun); + RevokePrivilege(policy, securityIdentifier, privilege, dryRun); } } @@ -209,7 +209,7 @@ public void ModifyPrivilege(IUserRights policy, string privilege, string[] grant { foreach (var principal in principals) { - this.RevokePrivilege(policy, principal, privilege, dryRun); + RevokePrivilege(policy, principal, privilege, dryRun); } // Ignore any further processing. @@ -228,7 +228,7 @@ public void ModifyPrivilege(IUserRights policy, string privilege, string[] grant var others = principals.Where(p => !grantSet.Contains(p)); foreach (var principal in others) { - this.RevokePrivilege(policy, principal, privilege, dryRun); + RevokePrivilege(policy, principal, privilege, dryRun); } } @@ -238,20 +238,20 @@ public void ModifyPrivilege(IUserRights policy, string privilege, string[] grant var matches = principals.Where(p => !grantSet.Contains(p) && revokePattern.IsMatch(p.Value)); foreach (var principal in matches) { - this.RevokePrivilege(policy, principal, privilege, dryRun); + RevokePrivilege(policy, principal, privilege, dryRun); } } // Grant any deficit principals. foreach (var sid in deficit) { - this.GrantPrivilege(policy, sid, privilege, dryRun); + GrantPrivilege(policy, sid, privilege, dryRun); } // Revoke any surplus principals. foreach (var sid in surplus) { - this.RevokePrivilege(policy, sid, privilege, dryRun); + RevokePrivilege(policy, sid, privilege, dryRun); } } @@ -270,7 +270,7 @@ private void GrantPrivilege(IUserRights policy, SecurityIdentifier principal, st if (dryRun) { - this.logger.LogInformation(OperationId.PrivilegeGrantDryrun, "Granting {Privilege:l} to {Principal}.", privilege, principal); + logger.LogInformation(OperationId.PrivilegeGrantDryrun, "Granting {Privilege:l} to {Principal}.", privilege, principal); return; } @@ -281,12 +281,12 @@ private void GrantPrivilege(IUserRights policy, SecurityIdentifier principal, st } catch { - this.logger.LogError(OperationId.PrivilegeGrantFailure, "Failed to grant {Privilege:l} to {Principal}.", privilege, principal); + logger.LogError(OperationId.PrivilegeGrantFailure, "Failed to grant {Privilege:l} to {Principal}.", privilege, principal); throw; } - this.logger.LogInformation(OperationId.PrivilegeGrantSuccess, "Successfully granted {Privilege:l} to {Principal}.", privilege, principal); + logger.LogInformation(OperationId.PrivilegeGrantSuccess, "Successfully granted {Privilege:l} to {Principal}.", privilege, principal); } /// @@ -304,7 +304,7 @@ private void RevokePrivilege(IUserRights policy, SecurityIdentifier principal, s if (dryRun) { - this.logger.LogInformation(OperationId.PrivilegeRevokeDryrun, "Revoking {Privilege:l} from {Principal}.", privilege, principal); + logger.LogInformation(OperationId.PrivilegeRevokeDryrun, "Revoking {Privilege:l} from {Principal}.", privilege, principal); return; } @@ -315,11 +315,11 @@ private void RevokePrivilege(IUserRights policy, SecurityIdentifier principal, s } catch { - this.logger.LogError(OperationId.PrivilegeRevokeFailure, "Failed to revoke {Privilege:l} from {Principal}.", privilege, principal); + logger.LogError(OperationId.PrivilegeRevokeFailure, "Failed to revoke {Privilege:l} from {Principal}.", privilege, principal); throw; } - this.logger.LogInformation(OperationId.PrivilegeRevokeSuccess, "Successfully revoked {Privilege:l} from {Principal}.", privilege, principal); + logger.LogInformation(OperationId.PrivilegeRevokeSuccess, "Successfully revoked {Privilege:l} from {Principal}.", privilege, principal); } } \ No newline at end of file diff --git a/src/UserRights.Cli/CliBuilder.cs b/src/UserRights.Cli/CliBuilder.cs index 863a87c..6fd1764 100644 --- a/src/UserRights.Cli/CliBuilder.cs +++ b/src/UserRights.Cli/CliBuilder.cs @@ -33,9 +33,9 @@ public class CliBuilder /// The user rights application instance. public CliBuilder(ILogger logger, ILsaUserRights policy, IUserRightsManager manager) { - this.logger = logger; - this.policy = policy; - this.manager = manager; + logger = logger; + policy = policy; + manager = manager; } /// @@ -46,9 +46,9 @@ public CommandLineConfiguration Build() { var rootCommand = new RootCommand("Windows User Rights Assignment Utility") { - this.BuildListCommand(), - this.BuildPrincipalCommand(), - this.BuildPrivilegeCommand() + BuildListCommand(), + BuildPrincipalCommand(), + BuildPrivilegeCommand() }; foreach (var option in rootCommand.Options) @@ -125,15 +125,15 @@ private Command BuildListCommand() command.SetAction(async (parseResult, cancellationToken) => { - this.logger.LogInformation(OperationId.ListMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); + logger.LogInformation(OperationId.ListMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); var json = parseResult.GetValue(jsonOption); var path = parseResult.GetValue(pathOption); var systemName = parseResult.GetValue(systemNameOption); - this.policy.Connect(systemName); + policy.Connect(systemName); - var results = this.manager.GetUserRights(this.policy); + var results = manager.GetUserRights(policy); if (string.IsNullOrWhiteSpace(path)) { @@ -348,14 +348,14 @@ private Command BuildPrincipalCommand() var dryRun = parseResult.GetValue(dryRunOption); var systemName = parseResult.GetValue(systemNameOption); - this.logger.BeginScope(new Dictionary(StringComparer.Ordinal) { { "DryRun", dryRun } }); + logger.BeginScope(new Dictionary(StringComparer.Ordinal) { { "DryRun", dryRun } }); - this.logger.LogInformation(OperationId.PrincipalMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); + logger.LogInformation(OperationId.PrincipalMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); - this.policy.Connect(systemName); + policy.Connect(systemName); - this.manager.ModifyPrincipal( - this.policy, + manager.ModifyPrincipal( + policy, principal!, grants!, revocations!, @@ -577,18 +577,18 @@ private Command BuildPrivilegeCommand() var dryRun = parseResult.GetValue(dryRunOption); var systemName = parseResult.GetValue(systemNameOption); - this.logger.BeginScope(new Dictionary(StringComparer.Ordinal) { { "DryRun", dryRun } }); + logger.BeginScope(new Dictionary(StringComparer.Ordinal) { { "DryRun", dryRun } }); - this.logger.LogInformation(OperationId.PrivilegeMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); + logger.LogInformation(OperationId.PrivilegeMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); var revokeRegex = string.IsNullOrWhiteSpace(revokePattern) ? null : new Regex(revokePattern, RegexOptions.None, TimeSpan.FromSeconds(1)); - this.policy.Connect(systemName); + policy.Connect(systemName); - this.manager.ModifyPrivilege( - this.policy, + manager.ModifyPrivilege( + policy, privilege!, grants!, revocations!, diff --git a/src/UserRights.Cli/HelpExamplesAction.cs b/src/UserRights.Cli/HelpExamplesAction.cs index f0bb168..69417e4 100644 --- a/src/UserRights.Cli/HelpExamplesAction.cs +++ b/src/UserRights.Cli/HelpExamplesAction.cs @@ -22,7 +22,7 @@ public HelpExamplesAction(HelpAction helpAction) { ArgumentNullException.ThrowIfNull(helpAction); - this.helpAction = helpAction; + helpAction = helpAction; } /// @@ -30,7 +30,7 @@ public override int Invoke(ParseResult parseResult) { ArgumentNullException.ThrowIfNull(parseResult); - var result = this.helpAction.Invoke(parseResult); + var result = helpAction.Invoke(parseResult); GenerateExamples(parseResult); From 42bfabbd4c525e6b16a3e4397a1e0653abded113 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:37:04 -0600 Subject: [PATCH 05/15] Fixes IDE1006: Naming rule violation: Missing prefix: '_'. --- .../LsaUserRightsTestBase.cs | 30 +++++----- .../UserRightsManagerTestBase.cs | 26 ++++----- src/Tests.Cli/CliTestBase.cs | 24 ++++---- src/Tests.Cli/ListSyntaxTests.cs | 16 +++--- src/Tests.Cli/PrincipalSyntaxTests.cs | 40 ++++++------- src/Tests.Cli/PrivilegeSyntaxTests.cs | 56 +++++++++---------- src/Tests/MockLsaUserRights.cs | 42 +++++++------- src/UserRights.Application/LsaUserRights.cs | 44 +++++++-------- .../UserRightsManager.cs | 16 +++--- src/UserRights.Cli/CliBuilder.cs | 38 ++++++------- src/UserRights.Cli/HelpExamplesAction.cs | 8 +-- 11 files changed, 170 insertions(+), 170 deletions(-) diff --git a/src/Tests.Application/LsaUserRightsTestBase.cs b/src/Tests.Application/LsaUserRightsTestBase.cs index f4f80ad..5ee34c9 100644 --- a/src/Tests.Application/LsaUserRightsTestBase.cs +++ b/src/Tests.Application/LsaUserRightsTestBase.cs @@ -26,10 +26,10 @@ public abstract class LsaUserRightsTestBase : IDisposable private const string RestoreSecurityTemplateName = "restore.ini"; private const string RestoreSecurityLogName = "restore.log"; - private readonly DirectoryInfo? directory = CreateTempDirectory(); - private readonly IReadOnlyDictionary> initialState; + private readonly DirectoryInfo? _directory = CreateTempDirectory(); + private readonly IReadOnlyDictionary> _initialState; - private bool disposed; + private bool _disposed; /// /// Initializes a new instance of the class. @@ -39,17 +39,17 @@ protected LsaUserRightsTestBase() try { // Create a backup to restore during disposal. - CreateSecurityDatabaseBackup(directory.FullName); + CreateSecurityDatabaseBackup(_directory.FullName); // Load the contents of the backup for use as initial state. - initialState = ReadSecurityDatabaseBackup(directory.FullName); + _initialState = ReadSecurityDatabaseBackup(_directory.FullName); // Create the updated configuration file to remove assignments for any privileges that were originally empty. - CreateRestoreTemplate(directory.FullName, initialState); + CreateRestoreTemplate(_directory.FullName, _initialState); } catch { - directory = null; + _directory = null; throw; } @@ -62,9 +62,9 @@ protected IReadOnlyDictionary> I { get { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - return initialState; + return _initialState; } } @@ -81,21 +81,21 @@ public void Dispose() /// A value indicating whether the method call comes from a dispose method (its value is ) or from a finalizer (its value is ). protected virtual void Dispose(bool disposing) { - if (disposed) + if (_disposed) { return; } if (disposing) { - if (directory is not null) + if (_directory is not null) { - RestoreSecurityDatabaseBackup(directory.FullName); + RestoreSecurityDatabaseBackup(_directory.FullName); - directory.Delete(true); + _directory.Delete(true); } - disposed = true; + _disposed = true; } } @@ -105,7 +105,7 @@ protected virtual void Dispose(bool disposing) /// A map of privilege to security identifiers. protected IReadOnlyDictionary> GetCurrentState() { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); var directoryInfo = CreateTempDirectory(); diff --git a/src/Tests.Application/UserRightsManagerTestBase.cs b/src/Tests.Application/UserRightsManagerTestBase.cs index 394faa4..9b3a8af 100644 --- a/src/Tests.Application/UserRightsManagerTestBase.cs +++ b/src/Tests.Application/UserRightsManagerTestBase.cs @@ -11,17 +11,17 @@ namespace Tests.Application; /// public abstract class UserRightsManagerTestBase : IDisposable { - private readonly IServiceCollection serviceCollection; - private readonly Lazy serviceProvider; + private readonly IServiceCollection _serviceCollection; + private readonly Lazy _serviceProvider; - private bool disposed; + private bool _disposed; /// /// Initializes a new instance of the class. /// protected UserRightsManagerTestBase() { - serviceCollection = new ServiceCollection() + _serviceCollection = new ServiceCollection() .AddSingleton() .AddLogging(builder => builder .ClearProviders() @@ -29,7 +29,7 @@ protected UserRightsManagerTestBase() .AddDebug()); // Defer the creation until the instance is accessed to allow inheritors to modify the service collection. - serviceProvider = new Lazy(serviceCollection.BuildServiceProvider); + _serviceProvider = new Lazy(_serviceCollection.BuildServiceProvider); } /// @@ -39,9 +39,9 @@ protected IServiceCollection ServiceCollection { get { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - return serviceCollection; + return _serviceCollection; } } @@ -52,9 +52,9 @@ protected ServiceProvider ServiceProvider { get { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - return serviceProvider.Value; + return _serviceProvider.Value; } } @@ -71,19 +71,19 @@ public void Dispose() /// A value indicating whether the method call comes from a dispose method (its value is ) or from a finalizer (its value is ). protected virtual void Dispose(bool disposing) { - if (disposed) + if (_disposed) { return; } if (disposing) { - if (serviceProvider.IsValueCreated) + if (_serviceProvider.IsValueCreated) { - serviceProvider.Value.Dispose(); + _serviceProvider.Value.Dispose(); } - disposed = true; + _disposed = true; } } } \ No newline at end of file diff --git a/src/Tests.Cli/CliTestBase.cs b/src/Tests.Cli/CliTestBase.cs index 8d66301..b9abe2b 100644 --- a/src/Tests.Cli/CliTestBase.cs +++ b/src/Tests.Cli/CliTestBase.cs @@ -10,23 +10,23 @@ namespace Tests.Cli; /// public abstract class CliTestBase : IDisposable { - private readonly IServiceCollection serviceCollection; - private readonly Lazy serviceProvider; + private readonly IServiceCollection _serviceCollection; + private readonly Lazy _serviceProvider; - private bool disposed; + private bool _disposed; /// /// Initializes a new instance of the class. /// protected CliTestBase() { - serviceCollection = new ServiceCollection() + _serviceCollection = new ServiceCollection() .AddLogging(builder => builder .ClearProviders() .SetMinimumLevel(LogLevel.Trace) .AddDebug()); - serviceProvider = new Lazy(serviceCollection.BuildServiceProvider); + _serviceProvider = new Lazy(_serviceCollection.BuildServiceProvider); } /// @@ -36,9 +36,9 @@ protected IServiceCollection ServiceCollection { get { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - return serviceCollection; + return _serviceCollection; } } @@ -49,9 +49,9 @@ protected ServiceProvider ServiceProvider { get { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - return serviceProvider.Value; + return _serviceProvider.Value; } } @@ -68,15 +68,15 @@ public void Dispose() /// A value indicating whether the method call comes from a dispose method (its value is ) or from a finalizer (its value is ). protected virtual void Dispose(bool disposing) { - if (disposed) + if (_disposed) { return; } if (disposing) { - serviceProvider.Value.Dispose(); - disposed = true; + _serviceProvider.Value.Dispose(); + _disposed = true; } } } \ No newline at end of file diff --git a/src/Tests.Cli/ListSyntaxTests.cs b/src/Tests.Cli/ListSyntaxTests.cs index cfb9601..dc9a523 100644 --- a/src/Tests.Cli/ListSyntaxTests.cs +++ b/src/Tests.Cli/ListSyntaxTests.cs @@ -10,7 +10,7 @@ namespace Tests.Cli; /// public sealed class ListSyntaxTests : CliTestBase { - private readonly CliBuilder builder; + private readonly CliBuilder _builder; /// /// Initializes a new instance of the class. @@ -21,7 +21,7 @@ public ListSyntaxTests() ServiceCollection.AddSingleton(); ServiceCollection.AddSingleton(); - builder = ServiceProvider.GetRequiredService(); + _builder = ServiceProvider.GetRequiredService(); } /// @@ -31,7 +31,7 @@ public ListSyntaxTests() public void CsvToStdoutShouldWork() { var args = new[] { "list" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -45,7 +45,7 @@ public void CsvToStdoutShouldWork() public void CsvToPathShouldWork() { var args = new[] { "list", "--path", "file.csv" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -60,7 +60,7 @@ public void CsvToPathShouldWork() [InlineData("list", "--path", "")] [InlineData("list", "--path", " ")] public void PathWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace system name is rejected. @@ -70,7 +70,7 @@ public void PathWithInvalidStringThrowsException(params string[] args) [InlineData("list", "--system-name", "")] [InlineData("list", "--system-name", " ")] public void SystemNameWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Verifies list mode with JSON formatted output sent to STDOUT is parsed successfully. @@ -79,7 +79,7 @@ public void SystemNameWithInvalidStringThrowsException(params string[] args) public void JsonToStdoutShouldWork() { var args = new[] { "list", "--json" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -93,7 +93,7 @@ public void JsonToStdoutShouldWork() public void JsonToPathShouldWork() { var args = new[] { "list", "--json", "--path", "file.csv" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); diff --git a/src/Tests.Cli/PrincipalSyntaxTests.cs b/src/Tests.Cli/PrincipalSyntaxTests.cs index e017432..b8223f0 100644 --- a/src/Tests.Cli/PrincipalSyntaxTests.cs +++ b/src/Tests.Cli/PrincipalSyntaxTests.cs @@ -10,7 +10,7 @@ namespace Tests.Cli; /// public sealed class PrincipalSyntaxTests : CliTestBase { - private readonly CliBuilder builder; + private readonly CliBuilder _builder; /// /// Initializes a new instance of the class. @@ -21,7 +21,7 @@ public PrincipalSyntaxTests() ServiceCollection.AddSingleton(); ServiceCollection.AddSingleton(); - builder = ServiceProvider.GetRequiredService(); + _builder = ServiceProvider.GetRequiredService(); } /// @@ -31,7 +31,7 @@ public PrincipalSyntaxTests() public void GrantAndRevokeShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--revoke", "SeBatchLogonRight" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -45,7 +45,7 @@ public void GrantAndRevokeShouldWork() public void GrantMultipleShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--grant", "SeBatchLogonRight" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -59,7 +59,7 @@ public void GrantMultipleShouldWork() public void GrantShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -74,7 +74,7 @@ public void GrantShouldWork() [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", "")] [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", " ")] public void GrantWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures granting a privilege and revoking all other privileges is rejected. @@ -83,7 +83,7 @@ public void GrantWithInvalidStringThrowsException(params string[] args) public void GrantWithRevokeAllThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--revoke-all" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -95,7 +95,7 @@ public void GrantWithRevokeAllThrowsException() public void NoOptionsThrowsException() { var args = new[] { "principal" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -109,7 +109,7 @@ public void NoOptionsThrowsException() [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--grant", "SeServiceLogonRight")] [InlineData("principal", "DOMAIN\\UserOrGroup", "--revoke", "SeServiceLogonRight", "--revoke", "SeServiceLogonRight")] public void OverlappingGrantsAndRevokesThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace principal is rejected. @@ -119,7 +119,7 @@ public void OverlappingGrantsAndRevokesThrowsException(params string[] args) [InlineData("principal", "", "--grant", "SeServiceLogonRight")] [InlineData("principal", " ", "--grant", "SeServiceLogonRight")] public void PrincipalWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures revoking all privileges is accepted. @@ -128,7 +128,7 @@ public void PrincipalWithInvalidStringThrowsException(params string[] args) public void RevokeAllShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-all" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -142,7 +142,7 @@ public void RevokeAllShouldWork() public void RevokeAllWithGrantsThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-all", "--grant", "SeServiceLogonRight" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -154,7 +154,7 @@ public void RevokeAllWithGrantsThrowsException() public void RevokeAllWithRevocationsThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-all", "--revoke", "SeServiceLogonRight" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -166,7 +166,7 @@ public void RevokeAllWithRevocationsThrowsException() public void RevokeAllWithRevokeOthersThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-all", "--revoke-others" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -178,7 +178,7 @@ public void RevokeAllWithRevokeOthersThrowsException() public void RevokeMultipleShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke", "SeServiceLogonRight", "--revoke", "SeBatchLogonRight" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -193,7 +193,7 @@ public void RevokeOthersWithOutGrantsThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-others" }; - Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); } /// @@ -203,7 +203,7 @@ public void RevokeOthersWithOutGrantsThrowsException() public void RevokeOthersWithRevocationsThrowsException() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke-others", "--revoke", "SeServiceLogonRight" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -215,7 +215,7 @@ public void RevokeOthersWithRevocationsThrowsException() public void RevokeShouldWork() { var args = new[] { "principal", "DOMAIN\\UserOrGroup", "--revoke", "SeServiceLogonRight" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -230,7 +230,7 @@ public void RevokeShouldWork() [InlineData("principal", "DOMAIN\\UserOrGroup", "--revoke", "")] [InlineData("principal", "DOMAIN\\UserOrGroup", "--revoke", " ")] public void RevokeWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace system name is rejected. @@ -240,5 +240,5 @@ public void RevokeWithInvalidStringThrowsException(params string[] args) [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--system-name", "")] [InlineData("principal", "DOMAIN\\UserOrGroup", "--grant", "SeServiceLogonRight", "--system-name", " ")] public void SystemNameWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); } \ No newline at end of file diff --git a/src/Tests.Cli/PrivilegeSyntaxTests.cs b/src/Tests.Cli/PrivilegeSyntaxTests.cs index d9e130e..9c4b5db 100644 --- a/src/Tests.Cli/PrivilegeSyntaxTests.cs +++ b/src/Tests.Cli/PrivilegeSyntaxTests.cs @@ -10,7 +10,7 @@ namespace Tests.Cli; /// public sealed class PrivilegeSyntaxTests : CliTestBase { - private readonly CliBuilder builder; + private readonly CliBuilder _builder; /// /// Initializes a new instance of the class. @@ -21,7 +21,7 @@ public PrivilegeSyntaxTests() ServiceCollection.AddSingleton(); ServiceCollection.AddSingleton(); - builder = ServiceProvider.GetRequiredService(); + _builder = ServiceProvider.GetRequiredService(); } /// @@ -31,7 +31,7 @@ public PrivilegeSyntaxTests() public void GrantAndRevokeShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\User", "--revoke", "DOMAIN\\Group" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -45,7 +45,7 @@ public void GrantAndRevokeShouldWork() public void GrantMultipleShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\User", "--grant", "DOMAIN\\Group" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -59,7 +59,7 @@ public void GrantMultipleShouldWork() public void GrantShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\User" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -74,7 +74,7 @@ public void GrantShouldWork() [InlineData("privilege", "SeServiceLogonRight", "--grant", "")] [InlineData("privilege", "SeServiceLogonRight", "--grant", " ")] public void GrantWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures granting a context and revoking all contexts is rejected. @@ -83,7 +83,7 @@ public void GrantWithInvalidStringThrowsException(params string[] args) public void GrantWithRevokeAllThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\User", "--revoke-all" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -95,7 +95,7 @@ public void GrantWithRevokeAllThrowsException() public void NoOptionsThrowsException() { var args = new[] { "privilege" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -109,7 +109,7 @@ public void NoOptionsThrowsException() [InlineData("privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\UserOrGroup", "--grant", "DOMAIN\\UserOrGroup")] [InlineData("privilege", "SeServiceLogonRight", "--revoke", "DOMAIN\\UserOrGroup", "--revoke", "DOMAIN\\UserOrGroup")] public void OverlappingGrantsAndRevokesThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace principal is rejected. @@ -119,7 +119,7 @@ public void OverlappingGrantsAndRevokesThrowsException(params string[] args) [InlineData("privilege", "", "--grant", "DOMAIN\\UserOrGroup")] [InlineData("privilege", " ", "--grant", "DOMAIN\\UserOrGroup")] public void PrivilegeWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures revoking all contexts is accepted. @@ -128,7 +128,7 @@ public void PrivilegeWithInvalidStringThrowsException(params string[] args) public void RevokeAllShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-all" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); int? rc = null; var exception = Record.Exception(() => rc = configuration.Parse(args).Validate().Invoke()); @@ -144,7 +144,7 @@ public void RevokeAllShouldWork() public void RevokeAllWithGrantsThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-all", "--grant", "DOMAIN\\UserOrGroup" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -156,7 +156,7 @@ public void RevokeAllWithGrantsThrowsException() public void RevokeAllWithRevocationsThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-all", "--revoke", "DOMAIN\\UserOrGroup" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -168,7 +168,7 @@ public void RevokeAllWithRevocationsThrowsException() public void RevokeAllWithRevokeOthersThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-all", "--revoke-others" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -180,7 +180,7 @@ public void RevokeAllWithRevokeOthersThrowsException() public void RevokeMultipleShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke", "DOMAIN\\User", "--revoke", "DOMAIN\\Group" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -194,7 +194,7 @@ public void RevokeMultipleShouldWork() public void RevokeOthersWithOutGrantsThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-others" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -206,7 +206,7 @@ public void RevokeOthersWithOutGrantsThrowsException() public void RevokeOthersWithRevocationsThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-others", "--revoke", "DOMAIN\\UserOrGroup" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -218,7 +218,7 @@ public void RevokeOthersWithRevocationsThrowsException() public void RevokePatternShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-pattern", "^S-1-5-21-" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -232,7 +232,7 @@ public void RevokePatternShouldWork() public void RevokePatternWithGrantShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\UserOrGroup", "--revoke-pattern", "^S-1-5-21-" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -249,7 +249,7 @@ public void RevokePatternWithGrantShouldWork() [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", "(?i)^[A-Z]+")] public void RevokePatternWithValidRegexShouldWork(params string[] args) { - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -263,7 +263,7 @@ public void RevokePatternWithValidRegexShouldWork(params string[] args) public void RevokePatternWithRevokeAllThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-pattern", "^S-1-5-21-", "--revoke-all" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -275,7 +275,7 @@ public void RevokePatternWithRevokeAllThrowsException() public void RevokePatternWithRevokeOthersThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-pattern", "^S-1-5-21-", "--revoke-others" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -287,7 +287,7 @@ public void RevokePatternWithRevokeOthersThrowsException() public void RevokePatternWithRevokeThrowsException() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke-pattern", "^S-1-5-21-", "--revoke", "DOMAIN\\UserOrGroup" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); Assert.Throws(() => configuration.Parse(args).Validate().Invoke()); } @@ -300,7 +300,7 @@ public void RevokePatternWithRevokeThrowsException() [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", "[0-9]{3,1}")] [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", "^[S-1-5-21-")] public void RevokePatternWithInvalidRegexThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace revocation pattern is rejected. @@ -310,7 +310,7 @@ public void RevokePatternWithInvalidRegexThrowsException(params string[] args) [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", "")] [InlineData("privilege", "SeServiceLogonRight", "--revoke-pattern", " ")] public void RevokePatternWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures revoking a context is accepted. @@ -319,7 +319,7 @@ public void RevokePatternWithInvalidStringThrowsException(params string[] args) public void RevokeShouldWork() { var args = new[] { "privilege", "SeServiceLogonRight", "--revoke", "DOMAIN\\UserOrGroup" }; - var configuration = builder.Build(); + var configuration = _builder.Build(); var rc = configuration.Parse(args).Validate().Invoke(); @@ -334,7 +334,7 @@ public void RevokeShouldWork() [InlineData("privilege", "SeServiceLogonRight", "--revoke", "")] [InlineData("privilege", "SeServiceLogonRight", "--revoke", " ")] public void RevokeWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); /// /// Ensures an empty or whitespace system name is rejected. @@ -344,5 +344,5 @@ public void RevokeWithInvalidStringThrowsException(params string[] args) [InlineData("privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\UserOrGroup", "--system-name", "")] [InlineData("privilege", "SeServiceLogonRight", "--grant", "DOMAIN\\UserOrGroup", "--system-name", " ")] public void SystemNameWithInvalidStringThrowsException(params string[] args) - => Assert.Throws(() => builder.Build().Parse(args).Validate().Invoke()); + => Assert.Throws(() => _builder.Build().Parse(args).Validate().Invoke()); } \ No newline at end of file diff --git a/src/Tests/MockLsaUserRights.cs b/src/Tests/MockLsaUserRights.cs index 6190c6b..f8a31e2 100644 --- a/src/Tests/MockLsaUserRights.cs +++ b/src/Tests/MockLsaUserRights.cs @@ -14,8 +14,8 @@ namespace Tests; /// public sealed class MockLsaUserRights : ILsaUserRights, IUserRightsSerializable { - private readonly IDictionary> database = new Dictionary>(StringComparer.InvariantCultureIgnoreCase); - private bool connected; + private readonly IDictionary> _database = new Dictionary>(StringComparer.InvariantCultureIgnoreCase); + private bool _connected; /// /// Initializes a new instance of the class. @@ -34,19 +34,19 @@ public MockLsaUserRights(IDictionary> da foreach (var kvp in database) { - database.Add(kvp.Key, kvp.Value); + _database.Add(kvp.Key, kvp.Value); } } /// public void Connect(string? systemName = default) { - if (connected) + if (_connected) { throw new InvalidOperationException("A connection to the policy database already exists."); } - connected = true; + _connected = true; } /// @@ -60,14 +60,14 @@ public void LsaAddAccountRights(SecurityIdentifier accountSid, params string[] u throw new ArgumentException("Value cannot be an empty collection.", nameof(userRights)); } - if (!connected) + if (!_connected) { throw new InvalidOperationException("A connection to the policy database is required."); } foreach (var userRight in userRights) { - if (database.TryGetValue(userRight, out var accountSids)) + if (_database.TryGetValue(userRight, out var accountSids)) { if (!accountSids.Contains(accountSid)) { @@ -78,7 +78,7 @@ public void LsaAddAccountRights(SecurityIdentifier accountSid, params string[] u { accountSids = [accountSid]; - database.Add(userRight, accountSids); + _database.Add(userRight, accountSids); } } } @@ -88,12 +88,12 @@ public string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) { ArgumentNullException.ThrowIfNull(accountSid); - if (!connected) + if (!_connected) { throw new InvalidOperationException("A connection to the policy database is required."); } - return database + return _database .Where(p => p.Value.Contains(accountSid)) .Select(p => p.Key) .ToArray(); @@ -102,17 +102,17 @@ public string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) /// public SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = default) { - if (!connected) + if (!_connected) { throw new InvalidOperationException("A connection to the policy database is required."); } if (string.IsNullOrWhiteSpace(userRight)) { - return database.Values.SelectMany(p => p).Distinct().ToArray(); + return _database.Values.SelectMany(p => p).Distinct().ToArray(); } - if (database.TryGetValue(userRight, out var accountSids)) + if (_database.TryGetValue(userRight, out var accountSids)) { return [.. accountSids]; } @@ -131,14 +131,14 @@ public void LsaRemoveAccountRights(SecurityIdentifier accountSid, params string[ throw new ArgumentException("Value cannot be an empty collection.", nameof(userRights)); } - if (!connected) + if (!_connected) { throw new InvalidOperationException("A connection to the policy database is required."); } foreach (var userRight in userRights) { - if (database.TryGetValue(userRight, out var principals) && principals.Contains(accountSid)) + if (_database.TryGetValue(userRight, out var principals) && principals.Contains(accountSid)) { principals.Remove(accountSid); } @@ -148,17 +148,17 @@ public void LsaRemoveAccountRights(SecurityIdentifier accountSid, params string[ /// /// Allow a test to assert the policy database before manipulating it. /// - public void ResetConnection() => connected = false; + public void ResetConnection() => _connected = false; /// public void Deserialize(IXunitSerializationInfo info) { ArgumentNullException.ThrowIfNull(info); - var items = info.GetValue(nameof(database)); + var items = info.GetValue(nameof(_database)); foreach (var item in items) { - database.Add(item[0], item[1..].Select(p => new SecurityIdentifier(p)).ToArray()); + _database.Add(item[0], item[1..].Select(p => new SecurityIdentifier(p)).ToArray()); } } @@ -168,15 +168,15 @@ public void Serialize(IXunitSerializationInfo info) ArgumentNullException.ThrowIfNull(info); // Flatten the map into an array of arrays composed of the principal and their security ids. - var data = database.Select(p => + var data = _database.Select(p => { string[] items = [p.Key, ..p.Value.Select(x => x.Value)]; return items; }).ToArray(); - info.AddValue(nameof(database), data); + info.AddValue(nameof(_database), data); } /// - public override string ToString() => $"{string.Join(" | ", database.Select(p => $"{p.Key}: {string.Join(',', p.Value)}"))}"; + public override string ToString() => $"{string.Join(" | ", _database.Select(p => $"{p.Key}: {string.Join(',', p.Value)}"))}"; } \ No newline at end of file diff --git a/src/UserRights.Application/LsaUserRights.cs b/src/UserRights.Application/LsaUserRights.cs index adb8285..4bfe8bb 100644 --- a/src/UserRights.Application/LsaUserRights.cs +++ b/src/UserRights.Application/LsaUserRights.cs @@ -15,15 +15,15 @@ namespace UserRights.Application; /// public class LsaUserRights : ILsaUserRights, IDisposable { - private bool disposed; - private LsaCloseSafeHandle? handle; + private bool _disposed; + private LsaCloseSafeHandle? _handle; /// public void Connect(string? systemName = default) { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - if (handle is not null) + if (_handle is not null) { throw new InvalidOperationException("A connection to the policy database already exists."); } @@ -34,7 +34,7 @@ public void Connect(string? systemName = default) PInvoke.POLICY_LOOKUP_NAMES | PInvoke.POLICY_VIEW_LOCAL_INFORMATION; - handle = LsaOpenPolicy(ref objectAttributes, desiredAccess, systemName); + _handle = LsaOpenPolicy(ref objectAttributes, desiredAccess, systemName); } /// @@ -47,9 +47,9 @@ public void Dispose() /// public unsafe void LsaAddAccountRights(SecurityIdentifier accountSid, params string[] userRights) { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - if (handle is null) + if (_handle is null) { throw new InvalidOperationException("A connection to the policy database is required."); } @@ -87,7 +87,7 @@ public unsafe void LsaAddAccountRights(SecurityIdentifier accountSid, params str } } - var status = PInvoke.LsaAddAccountRights(handle, ssid, rights); + var status = PInvoke.LsaAddAccountRights(_handle, ssid, rights); var error = PInvoke.LsaNtStatusToWinError(status); if ((WIN32_ERROR)error != WIN32_ERROR.ERROR_SUCCESS) @@ -100,9 +100,9 @@ public unsafe void LsaAddAccountRights(SecurityIdentifier accountSid, params str /// public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - if (handle is null) + if (_handle is null) { throw new InvalidOperationException("A connection to the policy database is required."); } @@ -119,7 +119,7 @@ public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) LSA_UNICODE_STRING* userRights = default; try { - var status = PInvoke.LsaEnumerateAccountRights(handle, ssid, out userRights, out var count); + var status = PInvoke.LsaEnumerateAccountRights(_handle, ssid, out userRights, out var count); var error = (WIN32_ERROR)PInvoke.LsaNtStatusToWinError(status); if (error != WIN32_ERROR.ERROR_SUCCESS) @@ -153,9 +153,9 @@ public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) /// public unsafe SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = default) { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - if (handle is null) + if (_handle is null) { throw new InvalidOperationException("A connection to the policy database is required."); } @@ -183,7 +183,7 @@ SecurityIdentifier[] Method(LSA_UNICODE_STRING right) void* buffer = default; try { - var status = PInvoke.LsaEnumerateAccountsWithUserRight(handle, right, out buffer, out var count); + var status = PInvoke.LsaEnumerateAccountsWithUserRight(_handle, right, out buffer, out var count); var error = (WIN32_ERROR)PInvoke.LsaNtStatusToWinError(status); if (error == WIN32_ERROR.ERROR_NO_MORE_ITEMS) @@ -222,9 +222,9 @@ SecurityIdentifier[] Method(LSA_UNICODE_STRING right) /// public unsafe void LsaRemoveAccountRights(SecurityIdentifier accountSid, params string[] userRights) { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - if (handle is null) + if (_handle is null) { throw new InvalidOperationException("A connection to the policy database is required."); } @@ -262,7 +262,7 @@ public unsafe void LsaRemoveAccountRights(SecurityIdentifier accountSid, params } } - var status = PInvoke.LsaRemoveAccountRights(handle, ssid, false, rights); + var status = PInvoke.LsaRemoveAccountRights(_handle, ssid, false, rights); var error = PInvoke.LsaNtStatusToWinError(status); if ((WIN32_ERROR)error != WIN32_ERROR.ERROR_SUCCESS) @@ -278,15 +278,15 @@ public unsafe void LsaRemoveAccountRights(SecurityIdentifier accountSid, params /// A value indicating whether the method call comes from a dispose method (its value is ) or from a finalizer (its value is ). protected virtual void Dispose(bool disposing) { - if (disposed) + if (_disposed) { return; } if (disposing) { - handle?.Dispose(); - disposed = true; + _handle?.Dispose(); + _disposed = true; } } @@ -299,9 +299,9 @@ protected virtual void Dispose(bool disposing) /// A handle to the Policy object. private unsafe LsaCloseSafeHandle LsaOpenPolicy(ref LSA_OBJECT_ATTRIBUTES objectAttributes, uint desiredAccess, string? systemName = default) { - ObjectDisposedException.ThrowIf(disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); - if (handle is not null) + if (_handle is not null) { throw new InvalidOperationException("A connection to the policy database already exists."); } diff --git a/src/UserRights.Application/UserRightsManager.cs b/src/UserRights.Application/UserRightsManager.cs index 44d5763..61761a2 100644 --- a/src/UserRights.Application/UserRightsManager.cs +++ b/src/UserRights.Application/UserRightsManager.cs @@ -14,13 +14,13 @@ namespace UserRights.Application; /// public class UserRightsManager : IUserRightsManager { - private readonly ILogger logger; + private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The logging instance. - public UserRightsManager(ILogger logger) => logger = logger ?? throw new ArgumentNullException(nameof(logger)); + public UserRightsManager(ILogger logger) => _logger = logger ?? throw new ArgumentNullException(nameof(logger)); /// public IEnumerable GetUserRights(IUserRights policy) @@ -270,7 +270,7 @@ private void GrantPrivilege(IUserRights policy, SecurityIdentifier principal, st if (dryRun) { - logger.LogInformation(OperationId.PrivilegeGrantDryrun, "Granting {Privilege:l} to {Principal}.", privilege, principal); + _logger.LogInformation(OperationId.PrivilegeGrantDryrun, "Granting {Privilege:l} to {Principal}.", privilege, principal); return; } @@ -281,12 +281,12 @@ private void GrantPrivilege(IUserRights policy, SecurityIdentifier principal, st } catch { - logger.LogError(OperationId.PrivilegeGrantFailure, "Failed to grant {Privilege:l} to {Principal}.", privilege, principal); + _logger.LogError(OperationId.PrivilegeGrantFailure, "Failed to grant {Privilege:l} to {Principal}.", privilege, principal); throw; } - logger.LogInformation(OperationId.PrivilegeGrantSuccess, "Successfully granted {Privilege:l} to {Principal}.", privilege, principal); + _logger.LogInformation(OperationId.PrivilegeGrantSuccess, "Successfully granted {Privilege:l} to {Principal}.", privilege, principal); } /// @@ -304,7 +304,7 @@ private void RevokePrivilege(IUserRights policy, SecurityIdentifier principal, s if (dryRun) { - logger.LogInformation(OperationId.PrivilegeRevokeDryrun, "Revoking {Privilege:l} from {Principal}.", privilege, principal); + _logger.LogInformation(OperationId.PrivilegeRevokeDryrun, "Revoking {Privilege:l} from {Principal}.", privilege, principal); return; } @@ -315,11 +315,11 @@ private void RevokePrivilege(IUserRights policy, SecurityIdentifier principal, s } catch { - logger.LogError(OperationId.PrivilegeRevokeFailure, "Failed to revoke {Privilege:l} from {Principal}.", privilege, principal); + _logger.LogError(OperationId.PrivilegeRevokeFailure, "Failed to revoke {Privilege:l} from {Principal}.", privilege, principal); throw; } - logger.LogInformation(OperationId.PrivilegeRevokeSuccess, "Successfully revoked {Privilege:l} from {Principal}.", privilege, principal); + _logger.LogInformation(OperationId.PrivilegeRevokeSuccess, "Successfully revoked {Privilege:l} from {Principal}.", privilege, principal); } } \ No newline at end of file diff --git a/src/UserRights.Cli/CliBuilder.cs b/src/UserRights.Cli/CliBuilder.cs index 6fd1764..2a5897f 100644 --- a/src/UserRights.Cli/CliBuilder.cs +++ b/src/UserRights.Cli/CliBuilder.cs @@ -21,9 +21,9 @@ namespace UserRights.Cli; /// public class CliBuilder { - private readonly ILogger logger; - private readonly ILsaUserRights policy; - private readonly IUserRightsManager manager; + private readonly ILogger _logger; + private readonly ILsaUserRights _policy; + private readonly IUserRightsManager _manager; /// /// Initializes a new instance of the class. @@ -33,9 +33,9 @@ public class CliBuilder /// The user rights application instance. public CliBuilder(ILogger logger, ILsaUserRights policy, IUserRightsManager manager) { - logger = logger; - policy = policy; - manager = manager; + _logger = logger; + _policy = policy; + _manager = manager; } /// @@ -125,15 +125,15 @@ private Command BuildListCommand() command.SetAction(async (parseResult, cancellationToken) => { - logger.LogInformation(OperationId.ListMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); + _logger.LogInformation(OperationId.ListMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); var json = parseResult.GetValue(jsonOption); var path = parseResult.GetValue(pathOption); var systemName = parseResult.GetValue(systemNameOption); - policy.Connect(systemName); + _policy.Connect(systemName); - var results = manager.GetUserRights(policy); + var results = _manager.GetUserRights(_policy); if (string.IsNullOrWhiteSpace(path)) { @@ -348,14 +348,14 @@ private Command BuildPrincipalCommand() var dryRun = parseResult.GetValue(dryRunOption); var systemName = parseResult.GetValue(systemNameOption); - logger.BeginScope(new Dictionary(StringComparer.Ordinal) { { "DryRun", dryRun } }); + _logger.BeginScope(new Dictionary(StringComparer.Ordinal) { { "DryRun", dryRun } }); - logger.LogInformation(OperationId.PrincipalMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); + _logger.LogInformation(OperationId.PrincipalMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); - policy.Connect(systemName); + _policy.Connect(systemName); - manager.ModifyPrincipal( - policy, + _manager.ModifyPrincipal( + _policy, principal!, grants!, revocations!, @@ -577,18 +577,18 @@ private Command BuildPrivilegeCommand() var dryRun = parseResult.GetValue(dryRunOption); var systemName = parseResult.GetValue(systemNameOption); - logger.BeginScope(new Dictionary(StringComparer.Ordinal) { { "DryRun", dryRun } }); + _logger.BeginScope(new Dictionary(StringComparer.Ordinal) { { "DryRun", dryRun } }); - logger.LogInformation(OperationId.PrivilegeMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); + _logger.LogInformation(OperationId.PrivilegeMode, "{Program:l} v{Version} executing in {Mode:l} mode.", ProgramInfo.Program, ProgramInfo.Version, command.Name); var revokeRegex = string.IsNullOrWhiteSpace(revokePattern) ? null : new Regex(revokePattern, RegexOptions.None, TimeSpan.FromSeconds(1)); - policy.Connect(systemName); + _policy.Connect(systemName); - manager.ModifyPrivilege( - policy, + _manager.ModifyPrivilege( + _policy, privilege!, grants!, revocations!, diff --git a/src/UserRights.Cli/HelpExamplesAction.cs b/src/UserRights.Cli/HelpExamplesAction.cs index 69417e4..add3481 100644 --- a/src/UserRights.Cli/HelpExamplesAction.cs +++ b/src/UserRights.Cli/HelpExamplesAction.cs @@ -1,4 +1,4 @@ -namespace UserRights.Cli; +namespace UserRights.Cli; using System; using System.CommandLine; @@ -12,7 +12,7 @@ /// public class HelpExamplesAction : SynchronousCommandLineAction { - private readonly HelpAction helpAction; + private readonly HelpAction _helpAction; /// /// Initializes a new instance of the class. @@ -22,7 +22,7 @@ public HelpExamplesAction(HelpAction helpAction) { ArgumentNullException.ThrowIfNull(helpAction); - helpAction = helpAction; + _helpAction = helpAction; } /// @@ -30,7 +30,7 @@ public override int Invoke(ParseResult parseResult) { ArgumentNullException.ThrowIfNull(parseResult); - var result = helpAction.Invoke(parseResult); + var result = _helpAction.Invoke(parseResult); GenerateExamples(parseResult); From 6f94d68d3660987e6e71f0e9a37f972970b8e126 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:41:10 -0600 Subject: [PATCH 06/15] Fixes IDE0300: Collection initialization can be simplified. --- src/Tests.Application/UserRightsManagerListTests.cs | 2 +- .../UserRightsManagerPrincipalTests.cs | 6 +++--- src/Tests.Cli/PrincipalCommandTests.cs | 6 +++--- src/Tests.Cli/PrivilegeCommandTests.cs | 12 ++++++------ src/Tests/MockLsaUserRights.cs | 9 +++------ 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/Tests.Application/UserRightsManagerListTests.cs b/src/Tests.Application/UserRightsManagerListTests.cs index 4c64d85..530c783 100644 --- a/src/Tests.Application/UserRightsManagerListTests.cs +++ b/src/Tests.Application/UserRightsManagerListTests.cs @@ -137,7 +137,7 @@ public async Task SerializingToJsonShouldWork() var policy = new MockLsaUserRights(database); policy.Connect("SystemName"); - Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight().Order()); + Assert.Equal([PrincipalSid1, PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight().Order()); Assert.Equal(new[] { Privilege1, Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege1, Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); diff --git a/src/Tests.Application/UserRightsManagerPrincipalTests.cs b/src/Tests.Application/UserRightsManagerPrincipalTests.cs index 38ebc4d..3553e1f 100644 --- a/src/Tests.Application/UserRightsManagerPrincipalTests.cs +++ b/src/Tests.Application/UserRightsManagerPrincipalTests.cs @@ -88,14 +88,14 @@ public void GrantAndRevokeOthersShouldWork() var policy = new MockLsaUserRights(database); policy.Connect("SystemName"); - Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight().Order()); + Assert.Equal([PrincipalSid1, PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight().Order()); Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); var manager = ServiceProvider.GetRequiredService(); manager.ModifyPrincipal(policy, PrincipalName1, [Privilege2], [], false, true, false); - Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight().Order()); + Assert.Equal([PrincipalSid1, PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight().Order()); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); } @@ -230,7 +230,7 @@ public void RevokeAllShouldWork() manager.ModifyPrincipal(policy, PrincipalName1, [], [], true, false, false); Assert.Empty(policy.LsaEnumerateAccountRights(PrincipalSid1)); - Assert.Equal(new[] { PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight()); + Assert.Equal([PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight()); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); } diff --git a/src/Tests.Cli/PrincipalCommandTests.cs b/src/Tests.Cli/PrincipalCommandTests.cs index 1bb953b..e97e376 100644 --- a/src/Tests.Cli/PrincipalCommandTests.cs +++ b/src/Tests.Cli/PrincipalCommandTests.cs @@ -42,7 +42,7 @@ public void GrantAndRevokeOthersShouldWork() var policy = new MockLsaUserRights(database); policy.Connect("SystemName"); - Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight().Order()); + Assert.Equal([PrincipalSid1, PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight().Order()); Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); @@ -68,7 +68,7 @@ public void GrantAndRevokeOthersShouldWork() var rc = configuration.Parse(args).Validate().Invoke(); Assert.Equal(0, rc); - Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight().Order()); + Assert.Equal([PrincipalSid1, PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight().Order()); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); } @@ -239,7 +239,7 @@ public void RevokeAllShouldWork() Assert.Equal(0, rc); Assert.Empty(policy.LsaEnumerateAccountRights(PrincipalSid1)); - Assert.Equal(new[] { PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight()); + Assert.Equal([PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight()); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); } diff --git a/src/Tests.Cli/PrivilegeCommandTests.cs b/src/Tests.Cli/PrivilegeCommandTests.cs index 2ac2ed9..ae144f7 100644 --- a/src/Tests.Cli/PrivilegeCommandTests.cs +++ b/src/Tests.Cli/PrivilegeCommandTests.cs @@ -47,7 +47,7 @@ public void GrantAndRevokeOthersShouldWork() Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight(Privilege1).Order()); - Assert.Equal(new[] { PrincipalSid2 }, policy.LsaEnumerateAccountsWithUserRight(Privilege2)); + Assert.Equal([PrincipalSid2], policy.LsaEnumerateAccountsWithUserRight(Privilege2)); policy.ResetConnection(); @@ -75,7 +75,7 @@ public void GrantAndRevokeOthersShouldWork() Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid1).Order(StringComparer.OrdinalIgnoreCase)); Assert.Equal(new[] { Privilege1 }, policy.LsaEnumerateAccountRights(PrincipalSid2)); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2 }.Order(), policy.LsaEnumerateAccountsWithUserRight(Privilege1).Order()); - Assert.Equal(new[] { PrincipalSid1 }, policy.LsaEnumerateAccountsWithUserRight(Privilege2)); + Assert.Equal([PrincipalSid1], policy.LsaEnumerateAccountsWithUserRight(Privilege2)); } /// @@ -196,8 +196,8 @@ public void GrantAndRevokePatternPasses() Assert.Equal(0, rc); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2, PrincipalSid3 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); Assert.Equal(new[] { Privilege1, Privilege2 }.Order(StringComparer.OrdinalIgnoreCase), policy.LsaEnumerateAccountRights(PrincipalSid1).Order(StringComparer.OrdinalIgnoreCase)); - Assert.Equal(new[] { Privilege1, Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); - Assert.Equal(new[] { Privilege1, Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid3).Order(StringComparer.OrdinalIgnoreCase)); + Assert.Equal([Privilege1, Privilege2], policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); + Assert.Equal([Privilege1, Privilege2], policy.LsaEnumerateAccountRights(PrincipalSid3).Order(StringComparer.OrdinalIgnoreCase)); } /// @@ -429,7 +429,7 @@ public void RevokePatternForAllButBuiltinAndVirtualPasses() Assert.Equal(0, rc); Assert.Equal(new[] { PrincipalSid1, PrincipalSid2, PrincipalSid3 }.Order(), policy.LsaEnumerateAccountsWithUserRight().Order()); Assert.Equal(new[] { Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid1)); - Assert.Equal(new[] { Privilege1, Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); - Assert.Equal(new[] { Privilege1, Privilege2 }, policy.LsaEnumerateAccountRights(PrincipalSid3).Order(StringComparer.OrdinalIgnoreCase)); + Assert.Equal([Privilege1, Privilege2], policy.LsaEnumerateAccountRights(PrincipalSid2).Order(StringComparer.OrdinalIgnoreCase)); + Assert.Equal([Privilege1, Privilege2], policy.LsaEnumerateAccountRights(PrincipalSid3).Order(StringComparer.OrdinalIgnoreCase)); } } \ No newline at end of file diff --git a/src/Tests/MockLsaUserRights.cs b/src/Tests/MockLsaUserRights.cs index f8a31e2..1db3834 100644 --- a/src/Tests/MockLsaUserRights.cs +++ b/src/Tests/MockLsaUserRights.cs @@ -93,10 +93,7 @@ public string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) throw new InvalidOperationException("A connection to the policy database is required."); } - return _database - .Where(p => p.Value.Contains(accountSid)) - .Select(p => p.Key) - .ToArray(); + return [.. _database.Where(p => p.Value.Contains(accountSid)).Select(p => p.Key)]; } /// @@ -109,7 +106,7 @@ public SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight if (string.IsNullOrWhiteSpace(userRight)) { - return _database.Values.SelectMany(p => p).Distinct().ToArray(); + return [.. _database.Values.SelectMany(p => p).Distinct()]; } if (_database.TryGetValue(userRight, out var accountSids)) @@ -158,7 +155,7 @@ public void Deserialize(IXunitSerializationInfo info) var items = info.GetValue(nameof(_database)); foreach (var item in items) { - _database.Add(item[0], item[1..].Select(p => new SecurityIdentifier(p)).ToArray()); + _database.Add(item[0], [.. item[1..].Select(p => new SecurityIdentifier(p))]); } } From e7acedfae63ea9d115a950050fa3be7f09c6d6c3 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:42:53 -0600 Subject: [PATCH 07/15] Disables CA1848: Use the LoggerMessage delegates. --- src/.editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/.editorconfig b/src/.editorconfig index 1b9cc02..608dc99 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -99,6 +99,7 @@ dotnet_diagnostic.IDE0046.severity = none dotnet_diagnostic.IDE0058.severity = none dotnet_diagnostic.CA1822.severity = none +dotnet_diagnostic.CA1848.severity = none dotnet_diagnostic.MA0003.severity = none dotnet_diagnostic.MA0007.severity = none From 705fc26620c543f735c771769637c0ffe515a60b Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:44:59 -0600 Subject: [PATCH 08/15] Disables CA1515: Consider making public types internal. --- src/.editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/.editorconfig b/src/.editorconfig index 608dc99..f0adb70 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -98,6 +98,7 @@ dotnet_diagnostic.IDE0039.severity = none dotnet_diagnostic.IDE0046.severity = none dotnet_diagnostic.IDE0058.severity = none +dotnet_diagnostic.CA1515.severity = none dotnet_diagnostic.CA1822.severity = none dotnet_diagnostic.CA1848.severity = none From 384aae6f60e32feaa29b9850ead86ded3f8b71f0 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:48:30 -0600 Subject: [PATCH 09/15] Replaces manual null/whitespace checks with `ThrowIfNullOrWhiteSpace`. --- .../LsaUserRightsTestBase.cs | 21 ++++--------------- .../Security/SecurityExtensions.cs | 5 +---- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/Tests.Application/LsaUserRightsTestBase.cs b/src/Tests.Application/LsaUserRightsTestBase.cs index 5ee34c9..dada9be 100644 --- a/src/Tests.Application/LsaUserRightsTestBase.cs +++ b/src/Tests.Application/LsaUserRightsTestBase.cs @@ -125,11 +125,7 @@ protected IReadOnlyDictionary> G /// The map of privilege to security identifiers for the backup configuration file. private static void CreateRestoreTemplate(string workingDirectory, IReadOnlyDictionary> stateBackup) { - if (string.IsNullOrWhiteSpace(workingDirectory)) - { - throw new ArgumentException("Value cannot be null or whitespace.", nameof(workingDirectory)); - } - + ArgumentException.ThrowIfNullOrWhiteSpace(workingDirectory); ArgumentNullException.ThrowIfNull(stateBackup); // Load existing assignments. @@ -173,10 +169,7 @@ private static void CreateRestoreTemplate(string workingDirectory, IReadOnlyDict /// The path to a directory where the backup files will be created. private static void CreateSecurityDatabaseBackup(string workingDirectory) { - if (string.IsNullOrWhiteSpace(workingDirectory)) - { - throw new ArgumentException("Value cannot be null or whitespace.", nameof(workingDirectory)); - } + ArgumentException.ThrowIfNullOrWhiteSpace(workingDirectory); var arguments = string.Format( CultureInfo.InvariantCulture, @@ -241,10 +234,7 @@ private static DirectoryInfo CreateTempDirectory() /// A map of privilege to security identifiers. private static IReadOnlyDictionary> ReadSecurityDatabaseBackup(string workingDirectory) { - if (string.IsNullOrWhiteSpace(workingDirectory)) - { - throw new ArgumentException("Value cannot be null or whitespace.", nameof(workingDirectory)); - } + ArgumentException.ThrowIfNullOrWhiteSpace(workingDirectory); var path = Path.Combine(workingDirectory, ExportSecurityTemplateName); @@ -289,10 +279,7 @@ private static IReadOnlyDictionaryThe path to a directory where the backup files exist. private static void RestoreSecurityDatabaseBackup(string workingDirectory) { - if (string.IsNullOrWhiteSpace(workingDirectory)) - { - throw new ArgumentException("Value cannot be null or whitespace.", nameof(workingDirectory)); - } + ArgumentException.ThrowIfNullOrWhiteSpace(workingDirectory); var arguments = string.Format( CultureInfo.InvariantCulture, diff --git a/src/UserRights.Extensions/Security/SecurityExtensions.cs b/src/UserRights.Extensions/Security/SecurityExtensions.cs index da044e3..7f8f7d1 100644 --- a/src/UserRights.Extensions/Security/SecurityExtensions.cs +++ b/src/UserRights.Extensions/Security/SecurityExtensions.cs @@ -15,10 +15,7 @@ public static class SecurityExtensions /// The security identifier (SID). public static SecurityIdentifier ToSecurityIdentifier(this string accountName) { - if (string.IsNullOrWhiteSpace(accountName)) - { - throw new ArgumentException("Value cannot be null or whitespace.", nameof(accountName)); - } + ArgumentException.ThrowIfNullOrWhiteSpace(accountName); try { From ec0f7dafb9ec432a33806af212fbc62d04080861 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:50:08 -0600 Subject: [PATCH 10/15] Disables MA0015: Specify the parameter name in ArgumentException. --- src/.editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/.editorconfig b/src/.editorconfig index f0adb70..5f7d499 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -104,6 +104,7 @@ dotnet_diagnostic.CA1848.severity = none dotnet_diagnostic.MA0003.severity = none dotnet_diagnostic.MA0007.severity = none +dotnet_diagnostic.MA0015.severity = none dotnet_diagnostic.MA0038.severity = none dotnet_diagnostic.MA0041.severity = none dotnet_diagnostic.MA0051.severity = none From 7d687905d1ed1ce349ee423d24e86baa6af469f2 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:52:09 -0600 Subject: [PATCH 11/15] Fixes CA1859: Use concrete types when possible for improved performance. --- src/Tests.Application/LsaUserRightsTestBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests.Application/LsaUserRightsTestBase.cs b/src/Tests.Application/LsaUserRightsTestBase.cs index dada9be..42406da 100644 --- a/src/Tests.Application/LsaUserRightsTestBase.cs +++ b/src/Tests.Application/LsaUserRightsTestBase.cs @@ -232,7 +232,7 @@ private static DirectoryInfo CreateTempDirectory() /// /// The path to a directory where the backup files exist. /// A map of privilege to security identifiers. - private static IReadOnlyDictionary> ReadSecurityDatabaseBackup(string workingDirectory) + private static ReadOnlyDictionary> ReadSecurityDatabaseBackup(string workingDirectory) { ArgumentException.ThrowIfNullOrWhiteSpace(workingDirectory); From ecb25e08a8ff461d1d6c281d73dbe9fe1c423983 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:53:53 -0600 Subject: [PATCH 12/15] Simplifies object initializations using target-typed new. --- src/Tests.Application/LsaUserRightsTestBase.cs | 4 ++-- src/Tests.Application/UserRightsManagerPrincipalTests.cs | 2 +- src/Tests.Application/UserRightsManagerPrivilegeTests.cs | 2 +- src/Tests.Application/UserRightsManagerTestBase.cs | 2 +- src/Tests.Cli/CliTestBase.cs | 2 +- src/UserRights.Application/LsaUserRights.cs | 8 ++++---- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Tests.Application/LsaUserRightsTestBase.cs b/src/Tests.Application/LsaUserRightsTestBase.cs index 42406da..2b89597 100644 --- a/src/Tests.Application/LsaUserRightsTestBase.cs +++ b/src/Tests.Application/LsaUserRightsTestBase.cs @@ -261,7 +261,7 @@ private static ReadOnlyDictionary>(dictionary); + return new(dictionary); } /// diff --git a/src/Tests.Application/UserRightsManagerPrincipalTests.cs b/src/Tests.Application/UserRightsManagerPrincipalTests.cs index 3553e1f..3e5fd15 100644 --- a/src/Tests.Application/UserRightsManagerPrincipalTests.cs +++ b/src/Tests.Application/UserRightsManagerPrincipalTests.cs @@ -28,7 +28,7 @@ public static TheoryData { PrincipalSid1 } } }); - return new TheoryData + return new() { // Verify null policy instance. { null!, PrincipalName1, [Privilege1], [], false, false, false }, diff --git a/src/Tests.Application/UserRightsManagerPrivilegeTests.cs b/src/Tests.Application/UserRightsManagerPrivilegeTests.cs index c442648..3ec99b4 100644 --- a/src/Tests.Application/UserRightsManagerPrivilegeTests.cs +++ b/src/Tests.Application/UserRightsManagerPrivilegeTests.cs @@ -28,7 +28,7 @@ public static TheoryData + return new() { // Verify null policy instance. { null!, Privilege1, [PrincipalName1], [], false, false, null!, false }, diff --git a/src/Tests.Application/UserRightsManagerTestBase.cs b/src/Tests.Application/UserRightsManagerTestBase.cs index 9b3a8af..2473187 100644 --- a/src/Tests.Application/UserRightsManagerTestBase.cs +++ b/src/Tests.Application/UserRightsManagerTestBase.cs @@ -29,7 +29,7 @@ protected UserRightsManagerTestBase() .AddDebug()); // Defer the creation until the instance is accessed to allow inheritors to modify the service collection. - _serviceProvider = new Lazy(_serviceCollection.BuildServiceProvider); + _serviceProvider = new(_serviceCollection.BuildServiceProvider); } /// diff --git a/src/Tests.Cli/CliTestBase.cs b/src/Tests.Cli/CliTestBase.cs index b9abe2b..33a8b12 100644 --- a/src/Tests.Cli/CliTestBase.cs +++ b/src/Tests.Cli/CliTestBase.cs @@ -26,7 +26,7 @@ protected CliTestBase() .SetMinimumLevel(LogLevel.Trace) .AddDebug()); - _serviceProvider = new Lazy(_serviceCollection.BuildServiceProvider); + _serviceProvider = new(_serviceCollection.BuildServiceProvider); } /// diff --git a/src/UserRights.Application/LsaUserRights.cs b/src/UserRights.Application/LsaUserRights.cs index 4bfe8bb..0f7871e 100644 --- a/src/UserRights.Application/LsaUserRights.cs +++ b/src/UserRights.Application/LsaUserRights.cs @@ -78,7 +78,7 @@ public unsafe void LsaAddAccountRights(SecurityIdentifier accountSid, params str { var length = checked((ushort)(privilege.Length * sizeof(char))); - rights[i] = new LSA_UNICODE_STRING + rights[i] = new() { Length = length, MaximumLength = length, @@ -135,7 +135,7 @@ public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) var ptr = nint.Add((nint)userRights, offset); var result = Marshal.PtrToStructure(ptr); - results[i] = new string(result.Buffer.Value); + results[i] = new(result.Buffer.Value); } return results; @@ -204,7 +204,7 @@ SecurityIdentifier[] Method(LSA_UNICODE_STRING right) var result = Marshal.PtrToStructure(nint.Add((nint)buffer, offset)); var sid = result.Sid; - results[i] = new SecurityIdentifier((nint)sid.Value); + results[i] = new((nint)sid.Value); } return results; @@ -253,7 +253,7 @@ public unsafe void LsaRemoveAccountRights(SecurityIdentifier accountSid, params { var length = checked((ushort)(privilege.Length * sizeof(char))); - rights[i] = new LSA_UNICODE_STRING + rights[i] = new() { Length = length, MaximumLength = length, From 0242a8871eea4086c33f4f1fddcf7e5dd35c09c1 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:54:30 -0600 Subject: [PATCH 13/15] Disables CA1031: Do not catch general exception types. --- src/.editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/.editorconfig b/src/.editorconfig index 5f7d499..e8a9830 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -98,6 +98,7 @@ dotnet_diagnostic.IDE0039.severity = none dotnet_diagnostic.IDE0046.severity = none dotnet_diagnostic.IDE0058.severity = none +dotnet_diagnostic.CA1031.severity = none dotnet_diagnostic.CA1515.severity = none dotnet_diagnostic.CA1822.severity = none dotnet_diagnostic.CA1848.severity = none From 142e2f4477c78658fc277ad59001edab7021afd8 Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:57:53 -0600 Subject: [PATCH 14/15] Replaces `default` with `null` for improved clarity and consistency. --- src/Tests/MockLsaUserRights.cs | 4 ++-- src/UserRights.Application/ILsaUserRights.cs | 2 +- src/UserRights.Application/IUserRights.cs | 2 +- src/UserRights.Application/LsaUserRights.cs | 10 +++++----- src/UserRights.Application/UserRightsManager.cs | 2 +- src/UserRights/EventIdProvider.cs | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Tests/MockLsaUserRights.cs b/src/Tests/MockLsaUserRights.cs index 1db3834..f6d6b9e 100644 --- a/src/Tests/MockLsaUserRights.cs +++ b/src/Tests/MockLsaUserRights.cs @@ -39,7 +39,7 @@ public MockLsaUserRights(IDictionary> da } /// - public void Connect(string? systemName = default) + public void Connect(string? systemName = null) { if (_connected) { @@ -97,7 +97,7 @@ public string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) } /// - public SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = default) + public SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = null) { if (!_connected) { diff --git a/src/UserRights.Application/ILsaUserRights.cs b/src/UserRights.Application/ILsaUserRights.cs index dc3461d..b27ca65 100644 --- a/src/UserRights.Application/ILsaUserRights.cs +++ b/src/UserRights.Application/ILsaUserRights.cs @@ -9,5 +9,5 @@ public interface ILsaUserRights : IUserRights /// Connects to the local security authority. /// /// The remote system name to execute the task on (default localhost). - void Connect(string? systemName = default); + void Connect(string? systemName = null); } \ No newline at end of file diff --git a/src/UserRights.Application/IUserRights.cs b/src/UserRights.Application/IUserRights.cs index abce001..e5bd908 100644 --- a/src/UserRights.Application/IUserRights.cs +++ b/src/UserRights.Application/IUserRights.cs @@ -26,7 +26,7 @@ public interface IUserRights /// /// The name of a privilege. /// The security identifier (SID) of each account that holds the specified privilege. - SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = default); + SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = null); /// /// Removes one or more privileges from an account. diff --git a/src/UserRights.Application/LsaUserRights.cs b/src/UserRights.Application/LsaUserRights.cs index 0f7871e..1369f4e 100644 --- a/src/UserRights.Application/LsaUserRights.cs +++ b/src/UserRights.Application/LsaUserRights.cs @@ -19,7 +19,7 @@ public class LsaUserRights : ILsaUserRights, IDisposable private LsaCloseSafeHandle? _handle; /// - public void Connect(string? systemName = default) + public void Connect(string? systemName = null) { ObjectDisposedException.ThrowIf(_disposed, this); @@ -116,7 +116,7 @@ public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) var psid = new PSID(b); using var ssid = new LsaCloseSafeHandle(psid); - LSA_UNICODE_STRING* userRights = default; + LSA_UNICODE_STRING* userRights = null; try { var status = PInvoke.LsaEnumerateAccountRights(_handle, ssid, out userRights, out var count); @@ -151,7 +151,7 @@ public unsafe string[] LsaEnumerateAccountRights(SecurityIdentifier accountSid) } /// - public unsafe SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = default) + public unsafe SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? userRight = null) { ObjectDisposedException.ThrowIf(_disposed, this); @@ -180,7 +180,7 @@ public unsafe SecurityIdentifier[] LsaEnumerateAccountsWithUserRight(string? use SecurityIdentifier[] Method(LSA_UNICODE_STRING right) { - void* buffer = default; + void* buffer = null; try { var status = PInvoke.LsaEnumerateAccountsWithUserRight(_handle, right, out buffer, out var count); @@ -297,7 +297,7 @@ protected virtual void Dispose(bool disposing) /// The requested access rights. /// The name of the target system. /// A handle to the Policy object. - private unsafe LsaCloseSafeHandle LsaOpenPolicy(ref LSA_OBJECT_ATTRIBUTES objectAttributes, uint desiredAccess, string? systemName = default) + private unsafe LsaCloseSafeHandle LsaOpenPolicy(ref LSA_OBJECT_ATTRIBUTES objectAttributes, uint desiredAccess, string? systemName = null) { ObjectDisposedException.ThrowIf(_disposed, this); diff --git a/src/UserRights.Application/UserRightsManager.cs b/src/UserRights.Application/UserRightsManager.cs index 61761a2..30915b4 100644 --- a/src/UserRights.Application/UserRightsManager.cs +++ b/src/UserRights.Application/UserRightsManager.cs @@ -34,7 +34,7 @@ public IEnumerable GetUserRights(IUserRights policy) var entries = new List(); foreach (var principal in principals) { - string? accountName = default; + string? accountName = null; try { accountName = principal.ToAccount().Value; diff --git a/src/UserRights/EventIdProvider.cs b/src/UserRights/EventIdProvider.cs index 4304f90..2c4effd 100644 --- a/src/UserRights/EventIdProvider.cs +++ b/src/UserRights/EventIdProvider.cs @@ -30,7 +30,7 @@ public ushort ComputeEventId(LogEvent logEvent) // The EventId property was provided by Microsoft.Extensions.Logging. StructureValue structure => structure.Properties.FirstOrDefault(p => string.Equals("Id", p.Name, StringComparison.OrdinalIgnoreCase))?.Value.ToString(), - _ => default + _ => null }; if (short.TryParse(id, NumberStyles.Any, CultureInfo.InvariantCulture, out var result)) From 385584d842e6761f53663f6b4f4a2f5a4231b46c Mon Sep 17 00:00:00 2001 From: "Joseph L. Casale" <9957114+jcasale@users.noreply.github.com> Date: Wed, 10 Sep 2025 17:03:59 -0600 Subject: [PATCH 15/15] Updates workflow actions. --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7c8e8b6..6a06894 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,13 +17,13 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 - name: Setup dotnet id: setup-dotnet - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: global-json-file: src/global.json