From 895d92ffe5fa31cfe97d0b3b822874b5993c7981 Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 28 Jan 2020 21:54:09 +0000 Subject: [PATCH] Ensure that feeds are appropriately restricted (#10018) (#10019) * Ensure that feeds are appropriately restricted * Placate golangci-lint --- models/action.go | 2 ++ models/repo_list.go | 17 +++++++++++++++++ routers/user/home.go | 14 ++++++++++---- routers/user/profile.go | 12 +++++++++--- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/models/action.go b/models/action.go index dd642c6c1f9..3bc88f00632 100644 --- a/models/action.go +++ b/models/action.go @@ -432,6 +432,8 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) { } cond = cond.And(builder.In("repo_id", repoIDs)) + } else { + cond = cond.And(builder.In("repo_id", AccessibleRepoIDsQuery(opts.RequestingUserID))) } cond = cond.And(builder.Eq{"user_id": opts.RequestedUser.ID}) diff --git a/models/repo_list.go b/models/repo_list.go index 7b48834dba9..1dd5cf2f063 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -315,6 +315,17 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) { // accessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible func accessibleRepositoryCondition(userID int64) builder.Cond { + if userID <= 0 { + return builder.And( + builder.Eq{"`repository`.is_private": false}, + builder.Or( + // A. Aren't in organisations __OR__ + builder.NotIn("`repository`.owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})), + // B. Is a public organisation. + builder.In("`repository`.owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"visibility": structs.VisibleTypePublic}))), + ) + } + return builder.Or( // 1. Be able to see all non-private repositories that either: builder.And( @@ -349,6 +360,12 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err return SearchRepository(opts) } +// AccessibleRepoIDsQuery queries accessible repository ids. Usable as a subquery wherever repo ids need to be filtered. +func AccessibleRepoIDsQuery(userID int64) *builder.Builder { + // NB: Please note this code needs to still work if user is nil + return builder.Select("id").From("repository").Where(accessibleRepositoryCondition(userID)) +} + // FindUserAccessibleRepoIDs find all accessible repositories' ID by user's id func FindUserAccessibleRepoIDs(userID int64) ([]int64, error) { var accessCond builder.Cond = builder.Eq{"is_private": false} diff --git a/routers/user/home.go b/routers/user/home.go index 512c60716d1..ff77bd0032d 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -142,11 +142,17 @@ func Dashboard(ctx *context.Context) { ctx.Data["MirrorCount"] = len(mirrors) ctx.Data["Mirrors"] = mirrors + requestingUserID := int64(0) + if ctx.User != nil { + requestingUserID = ctx.User.ID + } + retrieveFeeds(ctx, models.GetFeedsOptions{ - RequestedUser: ctxUser, - IncludePrivate: true, - OnlyPerformedBy: false, - IncludeDeleted: false, + RequestedUser: ctxUser, + RequestingUserID: requestingUserID, + IncludePrivate: true, + OnlyPerformedBy: false, + IncludeDeleted: false, }) if ctx.Written() { diff --git a/routers/user/profile.go b/routers/user/profile.go index 90e832b530c..fd29a176229 100644 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -156,14 +156,20 @@ func Profile(ctx *context.Context) { orderBy = models.SearchOrderByRecentUpdated } + requestingUserID := int64(0) + if ctx.User != nil { + requestingUserID = ctx.User.ID + } + keyword := strings.Trim(ctx.Query("q"), " ") ctx.Data["Keyword"] = keyword switch tab { case "activity": retrieveFeeds(ctx, models.GetFeedsOptions{RequestedUser: ctxUser, - IncludePrivate: showPrivate, - OnlyPerformedBy: true, - IncludeDeleted: false, + RequestingUserID: requestingUserID, + IncludePrivate: showPrivate, + OnlyPerformedBy: true, + IncludeDeleted: false, }) if ctx.Written() { return