コード例 #1
0
ファイル: CategoryService.cs プロジェクト: turenc/Plato
        public async Task <IPagedResults <TModel> > GetResultsAsync(CategoryIndexOptions options, PagerOptions pager)
        {
            if (options == null)
            {
                options = new CategoryIndexOptions();
            }

            if (pager == null)
            {
                pager = new PagerOptions();
            }

            // Ensure we have a sort column is non is specified
            if (options.Sort == SortBy.Auto)
            {
                options.Sort  = SortBy.SortOrder;
                options.Order = OrderBy.Asc;
            }

            // Get authenticated user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // Return tailored results
            return(await _categoryStore.QueryAsync()
                   .Take(pager.Page, pager.Size)
                   .Configure(_configureDb)
                   .Select <CategoryQueryParams>(q =>
            {
                // ----------------
                // Set current authenticated user id
                // This is required for various security checks
                // ----------------

                q.UserId.Equals(user?.Id ?? 0);

                // ----------------
                // Basic parameters
                // ----------------

                // FeatureId
                if (options.FeatureId > 0)
                {
                    q.FeatureId.Equals(options.FeatureId);
                }

                // ----------------
                // Additional parameter configuration
                // ----------------

                _configureParams?.Invoke(q);
            })
                   .OrderBy(options.Sort.ToString(), options.Order)
                   .ToList());
        }
コード例 #2
0
        async Task <IList <Role> > GetRolesToExamine(IIdentity identity)
        {
            var user = await _contextFacade.GetAuthenticatedUserAsync(identity);

            // Are the roles available in our scoped cache?
            if (_scopedUserRoles.ContainsKey(user?.Id ?? 0))
            {
                return(_scopedUserRoles[user?.Id ?? 0]);
            }

            // Add the roles to our scoped cache
            if (user != null)
            {
                if (!_scopedUserRoles.ContainsKey(user.Id))
                {
                    var roles = await _platoRoleStore.GetRolesByUserIdAsync(user.Id);

                    if (roles != null)
                    {
                        _scopedUserRoles.TryAdd(user.Id, roles);
                    }
                    else
                    {
                        // If the user does not belong to any roles ensure we check the default member role
                        var memberRole = await _platoRoleStore.GetByNameAsync(DefaultRoles.Member);

                        if (memberRole != null)
                        {
                            _scopedUserRoles.TryAdd(user.Id, new List <Role>()
                            {
                                memberRole
                            });
                        }
                    }
                }
            }
            else
            {
                if (!_scopedUserRoles.ContainsKey(0))
                {
                    var anonymousRole = await _platoRoleStore.GetByNameAsync(DefaultRoles.Anonymous);

                    if (anonymousRole != null)
                    {
                        _scopedUserRoles.TryAdd(0, new List <Role>()
                        {
                            anonymousRole
                        });
                    }
                }
            }

            return(_scopedUserRoles[user?.Id ?? 0]);
        }
コード例 #3
0
        public override async Task <IViewProviderResult> BuildEditAsync(Article entity, IViewProviderContext context)
        {
            if (entity == null)
            {
                return(await BuildIndexAsync(new Article(), context));
            }

            var entityId    = entity.Id;
            var contentGuid = string.Empty;
            var user        = await _contextFacade.GetAuthenticatedUserAsync();

            // Use posted guid if available
            var postedGuid = PostedGuidValue();

            if (!string.IsNullOrEmpty(postedGuid))
            {
                contentGuid = postedGuid;
            }
            else
            {
                // Create a new temporary 256 bit unique ASCII string
                var key = _keyGenerator.GenerateKey(o =>
                {
                    o.MaxLength        = 32;
                    o.UniqueIdentifier = $"{user.Id.ToString()}-{entity.Id.ToString()}";
                });
                // Convert to 256 bit / 32 character hexadecimal string
                contentGuid = key.ToStream(Encoding.ASCII).ToMD5().ToHex();
            }

            return(Views(
                       View <EntityAttachmentOptions>("Attachments.Edit.Sidebar", model =>
            {
                model.EntityId = entityId;
                model.Guid = contentGuid;
                model.GuidHtmlName = GuidHtmlName;
                return model;
            }).Zone("sidebar").Order(1)
                       ));
        }
コード例 #4
0
ファイル: TopicViewProvider.cs プロジェクト: vdandrade/Plato
        async Task HydrateModeratorContext(Topic topic, IViewProviderContext context)
        {
            // Add moderator to context
            if (context.Controller.HttpContext.Items[typeof(Moderator)] == null)
            {
                var user = await _contextFacade.GetAuthenticatedUserAsync();

                if (user != null)
                {
                    context.Controller.HttpContext.Items[typeof(Moderator)] = await GetModerator(user, topic);
                }
            }
        }
コード例 #5
0
ファイル: UserReputationManager.cs プロジェクト: radtek/Plato
        public async Task <ICommandResult <UserReputation> > CreateAsync(UserReputation model)
        {
            // Validate
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            if (model.Id > 0)
            {
                throw new ArgumentOutOfRangeException(nameof(model.Id));
            }

            if (String.IsNullOrEmpty(model.Name))
            {
                throw new ArgumentNullException(nameof(model.Name));
            }

            // Configure model
            if (model.CreatedUserId == 0)
            {
                var user = await _contextFacade.GetAuthenticatedUserAsync();

                model.CreatedUserId = user?.Id ?? 0;
            }

            // Invoke UserReputationCreating subscriptions
            foreach (var handler in _broker.Pub <UserReputation>(this, "UserReputationCreating"))
            {
                model = await handler.Invoke(new Message <UserReputation>(model, this));
            }

            var result = new CommandResult <UserReputation>();

            var newUserReputation = await _userReputationStore.CreateAsync(model);

            if (newUserReputation != null)
            {
                // Invoke UserReputationCreated subscriptions
                foreach (var handler in _broker.Pub <UserReputation>(this, "UserReputationCreated"))
                {
                    newUserReputation = await handler.Invoke(new Message <UserReputation>(newUserReputation, this));
                }

                // Return success
                return(result.Success(newUserReputation));
            }

            return(result.Failed(new CommandError("An unknown error occurred whilst attempting to create the user reputation entry.")));
        }
