diff --git a/CHANGELOG.md b/CHANGELOG.md index af581b2e6..d8745defd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ Represents the **NuGet** versions. +## v5.16.2 +- *Fixed:* `Operation.AuthEntity` and `Operation.AuthOperation` updated to code-gen the `Manager`-based authorization (`ExecutionContent.UserIsAuthorized`) invocation. +- *Fixed:* Code-generation logging/auditing of endpoints updated to also include the authorization configuration. +- *Fixed:* `CreateProperty` statement within generated entity updated to use the correct name for reference data properties. + ## v5.16.1 - *Fixed:* Upgraded dependencies related to `System.Text.Json`; resolve [Microsoft Security Advisory CVE-2024-43485](https://github.com/advisories/GHSA-8g4q-xg66-9fp4). diff --git a/Common.targets b/Common.targets index 14ef5d70f..a55ce5c00 100644 --- a/Common.targets +++ b/Common.targets @@ -1,6 +1,6 @@ - 5.16.1 + 5.16.2 preview Avanade Avanade diff --git a/docs/Entity-Entity-Config.md b/docs/Entity-Entity-Config.md index 96e0f0d2f..21ef5b32f 100644 --- a/docs/Entity-Entity-Config.md +++ b/docs/Entity-Entity-Config.md @@ -138,7 +138,9 @@ Provides the _Authorization_ configuration. Property | Description -|- -**`authRole`** | The role (permission) used by the `ExecutionContext.IsInRole(role)` for each `Operation`.
† Used where not overridden specifically for an `Operation`; i.e. acts as the default. +`authPermission` | The permission used by the `ExecutionContext.UserIsAuthorized(AuthPermission)` to determine whether the user is authorized. +`authEntity` | The permission used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized. +**`authRole`** | The role (permission) used by the `ExecutionContext.UserIsInRole(role)` for each `Operation`.
† Used where not overridden specifically for an `Operation`; i.e. acts as the default.
diff --git a/docs/Entity-Operation-Config.md b/docs/Entity-Operation-Config.md index 42682e093..82371f5e3 100644 --- a/docs/Entity-Operation-Config.md +++ b/docs/Entity-Operation-Config.md @@ -84,8 +84,10 @@ Provides the _Authorization_ configuration. Property | Description -|- -`authPermission` | The permission used by the `ExecutionContext.IsAuthorized(AuthPermission)` to determine whether the user is authorized. -`authRole` | The permission used by the `ExecutionContext.IsInRole(AuthRole)` to determine whether the user is authorized. +`authPermission` | The permission used by the `ExecutionContext.UserIsAuthorized(AuthPermission)` to determine whether the user is authorized. +`authEntity` | The permission used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized. Defaults to `Entity.AuthEntity`. Both the `AuthEntity` and `AuthAction` are required for code-generation. +`authAction` | The permission used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized. Both the `AuthEntity` and `AuthAction` are required for code-generation. +`authRole` | The permission used by the `ExecutionContext.UserIsInRole(AuthRole)` to determine whether the user is authorized.
diff --git a/samples/Cdr.Banking/Cdr.Banking.Api/Cdr.Banking.Api.csproj b/samples/Cdr.Banking/Cdr.Banking.Api/Cdr.Banking.Api.csproj index ea0fc80c5..743fc8bcf 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Api/Cdr.Banking.Api.csproj +++ b/samples/Cdr.Banking/Cdr.Banking.Api/Cdr.Banking.Api.csproj @@ -5,8 +5,8 @@ true
- - + + diff --git a/samples/Cdr.Banking/Cdr.Banking.Business/Cdr.Banking.Business.csproj b/samples/Cdr.Banking/Cdr.Banking.Business/Cdr.Banking.Business.csproj index 33e716c18..9fa8d17c5 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Business/Cdr.Banking.Business.csproj +++ b/samples/Cdr.Banking/Cdr.Banking.Business/Cdr.Banking.Business.csproj @@ -12,8 +12,8 @@ - - - + + +
\ No newline at end of file diff --git a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/Account.cs b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/Account.cs index d4ef0768a..2f9e88dee 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/Account.cs +++ b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/Account.cs @@ -88,10 +88,10 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(CreationDate), CreationDate, v => CreationDate = v); yield return CreateProperty(nameof(DisplayName), DisplayName, v => DisplayName = v); yield return CreateProperty(nameof(Nickname), Nickname, v => Nickname = v); - yield return CreateProperty(nameof(OpenStatusSid), OpenStatusSid, v => OpenStatusSid = v); + yield return CreateProperty(nameof(OpenStatus), OpenStatusSid, v => OpenStatusSid = v); yield return CreateProperty(nameof(IsOwned), IsOwned, v => IsOwned = v); yield return CreateProperty(nameof(MaskedNumber), MaskedNumber, v => MaskedNumber = v); - yield return CreateProperty(nameof(ProductCategorySid), ProductCategorySid, v => ProductCategorySid = v); + yield return CreateProperty(nameof(ProductCategory), ProductCategorySid, v => ProductCategorySid = v); yield return CreateProperty(nameof(ProductName), ProductName, v => ProductName = v); } } diff --git a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/AccountArgs.cs b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/AccountArgs.cs index e62bf0ea9..dc4b65470 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/AccountArgs.cs +++ b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/AccountArgs.cs @@ -48,8 +48,8 @@ public partial class AccountArgs : EntityBase /// protected override IEnumerable GetPropertyValues() { - yield return CreateProperty(nameof(ProductCategorySid), ProductCategorySid, v => ProductCategorySid = v); - yield return CreateProperty(nameof(OpenStatusSid), OpenStatusSid, v => OpenStatusSid = v); + yield return CreateProperty(nameof(ProductCategory), ProductCategorySid, v => ProductCategorySid = v); + yield return CreateProperty(nameof(OpenStatus), OpenStatusSid, v => OpenStatusSid = v); yield return CreateProperty(nameof(IsOwned), IsOwned, v => IsOwned = v); } } \ No newline at end of file diff --git a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/AccountDetail.cs b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/AccountDetail.cs index a36e44510..cf6d18556 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/AccountDetail.cs +++ b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/AccountDetail.cs @@ -63,7 +63,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Bsb), Bsb, v => Bsb = v); yield return CreateProperty(nameof(AccountNumber), AccountNumber, v => AccountNumber = v); yield return CreateProperty(nameof(BundleName), BundleName, v => BundleName = v); - yield return CreateProperty(nameof(SpecificAccountUTypeSid), SpecificAccountUTypeSid, v => SpecificAccountUTypeSid = v); + yield return CreateProperty(nameof(SpecificAccountUType), SpecificAccountUTypeSid, v => SpecificAccountUTypeSid = v); yield return CreateProperty(nameof(TermDeposit), TermDeposit, v => TermDeposit = v); yield return CreateProperty(nameof(CreditCard), CreditCard, v => CreditCard = v); } diff --git a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/TermDepositAccount.cs b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/TermDepositAccount.cs index ad93209bc..03d6ab328 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/TermDepositAccount.cs +++ b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/TermDepositAccount.cs @@ -55,6 +55,6 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(MaturityDate), MaturityDate, v => MaturityDate = v); yield return CreateProperty(nameof(MaturityAmount), MaturityAmount, v => MaturityAmount = v); yield return CreateProperty(nameof(MaturityCurrency), MaturityCurrency, v => MaturityCurrency = v); - yield return CreateProperty(nameof(MaturityInstructionsSid), MaturityInstructionsSid, v => MaturityInstructionsSid = v); + yield return CreateProperty(nameof(MaturityInstructions), MaturityInstructionsSid, v => MaturityInstructionsSid = v); } } \ No newline at end of file diff --git a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/Transaction.cs b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/Transaction.cs index cdb7dcb04..ba52e6d3f 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/Transaction.cs +++ b/samples/Cdr.Banking/Cdr.Banking.Business/Entities/Generated/Transaction.cs @@ -129,8 +129,8 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Id), Id, v => Id = v); yield return CreateProperty(nameof(AccountId), AccountId, v => AccountId = v); yield return CreateProperty(nameof(IsDetailAvailable), IsDetailAvailable, v => IsDetailAvailable = v); - yield return CreateProperty(nameof(TypeSid), TypeSid, v => TypeSid = v); - yield return CreateProperty(nameof(StatusSid), StatusSid, v => StatusSid = v); + yield return CreateProperty(nameof(Type), TypeSid, v => TypeSid = v); + yield return CreateProperty(nameof(Status), StatusSid, v => StatusSid = v); yield return CreateProperty(nameof(Description), Description, v => Description = v); yield return CreateProperty(nameof(PostingDateTime), PostingDateTime, v => PostingDateTime = v); yield return CreateProperty(nameof(ExecutionDateTime), ExecutionDateTime, v => ExecutionDateTime = v); diff --git a/samples/Cdr.Banking/Cdr.Banking.Common/Cdr.Banking.Common.csproj b/samples/Cdr.Banking/Cdr.Banking.Common/Cdr.Banking.Common.csproj index 2d12df7a5..ecec905fd 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Common/Cdr.Banking.Common.csproj +++ b/samples/Cdr.Banking/Cdr.Banking.Common/Cdr.Banking.Common.csproj @@ -8,6 +8,6 @@ - + \ No newline at end of file diff --git a/samples/Cdr.Banking/Cdr.Banking.Test/Cdr.Banking.Test.csproj b/samples/Cdr.Banking/Cdr.Banking.Test/Cdr.Banking.Test.csproj index 253879707..947fa8095 100644 --- a/samples/Cdr.Banking/Cdr.Banking.Test/Cdr.Banking.Test.csproj +++ b/samples/Cdr.Banking/Cdr.Banking.Test/Cdr.Banking.Test.csproj @@ -39,7 +39,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/samples/Demo/Beef.Demo.Api/Beef.Demo.Api.csproj b/samples/Demo/Beef.Demo.Api/Beef.Demo.Api.csproj index 00f7615fd..e14b3bc6f 100644 --- a/samples/Demo/Beef.Demo.Api/Beef.Demo.Api.csproj +++ b/samples/Demo/Beef.Demo.Api/Beef.Demo.Api.csproj @@ -12,9 +12,9 @@ - - - + + + diff --git a/samples/Demo/Beef.Demo.Business/Beef.Demo.Business.csproj b/samples/Demo/Beef.Demo.Business/Beef.Demo.Business.csproj index da6e54084..f2f4e055d 100644 --- a/samples/Demo/Beef.Demo.Business/Beef.Demo.Business.csproj +++ b/samples/Demo/Beef.Demo.Business/Beef.Demo.Business.csproj @@ -16,14 +16,14 @@ - - - - - - - - + + + + + + + + diff --git a/samples/Demo/Beef.Demo.Business/Entities/Generated/Contact.cs b/samples/Demo/Beef.Demo.Business/Entities/Generated/Contact.cs index 49feb548b..be135b42f 100644 --- a/samples/Demo/Beef.Demo.Business/Entities/Generated/Contact.cs +++ b/samples/Demo/Beef.Demo.Business/Entities/Generated/Contact.cs @@ -69,7 +69,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Id), Id, v => Id = v); yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); - yield return CreateProperty(nameof(StatusSid), StatusSid, v => StatusSid = v); + yield return CreateProperty(nameof(Status), StatusSid, v => StatusSid = v); yield return CreateProperty(nameof(InternalCode), InternalCode, v => InternalCode = v); yield return CreateProperty(nameof(Communications), Communications, v => Communications = v); } diff --git a/samples/Demo/Beef.Demo.Business/Entities/Generated/Gender.cs b/samples/Demo/Beef.Demo.Business/Entities/Generated/Gender.cs index 68ce79edb..f2e665716 100644 --- a/samples/Demo/Beef.Demo.Business/Entities/Generated/Gender.cs +++ b/samples/Demo/Beef.Demo.Business/Entities/Generated/Gender.cs @@ -61,7 +61,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(AlternateName), AlternateName, v => AlternateName = v); yield return CreateProperty(nameof(TripCode), TripCode, v => TripCode = v); - yield return CreateProperty(nameof(CountrySid), CountrySid, v => CountrySid = v); + yield return CreateProperty(nameof(Country), CountrySid, v => CountrySid = v); } /// diff --git a/samples/Demo/Beef.Demo.Business/Entities/Generated/Person.cs b/samples/Demo/Beef.Demo.Business/Entities/Generated/Person.cs index 4d441a797..959630984 100644 --- a/samples/Demo/Beef.Demo.Business/Entities/Generated/Person.cs +++ b/samples/Demo/Beef.Demo.Business/Entities/Generated/Person.cs @@ -127,8 +127,8 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); yield return CreateProperty(nameof(UniqueCode), UniqueCode, v => UniqueCode = v); - yield return CreateProperty(nameof(GenderSid), GenderSid, v => GenderSid = v); - yield return CreateProperty(nameof(EyeColorSid), EyeColorSid, v => EyeColorSid = v); + yield return CreateProperty(nameof(Gender), GenderSid, v => GenderSid = v); + yield return CreateProperty(nameof(EyeColor), EyeColorSid, v => EyeColorSid = v); yield return CreateProperty(nameof(Birthday), Birthday, v => Birthday = v); yield return CreateProperty(nameof(Address), Address, v => Address = v); yield return CreateProperty(nameof(ETag), ETag, v => ETag = v); diff --git a/samples/Demo/Beef.Demo.Business/Entities/Generated/PersonArgs.cs b/samples/Demo/Beef.Demo.Business/Entities/Generated/PersonArgs.cs index 1e4399cf9..f9665e5a4 100644 --- a/samples/Demo/Beef.Demo.Business/Entities/Generated/PersonArgs.cs +++ b/samples/Demo/Beef.Demo.Business/Entities/Generated/PersonArgs.cs @@ -64,7 +64,7 @@ protected override IEnumerable GetPropertyValues() { yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); - yield return CreateProperty(nameof(GendersSids), GendersSids, v => GendersSids = v); + yield return CreateProperty(nameof(Genders), GendersSids, v => GendersSids = v); yield return CreateProperty(nameof(OrderBy), OrderBy, v => OrderBy = v); } } diff --git a/samples/Demo/Beef.Demo.Business/Entities/Generated/PostalInfo.cs b/samples/Demo/Beef.Demo.Business/Entities/Generated/PostalInfo.cs index 21f7caba1..22809dbf1 100644 --- a/samples/Demo/Beef.Demo.Business/Entities/Generated/PostalInfo.cs +++ b/samples/Demo/Beef.Demo.Business/Entities/Generated/PostalInfo.cs @@ -60,7 +60,7 @@ public partial class PostalInfo : EntityBase, IETag /// protected override IEnumerable GetPropertyValues() { - yield return CreateProperty(nameof(CountrySid), CountrySid, v => CountrySid = v); + yield return CreateProperty(nameof(Country), CountrySid, v => CountrySid = v); yield return CreateProperty(nameof(City), City, v => City = v); yield return CreateProperty(nameof(State), State, v => State = v); yield return CreateProperty(nameof(Places), Places, v => Places = v); diff --git a/samples/Demo/Beef.Demo.Business/Entities/Generated/RefDataPrimaryKey.cs b/samples/Demo/Beef.Demo.Business/Entities/Generated/RefDataPrimaryKey.cs index 6b7f30773..750b8a358 100644 --- a/samples/Demo/Beef.Demo.Business/Entities/Generated/RefDataPrimaryKey.cs +++ b/samples/Demo/Beef.Demo.Business/Entities/Generated/RefDataPrimaryKey.cs @@ -54,7 +54,7 @@ public partial class RefDataPrimaryKey : EntityBase, IPrimaryKey /// protected override IEnumerable GetPropertyValues() { - yield return CreateProperty(nameof(Key1Sid), Key1Sid, v => Key1Sid = v); + yield return CreateProperty(nameof(Key1), Key1Sid, v => Key1Sid = v); yield return CreateProperty(nameof(Other), Other, v => Other = v); } } diff --git a/samples/Demo/Beef.Demo.Business/Entities/Generated/Robot.cs b/samples/Demo/Beef.Demo.Business/Entities/Generated/Robot.cs index b8eb116e0..da7958d7f 100644 --- a/samples/Demo/Beef.Demo.Business/Entities/Generated/Robot.cs +++ b/samples/Demo/Beef.Demo.Business/Entities/Generated/Robot.cs @@ -88,8 +88,8 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Id), Id, v => Id = v); yield return CreateProperty(nameof(ModelNo), ModelNo, v => ModelNo = v); yield return CreateProperty(nameof(SerialNo), SerialNo, v => SerialNo = v); - yield return CreateProperty(nameof(EyeColorSid), EyeColorSid, v => EyeColorSid = v); - yield return CreateProperty(nameof(PowerSourceSid), PowerSourceSid, v => PowerSourceSid = v); + yield return CreateProperty(nameof(EyeColor), EyeColorSid, v => EyeColorSid = v); + yield return CreateProperty(nameof(PowerSource), PowerSourceSid, v => PowerSourceSid = v); yield return CreateProperty(nameof(ETag), ETag, v => ETag = v); yield return CreateProperty(nameof(ChangeLog), ChangeLog, v => ChangeLog = v); } diff --git a/samples/Demo/Beef.Demo.Business/Entities/Generated/RobotArgs.cs b/samples/Demo/Beef.Demo.Business/Entities/Generated/RobotArgs.cs index 428da1037..49a175b34 100644 --- a/samples/Demo/Beef.Demo.Business/Entities/Generated/RobotArgs.cs +++ b/samples/Demo/Beef.Demo.Business/Entities/Generated/RobotArgs.cs @@ -46,7 +46,7 @@ protected override IEnumerable GetPropertyValues() { yield return CreateProperty(nameof(ModelNo), ModelNo, v => ModelNo = v); yield return CreateProperty(nameof(SerialNo), SerialNo, v => SerialNo = v); - yield return CreateProperty(nameof(PowerSourcesSids), PowerSourcesSids, v => PowerSourcesSids = v); + yield return CreateProperty(nameof(PowerSources), PowerSourcesSids, v => PowerSourcesSids = v); } } diff --git a/samples/Demo/Beef.Demo.Common/Beef.Demo.Common.csproj b/samples/Demo/Beef.Demo.Common/Beef.Demo.Common.csproj index 8c6f5fdc0..608f72760 100644 --- a/samples/Demo/Beef.Demo.Common/Beef.Demo.Common.csproj +++ b/samples/Demo/Beef.Demo.Common/Beef.Demo.Common.csproj @@ -7,8 +7,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/samples/Demo/Beef.Demo.Test/Beef.Demo.Test.csproj b/samples/Demo/Beef.Demo.Test/Beef.Demo.Test.csproj index e8d893a84..ac24e7ca7 100644 --- a/samples/Demo/Beef.Demo.Test/Beef.Demo.Test.csproj +++ b/samples/Demo/Beef.Demo.Test/Beef.Demo.Test.csproj @@ -52,7 +52,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/samples/My.Hr/My.Hr.Api/My.Hr.Api.csproj b/samples/My.Hr/My.Hr.Api/My.Hr.Api.csproj index 1d6252d66..0d5313a30 100644 --- a/samples/My.Hr/My.Hr.Api/My.Hr.Api.csproj +++ b/samples/My.Hr/My.Hr.Api/My.Hr.Api.csproj @@ -5,9 +5,9 @@ true - - - + + + diff --git a/samples/My.Hr/My.Hr.Business/Entities/Generated/Address.cs b/samples/My.Hr/My.Hr.Business/Entities/Generated/Address.cs index 4195f86bf..c2990e2da 100644 --- a/samples/My.Hr/My.Hr.Business/Entities/Generated/Address.cs +++ b/samples/My.Hr/My.Hr.Business/Entities/Generated/Address.cs @@ -59,7 +59,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Street1), Street1, v => Street1 = v); yield return CreateProperty(nameof(Street2), Street2, v => Street2 = v); yield return CreateProperty(nameof(City), City, v => City = v); - yield return CreateProperty(nameof(StateSid), StateSid, v => StateSid = v); + yield return CreateProperty(nameof(State), StateSid, v => StateSid = v); yield return CreateProperty(nameof(PostCode), PostCode, v => PostCode = v); } } \ No newline at end of file diff --git a/samples/My.Hr/My.Hr.Business/Entities/Generated/EmergencyContact.cs b/samples/My.Hr/My.Hr.Business/Entities/Generated/EmergencyContact.cs index 7fcf9e06e..f063fa7ce 100644 --- a/samples/My.Hr/My.Hr.Business/Entities/Generated/EmergencyContact.cs +++ b/samples/My.Hr/My.Hr.Business/Entities/Generated/EmergencyContact.cs @@ -60,7 +60,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); yield return CreateProperty(nameof(PhoneNo), PhoneNo, v => PhoneNo = v); - yield return CreateProperty(nameof(RelationshipSid), RelationshipSid, v => RelationshipSid = v); + yield return CreateProperty(nameof(Relationship), RelationshipSid, v => RelationshipSid = v); } } diff --git a/samples/My.Hr/My.Hr.Business/Entities/Generated/EmployeeArgs.cs b/samples/My.Hr/My.Hr.Business/Entities/Generated/EmployeeArgs.cs index 70704b628..4bd6b8aa0 100644 --- a/samples/My.Hr/My.Hr.Business/Entities/Generated/EmployeeArgs.cs +++ b/samples/My.Hr/My.Hr.Business/Entities/Generated/EmployeeArgs.cs @@ -60,7 +60,7 @@ protected override IEnumerable GetPropertyValues() { yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); - yield return CreateProperty(nameof(GendersSids), GendersSids, v => GendersSids = v); + yield return CreateProperty(nameof(Genders), GendersSids, v => GendersSids = v); yield return CreateProperty(nameof(StartFrom), StartFrom, v => StartFrom = v); yield return CreateProperty(nameof(StartTo), StartTo, v => StartTo = v); yield return CreateProperty(nameof(IsIncludeTerminated), IsIncludeTerminated, v => IsIncludeTerminated = v); diff --git a/samples/My.Hr/My.Hr.Business/Entities/Generated/EmployeeBase.cs b/samples/My.Hr/My.Hr.Business/Entities/Generated/EmployeeBase.cs index b26dd32f8..334e756ae 100644 --- a/samples/My.Hr/My.Hr.Business/Entities/Generated/EmployeeBase.cs +++ b/samples/My.Hr/My.Hr.Business/Entities/Generated/EmployeeBase.cs @@ -84,7 +84,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Email), Email, v => Email = v); yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); - yield return CreateProperty(nameof(GenderSid), GenderSid, v => GenderSid = v); + yield return CreateProperty(nameof(Gender), GenderSid, v => GenderSid = v); yield return CreateProperty(nameof(Birthday), Birthday, v => Birthday = v); yield return CreateProperty(nameof(StartDate), StartDate, v => StartDate = v); yield return CreateProperty(nameof(Termination), Termination, v => Termination = v); diff --git a/samples/My.Hr/My.Hr.Business/Entities/Generated/PerformanceReview.cs b/samples/My.Hr/My.Hr.Business/Entities/Generated/PerformanceReview.cs index d67d7c45b..7785e5aec 100644 --- a/samples/My.Hr/My.Hr.Business/Entities/Generated/PerformanceReview.cs +++ b/samples/My.Hr/My.Hr.Business/Entities/Generated/PerformanceReview.cs @@ -78,7 +78,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Id), Id, v => Id = v); yield return CreateProperty(nameof(EmployeeId), EmployeeId, v => EmployeeId = v); yield return CreateProperty(nameof(Date), Date, v => Date = v); - yield return CreateProperty(nameof(OutcomeSid), OutcomeSid, v => OutcomeSid = v); + yield return CreateProperty(nameof(Outcome), OutcomeSid, v => OutcomeSid = v); yield return CreateProperty(nameof(Reviewer), Reviewer, v => Reviewer = v); yield return CreateProperty(nameof(Notes), Notes, v => Notes = v); yield return CreateProperty(nameof(ETag), ETag, v => ETag = v); diff --git a/samples/My.Hr/My.Hr.Business/Entities/Generated/TerminationDetail.cs b/samples/My.Hr/My.Hr.Business/Entities/Generated/TerminationDetail.cs index 7b53c3965..830bf7c03 100644 --- a/samples/My.Hr/My.Hr.Business/Entities/Generated/TerminationDetail.cs +++ b/samples/My.Hr/My.Hr.Business/Entities/Generated/TerminationDetail.cs @@ -39,6 +39,6 @@ public partial class TerminationDetail : EntityBase protected override IEnumerable GetPropertyValues() { yield return CreateProperty(nameof(Date), Date, v => Date = v); - yield return CreateProperty(nameof(ReasonSid), ReasonSid, v => ReasonSid = v); + yield return CreateProperty(nameof(Reason), ReasonSid, v => ReasonSid = v); } } \ No newline at end of file diff --git a/samples/My.Hr/My.Hr.Business/My.Hr.Business.csproj b/samples/My.Hr/My.Hr.Business/My.Hr.Business.csproj index f63d6b342..b06e96089 100644 --- a/samples/My.Hr/My.Hr.Business/My.Hr.Business.csproj +++ b/samples/My.Hr/My.Hr.Business/My.Hr.Business.csproj @@ -6,10 +6,10 @@ latest - - - - + + + + \ No newline at end of file diff --git a/samples/My.Hr/My.Hr.Common/My.Hr.Common.csproj b/samples/My.Hr/My.Hr.Common/My.Hr.Common.csproj index 1220fc6c7..0ec02a326 100644 --- a/samples/My.Hr/My.Hr.Common/My.Hr.Common.csproj +++ b/samples/My.Hr/My.Hr.Common/My.Hr.Common.csproj @@ -4,6 +4,6 @@ enable - + \ No newline at end of file diff --git a/samples/My.Hr/My.Hr.Test/My.Hr.Test.csproj b/samples/My.Hr/My.Hr.Test/My.Hr.Test.csproj index af817b6ac..67303f64d 100644 --- a/samples/My.Hr/My.Hr.Test/My.Hr.Test.csproj +++ b/samples/My.Hr/My.Hr.Test/My.Hr.Test.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/samples/MyEf.Hr/MyEf.Hr.Api/MyEf.Hr.Api.csproj b/samples/MyEf.Hr/MyEf.Hr.Api/MyEf.Hr.Api.csproj index 2aff7b6a1..b77f20f4c 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Api/MyEf.Hr.Api.csproj +++ b/samples/MyEf.Hr/MyEf.Hr.Api/MyEf.Hr.Api.csproj @@ -6,12 +6,12 @@ True - - + + - + diff --git a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/Address.cs b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/Address.cs index 58ecd176b..99e715241 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/Address.cs +++ b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/Address.cs @@ -59,7 +59,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Street1), Street1, v => Street1 = v); yield return CreateProperty(nameof(Street2), Street2, v => Street2 = v); yield return CreateProperty(nameof(City), City, v => City = v); - yield return CreateProperty(nameof(StateSid), StateSid, v => StateSid = v); + yield return CreateProperty(nameof(State), StateSid, v => StateSid = v); yield return CreateProperty(nameof(PostCode), PostCode, v => PostCode = v); } } \ No newline at end of file diff --git a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmergencyContact.cs b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmergencyContact.cs index a3020b903..bcdbde778 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmergencyContact.cs +++ b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmergencyContact.cs @@ -60,7 +60,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); yield return CreateProperty(nameof(PhoneNo), PhoneNo, v => PhoneNo = v); - yield return CreateProperty(nameof(RelationshipSid), RelationshipSid, v => RelationshipSid = v); + yield return CreateProperty(nameof(Relationship), RelationshipSid, v => RelationshipSid = v); } } diff --git a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmployeeArgs.cs b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmployeeArgs.cs index aa9410d5c..f9073eb13 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmployeeArgs.cs +++ b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmployeeArgs.cs @@ -60,7 +60,7 @@ protected override IEnumerable GetPropertyValues() { yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); - yield return CreateProperty(nameof(GendersSids), GendersSids, v => GendersSids = v); + yield return CreateProperty(nameof(Genders), GendersSids, v => GendersSids = v); yield return CreateProperty(nameof(StartFrom), StartFrom, v => StartFrom = v); yield return CreateProperty(nameof(StartTo), StartTo, v => StartTo = v); yield return CreateProperty(nameof(IsIncludeTerminated), IsIncludeTerminated, v => IsIncludeTerminated = v); diff --git a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmployeeBase.cs b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmployeeBase.cs index 70d09a1b9..3b069c793 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmployeeBase.cs +++ b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/EmployeeBase.cs @@ -84,7 +84,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Email), Email, v => Email = v); yield return CreateProperty(nameof(FirstName), FirstName, v => FirstName = v); yield return CreateProperty(nameof(LastName), LastName, v => LastName = v); - yield return CreateProperty(nameof(GenderSid), GenderSid, v => GenderSid = v); + yield return CreateProperty(nameof(Gender), GenderSid, v => GenderSid = v); yield return CreateProperty(nameof(Birthday), Birthday, v => Birthday = v); yield return CreateProperty(nameof(StartDate), StartDate, v => StartDate = v); yield return CreateProperty(nameof(Termination), Termination, v => Termination = v); diff --git a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/PerformanceReview.cs b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/PerformanceReview.cs index 0070241f2..bf0aa10b5 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/PerformanceReview.cs +++ b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/PerformanceReview.cs @@ -78,7 +78,7 @@ protected override IEnumerable GetPropertyValues() yield return CreateProperty(nameof(Id), Id, v => Id = v); yield return CreateProperty(nameof(EmployeeId), EmployeeId, v => EmployeeId = v); yield return CreateProperty(nameof(Date), Date, v => Date = v); - yield return CreateProperty(nameof(OutcomeSid), OutcomeSid, v => OutcomeSid = v); + yield return CreateProperty(nameof(Outcome), OutcomeSid, v => OutcomeSid = v); yield return CreateProperty(nameof(Reviewer), Reviewer, v => Reviewer = v); yield return CreateProperty(nameof(Notes), Notes, v => Notes = v); yield return CreateProperty(nameof(ETag), ETag, v => ETag = v); diff --git a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/TerminationDetail.cs b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/TerminationDetail.cs index a215d7698..f434cfbb2 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/TerminationDetail.cs +++ b/samples/MyEf.Hr/MyEf.Hr.Business/Entities/Generated/TerminationDetail.cs @@ -39,6 +39,6 @@ public partial class TerminationDetail : EntityBase protected override IEnumerable GetPropertyValues() { yield return CreateProperty(nameof(Date), Date, v => Date = v); - yield return CreateProperty(nameof(ReasonSid), ReasonSid, v => ReasonSid = v); + yield return CreateProperty(nameof(Reason), ReasonSid, v => ReasonSid = v); } } \ No newline at end of file diff --git a/samples/MyEf.Hr/MyEf.Hr.Business/MyEf.Hr.Business.csproj b/samples/MyEf.Hr/MyEf.Hr.Business/MyEf.Hr.Business.csproj index 4dc09ccc7..2ac37858c 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Business/MyEf.Hr.Business.csproj +++ b/samples/MyEf.Hr/MyEf.Hr.Business/MyEf.Hr.Business.csproj @@ -6,10 +6,10 @@ latest - - - - + + + + diff --git a/samples/MyEf.Hr/MyEf.Hr.Common/MyEf.Hr.Common.csproj b/samples/MyEf.Hr/MyEf.Hr.Common/MyEf.Hr.Common.csproj index ab69a4fe9..9f5217397 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Common/MyEf.Hr.Common.csproj +++ b/samples/MyEf.Hr/MyEf.Hr.Common/MyEf.Hr.Common.csproj @@ -5,6 +5,6 @@ True - + \ No newline at end of file diff --git a/samples/MyEf.Hr/MyEf.Hr.Security.Subscriptions/MyEf.Hr.Security.Subscriptions.csproj b/samples/MyEf.Hr/MyEf.Hr.Security.Subscriptions/MyEf.Hr.Security.Subscriptions.csproj index 98a8eb7d4..6aed65293 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Security.Subscriptions/MyEf.Hr.Security.Subscriptions.csproj +++ b/samples/MyEf.Hr/MyEf.Hr.Security.Subscriptions/MyEf.Hr.Security.Subscriptions.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/samples/MyEf.Hr/MyEf.Hr.Security.Test/MyEf.Hr.Security.Test.csproj b/samples/MyEf.Hr/MyEf.Hr.Security.Test/MyEf.Hr.Security.Test.csproj index c517b133a..a65e342e7 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Security.Test/MyEf.Hr.Security.Test.csproj +++ b/samples/MyEf.Hr/MyEf.Hr.Security.Test/MyEf.Hr.Security.Test.csproj @@ -27,7 +27,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/samples/MyEf.Hr/MyEf.Hr.Test/MyEf.Hr.Test.csproj b/samples/MyEf.Hr/MyEf.Hr.Test/MyEf.Hr.Test.csproj index 84025c71b..703ad80b2 100644 --- a/samples/MyEf.Hr/MyEf.Hr.Test/MyEf.Hr.Test.csproj +++ b/samples/MyEf.Hr/MyEf.Hr.Test/MyEf.Hr.Test.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/templates/Beef.Template.Solution/content/.template.config/template.json b/templates/Beef.Template.Solution/content/.template.config/template.json index 2949727b8..354581c36 100644 --- a/templates/Beef.Template.Solution/content/.template.config/template.json +++ b/templates/Beef.Template.Solution/content/.template.config/template.json @@ -85,7 +85,7 @@ "type": "generated", "generator": "constant", "parameters": { - "value": "3.27.0" + "value": "3.27.1" }, "replaces": "CoreExVersion" }, @@ -93,7 +93,7 @@ "type": "generated", "generator": "constant", "parameters": { - "value": "5.16.1" + "value": "5.16.2" }, "replaces": "BeefVersion" }, diff --git a/templates/Beef.Template.Solution/content/Company.AppName.Api/appsettings.json b/templates/Beef.Template.Solution/content/Company.AppName.Api/appsettings.json index a24e164f0..d08dc386e 100644 --- a/templates/Beef.Template.Solution/content/Company.AppName.Api/appsettings.json +++ b/templates/Beef.Template.Solution/content/Company.AppName.Api/appsettings.json @@ -52,7 +52,12 @@ //#endif "Invokers": { "Default": { - "TracingEnabled": true + "TracingEnabled": true, + "LoggingEnabled": true + }, + "CoreEx.Validation.ValidationInvoker": { + "TracingEnabled": false, + "LoggingEnabled": false } }, "IncludeExceptionInResult": true diff --git a/tools/Beef.CodeGen.Core/Config/Entity/EntityConfig.cs b/tools/Beef.CodeGen.Core/Config/Entity/EntityConfig.cs index ad697c995..3c5beb25c 100644 --- a/tools/Beef.CodeGen.Core/Config/Entity/EntityConfig.cs +++ b/tools/Beef.CodeGen.Core/Config/Entity/EntityConfig.cs @@ -1000,11 +1000,25 @@ public class EntityConfig : ConfigBase #region Auth + /// + /// Gets or sets the permission used by the `ExecutionContext.UserIsAuthorized(AuthPermission)` to determine whether the user is authorized. + /// + [JsonPropertyName("authPermission")] + [CodeGenProperty("Auth", Title = "The permission used by the `ExecutionContext.UserIsAuthorized(AuthPermission)` to determine whether the user is authorized.")] + public string? AuthPermission { get; set; } + + /// + /// Gets or sets the entity-based authorization entity used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized. + /// + [JsonPropertyName("authEntity")] + [CodeGenProperty("Auth", Title = "The permission used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized.")] + public string? AuthEntity { get; set; } + /// /// Gets or sets the role (permission) used by the ExecutionContext.IsInRole(role) for each Operation. /// [JsonPropertyName("authRole")] - [CodeGenProperty("Auth", Title = "The role (permission) used by the `ExecutionContext.IsInRole(role)` for each `Operation`.", IsImportant = true, + [CodeGenProperty("Auth", Title = "The role (permission) used by the `ExecutionContext.UserIsInRole(role)` for each `Operation`.", IsImportant = true, Description = "Used where not overridden specifically for an `Operation`; i.e. acts as the default.")] public string? AuthRole { get; set; } @@ -1734,33 +1748,33 @@ private async Task PrepareOperationsAsync() // Add in selected operations where applicable (in reverse order in which output). if (CompareValue(Delete, true) && !Operations.Any(x => x.Name == "Delete")) - Operations.Insert(0, new OperationConfig { Name = "Delete", Type = "Delete", PrimaryKey = true }); + Operations.Insert(0, new OperationConfig { Name = "Delete", Type = "Delete", PrimaryKey = true, AuthAction = "Delete" }); if (CompareValue(Patch, true) && !Operations.Any(x => x.Name == "Patch")) Operations.Insert(0, new OperationConfig { Name = "Patch", Type = "Patch", PrimaryKey = true }); if (CompareValue(Update, true) && !Operations.Any(x => x.Name == "Update")) - Operations.Insert(0, new OperationConfig { Name = "Update", Type = "Update", PrimaryKey = true }); + Operations.Insert(0, new OperationConfig { Name = "Update", Type = "Update", PrimaryKey = true, AuthAction = "Update" }); if (CompareValue(Create, true) && !Operations.Any(x => x.Name == "Create")) - Operations.Insert(0, new OperationConfig { Name = "Create", Type = "Create", WebApiRoute = "" }); + Operations.Insert(0, new OperationConfig { Name = "Create", Type = "Create", WebApiRoute = "", AuthAction = "Create" }); if (CompareValue(Get, true) && !Operations.Any(x => x.Name == "Get")) - Operations.Insert(0, new OperationConfig { Name = "Get", Type = "Get", PrimaryKey = true }); + Operations.Insert(0, new OperationConfig { Name = "Get", Type = "Get", PrimaryKey = true, AuthAction = "Read" }); if (CompareValue(GetByArgs, true) && !Operations.Any(x => x.Name == "GetByArgs")) { var at = $"{Name}Args"; - Operations.Insert(0, new OperationConfig { Name = "GetByArgs", Type = "GetColl", Paging = true, WebApiRoute = "", Parameters = [new ParameterConfig() { Name = "Args", Type = at, Validator = $"{Name}ArgsValidator" }] }); + Operations.Insert(0, new OperationConfig { Name = "GetByArgs", Type = "GetColl", Paging = true, WebApiRoute = "", AuthAction = "Read", Parameters = [new ParameterConfig() { Name = "Args", Type = at, Validator = $"{Name}ArgsValidator" }] }); if (!Parent!.Entities!.Any(x => x.Name == at)) Root!.CodeGenArgs?.Logger?.LogWarning("{Warning}", $"Warning: Config [{BuildFullyQualifiedName(nameof(GetByArgs))}] references entity '{at}' that has not been defined; this is needed to complete implementation."); } if (CompareValue(GetAll, true) && !Operations.Any(x => x.Name == "GetAll")) - Operations.Insert(0, new OperationConfig { Name = "GetAll", Type = "GetColl", WebApiRoute = GetByArgs is not null && GetByArgs.Value ? "all" : "" }); + Operations.Insert(0, new OperationConfig { Name = "GetAll", Type = "GetColl", WebApiRoute = GetByArgs is not null && GetByArgs.Value ? "all" : "", AuthAction = "Read" }); if (CompareValue(GetByQuery, true) && !Operations.Any(x => x.Name == "GetByQuery")) - Operations.Insert(0, new OperationConfig { Name = "GetByQuery", Type = "GetColl", Paging = true, Query = true, WebApiRoute = "query" }); + Operations.Insert(0, new OperationConfig { Name = "GetByQuery", Type = "GetColl", Paging = true, Query = true, WebApiRoute = "query", AuthAction = "Read" }); // Prepare each operations. foreach (var operation in Operations) diff --git a/tools/Beef.CodeGen.Core/Config/Entity/OperationConfig.cs b/tools/Beef.CodeGen.Core/Config/Entity/OperationConfig.cs index 4bcc25bd9..ca429396a 100644 --- a/tools/Beef.CodeGen.Core/Config/Entity/OperationConfig.cs +++ b/tools/Beef.CodeGen.Core/Config/Entity/OperationConfig.cs @@ -554,17 +554,31 @@ public class OperationConfig : ConfigBase #region Auth /// - /// Gets or sets the permission used by the `ExecutionContext.IsAuthorized(AuthPermission)` to determine whether the user is authorized. + /// Gets or sets the permission used by the `ExecutionContext.UserIsAuthorized(AuthPermission)` to determine whether the user is authorized. /// [JsonPropertyName("authPermission")] - [CodeGenProperty("Auth", Title = "The permission used by the `ExecutionContext.IsAuthorized(AuthPermission)` to determine whether the user is authorized.")] + [CodeGenProperty("Auth", Title = "The permission used by the `ExecutionContext.UserIsAuthorized(AuthPermission)` to determine whether the user is authorized.")] public string? AuthPermission { get; set; } /// - /// Gets or sets the permission used by the `ExecutionContext.IsInRole(AuthRole)` to determine whether the user is authorized. + /// Gets or sets the entity-based authorization action used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized. + /// + [JsonPropertyName("authEntity")] + [CodeGenProperty("Auth", Title = "The permission used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized. Defaults to `Entity.AuthEntity`. Both the `AuthEntity` and `AuthAction` are required for code-generation.")] + public string? AuthEntity { get; set; } + + /// + /// Gets or sets the entity-based authorization entity used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized. + /// + [JsonPropertyName("authAction")] + [CodeGenProperty("Auth", Title = "The permission used by the `ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)` to determine whether the user is authorized. Both the `AuthEntity` and `AuthAction` are required for code-generation.")] + public string? AuthAction { get; set; } + + /// + /// Gets or sets the permission used by the `ExecutionContext.UserIsInRole(AuthRole)` to determine whether the user is authorized. /// [JsonPropertyName("authRole")] - [CodeGenProperty("Auth", Title = "The permission used by the `ExecutionContext.IsInRole(AuthRole)` to determine whether the user is authorized.")] + [CodeGenProperty("Auth", Title = "The permission used by the `ExecutionContext.UserIsInRole(AuthRole)` to determine whether the user is authorized.")] public string? AuthRole { get; set; } #endregion @@ -1137,6 +1151,8 @@ protected override async Task PrepareAsync() WebApiReturnText = Type == "GetColl" ? StringConverter.ToComments($"The {{{{{BaseReturnType}Collection}}}}") : ReturnText; PrivateName = DefaultWhereNull(PrivateName, () => StringConverter.ToPrivateCase(Name)); + AuthPermission = DefaultWhereNull(AuthPermission, () => Parent!.AuthPermission); + AuthEntity = DefaultWhereNull(AuthEntity, () => Parent!.AuthEntity); AuthRole = DefaultWhereNull(AuthRole, () => Parent!.AuthRole); Validator = DefaultWhereNull(Validator, () => Parent!.Validator); AutoImplement = DefaultWhereNull(AutoImplement, () => Parent!.AutoImplement); diff --git a/tools/Beef.CodeGen.Core/EndPointStatistics.cs b/tools/Beef.CodeGen.Core/EndPointStatistics.cs index f966c3ea3..3dbd2c2e8 100644 --- a/tools/Beef.CodeGen.Core/EndPointStatistics.cs +++ b/tools/Beef.CodeGen.Core/EndPointStatistics.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; namespace Beef.CodeGen { @@ -34,14 +35,56 @@ public void AddEntityEndPoints(Config.Entity.CodeGenConfig root) Route = o.AgentWebApiRoute, Method = o.WebApiMethod![4..], Status = o.WebApiStatus!, - Auth = o.WebApiAuthorize ?? e.WebApiAuthorize, + ApiAuth = o.WebApiAuthorize ?? e.WebApiAuthorize, Tags = string.Join(", ", o.WebApiTags!.Count > 0 ? o.WebApiTags : e.WebApiTags!), - Name = $"{e.Name}.{o.Name}" + Name = $"{e.Name}.{o.Name}", + MgrAuth = GetRolePermission(o) }); } } } + /// + /// Create the role/permission text. + /// + private static string? GetRolePermission(Config.Entity.OperationConfig o) + { + if (o.IsPatch) + { + var po = o.Parent!.Operations!.Where(x => x.Name == o.WebApiUpdateOperation).FirstOrDefault(); + if (po is not null) + o = po; + } + + if (o.ExcludeManager.HasValue && o.ExcludeManager.Value) + return ""; + + var sb = new StringBuilder(); + + if (!string.IsNullOrEmpty(o.AuthRole)) + sb.Append(o.AuthRole); + + if (!string.IsNullOrEmpty(o.AuthPermission)) + { + if (sb.Length > 0) + sb.Append(" / "); + + sb.Append(o.AuthPermission); + } + + if (!string.IsNullOrEmpty(o.AuthEntity)) + { + if (sb.Length > 0) + sb.Append(" / "); + + sb.Append(o.AuthEntity); + sb.Append('.'); + sb.Append(string.IsNullOrEmpty(o.AuthAction) ? "" : o.AuthAction); + } + + return sb.Length == 0 ? null : sb.ToString(); + } + /// /// Adds the endpoints. /// @@ -53,7 +96,7 @@ public void AddRefDataEndPoints(Config.Entity.CodeGenConfig root) Route = root.RefDataWebApiRoute, Method = "GET", Status = "OK", - Auth = root.WebApiAuthorize, + ApiAuth = root.WebApiAuthorize, Tags = null, Name = "ReferenceData.GetNamed" }); @@ -67,7 +110,7 @@ public void AddRefDataEndPoints(Config.Entity.CodeGenConfig root) Route = e.WebApiRoutePrefix!, Method = "GET", Status = "OK", - Auth = e.WebApiAuthorize, + ApiAuth = e.WebApiAuthorize, Tags = string.Join(", ", e.WebApiTags!), Name = $"ReferenceData.{e.Name}GetAll" }); @@ -103,22 +146,24 @@ private void WriteTabulated(ILogger logger, bool indent) var routeLength = Math.Max(5, _endPoints.Max(x => x.Route?.Length ?? 0)); var methodLength = Math.Max(6, _endPoints.Max(x => x.Method?.Length ?? 0)); var statusLength = Math.Max(6, _endPoints.Max(x => x.Status?.Length ?? 0)); - var authLength = Math.Max(4, _endPoints.Max(x => x.Auth?.Length ?? 0)); + var authLength = Math.Max(8, _endPoints.Max(x => x.ApiAuth?.Length ?? 0)); var tagsLength = Math.Max(4, _endPoints.Max(x => x.Tags?.Length ?? 0)); + var nameLength = Math.Max(4, _endPoints.Max(x => x.Name?.Length ?? 0)); var hdrRoute = string.Format("{0, -" + routeLength + "}", "Route"); var hdrMethod = string.Format("{0, -" + methodLength + "}", "Method"); var hdrStatus = string.Format("{0, -" + statusLength + "}", "Status"); - var hdrAuth = string.Format("{0, -" + authLength + "}", "Auth"); + var hdrApiAuth = string.Format("{0, -" + authLength + "}", "Api-Auth"); var hdrTags = string.Format("{0, -" + tagsLength + "}", "Tags"); + var hdrName = string.Format("{0, -" + nameLength + "}", "Name"); if (_endPoints.Count == 0) return; var prefix = indent ? new string(' ', 6) : string.Empty; - logger.LogInformation("{Content}", $"{prefix}{hdrRoute} | {hdrMethod} | {hdrStatus} | {hdrAuth} | {hdrTags} | Name"); - logger.LogInformation("{Content}", $"{prefix}{new string('-', routeLength + methodLength + statusLength + authLength + tagsLength + 15 + Math.Max(4, _endPoints.Max(x => x.Name?.Length ?? 0)))}"); + logger.LogInformation("{Content}", $"{prefix}{hdrRoute} | {hdrMethod} | {hdrStatus} | {hdrApiAuth} | {hdrTags} | {hdrName} | Role/Permission"); + logger.LogInformation("{Content}", $"{prefix}{new string('-', routeLength + methodLength + statusLength + authLength + tagsLength + nameLength + 18 + Math.Max(15, _endPoints.Max(x => x.MgrAuth?.Length ?? 0)))}"); // Write the data. foreach (var ep in _endPoints.OrderBy(x => x.Route).ThenBy(x => x.Method).ThenBy(x => x.Name)) @@ -126,10 +171,11 @@ private void WriteTabulated(ILogger logger, bool indent) var route = string.Format("{0, -" + routeLength + "}", ep.Route); var method = string.Format("{0, -" + methodLength + "}", ep.Method); var status = string.Format("{0, -" + statusLength + "}", ep.Status); - var auth = string.Format("{0, -" + authLength + "}", ep.Auth); + var auth = string.Format("{0, -" + authLength + "}", ep.ApiAuth); var tags = string.Format("{0, -" + tagsLength + "}", ep.Tags); + var name = string.Format("{0, -" + nameLength + "}", ep.Name); - logger.LogInformation("{Content}", $"{prefix}{route} | {method.ToUpperInvariant()} | {status} | {auth} | {tags} | {ep.Name}"); + logger.LogInformation("{Content}", $"{prefix}{route} | {method.ToUpperInvariant()} | {status} | {auth} | {tags} | {name} | {ep.MgrAuth}"); } } @@ -153,8 +199,9 @@ internal class EndPointData public string? Route { get; set; } public string? Method { get; set; } public string? Status { get; set; } - public string? Auth { get; set; } + public string? ApiAuth { get; set; } public string? Tags { get; set; } public string? Name { get; set; } + public string? MgrAuth { get; set; } } } diff --git a/tools/Beef.CodeGen.Core/Schema/entity.beef-5.json b/tools/Beef.CodeGen.Core/Schema/entity.beef-5.json index eafed485b..3786110ca 100644 --- a/tools/Beef.CodeGen.Core/Schema/entity.beef-5.json +++ b/tools/Beef.CodeGen.Core/Schema/entity.beef-5.json @@ -973,9 +973,17 @@ "type": "boolean", "title": "Indicates whether to exclude the generation of the gRPC consuming \u0060Agent\u0060 class (\u0060XxxAgent.cs\u0060)." }, + "authPermission": { + "type": "string", + "title": "The permission used by the \u0060ExecutionContext.UserIsAuthorized(AuthPermission)\u0060 to determine whether the user is authorized." + }, + "authEntity": { + "type": "string", + "title": "The permission used by the \u0060ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)\u0060 to determine whether the user is authorized." + }, "authRole": { "type": "string", - "title": "The role (permission) used by the \u0060ExecutionContext.IsInRole(role)\u0060 for each \u0060Operation\u0060.", + "title": "The role (permission) used by the \u0060ExecutionContext.UserIsInRole(role)\u0060 for each \u0060Operation\u0060.", "description": "Used where not overridden specifically for an \u0060Operation\u0060; i.e. acts as the default." }, "grpc": { @@ -1669,11 +1677,19 @@ }, "authPermission": { "type": "string", - "title": "The permission used by the \u0060ExecutionContext.IsAuthorized(AuthPermission)\u0060 to determine whether the user is authorized." + "title": "The permission used by the \u0060ExecutionContext.UserIsAuthorized(AuthPermission)\u0060 to determine whether the user is authorized." + }, + "authEntity": { + "type": "string", + "title": "The permission used by the \u0060ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)\u0060 to determine whether the user is authorized. Defaults to \u0060Entity.AuthEntity\u0060. Both the \u0060AuthEntity\u0060 and \u0060AuthAction\u0060 are required for code-generation." + }, + "authAction": { + "type": "string", + "title": "The permission used by the \u0060ExecutionContext.UserIsAuthorized(AuthEntity, AuthAction)\u0060 to determine whether the user is authorized. Both the \u0060AuthEntity\u0060 and \u0060AuthAction\u0060 are required for code-generation." }, "authRole": { "type": "string", - "title": "The permission used by the \u0060ExecutionContext.IsInRole(AuthRole)\u0060 to determine whether the user is authorized." + "title": "The permission used by the \u0060ExecutionContext.UserIsInRole(AuthRole)\u0060 to determine whether the user is authorized." }, "excludeAll": { "type": "boolean", diff --git a/tools/Beef.CodeGen.Core/Templates/EntityManager_cs.hbs b/tools/Beef.CodeGen.Core/Templates/EntityManager_cs.hbs index 39e823539..2c557b78f 100644 --- a/tools/Beef.CodeGen.Core/Templates/EntityManager_cs.hbs +++ b/tools/Beef.CodeGen.Core/Templates/EntityManager_cs.hbs @@ -93,6 +93,9 @@ public partial class {{Name}}Manager{{#if GenericWithT}}{{/if}} : I{{Name}}Ma {{#ifval AuthPermission}} {{#if WithResult}} .UserIsAuthorized("{{AuthPermission}}"){{else}}ExecutionContext.Current.UserIsAuthorized("{{AuthPermission}}").ThrowOnError();{{/if}} {{/ifval}} + {{#ifval AuthEntity}} + {{#if WithResult}} .UserIsAuthorized("{{AuthEntity}}", "{{AuthAction}}"){{else}}ExecutionContext.Current.UserIsAuthorized("{{AuthEntity}}", "{{AuthAction}}").ThrowOnError();{{/if}} + {{/ifval}} {{#ifeq Type 'Create'}} {{#each Parent.Properties}} {{#if IdentifierGenerator}} diff --git a/tools/Beef.CodeGen.Core/Templates/Entity_cs.hbs b/tools/Beef.CodeGen.Core/Templates/Entity_cs.hbs index e569aedf5..b80074a03 100644 --- a/tools/Beef.CodeGen.Core/Templates/Entity_cs.hbs +++ b/tools/Beef.CodeGen.Core/Templates/Entity_cs.hbs @@ -278,7 +278,7 @@ public {{#if Abstract}}abstract {{/if}}partial class {{{EntityName}}} : {{{Entit {{/if}} {{#each CoreProperties}} - yield return CreateProperty(nameof({{PropertyName}}), {{PropertyName}}, v => {{PropertyName}} = v{{#ifval Default}}, {{Default}}{{/ifval}}); + yield return CreateProperty(nameof({{Name}}), {{PropertyName}}, v => {{PropertyName}} = v{{#ifval Default}}, {{Default}}{{/ifval}}); {{/each}} } {{/ifne}} diff --git a/tools/Beef.Database.Core/Beef.Database.Core.csproj b/tools/Beef.Database.Core/Beef.Database.Core.csproj index 2d1ce8781..708652a40 100644 --- a/tools/Beef.Database.Core/Beef.Database.Core.csproj +++ b/tools/Beef.Database.Core/Beef.Database.Core.csproj @@ -14,7 +14,7 @@ - + diff --git a/tools/Beef.Database.MySql/Beef.Database.MySql.csproj b/tools/Beef.Database.MySql/Beef.Database.MySql.csproj index b5fe61653..adf266f1f 100644 --- a/tools/Beef.Database.MySql/Beef.Database.MySql.csproj +++ b/tools/Beef.Database.MySql/Beef.Database.MySql.csproj @@ -14,7 +14,7 @@ - + diff --git a/tools/Beef.Database.Postgres/Beef.Database.Postgres.csproj b/tools/Beef.Database.Postgres/Beef.Database.Postgres.csproj index 6bb262f86..e9189dc26 100644 --- a/tools/Beef.Database.Postgres/Beef.Database.Postgres.csproj +++ b/tools/Beef.Database.Postgres/Beef.Database.Postgres.csproj @@ -14,7 +14,7 @@ - + diff --git a/tools/Beef.Database.SqlServer/Beef.Database.SqlServer.csproj b/tools/Beef.Database.SqlServer/Beef.Database.SqlServer.csproj index 8c1e920d3..a056c687c 100644 --- a/tools/Beef.Database.SqlServer/Beef.Database.SqlServer.csproj +++ b/tools/Beef.Database.SqlServer/Beef.Database.SqlServer.csproj @@ -14,7 +14,7 @@ - + diff --git a/tools/Beef.Test.NUnit/Beef.Test.NUnit.csproj b/tools/Beef.Test.NUnit/Beef.Test.NUnit.csproj index cc03131af..3cd0d9081 100644 --- a/tools/Beef.Test.NUnit/Beef.Test.NUnit.csproj +++ b/tools/Beef.Test.NUnit/Beef.Test.NUnit.csproj @@ -8,7 +8,7 @@ - +