Skip to content

Commit

Permalink
Simplify IUserCacheInvalidator by renaming to IRemoveCachedUser with …
Browse files Browse the repository at this point in the history
…only one method.
  • Loading branch information
volkanceylan committed Oct 20, 2024
1 parent 844b436 commit 6a05168
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ bool validatePassword() => UserHelper.CalculateHash(password, user.PasswordSalt)

uow.Commit();

userRetriever.InvalidateItem(user, cache);
userRetriever.RemoveCachedUser(user, cache);

return PasswordValidationResult.Valid;
}
Expand Down Expand Up @@ -183,8 +183,7 @@ private PasswordValidationResult ValidateFirstTimeUser(ref string username, stri

uow.Commit();

userRetriever.InvalidateById(userId.ToInvariant(), cache);
userRetriever.InvalidateByUsername(username, cache);
userRetriever.RemoveCachedUser(userId.ToInvariant(), username, cache);

return PasswordValidationResult.Valid;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Serene.AppServices;

public class UserRetrieveService(ITwoLevelCache cache, ISqlConnections sqlConnections) : IUserRetrieveService, IUserCacheInvalidator
public class UserRetrieveService(ITwoLevelCache cache, ISqlConnections sqlConnections) : IUserRetrieveService, IRemoveAll, IRemoveCachedUser
{
protected readonly ITwoLevelCache cache = cache ?? throw new ArgumentNullException(nameof(cache));
protected readonly ISqlConnections sqlConnections = sqlConnections ?? throw new ArgumentNullException(nameof(cache));
Expand Down Expand Up @@ -52,30 +52,16 @@ public IUserDefinition ByUsername(string username)
});
}

public void InvalidateAll()
public void RemoveAll()
{
cache.ExpireGroupItems(MyRow.Fields.GenerationKey);
}

public void InvalidateById(string userId)
{
if (userId == null ||
!int.TryParse(userId, CultureInfo.InvariantCulture, out int id))
return;
cache.Remove("UserByID_" + id.ToInvariant());
}

public void InvalidateByUsername(string username)
public void RemoveCachedUser(string userId, string username)
{
if (userId != null && int.TryParse(userId, CultureInfo.InvariantCulture, out int id))
cache.Remove("UserByID_" + id.ToInvariant());
if (username != null)
cache.Remove("UserByName_" + username.ToLowerInvariant());
}

