@@ -22,6 +22,7 @@ import (
2222 "code.gitea.io/gitea/modules/git"
2323 "code.gitea.io/gitea/modules/log"
2424 "code.gitea.io/gitea/modules/setting"
25+ "code.gitea.io/gitea/modules/structs"
2526 "code.gitea.io/gitea/modules/timeutil"
2627 "code.gitea.io/gitea/modules/util"
2728
@@ -315,29 +316,36 @@ func (a *Action) GetIssueContent() string {
315316
316317// GetFeedsOptions options for retrieving feeds
317318type GetFeedsOptions struct {
318- RequestedUser * user_model.User // the user we want activity for
319- RequestedTeam * Team // the team we want activity for
320- Actor * user_model.User // the user viewing the activity
321- IncludePrivate bool // include private actions
322- OnlyPerformedBy bool // only actions performed by requested user
323- IncludeDeleted bool // include deleted actions
324- Date string // the day we want activity for: YYYY-MM-DD
319+ db.ListOptions
320+ RequestedUser * user_model.User // the user we want activity for
321+ RequestedTeam * Team // the team we want activity for
322+ RequestedRepo * repo_model.Repository // the repo we want activity for
323+ Actor * user_model.User // the user viewing the activity
324+ IncludePrivate bool // include private actions
325+ OnlyPerformedBy bool // only actions performed by requested user
326+ IncludeDeleted bool // include deleted actions
327+ Date string // the day we want activity for: YYYY-MM-DD
325328}
326329
327330// GetFeeds returns actions according to the provided options
328331func GetFeeds (opts GetFeedsOptions ) ([]* Action , error ) {
329- if ! activityReadable ( opts .RequestedUser , opts .Actor ) {
330- return make ([] * Action , 0 ), nil
332+ if opts .RequestedUser == nil && opts .RequestedTeam == nil && opts . RequestedRepo == nil {
333+ return nil , fmt . Errorf ( "need at least one of these filters: RequestedUser, RequestedTeam, RequestedRepo" )
331334 }
332335
333336 cond , err := activityQueryCondition (opts )
334337 if err != nil {
335338 return nil , err
336339 }
337340
338- actions := make ([] * Action , 0 , setting . UI . FeedPagingNum )
341+ sess := db . GetEngine ( db . DefaultContext ). Where ( cond )
339342
340- if err := db .GetEngine (db .DefaultContext ).Limit (setting .UI .FeedPagingNum ).Desc ("created_unix" ).Where (cond ).Find (& actions ); err != nil {
343+ opts .SetDefaultValues ()
344+ sess = db .SetSessionPagination (sess , & opts )
345+
346+ actions := make ([]* Action , 0 , opts .PageSize )
347+
348+ if err := sess .Desc ("created_unix" ).Find (& actions ); err != nil {
341349 return nil , fmt .Errorf ("Find: %v" , err )
342350 }
343351
@@ -349,41 +357,44 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
349357}
350358
351359func activityReadable (user , doer * user_model.User ) bool {
352- var doerID int64
353- if doer != nil {
354- doerID = doer .ID
355- }
356- if doer == nil || ! doer .IsAdmin {
357- if user .KeepActivityPrivate && doerID != user .ID {
358- return false
359- }
360- }
361- return true
360+ return ! user .KeepActivityPrivate ||
361+ doer != nil && (doer .IsAdmin || user .ID == doer .ID )
362362}
363363
364364func activityQueryCondition (opts GetFeedsOptions ) (builder.Cond , error ) {
365365 cond := builder .NewCond ()
366366
367- var repoIDs []int64
368- var actorID int64
369- if opts .Actor != nil {
370- actorID = opts .Actor .ID
367+ if opts .RequestedTeam != nil && opts .RequestedUser == nil {
368+ org , err := user_model .GetUserByID (opts .RequestedTeam .OrgID )
369+ if err != nil {
370+ return nil , err
371+ }
372+ opts .RequestedUser = org
373+ }
374+
375+ // check activity visibility for actor ( similar to activityReadable() )
376+ if opts .Actor == nil {
377+ cond = cond .And (builder .In ("act_user_id" ,
378+ builder .Select ("`user`.id" ).Where (
379+ builder.Eq {"keep_activity_private" : false , "visibility" : structs .VisibleTypePublic },
380+ ).From ("`user`" ),
381+ ))
382+ } else if ! opts .Actor .IsAdmin {
383+ cond = cond .And (builder .In ("act_user_id" ,
384+ builder .Select ("`user`.id" ).Where (
385+ builder.Eq {"keep_activity_private" : false }.
386+ And (builder .In ("visibility" , structs .VisibleTypePublic , structs .VisibleTypeLimited ))).
387+ Or (builder.Eq {"id" : opts .Actor .ID }).From ("`user`" ),
388+ ))
371389 }
372390
373391 // check readable repositories by doer/actor
374392 if opts .Actor == nil || ! opts .Actor .IsAdmin {
375- if opts .RequestedUser .IsOrganization () {
376- env , err := OrgFromUser (opts .RequestedUser ).AccessibleReposEnv (actorID )
377- if err != nil {
378- return nil , fmt .Errorf ("AccessibleReposEnv: %v" , err )
379- }
380- if repoIDs , err = env .RepoIDs (1 , opts .RequestedUser .NumRepos ); err != nil {
381- return nil , fmt .Errorf ("GetUserRepositories: %v" , err )
382- }
383- cond = cond .And (builder .In ("repo_id" , repoIDs ))
384- } else {
385- cond = cond .And (builder .In ("repo_id" , AccessibleRepoIDsQuery (opts .Actor )))
386- }
393+ cond = cond .And (builder .In ("repo_id" , AccessibleRepoIDsQuery (opts .Actor )))
394+ }
395+
396+ if opts .RequestedRepo != nil {
397+ cond = cond .And (builder.Eq {"repo_id" : opts .RequestedRepo .ID })
387398 }
388399
389400 if opts .RequestedTeam != nil {
@@ -395,11 +406,14 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
395406 cond = cond .And (builder .In ("repo_id" , teamRepoIDs ))
396407 }
397408
398- cond = cond .And (builder.Eq {"user_id" : opts .RequestedUser .ID })
409+ if opts .RequestedUser != nil {
410+ cond = cond .And (builder.Eq {"user_id" : opts .RequestedUser .ID })
399411
400- if opts .OnlyPerformedBy {
401- cond = cond .And (builder.Eq {"act_user_id" : opts .RequestedUser .ID })
412+ if opts .OnlyPerformedBy {
413+ cond = cond .And (builder.Eq {"act_user_id" : opts .RequestedUser .ID })
414+ }
402415 }
416+
403417 if ! opts .IncludePrivate {
404418 cond = cond .And (builder.Eq {"is_private" : false })
405419 }
0 commit comments