コード例 #6
0
        public async Task <TModel> GetResultAsync()
        {
            // Get authenticated user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // Return tailored results
            var results = await _entityStore.QueryAsync()
                          .Take(1, false)
                          .Configure(_configureDb)
                          .Select <EntityQueryParams>(q =>
            {
                // ----------------
                // Set current authenticated user id
                // This is required for various security checks
                // i.e. Role based security & displaying private entities
                // ----------------

                q.UserId.Equals(user?.Id ?? 0);

                // ----------------
                // Additional parameter configuration
                // ----------------

                _configureParams?.Invoke(q);
            })
                          .ToList();

            if (results?.Data != null)
            {
                if (results.Data.Count > 0)
                {
                    return(results.Data[0] as TModel);
                }
            }

            return(null);
        }
コード例 #7
0
        public override async Task <IViewProviderResult> BuildDisplayAsync(Doc entity, IViewProviderContext updater)
        {
            if (entity == null)
            {
                return(await BuildIndexAsync(new Doc(), updater));
            }

            var isFollowing = false;
            var followType  = FollowTypes.Doc;

            var user = await _contextFacade.GetAuthenticatedUserAsync();

            if (user != null)
            {
                var entityFollow = await _followStore.SelectByNameThingIdAndCreatedUserId(
                    followType.Name,
                    entity.Id,
                    user.Id);

                if (entityFollow != null)
                {
                    isFollowing = true;
                }
            }

            return(Views(
                       View <FollowViewModel>("Follow.Display.Tools", model =>
            {
                model.FollowType = followType;
                model.ThingId = entity.Id;
                model.IsFollowing = isFollowing;
                model.Permission = Permissions.FollowDocs;
                return model;
            }).Zone("tools").Order(-4)
                       ));
        }
コード例 #8
0
        public async Task OnActionExecutingAsync(ResultExecutingContext context)
        {
            // Not a view result
            if (!(context.Result is ViewResult))
            {
                return;
            }

            // Tracking cookie already exists, simply execute the controller result
            if (_active)
            {
                return;
            }

            // Get authenticated user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // Not authenticated, simply execute the controller result
            if (user == null)
            {
                return;
            }

            user.Visits           += 1;
            user.VisitsUpdatedDate = DateTimeOffset.UtcNow;
            user.LastLoginDate     = DateTimeOffset.UtcNow;

            var result = await _userStore.UpdateAsync(user);

            if (result != null)
            {
                // Award visit reputation
                await _userReputationAwarder.AwardAsync(new Reputation("Visit", 1), result.Id, "Unique Visit");

                // Set client cookie to ensure update does not
                // occur again for as long as the cookie exists
                _cookieBuilder
                .Contextulize(context.HttpContext)
                .Append(
                    _cookieName,
                    true.ToString(),
                    new CookieOptions
                {
                    HttpOnly = true,
                    Expires  = DateTime.Now.AddMinutes(_sessionLength)
                });
            }
        }
