public async Task UpdateSectionEditAsync(SectionEdit newValues, IUser?currentUser) { var ds = DataSource(currentUser); var oldValues = (await ds.From("Sources.Section", new { newValues.SectionKey }).ToObject <SectionEdit>().ExecuteAsync()); await CheckPermissionSectionAsync(oldValues.SectionKey !.Value, currentUser); if (oldValues.PartKey != newValues.PartKey) { throw new InvalidOperationException("Cannot move section to a different book/part."); } if (newValues.ParentSectionKey.HasValue) { var parentPartKey = await ds.From("Sources.Section", new { SectionKey = newValues.ParentSectionKey }).ToInt32("PartKey").ExecuteAsync(); if (parentPartKey != newValues.PartKey) { throw new InvalidOperationException("Parent Section is not in the same book/part as this section."); } } if (string.IsNullOrWhiteSpace(newValues.PageReference)) { newValues.PageReference = null; } await ds.Update("Sources.Section", newValues).AsNonQuery().ClearCache().ExecuteAsync(); return; }
public async Task CreateSectionAsync(SectionEdit newValues, IUser?currentUser) { var ds = DataSource(currentUser); await CheckPermissionPartAsync(newValues.PartKey, currentUser); if (newValues.ParentSectionKey.HasValue) { var parentPartKey = await ds.From("Sources.Section", new { SectionKey = newValues.ParentSectionKey }).ToInt32("PartKey").ExecuteAsync(); if (parentPartKey != newValues.PartKey) { throw new InvalidOperationException("Parent Section is not in the same book/part as this section."); } } if (string.IsNullOrWhiteSpace(newValues.PageReference)) { newValues.PageReference = null; } await ds.Insert("Sources.Section", newValues).AsNonQuery().ClearCache().ExecuteAsync(); return; }
public ContentAccess CheckPermissions( IUmbracoEntity entity, IUser?user, IReadOnlyList <char> permissionsToCheck) { if (user == null) { throw new ArgumentNullException(nameof(user)); } if (entity == null) { return(ContentAccess.NotFound); } var hasPathAccess = user.HasContentPathAccess(entity, _entityService, _appCaches); if (hasPathAccess == false) { return(ContentAccess.Denied); } if (permissionsToCheck == null || permissionsToCheck.Count == 0) { return(ContentAccess.Granted); } //get the implicit/inherited permissions for the user for this path return(CheckPermissionsPath(entity.Path, user, permissionsToCheck) ? ContentAccess.Granted : ContentAccess.Denied); }
/// <summary> /// Get explicitly assigned permissions for a user and optional node ids /// </summary> /// <param name="user">User to retrieve permissions for</param> /// <param name="nodeIds">Specifying nothing will return all permissions for all nodes</param> /// <returns>An enumerable list of <see cref="EntityPermission" /></returns> public EntityPermissionCollection GetPermissions(IUser?user, params int[] nodeIds) { using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) { return(_userGroupRepository.GetPermissions(user?.Groups.ToArray(), true, nodeIds)); } }
public async Task <ImageDetail> GetImageDetail(int imageKey, IUser?currentUser) { var ds = DataSource(currentUser); var cacheKey = $"{nameof(ImageService)}.{nameof(GetImageDetail)}:{imageKey}"; var cachedResult = await ds.Cache.TryReadAsync <ImageDetail>(cacheKey); if (cachedResult.KeyFound) { return(cachedResult.Value); } var result = (await ds.From("Images.ImageDetail", new { imageKey }) .ToObject <ImageDetail>() .ExecuteAsync()); result.StorageBaseUrl = Settings.StorageBaseUrl; result.ImageStorageContainer = Settings.ImageStorageContainer; result.ThumbnailStorageContainer = Settings.ThumbnailStorageContainer; result.Sections.AddRange(await ds.From("Images.ImageSectionMapDetail", new { imageKey }).ToCollection <ImageDetail.SectionSummary>().ExecuteAsync()); await ds.Cache.WriteAsync(cacheKey, result, DefaultCachePolicy()); return(result); }
/// <inheritdoc /> protected override async Task <RetrieveEntityResult <Character> > RetrieveEntityAsync ( IUser?entityOwner, string?entityName, ICommandContext context, IServiceProvider services ) { var characterService = services.GetRequiredService <CharacterDiscordService>(); // Special case if (!string.Equals(entityName, "current", StringComparison.OrdinalIgnoreCase)) { return(await characterService.GetBestMatchingCharacterAsync ( context.Guild, entityOwner as IGuildUser, entityName )); } if (!(context.User is IGuildUser invoker)) { return(RetrieveEntityResult <Character> .FromError("The current user isn't a guild user.")); } return(await characterService.GetCurrentCharacterAsync(invoker)); }
private async Task GetSectionDetailCore(SectionDetail section, IUser?currentUser) { var(subsections, previousPage, nextPage, up, previousSection, nextSection, breadCrumb) = await GetSubsectionsAsync(section.PartKey, section.SectionKey, /*includeSubsectionWeapons, includeSubsectionPlays,*/ currentUser); breadCrumb.Insert(0, new AppLink() { Name = section.PartName, UrlFragment = section.PartUrlFragment }); breadCrumb.Insert(0, new AppLink() { Name = section.BookName, UrlFragment = section.BookUrlFragment }); section.Subsections.AddRange(subsections); section.PreviousPage = previousPage; section.NextPage = nextPage; section.Up = up; section.PreviousSection = previousSection; section.NextSection = nextSection; section.BreadCrumb = breadCrumb; section.Videos.AddRange(await GetSectionVideosAsync(section.SectionKey, currentUser)); section.Weapons.AddRange(await GetSectionWeaponsAsync(section.SectionKey, currentUser)); section.Plays.AddRange(await GetPlayDetailsForSectionAsync(section.SectionKey, currentUser)); //section.Translations.AddRange(await ds.From("Translations.SectionTranslationDetail", filter).ToCollection<SectionTranslationDetail>().ExecuteAsync()); //section.CanEdit = await CanEditBookAsync(section.BookKey, currentUser); }
public async Task GetRecentGames(IUser?user = null) { user ??= Context.User; var steamId = await _ids.Get(user.Id); if (!steamId.HasValue) { await TypingReplyAsync("I'm sorry, I don't know your steam ID. Please use `setid` to set it"); return; } var played = await _steamApi.GetRecentlyPlayedGames(steamId.Value); if (played == null) { await TypingReplyAsync("I'm sorry, I can't find your recently played games right now"); return; } var games = played.ToArray(); await DisplayItemList(games, () => "No games played recently", ls => $"{ls.Count} games played recently:", (a, i) => $"{i}. {a.Name}"); }
public async Task UserInfo(IUser? runner = null) { DatabaseUser databaseUser; if (runner is null) databaseUser = Database.GetUser(Context.User.Id); else databaseUser = Database.GetUser(runner.Id); var user = Client.GetUser(databaseUser.Id); var guildUser = Context.Guild?.GetUser(databaseUser.Id); var embedBuilder = MessagingUtils.GetShrimpbotEmbedBuilder(); embedBuilder.WithAuthor(user); embedBuilder.WithDescription(user.Status.ToString()); embedBuilder.AddField("General", $"**User ID**: {user.Id}\n" + $"**Created**: {user.CreatedAt}\n" + $"**Human?**: {!user.IsBot}"); if (guildUser != null) embedBuilder.AddField("This Server", $"**Nickname**: {guildUser.Nickname}\n" + $"**Joined**: {guildUser.JoinedAt}\n"); embedBuilder.AddField("ShrimpBot", $"**Money**: {Config.CurrencySymbol}{databaseUser.Money}\n" + $"**Cuteness**: {databaseUser.Cuteness}\n" + $"**Bot Permission Level**: {databaseUser.BotPermissions}\n"); await ReplyAsync(embed: embedBuilder.Build()); }
/// <summary> /// Authorize that the current user belongs to these groups /// </summary> /// <param name="currentUser"></param> /// <param name="groupAliases"></param> /// <returns></returns> public Attempt <string?> AuthorizeGroupAccess(IUser?currentUser, params string[] groupAliases) { if (currentUser?.IsAdmin() ?? false) { return(Attempt <string?> .Succeed()); } var existingGroups = _userService.GetUserGroupsByAlias(groupAliases); if (!existingGroups.Any()) { // We're dealing with new groups, // so authorization should be given to any user with access to Users section if (currentUser?.AllowedSections.Contains(Constants.Applications.Users) ?? false) { return(Attempt <string?> .Succeed()); } } var userGroups = currentUser?.Groups.Select(x => x.Alias).ToArray(); var missingAccess = groupAliases.Except(userGroups ?? Array.Empty <string>()).ToArray(); return(missingAccess.Length == 0 ? Attempt <string?> .Succeed() : Attempt.Fail("User is not a member of " + string.Join(", ", missingAccess))); }
/// <summary> /// Changes the users password /// </summary> /// <param name="changingPasswordModel">The changing password model</param> /// <returns> /// If the password is being reset it will return the newly reset password, otherwise will return an empty value /// </returns> public async Task <ActionResult <ModelWithNotifications <string?> >?> PostChangePassword( ChangingPasswordModel changingPasswordModel) { IUser?currentUser = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser; if (currentUser is null) { return(null); } changingPasswordModel.Id = currentUser.Id; // all current users have access to reset/manually change their password Attempt <PasswordChangedModel?> passwordChangeResult = await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _backOfficeUserManager); if (passwordChangeResult.Success) { // even if we weren't resetting this, it is the correct value (null), otherwise if we were resetting then it will contain the new pword var result = new ModelWithNotifications <string?>(passwordChangeResult.Result?.ResetPassword); result.AddSuccessNotification(_localizedTextService.Localize("user", "password"), _localizedTextService.Localize("user", "passwordChanged")); return(result); } if (passwordChangeResult.Result?.ChangeError?.MemberNames is not null) { foreach (var memberName in passwordChangeResult.Result.ChangeError.MemberNames) { ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage ?? string.Empty); } } return(ValidationProblem(ModelState)); }
protected void CheckPermissionLoggedIn(IUser?currentUser) { if (currentUser == null || currentUser.UserKey == 0) { throw new UnauthorizedAccessException("Please login."); } }
/// <summary> /// Performs a permissions check for the user to check if it has access to the node based on /// start node and/or permissions for the node /// </summary> /// <param name="user"></param> /// <param name="nodeId">The content to lookup, if the contentItem is not specified</param> /// <param name="media"></param> /// <returns></returns> public MediaAccess CheckPermissions(IUser?user, int nodeId, out IMedia?media) { if (user == null) { throw new ArgumentNullException(nameof(user)); } media = null; if (nodeId != Constants.System.Root && nodeId != Constants.System.RecycleBinMedia) { media = _mediaService.GetById(nodeId); } if (media == null && nodeId != Constants.System.Root && nodeId != Constants.System.RecycleBinMedia) { return(MediaAccess.NotFound); } var hasPathAccess = nodeId == Constants.System.Root ? user.HasMediaRootAccess(_entityService, _appCaches) : nodeId == Constants.System.RecycleBinMedia ? user.HasMediaBinAccess(_entityService, _appCaches) : user.HasPathAccess(media, _entityService, _appCaches); return(hasPathAccess ? MediaAccess.Granted : MediaAccess.Denied); }
public override async Task <TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services) { try { var ctx = (ICustomCommandContext)context; IUser?user = null; if (MentionUtils.TryParseUser(input, out ulong userId) || ulong.TryParse(input, out userId)) { if (userId == 0) { return(TypeReaderResult.FromError(CommandError.ParseFailed, Texts.CommandInvalidUserError)); } user ??= await ctx.GetUserAsync(userId).ConfigureAwait(false); } if (ctx.Guild is SocketGuild socketGuild) { user ??= await GetSocketGuildUserByName(socketGuild, input); user ??= await GetUserByBan(socketGuild, input); } Thread.CurrentThread.CurrentUICulture = ctx.BonusGuild?.Settings.CultureInfo ?? Constants.DefaultCultureInfo; return(user is { } ? TypeReaderResult.FromSuccess(user) : TypeReaderResult.FromError(CommandError.ParseFailed, Texts.CommandInvalidUserError)); }
public async Task UserInfoAsync(IUser?user = null) { // Use self if no user was specified. user ??= Context.User; string avatarUrl = user.GetAvatarUrl(); var embed = new EmbedBuilder() .WithTitle("User info") .WithAuthor(user.ToString(), avatarUrl) .WithColor(Config.Value.EmbedColor) .WithThumbnailUrl(avatarUrl) .WithFooter($"Created: {user.CreatedAt.ToString("R")}") .AddField( "ID", user.Id.ToString(), true) .AddField( "Bot", user.IsBot.ToString(), true) .AddField( "Presence", Enum.GetName(user.Status), true) .Build(); var components = new ComponentBuilder() .WithButton("Avatar direct link", style: ButtonStyle.Link, url: avatarUrl) .Build(); await RespondAsync(embed : embed, components : components); }
/// <summary> /// Authorize that the user is not changing to a start node that they don't have access to (including admins) /// </summary> /// <param name="currentUser"></param> /// <param name="currentContentStartId"></param> /// <param name="proposedContentStartId"></param> /// <param name="currentMediaStartId"></param> /// <param name="proposedMediaStartId"></param> /// <returns></returns> public Attempt <string?> AuthorizeStartNodeChanges(IUser?currentUser, int?currentContentStartId, int?proposedContentStartId, int?currentMediaStartId, int?proposedMediaStartId) { if (currentContentStartId != proposedContentStartId && proposedContentStartId.HasValue) { var content = _contentService.GetById(proposedContentStartId.Value); if (content != null) { if (currentUser?.HasPathAccess(content, _entityService, _appCaches) == false) { return(Attempt.Fail("Current user doesn't have access to the content path " + content.Path)); } } } if (currentMediaStartId != proposedMediaStartId && proposedMediaStartId.HasValue) { var media = _mediaService.GetById(proposedMediaStartId.Value); if (media != null) { if (currentUser?.HasPathAccess(media, _entityService, _appCaches) == false) { return(Attempt.Fail("Current user doesn't have access to the media path " + media.Path)); } } } return(Attempt <string?> .Succeed()); }
/// <inheritdoc/> protected override Task <bool> IsAuthorized(AuthorizationHandlerContext context, UserGroupRequirement requirement) { IUser?currentUser = _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser; var querystring = _httpContextAccessor.HttpContext?.Request.Query[requirement.QueryStringName]; if (querystring is null) { // Must succeed this requirement since we cannot process it. return(Task.FromResult(true)); } if (querystring.Value.Count == 0) { // Must succeed this requirement since we cannot process it. return(Task.FromResult(true)); } var intIds = querystring.Value.ToString().Split(Constants.CharArrays.Comma) .Select(x => int.TryParse(x, NumberStyles.Integer, CultureInfo.InvariantCulture, out var output) ? Attempt <int> .Succeed(output) : Attempt <int> .Fail()) .Where(x => x.Success).Select(x => x.Result).ToArray(); var authHelper = new UserGroupEditorAuthorizationHelper( _userService, _contentService, _mediaService, _entityService, _appCaches); Attempt <string?> isAuth = authHelper.AuthorizeGroupAccess(currentUser, intIds); return(Task.FromResult(isAuth.Success)); }
/// <inheritdoc /> protected override async Task <RetrieveEntityResult <Roleplay> > RetrieveEntityAsync ( IUser?entityOwner, string?entityName, ICommandContext context, IServiceProvider services ) { var roleplayService = services.GetRequiredService <RoleplayDiscordService>(); if (!(context.Channel is ITextChannel textChannel)) { return(RetrieveEntityResult <Roleplay> .FromError("The channel was not a text channel.")); } if (!entityName.IsNullOrWhitespace() && string.Equals(entityName, "current", StringComparison.OrdinalIgnoreCase)) { return(await roleplayService.GetActiveRoleplayAsync(textChannel)); } return(await roleplayService.GetBestMatchingRoleplayAsync ( (ITextChannel)context.Channel, context.Guild, entityOwner, entityName )); }
public IActionResult ExportMemberData(Guid key) { IUser?currentUser = _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser; if (currentUser?.HasAccessToSensitiveData() == false) { return(Forbid()); } MemberExportModel?member = ((MemberService)_memberService).ExportMember(key); if (member is null) { throw new NullReferenceException("No member found with key " + key); } var json = _jsonSerializer.Serialize(member); var fileName = $"{member.Name}_{member.Email}.txt"; // Set custom header so umbRequestHelper.downloadFile can save the correct filename HttpContext.Response.Headers.Add("x-filename", fileName); return(File(Encoding.UTF8.GetBytes(json), MediaTypeNames.Application.Octet, fileName)); }
public Task <List <VideoDetail> > GetSectionVideosAsync(int sectionKey, IUser?currentUser) { return(DataSource(currentUser) .From("Interpretations.VideoDetail", new { SectionKey = sectionKey }) .ToCollection <VideoDetail>() .ExecuteAsync()); }
public async Task ViewUserAsync(IUser?user = null) { var embed = new EmbedBuilder(); await AddUserInfo(embed, user ?? Context.User); await ReplyAsync(embed : embed.Build()); }
public async Task <BookDetail> GetBookDetailAsync(string bookSlug, IUser?currentUser) { var ds = DataSource(currentUser); var cacheKey = $"{nameof(BookService)}.{nameof(GetBookDetailAsync)}:{bookSlug}"; var cachedResult = await ds.Cache.TryReadAsync <BookDetail>(cacheKey); if (cachedResult.KeyFound) { return(cachedResult.Value); } var result = (await ds.From("Sources.BookDetail", new { BookSlug = bookSlug }) .ToObject <BookDetail>() .ReadOrCache($"{nameof(BookService)}.{nameof(GetBookDetailAsync)}:{bookSlug}", DefaultCachePolicy()) .ExecuteAsync()); result.AlternateNames.AddRange(await GetBookAlternateNamesAsync(result.BookKey, currentUser)); result.Authors.AddRange(await GetAuthorsByBookAsync(result.BookKey, currentUser)); result.Parts.AddRange(await GetBookPartsAsync(result.BookKey, currentUser)); result.Weapons.AddRange(await GetBookWeaponsAsync(result.BookKey, currentUser)); await ds.Cache.WriteAsync(cacheKey, result, DefaultCachePolicy()); return(result); }
/// <inheritdoc /> public IEnumerable <Tab <IDashboard> > GetDashboards(string section, IUser?currentUser) { var tabs = new List <Tab <IDashboard> >(); var tabId = 0; foreach (var dashboard in _dashboardCollection.Where(x => x.Sections.InvariantContains(section))) { // validate access if (currentUser is null || !CheckUserAccessByRules(currentUser, _sectionService, dashboard.AccessRules)) { continue; } if (dashboard.View?.InvariantEndsWith(".ascx") ?? false) { throw new NotSupportedException("Legacy UserControl (.ascx) dashboards are no longer supported."); } var dashboards = new List <IDashboard> { dashboard }; tabs.Add(new Tab <IDashboard> { Id = tabId++, Label = _localizedText.Localize("dashboardTabs", dashboard.Alias), Alias = dashboard.Alias, Properties = dashboards }); } return(tabs); }
public ActionResult<string[]> PostClearAvatar(int id) { IUser? found = _userService.GetUserById(id); if (found == null) { return NotFound(); } var filePath = found.Avatar; //if the filePath is already null it will mean that the user doesn't have a custom avatar and their gravatar is currently //being used (if they have one). This means they want to remove their gravatar too which we can do by setting a special value //for the avatar. if (filePath.IsNullOrWhiteSpace() == false) { found.Avatar = null; } else { //set a special value to indicate to not have any avatar found.Avatar = "none"; } _userService.Save(found); if (filePath.IsNullOrWhiteSpace() == false) { if (_mediaFileManager.FileSystem.FileExists(filePath!)) { _mediaFileManager.FileSystem.DeleteFile(filePath!); } } return found.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileManager, _imageUrlGenerator); }
public override async ValueTask <TypeParserResult <IUser> > ParseAsync(Parameter parameter, string value, RiasCommandContext context) { var cachedMemberTypeParser = await new CachedMemberTypeParser().ParseAsync(parameter, value, context); if (cachedMemberTypeParser.IsSuccessful) { return(TypeParserResult <IUser> .Successful(cachedMemberTypeParser.Value)); } var localization = context.ServiceProvider.GetRequiredService <Localization>(); IUser?user = null; if (Snowflake.TryParse(value, out var id)) { user = await context.ServiceProvider.GetRequiredService <Rias>().GetUserAsync(id); } if (user != null) { return(TypeParserResult <IUser> .Successful(user)); } if (parameter.IsOptional) { return(TypeParserResult <IUser> .Successful((CachedMember)parameter.DefaultValue)); } return(TypeParserResult <IUser> .Unsuccessful(localization.GetText(context.Guild?.Id, Localization.AdministrationUserNotFound))); }
/// <summary> /// Retrieves the named entity from the given user. /// </summary> /// <param name="entityOwner">The owner of the entity.</param> /// <param name="entityName">The name of the entity.</param> /// <param name="context">The context of the command.</param> /// <param name="services">The injected services.</param> /// <returns>A retrieval result which may or may not have succeeded.</returns> protected abstract Task <RetrieveEntityResult <TEntity> > RetrieveEntityAsync ( IUser?entityOwner, string?entityName, ICommandContext context, IServiceProvider services );
public async Task <Result> ListOwnedRoleplaysAsync(IUser?discordUser = null) { discordUser ??= _context.User; var roleplays = await _discordRoleplays.QueryRoleplaysAsync ( q => q .Where(rp => rp.Server.DiscordID == _context.GuildID.Value) .Where(rp => rp.Owner.DiscordID == discordUser.ID) ); var pages = PaginatedEmbedFactory.SimpleFieldsFromCollection ( roleplays, r => r.Name, r => r.GetSummaryOrDefault(), "You don't have any roleplays." ); return((Result)await _feedback.SendContextualPaginatedMessageAsync ( _context.User.ID, pages, ct : this.CancellationToken )); }
private void WriteAudit(string performingId, string?affectedId, string ipAddress, string eventType, string eventDetails, string?affectedDetails = null) { IUser?performingUser = null; if (int.TryParse(performingId, NumberStyles.Integer, CultureInfo.InvariantCulture, out int asInt)) { performingUser = _userService.GetUserById(asInt); } var performingDetails = performingUser == null ? $"User UNKNOWN:{performingId}" : $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}"; if (!int.TryParse(performingId, NumberStyles.Integer, CultureInfo.InvariantCulture, out int performingIdAsInt)) { performingIdAsInt = 0; } if (!int.TryParse(affectedId, NumberStyles.Integer, CultureInfo.InvariantCulture, out int affectedIdAsInt)) { affectedIdAsInt = 0; } WriteAudit(performingIdAsInt, performingDetails, affectedIdAsInt, ipAddress, eventType, eventDetails, affectedDetails); }
public async Task <bool> BanAsync(IUser user, IUser?instigator = null, string?reason = null, DateTime?expireDate = null) { expireDate ??= DateTime.MaxValue; var duration = (expireDate.Value - DateTime.Now).TotalSeconds; if (duration <= 0) { return(false); } reason ??= m_StringLocalizer["ban_default"]; var data = await m_UserDataStore.GetUserDataAsync(user.Id, user.Type); if (data != null) { data.BanInfo = new BanData(reason, instigator, expireDate); await m_UserDataStore.SetUserDataAsync(data); } await UniTask.SwitchToMainThread(); Provider.ban(new CSteamID(ulong.Parse(user.Id)), reason, duration > uint.MaxValue ? SteamBlacklist.PERMANENT : (uint)duration); return(true); }
private async Task CheckStaleData(ActionExecutingContext actionContext) { using (ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true)) { if (actionContext?.HttpContext.Request == null || actionContext.HttpContext.User?.Identity == null) { return; } // don't execute if it's already been done if (!(_requestCache.Get(nameof(CheckIfUserTicketDataIsStaleFilter)) is null)) { return; } if (actionContext.HttpContext.User.Identity is not ClaimsIdentity identity) { return; } var id = identity.GetId(); if (id is null) { return; } IUser?user = _userService.GetUserById(id.Value); if (user == null) { return; } // a list of checks to execute, if any of them pass then we resync var checks = new Func <bool>[] { () => user.Username != identity.GetUsername(), () => { CultureInfo culture = user.GetUserCulture(_localizedTextService, _globalSettings); return(culture != null && culture.ToString() != identity.GetCultureString()); }, () => user.AllowedSections.UnsortedSequenceEqual(identity.GetAllowedApplications()) == false, () => user.Groups.Select(x => x.Alias).UnsortedSequenceEqual(identity.GetRoles()) == false, () => { var startContentIds = user.CalculateContentStartNodeIds(_entityService, _appCaches); return(startContentIds.UnsortedSequenceEqual(identity.GetStartContentNodes()) == false); }, () => { var startMediaIds = user.CalculateMediaStartNodeIds(_entityService, _appCaches); return(startMediaIds.UnsortedSequenceEqual(identity.GetStartMediaNodes()) == false); } }; if (checks.Any(check => check())) { await ReSync(user, actionContext); } } }