Перейти к содержанию

Изменение имен пользователей в обсуждениях

Изменение имен пользователей в обсуждениях

Начиная с версии 4.0 в платформе появилась возможность изменять имена пользователей в обсуждениях и уведомлениях по ним. Для этого необходимо переопределить интерфейс IForumUserNamingStrategy.

Для демонстрации реализуем указанный интерфейс таким образом, чтобы заменялись имена и идентификаторы пользователей с уровнем доступа “Администратор”, при этом обычные пользователи будут видеть измененную информацию, а администраторы - изначальную.

public class ForumUserNamingStrategy : IForumUserNamingStrategy { #region Private static fields and consts

private static readonly Guid AdministratorIDMasked = Guid.Empty; private const string AdministratorNameMasked = "Администраторы"; private const string MaskAuthorKey = ".maskAuthor"; private const string MaskFormat = "<mask>{0}</mask>"; private const string MaskRegex = LeftBraket + @"[^\s]+" + RightBraket; private const string LeftBraket = "&lt;mask&gt;"; private const string RightBraket = "&lt;/mask&gt;";

#endregion

#region Private Fields

private readonly IDbScope dbScope;

#endregion

#region Constructor

public ForumUserNamingStrategy(IDbScope dbScope) { this.dbScope = NotNullOrThrow(dbScope); }

#endregion

#region IForumUserNamingStrategy Members

public async ValueTask ReplaceAsync( IReadOnlyList<ITopicNotificationInfo> topicNotificationInfos, CancellationToken cancellationToken = default) { Dictionary<Guid, bool> users = new();

foreach (var info in topicNotificationInfos) { if (!users.TryGetValue(info.UserID, out var isAdmin)) { isAdmin = await this.CheckUserIsAdminAsync(info.UserID, cancellationToken); users[info.UserID] = isAdmin; }

if (isAdmin) { info.HtmlText = info.HtmlText .Replace(LeftBraket, string.Empty, StringComparison.OrdinalIgnoreCase) .Replace(RightBraket, string.Empty, StringComparison.OrdinalIgnoreCase); } else { info.HtmlText = Regex.Replace(info.HtmlText, MaskRegex, AdministratorNameMasked); }

if (!isAdmin && info.Info.TryGet<bool>(MaskAuthorKey)) { info.AuthorName = AdministratorNameMasked; } } }

public ValueTask ReplaceAsync( Guid userID, IReadOnlyList<NotificationModel> notificationModels, CancellationToken cancellationToken = default) => this.ReplaceBodyInMessageAsync( notificationModels, userID, cancellationToken);

public ValueTask ReplaceAsync( Guid cardID, Guid userID, IReadOnlyList<MessageModel> messageModels, CancellationToken cancellationToken = default) => this.ReplaceBodyInMessageAsync( messageModels, userID, cancellationToken);

public async ValueTask PrepareForReplaceAsync( Guid cardID, MessageModel messageModel, CancellationToken cancellationToken = default) { messageModel.Body.Info[MaskAuthorKey] = BooleanBoxes.Box( await this.CheckUserIsAdminAsync(messageModel.AuthorID, cancellationToken)); }

public async ValueTask<string> PrepareForReplaceAsync( Guid cardID, Guid topicID, Guid userID, string userName, CancellationToken cancellationToken = default) { return await this.CheckUserIsAdminAsync(userID, cancellationToken) ? string.Format(MaskFormat, userName) : userName; }

#endregion

#region Private Methods

private async ValueTask ReplaceBodyInMessageAsync( IReadOnlyList<MessageModelBase> messageModels, Guid userID, CancellationToken cancellationToken = default) { Regex regex = null; var isAdmin = await this.CheckUserIsAdminAsync(userID, cancellationToken);

foreach (var messageModel in messageModels) { if (isAdmin) { messageModel.Body.Text = messageModel.Body.Text .Replace(LeftBraket, string.Empty, StringComparison.OrdinalIgnoreCase) .Replace(RightBraket, string.Empty, StringComparison.OrdinalIgnoreCase); } else { regex ??= new Regex(MaskRegex); messageModel.Body.Text = regex.Replace(messageModel.Body.Text, AdministratorNameMasked); }

if (!isAdmin && messageModel.Body.Info.TryGet<bool>(MaskAuthorKey)) { messageModel.AuthorID = AdministratorIDMasked; messageModel.AuthorName = AdministratorNameMasked; } } }

private async ValueTask<bool> CheckUserIsAdminAsync( Guid userID, CancellationToken cancellationToken = default) { await using var _ = this.dbScope.Create();

return await this.dbScope.Db .SetCommand(this.dbScope.BuilderFactory .Select().V(true) .From("PersonalRoles").NoLock() .Where() .C("ID").Equals().P("ID") .And().C("AccessLevelID").Equals().P("AccessLevelID") .Build(), this.dbScope.Db.Parameter("ID", userID), this.dbScope.Db.Parameter("AccessLevelID", (int) UserAccessLevel.Administrator)) .LogCommand() .ExecuteAsync<bool>(cancellationToken); }

#endregion }

Также необходимо зарегистрировать данный класс:

[Registrator] public class Registrator : RegistratorBase { #region Base Overrides

public override void RegisterUnity() { this.UnityContainer .RegisterType<IForumUserNamingStrategy, ForumUserNamingStrategy>(new ContainerControlledLifetimeManager()); }

#endregion }

Back to top