コード例 #9
0
        public override async Task <IViewProviderResult> BuildUpdateAsync(TagAdmin tag, IViewProviderContext context)
        {
            if (tag == null)
            {
                throw new ArgumentNullException(nameof(tag));
            }

            if (tag.IsNewTag)
            {
                return(await BuildEditAsync(tag, context));
            }

            var model = new EditTagViewModel();

            if (!await context.Updater.TryUpdateModelAsync(model))
            {
                return(await BuildEditAsync(tag, context));
            }

            model.Name        = model.Name?.Trim();
            model.Description = model.Description?.Trim();

            if (context.Updater.ModelState.IsValid)
            {
                var user = await _contextFacade.GetAuthenticatedUserAsync();

                if (user == null)
                {
                    return(await BuildEditAsync(tag, context));
                }

                // Update tag
                tag.Name        = model.Name;
                tag.Description = model.Description;

                // Persist changes
                var result = await _tagManager.UpdateAsync((Tag)tag);

                foreach (var error in result.Errors)
                {
                    context.Updater.ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            return(await BuildEditAsync(tag, context));
        }
コード例 #10
0
        public async Task <IActionResult> Delete(string id)
        {
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            if (user == null)
            {
                return(Unauthorized());
            }

            var ok = int.TryParse(id, out int categoryId);

            if (!ok)
            {
                return(NotFound());
            }

            var file = await _fileStore.GetByIdAsync(categoryId);

            if (file == null)
            {
                return(NotFound());
            }

            var deletePermission = file.CreatedUserId == user.Id
                 ? Permissions.DeleteOwnFiles
                 : Permissions.DeleteAnyFile;

            // Ensure we have permission
            if (!await _authorizationService.AuthorizeAsync(User, deletePermission))
            {
                return(Unauthorized());
            }

            var result = await _fileManager.DeleteAsync(file);

            if (result.Succeeded)
            {
                _alerter.Success(T["File Deleted Successfully"]);
            }
            else
            {
                _alerter.Danger(T["Could not delete the file"]);
            }

            return(RedirectToAction(nameof(Index)));
        }
コード例 #11
0
        async Task <ICommandResultBase> InstallLabelAsync(IShellFeature feature, int sortOrder = 0)
        {
            // Validate

            if (feature == null)
            {
                throw new ArgumentNullException(nameof(feature));
            }

            if (string.IsNullOrEmpty(feature.ModuleId))
            {
                throw new ArgumentNullException(nameof(feature.ModuleId));
            }

            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // Our result
            var result = new CommandResultBase();

            var foreColor = "#ffffff";
            var backColor = $"#{_colorProvider.GetColor()}";

            var categoryResult = await _labelManager.CreateAsync(new LabelBase()
            {
                FeatureId     = feature.Id,
                ParentId      = 0,
                Name          = $"Example Label {_random.Next(0, 2000).ToString()}",
                Description   = $"This is an example label description.",
                ForeColor     = foreColor,
                BackColor     = backColor,
                SortOrder     = sortOrder,
                CreatedUserId = user?.Id ?? 0,
                CreatedDate   = DateTimeOffset.UtcNow
            });

            if (!categoryResult.Succeeded)
            {
                return(result.Failed(result.Errors.ToArray()));
            }

            return(result.Success());
        }
コード例 #12
0
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            // Client & server
            var utcDateTime = Utc ?? DateTimeOffset.UtcNow;
            var user        = await _contextFacade.GetAuthenticatedUserAsync();

            // Get local date time, only apply client offset if user is authenticated
            var localDateTime = await _localDateTimeProvider.GetLocalDateTimeAsync(new LocalDateTimeOptions()
            {
                UtcDateTime               = utcDateTime,
                ServerTimeZone            = _settings?.TimeZone,
                ClientTimeZone            = user?.TimeZone,
                ApplyClientTimeZoneOffset = user != null
            });

            // Date format
            var dateTimeFormat = GetDefaultDateTimeFormat();

            // We always need the full regular date for the title attribute (not the pretty date)
            var formattedDateTime = localDateTime.DateTime.ToString(dateTimeFormat);

            // Build output

            var builder = new HtmlContentBuilder();

            output.TagName = "span";
            output.TagMode = TagMode.StartTagAndEndTag;

            if (!output.Attributes.ContainsName("title"))
            {
                output.Attributes.Add("title", formattedDateTime);
            }

            if (!output.Attributes.ContainsName("data-toggle"))
            {
                output.Attributes.Add("data-toggle", "tooltip");
            }

            output.Content.SetHtmlContent(Pretty
                ? builder.AppendHtml(utcDateTime.DateTime.ToPrettyDate(dateTimeFormat))
                : builder.AppendHtml(formattedDateTime));
        }
コード例 #13
0
        public override async Task <IViewProviderResult> BuildDisplayAsync(Label label, IViewProviderContext context)
        {
            var existingTag = await _labelStore.GetByIdAsync(label.Id);

            if (existingTag == null)
            {
                return(await BuildIndexAsync(label, context));
            }

            var followType  = FollowTypes.Label;
            var isFollowing = false;

            var currentUser = await _contextFacade.GetAuthenticatedUserAsync();

            if (currentUser != null)
            {
                var existingFollow = await _followStore.SelectByNameThingIdAndCreatedUserId(
                    followType.Name,
                    existingTag.Id,
                    currentUser.Id);

                if (existingFollow != null)
                {
                    isFollowing = true;
                }
            }

            return(Views(
                       View <FollowViewModel>("Follow.Display.Tools", model =>
            {
                model.FollowType = followType;
                model.ThingId = existingTag.Id;
                model.IsFollowing = isFollowing;
                model.Permission = Permissions.FollowDiscussLabels;
                return model;
            }).Zone("header-right").Order(-4)
                       ));
        }
コード例 #14
0
ファイル: WebApiOptionsFactory.cs プロジェクト: mrs2020/Plato
        async Task <string> GetApiKey()
        {
            var settings = await _contextFacade.GetSiteSettingsAsync();

            if (settings == null)
            {
                return(string.Empty);
            }

            var user = await _contextFacade.GetAuthenticatedUserAsync();

            if (user == null)
            {
                return(settings.ApiKey);
            }

            if (String.IsNullOrWhiteSpace(user.ApiKey))
            {
                return(settings.ApiKey);
            }

            return($"{settings.ApiKey}:{user.ApiKey}");
        }
コード例 #15
0
ファイル: AdminViewProvider.cs プロジェクト: radtek/Plato
        public override async Task <IViewProviderResult> BuildEditAsync(File file, IViewProviderContext context)
        {
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // Add Files
            ShareFileDialogViewModel viewModel = null;

            if (file.Id == 0)
            {
                return(default(IViewProviderResult));
            }

            // Edit File

            viewModel = new ShareFileDialogViewModel()
            {
                File = file
            };

            return(Views(
                       View <ShareFileDialogViewModel>("Admin.ShareFile.Sidebar", model => viewModel).Zone("content-right").Order(10)
                       ));
        }
コード例 #16
0
ファイル: ProfileViewProvider.cs プロジェクト: tchigher/plato
        public override async Task <IViewProviderResult> BuildDisplayAsync(Profile discuss, IViewProviderContext context)
        {
            var user = await _platoUserStore.GetByIdAsync(discuss.Id);

            if (user == null)
            {
                return(await BuildIndexAsync(discuss, context));
            }

            var followType  = FollowTypes.User;
            var isFollowing = false;

            var currentUser = await _contextFacade.GetAuthenticatedUserAsync();

            if (currentUser != null)
            {
                var existingFollow = await _followStore.SelectByNameThingIdAndCreatedUserId(
                    followType.Name,
                    user.Id,
                    currentUser.Id);

                if (existingFollow != null)
                {
                    isFollowing = true;
                }
            }

            return(Views(
                       View <FollowViewModel>("Follow.Display.Tools", model =>
            {
                model.FollowType = followType;
                model.ThingId = user.Id;
                model.IsFollowing = isFollowing;
                return model;
            }).Zone("tools").Order(1)
                       ));
        }
コード例 #17
0
        // -----------------
        // Get User
        // -----------------

        public async Task <IActionResult> GetEntity(EntityOptions opts)
        {
            if (opts == null)
            {
                opts = new EntityOptions();
            }

            if (opts.Id <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(opts.Id));
            }

            // Get authenticated user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // Get entity checking to ensure the entity is visible
            var entities = await _entityStore.QueryAsync()
                           .Select <EntityQueryParams>(q =>
            {
                q.UserId.Equals(user?.Id ?? 0);
                q.Id.Equals(opts.Id);
                q.HideSpam.True();
                q.HideHidden.True();
                q.HideDeleted.True();
                q.HidePrivate.True();
            })
                           .ToList();

            // Ensure entity exists
            if (entities?.Data == null)
            {
                return(View());
            }

            // Return view
            return(View(entities.Data[0]));
        }
