Skip to content

Commit 26ecd3a

Browse files
authored
v3.27.1 (#126)
- *Fixed:* Updated `Microsoft.Extensions.Caching.Memory` package depenedency to latest (including related); resolve [Microsoft Security Advisory CVE-2024-43483](GHSA-qj66-m88j-hmgj). - *Fixed:* Fixed the `ExecutionContext.UserIsAuthorized` to have base implementation similar to `UserIsInRole`. - *Fixed:* Rationalize the `UtcNow` usage to be consistent, where applicable `ExecutionContext.SystemTime.UtcNow` is leveraged.
1 parent 6738a92 commit 26ecd3a

7 files changed

Lines changed: 31 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
Represents the **NuGet** versions.
44

5+
## v3.27.1
6+
- *Fixed:* Updated `Microsoft.Extensions.Caching.Memory` package depenedency to latest (including related); resolve [Microsoft Security Advisory CVE-2024-43483](https://github.com/advisories/GHSA-qj66-m88j-hmgj).
7+
- *Fixed:* Fixed the `ExecutionContext.UserIsAuthorized` to have base implementation similar to `UserIsInRole`.
8+
- *Fixed:* Rationalize the `UtcNow` usage to be consistent, where applicable `ExecutionContext.SystemTime.UtcNow` is leveraged.
9+
510
## v3.27.0
611
- *Fixed:* The `ValueContentResult.TryCreateValueContentResult` would return `NotModified` where the request `ETag` was `null`; this has been corrected to return `OK` with the resulting `value`.
712
- *Fixed:* The `ValueContentResult.TryCreateValueContentResult` now returns `ExtendedStatusCodeResult` versus `StatusCodeResult` as this offers additional capabilities where required.

Common.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>3.27.0</Version>
3+
<Version>3.27.1</Version>
44
<LangVersion>preview</LangVersion>
55
<Authors>Avanade</Authors>
66
<Company>Avanade</Company>

src/CoreEx/CoreEx.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
</ItemGroup>
5353

5454
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
55-
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
55+
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.2" />
5656
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
5757
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="6.0.31" />
5858
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />

src/CoreEx/Entities/ChangeLog.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,6 @@ public static IChangeLogAudit PrepareUpdated(IChangeLogAudit changeLog, Executio
8989
/// <summary>
9090
/// Gets the timestamp.
9191
/// </summary>
92-
private static DateTime GetTimestamp(ExecutionContext? ec) => ec != null ? ec.Timestamp : (ExecutionContext.HasCurrent ? ExecutionContext.Current.Timestamp : DateTime.UtcNow);
92+
private static DateTime GetTimestamp(ExecutionContext? ec) => ec != null ? ec.Timestamp : ExecutionContext.SystemTime.UtcNow;
9393
}
9494
}

src/CoreEx/Events/EventDataFormatter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public virtual void Format(EventData @event)
152152
var value = @event.Value;
153153

154154
@event.Id ??= Guid.NewGuid().ToString();
155-
@event.Timestamp ??= DateTimeOffset.UtcNow;
155+
@event.Timestamp ??= new DateTimeOffset(ExecutionContext.SystemTime.UtcNow);
156156

157157
if (PropertySelection.HasFlag(EventDataProperty.Key))
158158
{

src/CoreEx/ExecutionContext.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class ExecutionContext : ITenantId, IDisposable
2727
private Lazy<ConcurrentDictionary<string, object?>> _properties = new(true);
2828
private IReferenceDataContext? _referenceDataContext;
2929
private HashSet<string>? _roles;
30+
private HashSet<string>? _permissions;
3031
private bool _disposed;
3132
private readonly object _lock = new();
3233

@@ -170,7 +171,7 @@ public static object GetRequiredService(Type type)
170171
/// Gets or sets the timestamp for the <see cref="ExecutionContext"/> lifetime; i.e (to enable consistent execution-related timestamping).
171172
/// </summary>
172173
/// <remarks>Defaults the value from <see cref="ISystemTime"/>, where this has not been registered it will default to <see cref="DateTime.UtcNow"/>. The value will also be passed through <see cref="Cleaner.Clean(DateTime)"/>.</remarks>
173-
public DateTime Timestamp { get => _timestamp ??= Cleaner.Clean(GetService<ISystemTime>()?.UtcNow ?? DateTime.UtcNow); set => _timestamp = Cleaner.Clean(value); }
174+
public DateTime Timestamp { get => _timestamp ??= SystemTime.UtcNow; set => _timestamp = Cleaner.Clean(value); }
174175

175176
/// <summary>
176177
/// Gets the <see cref="MessageItemCollection"/> to be passed back to the originating consumer.
@@ -249,18 +250,28 @@ public void Dispose()
249250
/// Sets (replaces) the roles the current user is in (the roles should be unique).
250251
/// </summary>
251252
/// <param name="roles">The <see cref="IEnumerable{String}"/> of roles the user is in.</param>
252-
public virtual void SetRoles(IEnumerable<string> roles) => _roles = new HashSet<string>(roles.Distinct());
253+
public virtual void SetRoles(IEnumerable<string> roles) => _roles = new HashSet<string>(roles);
253254

254255
/// <summary>
255-
/// Checks whether the user has the required <paramref name="permission"/>.
256+
/// Gets the list of permissions for the <see cref="UserName"/> (as previously <see cref="SetPermissions(IEnumerable{string})">set</see>).
257+
/// </summary>
258+
public IEnumerable<string> GetPermissions() => _permissions == null ? Array.Empty<string>() : _permissions;
259+
260+
/// <summary>
261+
/// Sets (replaces) the permissions the current user is in (the roles should be unique).
262+
/// </summary>
263+
/// <param name="roles">The <see cref="IEnumerable{String}"/> of roles the user is in.</param>
264+
public virtual void SetPermissions(IEnumerable<string> roles) => _permissions = new HashSet<string>(roles);
265+
266+
/// <summary>
267+
/// Checks whether the user has the required <paramref name="permission"/> (see <see cref="SetPermissions"/> and <see cref="GetPermissions"/>).
256268
/// </summary>
257269
/// <param name="permission">The permission to validate.</param>
258270
/// <returns>The corresponding <see cref="Result"/>.</returns>
259-
/// <remarks>This method is intended to be overridden; this implementation always returns <see cref="Result.AuthorizationError"/>.</remarks>
260271
public virtual Result UserIsAuthorized(string permission)
261272
{
262273
permission.ThrowIfNullOrEmpty(nameof(permission));
263-
return Result.AuthorizationError();
274+
return _permissions is not null && _permissions.Contains(permission) ? Result.Success : Result.AuthorizationError();
264275
}
265276

266277
/// <summary>
@@ -269,12 +280,13 @@ public virtual Result UserIsAuthorized(string permission)
269280
/// <param name="entity">The entity name.</param>
270281
/// <param name="action">The action name.</param>
271282
/// <returns>The corresponding <see cref="Result"/>.</returns>
272-
/// <remarks>This method is intended to be overridden; this implementation always returns <see cref="Result.AuthorizationError"/>.</remarks>
283+
/// <remarks>This default implementation formats as <c>{entity}.{action}</c> and invokes <see cref="UserIsAuthorized(string)"/>.
284+
/// <para>An example is <c>Customer</c> and <c>Create</c> formatted as <c>Customer.Create</c>.</para></remarks>
273285
public virtual Result UserIsAuthorized(string entity, string action)
274286
{
275287
entity.ThrowIfNullOrEmpty(nameof(entity));
276288
action.ThrowIfNullOrEmpty(nameof(action));
277-
return Result.AuthorizationError();
289+
return UserIsAuthorized($"{entity}.{action}");
278290
}
279291

280292
/// <summary>
@@ -284,8 +296,8 @@ public virtual Result UserIsAuthorized(string entity, string action)
284296
/// <returns>The corresponding <see cref="Result"/>.</returns>
285297
public virtual Result UserIsInRole(string role)
286298
{
287-
var isInRole = (_roles != null) && _roles.TryGetValue(role, out _);
288-
return isInRole ? Result.Success : Result.AuthorizationError();
299+
role.ThrowIfNullOrEmpty(nameof(role));
300+
return _roles is not null && _roles.Contains(role) ? Result.Success : Result.AuthorizationError();
289301
}
290302

291303
#endregion

src/CoreEx/RefData/Extended/ReferenceDataBaseEx.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public virtual bool IsActive
7171

7272
if (StartDate != null || EndDate != null)
7373
{
74-
var date = ExecutionContext.HasCurrent ? ExecutionContext.Current.ReferenceDataContext[GetType()] : Cleaner.Clean(DateTime.UtcNow, DateTimeTransform.DateOnly);
74+
var date = ExecutionContext.HasCurrent ? ExecutionContext.Current.ReferenceDataContext[GetType()] : Cleaner.Clean(ExecutionContext.SystemTime.UtcNow, DateTimeTransform.DateOnly);
7575
if (StartDate != null && date < StartDate)
7676
return false;
7777

0 commit comments

Comments
 (0)