public void InvalidateItem(IUserDefinition user)
{
if (user is null)
return;
InvalidateById(user.Id);
InvalidateByUsername(user.Username);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ public Result<SignUpResponse> SignUp(SignUpRequest request,
uow.Commit();
userRetriever.InvalidateById(userId.ToInvariant(), Cache);
userRetriever.InvalidateByUsername(username, Cache);
userRetriever.RemoveCachedUser(userId.ToInvariant(), username, Cache);
if (environmentOptions?.Value.IsPublicDemo == true)
{
Expand Down
57 changes: 16 additions & 41 deletions src/Serenity.Net.Core/Authorization/AuthorizationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,65 +135,40 @@ public static void Impersonate(this IUserProvider userProvider, string username,
userProvider.Impersonate(principal);
}

/// <summary>
/// Tries to invalidate all users in cache if the user retrieve service implements IUserCacheInvalidator.
/// If not, it tries to expire all users in cache by group name "Default.Users" if cache is not null.
/// </summary>
/// <param name="userRetriever">User retrieve service</param>
/// <param name="cache">Optional cache</param>
public static void InvalidateAll(this IUserRetrieveService userRetriever, ITwoLevelCache? cache)
{
if (userRetriever is IUserCacheInvalidator invalidator)
invalidator.InvalidateAll();
else
cache?.ExpireGroupItems("Default.Users");
}

/// <summary>
/// Tries to invalidate user in cache if the user retrieve service implements IUserCacheInvalidator.
/// If not, and cache is not null and user is not null, it tries to remove user by id and username from cache.
/// </summary>
/// <param name="userRetriever">User retrieve service</param>
/// <param name="user">User</param>
/// <param name="cache">Cache</param>
public static void InvalidateItem(this IUserRetrieveService userRetriever, IUserDefinition? user, ITwoLevelCache? cache)
public static void RemoveCachedUser(this IUserRetrieveService userRetriever, IUserDefinition? user, ITwoLevelCache? cache)
{
if (userRetriever is IUserCacheInvalidator invalidator)
invalidator.InvalidateItem(user);
else if (user != null)
{
userRetriever.InvalidateById(user.Id, cache);
userRetriever.InvalidateByUsername(user.Username, cache);
}
RemoveCachedUser(userRetriever, user?.Id, user?.Username, cache);
}


/// <summary>
/// Tries to invalidate user by its id if the user retrieve service implements IUserCacheInvalidator.
/// Tries to invalidate user by its id / name if the user retrieve service implements IUserCacheInvalidator.
/// If not, and cache is not null, it tries to remove user by id from cache.
/// </summary>
/// <param name="userRetriever">User retrieve service</param>
/// <param name="userId">UserId</param>
/// <param name="username">Username</param>
/// <param name="cache"></param>
public static void InvalidateById(this IUserRetrieveService userRetriever, string? userId, ITwoLevelCache? cache)
public static void RemoveCachedUser(this IUserRetrieveService userRetriever, string? userId, string? username, ITwoLevelCache? cache)
{
if (userRetriever is IUserCacheInvalidator invalidator)
invalidator.InvalidateById(userId);
else if (userId != null)
cache?.Remove("UserByID_" + userId);
}
if (userRetriever is IRemoveCachedUser removeCachedUser)
{
removeCachedUser.RemoveCachedUser(userId, username);
return;
}

/// <summary>
/// Tries to invalidate user by its usernae if the user retrieve service implements IUserCacheInvalidator.
/// If not, and cache is not null, it tries to remove user by id from cache.
/// </summary>
/// <param name="userRetriever">User retrieve service</param>
/// <param name="username">Username</param>
/// <param name="cache">Cache</param>
public static void InvalidateByUsername(this IUserRetrieveService userRetriever, string? username, ITwoLevelCache? cache)
{
if (userRetriever is IUserCacheInvalidator invalidator)
invalidator.InvalidateByUsername(username);
else if (username != null)
if (userId != null)
cache?.Remove("UserById_" + userId);

if (username != null)
cache?.Remove("UserByName_" + username.ToLowerInvariant());

}
}
23 changes: 7 additions & 16 deletions src/Serenity.Net.Core/Authorization/DefaultUserProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,27 +49,18 @@ public void UndoImpersonate()
}

/// <inheritdoc/>
public void InvalidateAll()
public void RemoveAll()
{
userRetriever.InvalidateAll(cache);
if (userRetriever is IRemoveAll removeAll)
removeAll.RemoveAll();
else
cache?.ExpireGroupItems("Default.Users");
}

/// <inheritdoc/>
public void InvalidateItem(IUserDefinition? user)
public void RemoveCachedUser(string? userId, string? username)
{
userRetriever.InvalidateItem(user, cache);
}

/// <inheritdoc/>
public void InvalidateById(string? userId)
{
userRetriever.InvalidateById(userId, cache);
}

/// <inheritdoc/>
public void InvalidateByUsername(string? username)
{
userRetriever.InvalidateByUsername(username, cache);
userRetriever.RemoveCachedUser(userId, username, cache);
}

/// <inheritdoc/>
Expand Down
13 changes: 13 additions & 0 deletions src/Serenity.Net.Core/Authorization/IRemoveCachedUser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

namespace Serenity.Abstractions;

/// <summary>
/// Abstraction to remove a cached user by its id or username
/// </summary>
public interface IRemoveCachedUser
{
/// <summary>
/// Removed cached user by its user ID and/or username
/// </summary>
void RemoveCachedUser(string? userId, string? username);
}
28 changes: 0 additions & 28 deletions src/Serenity.Net.Core/Authorization/IUserCacheInvalidator.cs

This file was deleted.

7 changes: 2 additions & 5 deletions src/Serenity.Net.Core/Authorization/IUserProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ namespace Serenity.Abstractions;

/// <summary>
/// Abstraction that is a combination of IUserAccessor, IImpersonator, IUserClaimCreator, IUserRetrieveService and IUserCacheInvalidator.
/// Note that although it implements IImpersonator, its methods may throw exceptions if the underlying
/// Note that although the <see cref="DefaultUserProvider"/> implements IImpersonator, its methods may throw exceptions if the underlying
/// IUserAccessor does not implement IImpersonator.
/// It implements IUserCacheInvalidator but its methods may silently ignore or throw exceptions if the underlying IUserRetrieveService
/// does not implement IUserCacheInvalidator. The DefaultUserRetriever implementation does not throw exceptions in such cases and tries
/// to handle them gracefully.
/// </summary>
public interface IUserProvider : IUserAccessor, IUserRetrieveService, IUserClaimCreator, IImpersonator, IUserCacheInvalidator
public interface IUserProvider : IUserAccessor, IUserRetrieveService, IUserClaimCreator, IImpersonator, IRemoveCachedUser, IRemoveAll
{
}

0 comments on commit 6a05168

Please sign in to comment.