コード例 #18
0
ファイル: DocViewProvider.cs プロジェクト: vdandrade/Plato
        public override async Task <IViewProviderResult> BuildDisplayAsync(Doc entity, IViewProviderContext updater)
        {
            if (entity == null)
            {
                return(await BuildIndexAsync(new Doc(), updater));
            }

            var isStarred = false;
            var starType  = StarTypes.Doc;

            var user = await _contextFacade.GetAuthenticatedUserAsync();

            if (user != null)
            {
                var entityStar = await _starStore.SelectByNameThingIdAndCreatedUserId(
                    starType.Name,
                    entity.Id,
                    user.Id);

                if (entityStar != null)
                {
                    isStarred = true;
                }
            }

            return(Views(
                       View <StarViewModel>("Star.Display.Tools", model =>
            {
                model.StarType = starType;
                model.ThingId = entity.Id;
                model.IsStarred = isStarred;
                model.TotalStars = entity.TotalStars;
                model.Permission = Permissions.StarDocs;
                return model;
            }).Zone("tools").Order(-5)
                       ));
        }
コード例 #19
0
        protected override async Task HandleRequirementAsync(
            AuthorizationHandlerContext context,
            PermissionRequirement requirement)
        {
            if (context.HasSucceeded)
            {
                // This handler is not revoking any pre-existing grants.
                return;
            }

            // The resource represents the category we are checking against
            // For moderator permissions we always need a resource to test
            if (context.Resource == null)
            {
                return;
            }

            // We always need to be authenticated for moderator permissions to apply
            if (!context.User.Identity.IsAuthenticated)
            {
                return;
            }

            // Ensure we can convert our resource Id
            var validChannel = int.TryParse(context.Resource.ToString(), out var categoryId);

            if (!validChannel)
            {
                return;
            }

            // Get all moderators
            var moderators = await _moderatorStore
                             .QueryAsync()
                             .ToList();

            // No need to check permissions if we don't have any moderators
            if (moderators == null)
            {
                return;
            }

            // Get supplied user
            var user = await _contextFacade.GetAuthenticatedUserAsync(context.User.Identity);

            // We need a user to perform access checks against
            if (user == null)
            {
                return;
            }

            // Get all moderator entries for given user and resource
            var userEntries = moderators.Data
                              .Where(m => m.UserId == user.Id & m.CategoryId == categoryId)
                              .ToList();

            // No moderator entries for the user and resource
            if (!userEntries.Any())
            {
                return;
            }

            // Reduce our user entries to only parents of current resource we are checking

            var moderatorsToExamine = new List <Moderator>();

            foreach (var moderator in userEntries)
            {
                moderatorsToExamine.Add(moderator);
            }

            // Accumulate the set of permissions that would satisfy the access check
            var grantingNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            // Accumulate permissions implied by supplied permission
            ImpliedPermissionNames(requirement.Permission, grantingNames);

            // Accumulate permissions that imply supplied permission
            var permissions = _permissionsManager.GetPermissions();

            if (permissions != null)
            {
                InferredPermissionNames(requirement.Permission, permissions.ToList(), grantingNames);
            }

            // Determine if  we satisfy any of the accumulated permissions
            foreach (var moderator in moderatorsToExamine)
            {
                foreach (var claim in moderator.Claims)
                {
                    if (!String.Equals(claim.ClaimType, ModeratorPermission.ClaimTypeName,
                                       StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    var permissionName = claim.ClaimValue;
                    if (grantingNames.Contains(permissionName))
                    {
                        context.Succeed(requirement);
                        return;
                    }
                }
            }
        }
コード例 #20
0
ファイル: QuestionViewProvider.cs プロジェクト: radtek/Plato
        public override async Task <IViewProviderResult> BuildUpdateAsync(Question question, IViewProviderContext context)
        {
            // Ensure entity exists before attempting to update
            var entity = await _entityStore.GetByIdAsync(question.Id);

            if (entity == null)
            {
                return(await BuildIndexAsync(question, context));
            }

            // Validate model
            if (await ValidateModelAsync(question, context.Updater))
            {
                // Get selected labels
                //var labelsToAdd = GetLabelsToAdd();
                var labelsToAdd = await GetLabelsToAddAsync();

                // Build labels to remove
                var labelsToRemove = new List <EntityLabel>();
                foreach (var entityLabel in await GetEntityLabelsByEntityIdAsync(question.Id))
                {
                    // Entry already exists remove from labels to add
                    if (labelsToAdd.Contains(entityLabel.LabelId))
                    {
                        labelsToAdd.Remove(entityLabel.LabelId);
                    }
                    else
                    {
                        // Entry does NOT exist in labels to add ensure it's removed
                        labelsToRemove.Add(entityLabel);
                    }
                }

                // Remove entity labels
                foreach (var entityLabel in labelsToRemove)
                {
                    var result = await _entityLabelManager.DeleteAsync(entityLabel);

                    if (!result.Succeeded)
                    {
                        foreach (var error in result.Errors)
                        {
                            context.Updater.ModelState.AddModelError(string.Empty, error.Description);
                        }
                    }
                }

                // Get authenticated user
                var user = await _contextFacade.GetAuthenticatedUserAsync();

                // Add new entity labels
                foreach (var labelId in labelsToAdd)
                {
                    var result = await _entityLabelManager.CreateAsync(new EntityLabel()
                    {
                        EntityId      = question.Id,
                        LabelId       = labelId,
                        CreatedUserId = user?.Id ?? 0,
                        CreatedDate   = DateTime.UtcNow
                    });

                    if (!result.Succeeded)
                    {
                        foreach (var error in result.Errors)
                        {
                            context.Updater.ModelState.AddModelError(string.Empty, error.Description);
                        }
                    }

                    // Ensure we clear our labels cache to return new associations
                    _cacheManager.CancelTokens(typeof(LabelStore <Label>));
                }
            }

            return(await BuildEditAsync(question, context));
        }
コード例 #21
0
        public override async Task <IViewProviderResult> BuildUpdateAsync(Comment comment, IViewProviderContext context)
        {
            // Ensure entity reply exists before attempting to update
            var entity = await _replyStore.GetByIdAsync(comment.Id);

            if (entity == null)
            {
                return(await BuildIndexAsync(comment, context));
            }

            // Validate model
            if (await ValidateModelAsync(comment, context.Updater))
            {
                // Get selected tags
                var tagsToAdd = await GetTagsToAddAsync();

                // Build tags to remove
                var tagsToRemove = new List <EntityTag>();

                // Iterate over existing tags
                var existingTags = await GetEntityTagsByEntityReplyIdAsync(comment.Id);

                if (existingTags != null)
                {
                    foreach (var entityTag in existingTags)
                    {
                        // Is our existing tag in our list of tags to add
                        var existingTag = tagsToAdd.FirstOrDefault(t => t.Id == entityTag.TagId);
                        if (existingTag != null)
                        {
                            tagsToAdd.Remove(existingTag);
                        }
                        else
                        {
                            // Entry no longer exist in tags so ensure it's removed
                            tagsToRemove.Add(entityTag);
                        }
                    }
                }

                // Remove entity tags
                foreach (var entityTag in tagsToRemove)
                {
                    var result = await _entityTagManager.DeleteAsync(entityTag);

                    if (!result.Succeeded)
                    {
                        foreach (var error in result.Errors)
                        {
                            context.Updater.ModelState.AddModelError(string.Empty, error.Description);
                        }
                    }
                }

                // Get authenticated user
                var user = await _contextFacade.GetAuthenticatedUserAsync();

                // Add new entity labels
                foreach (var tag in tagsToAdd)
                {
                    var result = await _entityTagManager.CreateAsync(new EntityTag()
                    {
                        EntityId      = comment.EntityId,
                        EntityReplyId = comment.Id,
                        TagId         = tag.Id,
                        CreatedUserId = user?.Id ?? 0,
                        CreatedDate   = DateTime.UtcNow
                    });

                    if (!result.Succeeded)
                    {
                        foreach (var error in result.Errors)
                        {
                            context.Updater.ModelState.AddModelError(string.Empty, error.Description);
                        }
                    }
                }
            }

            return(await BuildEditAsync(comment, context));
        }
コード例 #22
0
        // ----------

        async Task <ICommandResultBase> InstallInternalAsync(IShellFeature feature)
        {
            // Validate

            if (feature == null)
            {
                throw new ArgumentNullException(nameof(feature));
            }

            if (string.IsNullOrEmpty(feature.ModuleId))
            {
                throw new ArgumentNullException(nameof(feature.ModuleId));
            }

            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // Get all feature tags
            var labels = await _labelStore.QueryAsync()
                         .Select <LabelQueryParams>(Q =>
            {
                Q.FeatureId.Equals(feature.Id);
            })
                         .ToList();

            // Associate every tag with at least 1 entity

            var output = new CommandResultBase();

            if (labels != null)
            {
                var entities = await _entityStore.QueryAsync()
                               .Select <EntityQueryParams>(q =>
                {
                    q.FeatureId.Equals(feature.Id);
                })
                               .ToList();

                var alreadyAdded = new Dictionary <int, Entity>();
                foreach (var label in labels?.Data)
                {
                    var randomEntities = GetRandomEntities(entities?.Data, alreadyAdded);
                    if (randomEntities == null)
                    {
                        return(output.Success());
                    }
                    foreach (var entity in randomEntities)
                    {
                        var result = await _entityLabelManager.CreateAsync(new EntityLabel()
                        {
                            EntityId      = entity.Id,
                            LabelId       = label.Id,
                            CreatedUserId = user?.Id ?? 0,
                            CreatedDate   = DateTime.UtcNow
                        });

                        if (!result.Succeeded)
                        {
                            return(output.Failed(result.Errors.ToArray()));
                        }
                    }
                }
            }

            return(output.Success());
        }
コード例 #23
0
        public override async Task <IViewProviderResult> BuildIndexAsync(Category category, IViewProviderContext context)
        {
            // Get category Id
            var categoryId = 0;

            if (category != null)
            {
                categoryId = category.Id;
            }

            // Get follow type
            var followType = categoryId == 0
                ? FollowTypes.AllCategories
                : FollowTypes.Category;

            // Get permission
            var permission = categoryId == 0
                ? Follow.Permissions.FollowIdeaCategories
                : Follow.Permissions.FollowIdeaCategory;

            // Get thingId if available
            var thingId = 0;

            if (categoryId > 0)
            {
                var existingCategory = await _categoryStore.GetByIdAsync(categoryId);

                if (existingCategory != null)
                {
                    thingId = existingCategory.Id;
                }
            }

            // Are we already following?
            var isFollowing = false;
            var currentUser = await _contextFacade.GetAuthenticatedUserAsync();

            if (currentUser != null)
            {
                var existingFollow = await _followStore.SelectByNameThingIdAndCreatedUserId(
                    followType.Name,
                    thingId,
                    currentUser.Id);

                if (existingFollow != null)
                {
                    isFollowing = true;
                }
            }

            return(Views(
                       View <FollowViewModel>("Follow.Display.Tools", model =>
            {
                model.FollowType = followType;
                model.ThingId = thingId;
                model.IsFollowing = isFollowing;
                model.Permission = permission;
                return model;
            }).Zone("tools").Order(-4)
                       ));
        }
コード例 #24
0
ファイル: HomeController.cs プロジェクト: mrs2020/Plato
        public async Task <IActionResult> ToAnswer(string id)
        {
            // Get authenticated user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // We need to be authenticated
            if (user == null)
            {
                return(Unauthorized());
            }

            // Ensure we have a valid id
            var ok = int.TryParse(id, out var replyId);

            if (!ok)
            {
                return(NotFound());
            }

            var reply = await _entityReplyStore.GetByIdAsync(replyId);

            if (reply == null)
            {
                return(NotFound());
            }

            var entity = await _entityStore.GetByIdAsync(reply.EntityId);

            // Ensure the entity exists
            if (entity == null)
            {
                return(NotFound());
            }

            // Get permission
            var permission = entity.CreatedUserId == user.Id
                ? Permissions.MarkOwnRepliesAnswer
                : Permissions.MarkAnyReplyAnswer;

            // Ensure we have permission
            if (!await _authorizationService.AuthorizeAsync(User, entity.CategoryId, permission))
            {
                return(Unauthorized());
            }

            // Update reply
            reply.ModifiedUserId = user?.Id ?? 0;
            reply.ModifiedDate   = DateTimeOffset.UtcNow;
            reply.IsAnswer       = true;

            // Save changes and return results
            var result = await _replyManager.UpdateAsync(reply);

            if (result.Succeeded)
            {
                await UpdateEntityAsync(entity);

                _alerter.Success(T["Marked As Answer Successfully"]);
            }
            else
            {
                _alerter.Danger(T["Could not mark the reply as an answer"]);
            }

            // Redirect back to reply
            return(Redirect(_contextFacade.GetRouteUrl(new RouteValueDictionary()
            {
                ["area"] = "Plato.Questions",
                ["controller"] = "Home",
                ["action"] = "Reply",
                ["opts.id"] = entity.Id,
                ["opts.alias"] = entity.Alias,
                ["opts.replyId"] = reply.Id
            })));
        }
コード例 #25
0
        public override async Task <IViewAdapterResult> ConfigureAsync(string viewName)
        {
            // Ensure adapter is for current view
            if (!viewName.Equals(ViewName, StringComparison.OrdinalIgnoreCase))
            {
                return(default(IViewAdapterResult));
            }

            // Adapt the view
            return(await AdaptAsync(ViewName, v =>
            {
                v.AdaptModel <EntityListItemViewModel <Doc> >(async model =>
                {
                    // Build last visits from metrics
                    if (_lastVisits == null)
                    {
                        // Get authenticated user
                        var user = await _contextFacade.GetAuthenticatedUserAsync();

                        // We need to be authenticated
                        if (user == null)
                        {
                            // Return an anonymous type, we are adapting a view component
                            return new
                            {
                                model
                            };
                        }

                        // Get index view model from context
                        var viewModel = _actionContextAccessor.ActionContext.HttpContext.Items[typeof(EntityIndexViewModel <Doc>)] as EntityIndexViewModel <Doc>;
                        if (viewModel == null)
                        {
                            // Return an anonymous type, we are adapting a view component
                            return new
                            {
                                model
                            };
                        }

                        if (viewModel.Results == null)
                        {
                            // Return an anonymous type, we are adapting a view component
                            return new
                            {
                                model
                            };
                        }

                        if (viewModel.Results.Data != null)
                        {
                            _lastVisits = await _agggregatedEntityMetricsRepository.SelectMaxViewDateForEntitiesAsync(user.Id, viewModel.Results.Data.Select(e => e.Id).ToArray());
                        }
                    }

                    // No metrics available to adapt the view
                    if (_lastVisits == null)
                    {
                        // Return an anonymous type, we are adapting a view component
                        return new
                        {
                            model
                        };
                    }

                    if (model.Entity == null)
                    {
                        // Return an anonymous type, we are adapting a view component
                        return new
                        {
                            model
                        };
                    }

                    DateTimeOffset?lastVisit = null;
                    if (_lastVisits.ContainsKey(model.Entity.Id))
                    {
                        lastVisit = _lastVisits[model.Entity.Id];
                    }

                    // Build tag adapters
                    var adapters = new[]
                    {
                        // Add a "New" label after the title tag
                        new TagHelperAdapter("title", (context, output) =>
                        {
                            if (lastVisit != null)
                            {
                                // Optionally remove bold title for read entities
                                // output.Attributes.RemoveAll("class");

                                // New
                                if (model.Entity.LastReplyAfter(lastVisit))
                                {
                                    output.PostElement.SetHtmlContent(
                                        $"<span data-toggle=\"tooltip\" title=\"{T["This doc has new replies"].Value}\" class=\"badge badge-primary ml-2\">{T["New"].Value}</span>");
                                }
                                else
                                {
                                    // Modified
                                    if (model.Entity.ModifiedAfter(lastVisit))
                                    {
                                        output.PostElement.SetHtmlContent(
                                            $"<span data-toggle=\"tooltip\" title=\"{T["This doc has been updated since it was last read"].Value}\" class=\"badge badge-secondary ml-2\">{T["Updated"].Value}</span>");
                                    }
                                }
                            }
                            else
                            {
                                output.PreElement.SetHtmlContent(
                                    $"<span data-toggle=\"tooltip\" title=\"{T["You've not read this doc yet"].Value}\" class=\"text-primary mr-2 smaller\"><i class=\"fa fa-circle\"></i></span>");
                            }
                        })
                    };

                    // Add tag adapters
                    model.TagHelperAdapters.Add(adapters);

                    // Return an anonymous type, we are adapting a view component
                    return new
                    {
                        model
                    };
                });
            }));
        }
コード例 #26
0
        public override async Task <IViewAdapterResult> ConfigureAsync(string viewName)
        {
            // Ensure adapter is for current view
            if (!viewName.Equals(ViewName, StringComparison.OrdinalIgnoreCase))
            {
                return(default(IViewAdapterResult));
            }

            return(await AdaptAsync(ViewName, v =>
            {
                v.AdaptModel <EntityViewModel <Question, Answer> >(async model =>
                {
                    if (model.Entity == null)
                    {
                        // Return an anonymous type, we are adapting a view component
                        return new
                        {
                            model
                        };
                    }

                    // Build last visits from metrics
                    if (_lastVisits == null)
                    {
                        // Get authenticated user
                        var user = await _contextFacade.GetAuthenticatedUserAsync();

                        // We need to be authenticated
                        if (user == null)
                        {
                            // Return an anonymous type, we are adapting a view component
                            return new
                            {
                                model
                            };
                        }

                        _lastVisits = await _agggregatedEntityMetricsRepository.SelectMaxViewDateForEntitiesAsync(user.Id, new int[] { model.Entity.Id });
                    }

                    // No metrics available to adapt the view
                    if (_lastVisits == null)
                    {
                        // Return an anonymous type, we are adapting a view component
                        return new
                        {
                            model
                        };
                    }

                    // No metrics available to adapt the view
                    if (_lastVisits.Count == 0)
                    {
                        // Return an anonymous type, we are adapting a view component
                        return new
                        {
                            model
                        };
                    }

                    DateTimeOffset?lastVisit = null;
                    if (_lastVisits.ContainsKey(model.Entity.Id))
                    {
                        lastVisit = _lastVisits[model.Entity.Id];
                    }

                    // Build tag adapters
                    var adapters = new[]
                    {
                        // Add a "New" label after the title tag
                        new TagHelperAdapter(ViewName, "title", (context, output) =>
                        {
                            if (lastVisit != null)
                            {
                                // New
                                if (model.Entity.LastReplyAfter(lastVisit))
                                {
                                    output.PostElement.SetHtmlContent(
                                        $"<span data-toggle=\"tooltip\" title=\"{T["This question has new replies"].Value}\" class=\"badge badge-primary ml-2\">{T["New"].Value}</span>");
                                }
                            }
                        })
                    };

                    // Add tag adapters
                    model.TagHelperAdapters.Add(adapters);

                    // Return an anonymous type, we are adapting a view component
                    return new
                    {
                        model
                    };
                });
            }));
        }
コード例 #27
0
        public async Task <ICommandResult <Models.File> > ValidateAsync(Models.File file)
        {
            // We need a file to validate
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            // Our result
            var result = new CommandResult <Models.File>();

            // Our file must have a name
            if (string.IsNullOrEmpty(file.Name))
            {
                return(result.Failed("The file must have a name"));
            }

            // Get authenticated user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            // We need to be authenticated to post files
            if (user == null)
            {
                return(result.Failed("You must be authenticated to post files"));
            }

            // Get users file options (max file size, total available space & allowed extensions)
            var options = await _fileOptionsFactory.GetOptionsAsync(user);

            // We need options to validate
            if (options == null)
            {
                return(result.Failed("Could not obtain file options for your account.."));
            }

            // Compile errors
            var errors = new List <string>();

            // Validate file size

            // Is the file larger than our max file size?
            if (file.ContentLength > options.MaxFileSize)
            {
                var error = T["The file is {0} which exceeds your configured maximum allowed file size of {1}."];
                errors.Add(string.Format(
                               error.Value,
                               result.Response.ContentLength.ToFriendlyFileSize(),
                               options.MaxFileSize.ToFriendlyFileSize()));
            }

            // Validate file extension

            var validExtension = false;

            if (!string.IsNullOrEmpty(file.Extension))
            {
                foreach (var allowedExtension in options.AllowedExtensions)
                {
                    if (file.Extension.Equals($".{allowedExtension}", StringComparison.OrdinalIgnoreCase))
                    {
                        validExtension = true;
                    }
                }
            }

            if (!validExtension)
            {
                var allowedExtensions = string.Join(",", options.AllowedExtensions.Select(e => e));
                if (!string.IsNullOrEmpty(allowedExtensions))
                {
                    // Our extension does not appear within the allowed extensions white list
                    var error = T["The file is not an allowed type. You are allowed to attach the following types:- {0}"];
                    errors.Add(string.Format(
                                   error.Value,
                                   allowedExtensions.Replace(",", ", ")));
                }
                else
                {
                    // We don't have any configured allowed extensions
                    var error = T["The file is not an allowed type. No allowed file extensions have been configured for your account."];
                    errors.Add(error.Value);
                }
            }

            // Validate available space

            var  validSpace    = false;
            long currentLength = 0;
            var  info          = await _fileInfoStore.GetByUserIdAsync(user?.Id ?? 0);

            if (info != null)
            {
                // Ensure the upload would not exceed available space
                if ((info.Length + file.ContentLength) <= options.AvailableSpace)
                {
                    validSpace = true;
                }
                currentLength = info.Length;
            }

            if (!validSpace)
            {
                var remaining = options.AvailableSpace - currentLength;
                if (remaining < 0)
                {
                    remaining = 0;
                }
                var error = T["Not enough free space. You have {0} of free space available but the file was {1}."];
                errors.Add(string.Format(
                               error.Value,
                               remaining.ToFriendlyFileSize(),
                               file.ContentLength.ToFriendlyFileSize()));
            }

            return(errors.Count > 0
                ? result.Failed(errors)
                : result.Success(file));
        }
コード例 #28
0
        protected override async Task HandleRequirementAsync(
            AuthorizationHandlerContext context,
            PermissionRequirement requirement)
        {
            if (context.HasSucceeded)
            {
                // This handler is not revoking any pre-existing grants.
                return;
            }

            // Determine which set of permissions would satisfy the access check
            var grantingNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            PermissionNames(requirement.Permission, grantingNames);

            // Determine what set of roles should be examined by the access check
            var rolesToExamine = new List <Role>();

            // Removed for performance reasons but left in place for easy fallback if needed
            //// Search specific roles within supplied identity
            //var roleClaims = context.User
            //    .Claims
            //    .Where(c => c.Type == ClaimTypes.Role)
            //    .ToList();

            //if (roleClaims.Count > 0)
            //{
            //    rolesToExamine.AddRange(roleClaims.Select(r => r.Value));
            //}
            //else
            //{
            // Get authenticated user
            var user = await _contextFacade.GetAuthenticatedUserAsync(context.User.Identity);

            if (user != null)
            {
                rolesToExamine.AddRange(await _platoRoleStore.GetRolesByUserIdAsync(user.Id));
            }
            else
            {
                rolesToExamine.Add(await _platoRoleStore.GetByNameAsync(DefaultRoles.Anonymous));
            }

            //}

            // Iterate roles checking claims
            foreach (var role in rolesToExamine)
            {
                //Role role = await _platoRoleStore.GetByNameAsync(roleName);
                //if (role != null)
                //{
                foreach (var claim in role.RoleClaims)
                {
                    // Simple case-sensitive comparison for performance
                    if (claim.ClaimType != Permission.ClaimTypeName)
                    {
                        continue;
                    }

                    //if (!String.Equals(claim.ClaimType, Permission.ClaimTypeName, StringComparison.OrdinalIgnoreCase))
                    //{
                    //    continue;
                    //}

                    var permissionName = claim.ClaimValue;
                    if (grantingNames.Contains(permissionName))
                    {
                        context.Succeed(requirement);
                        return;
                    }
                }
                //}
            }
        }
コード例 #29
0
        // ------------
        // Validate User
        // ------------

        public async Task <IActionResult> ValidateUser(string id)
        {
            // Ensure we have permission
            if (!await _authorizationService.AuthorizeAsync(User,
                                                            Permissions.UserToVerify))
            {
                return(Unauthorized());
            }

            // Get current user
            var user = await _contextFacade.GetAuthenticatedUserAsync();

            if (user == null)
            {
                return(Unauthorized());
            }

            // Get user we are editing
            var currentUser = await _userManager.FindByIdAsync(id);

            if (currentUser == null)
            {
                return(NotFound());
            }

            // Reset spam status
            currentUser.IsSpam = false;
            currentUser.IsSpamUpdatedUserId = 0;
            currentUser.IsSpamUpdatedDate   = null;

            // Reset banned status
            currentUser.IsBanned = false;
            currentUser.IsBannedUpdatedUserId = 0;
            currentUser.IsBannedUpdatedDate   = null;

            // Reset staff status
            currentUser.IsStaff = false;
            currentUser.IsStaffUpdatedUserId = 0;
            currentUser.IsStaffUpdatedDate   = null;

            // Update verified status
            currentUser.IsVerified = true;
            currentUser.IsVerifiedUpdatedUserId = user.Id;
            currentUser.IsVerifiedUpdatedDate   = DateTimeOffset.UtcNow;

            // Update user
            var result = await _userManager.UpdateAsync(currentUser);

            if (result.Succeeded)
            {
                _alerter.Success(T["User Verified Successfully!"]);
            }
            else
            {
                foreach (var error in result.Errors)
                {
                    _alerter.Danger(T[error.Description]);
                }
            }

            // Redirect back to edit user
            return(RedirectToAction(nameof(Edit), new RouteValueDictionary()
            {
                ["id"] = id
            }));
        }
コード例 #30
0
        public override async Task <IViewProviderResult> BuildUpdateAsync(Topic topic, IViewProviderContext context)
        {
            // Ensure entity exists before attempting to update
            var entity = await _entityStore.GetByIdAsync(topic.Id);

            if (entity == null)
            {
                return(await BuildIndexAsync(topic, context));
            }

            // Validate model
            if (await ValidateModelAsync(topic, context.Updater))
            {
                // Get selected categories
                var categoriesToAdd = GetCategoriesToAdd();
                if (categoriesToAdd != null)
                {
                    // Build categories to remove
                    var categoriesToRemove = new List <int>();
                    foreach (var categoryId in await GetCategoryIdsByEntityIdAsync(topic))
                    {
                        if (!categoriesToAdd.Contains(categoryId))
                        {
                            categoriesToRemove.Add(categoryId);
                        }
                    }

                    // Remove categories
                    foreach (var categoryId in categoriesToRemove)
                    {
                        var entityCategory = await _entityCategoryStore.GetByEntityIdAndCategoryIdAsync(topic.Id, categoryId);

                        if (entityCategory != null)
                        {
                            await _entityCategoryManager.DeleteAsync(entityCategory);
                        }
                    }

                    // Get current user
                    var user = await _contextFacade.GetAuthenticatedUserAsync();

                    // Add new entity category relationships
                    foreach (var categoryId in categoriesToAdd)
                    {
                        // Ensure relationship does not already exist
                        var entityCategory = await _entityCategoryStore.GetByEntityIdAndCategoryIdAsync(topic.Id, categoryId);

                        if (entityCategory == null)
                        {
                            // Add relationship
                            await _entityCategoryManager.CreateAsync(new EntityCategory()
                            {
                                EntityId       = topic.Id,
                                CategoryId     = categoryId,
                                CreatedUserId  = user?.Id ?? 0,
                                ModifiedUserId = user?.Id ?? 0,
                            });
                        }
                    }

                    //// Update entity with first found category
                    //foreach (var id in categoriesToAdd)
                    //{
                    //    topic.CategoryId = id;
                    //    await _entityStore.UpdateAsync(topic);
                    //    break;
                    //}

                    // Update added category meta data
                    foreach (var id in categoriesToAdd)
                    {
                        await _categoryDetailsUpdater.UpdateAsync(id);
                    }

                    // Update removed category meta data
                    foreach (var id in categoriesToRemove)
                    {
                        await _categoryDetailsUpdater.UpdateAsync(id);
                    }
                }
            }

            return(await BuildEditAsync(topic, context));
        }