@@ -25,7 +25,7 @@ import (
2525
2626 "github.com/keybase/go-crypto/openpgp"
2727 "github.com/keybase/go-crypto/openpgp/armor"
28- "github.com/unknwon/com "
28+ "xorm.io/builder "
2929)
3030
3131const (
@@ -173,135 +173,114 @@ func Milestones(ctx *context.Context) {
173173 return
174174 }
175175
176- sortType := ctx .Query ("sort" )
177- page := ctx .QueryInt ("page" )
176+ var (
177+ repoOpts = models.SearchRepoOptions {
178+ Actor : ctxUser ,
179+ OwnerID : ctxUser .ID ,
180+ Private : true ,
181+ AllPublic : false , // Include also all public repositories of users and public organisations
182+ AllLimited : false , // Include also all public repositories of limited organisations
183+ HasMilestones : util .OptionalBoolTrue , // Just needs display repos has milestones
184+ }
185+
186+ userRepoCond = models .SearchRepositoryCondition (& repoOpts ) // all repo condition user could visit
187+ repoCond = userRepoCond
188+ repoIDs []int64
189+
190+ reposQuery = ctx .Query ("repos" )
191+ isShowClosed = ctx .Query ("state" ) == "closed"
192+ sortType = ctx .Query ("sort" )
193+ page = ctx .QueryInt ("page" )
194+ )
195+
178196 if page <= 1 {
179197 page = 1
180198 }
181199
182- reposQuery := ctx .Query ("repos" )
183- isShowClosed := ctx .Query ("state" ) == "closed"
184-
185- // Get repositories.
186- var err error
187- var userRepoIDs []int64
188- if ctxUser .IsOrganization () {
189- env , err := ctxUser .AccessibleReposEnv (ctx .User .ID )
190- if err != nil {
191- ctx .ServerError ("AccessibleReposEnv" , err )
192- return
193- }
194- userRepoIDs , err = env .RepoIDs (1 , ctxUser .NumRepos )
195- if err != nil {
196- ctx .ServerError ("env.RepoIDs" , err )
197- return
198- }
199- userRepoIDs , err = models .FilterOutRepoIdsWithoutUnitAccess (ctx .User , userRepoIDs , models .UnitTypeIssues , models .UnitTypePullRequests )
200- if err != nil {
201- ctx .ServerError ("FilterOutRepoIdsWithoutUnitAccess" , err )
202- return
203- }
204- } else {
205- userRepoIDs , err = ctxUser .GetAccessRepoIDs (models .UnitTypeIssues , models .UnitTypePullRequests )
206- if err != nil {
207- ctx .ServerError ("ctxUser.GetAccessRepoIDs" , err )
208- return
209- }
210- }
211- if len (userRepoIDs ) == 0 {
212- userRepoIDs = []int64 {- 1 }
213- }
214-
215- var repoIDs []int64
216200 if len (reposQuery ) != 0 {
217201 if issueReposQueryPattern .MatchString (reposQuery ) {
218202 // remove "[" and "]" from string
219203 reposQuery = reposQuery [1 : len (reposQuery )- 1 ]
220204 //for each ID (delimiter ",") add to int to repoIDs
221- reposSet := false
205+
222206 for _ , rID := range strings .Split (reposQuery , "," ) {
223207 // Ensure nonempty string entries
224208 if rID != "" && rID != "0" {
225- reposSet = true
226209 rIDint64 , err := strconv .ParseInt (rID , 10 , 64 )
227210 // If the repo id specified by query is not parseable or not accessible by user, just ignore it.
228- if err == nil && com . IsSliceContainsInt64 ( userRepoIDs , rIDint64 ) {
211+ if err == nil {
229212 repoIDs = append (repoIDs , rIDint64 )
230213 }
231214 }
232215 }
233- if reposSet && len (repoIDs ) == 0 {
234- // force an empty result
235- repoIDs = []int64 {- 1 }
216+ if len (repoIDs ) > 0 {
217+ // Don't just let repoCond = builder.In("id", repoIDs) because user may has no permission on repoIDs
218+ // But the original repoCond has a limitation
219+ repoCond = repoCond .And (builder .In ("id" , repoIDs ))
236220 }
237221 } else {
238222 log .Warn ("issueReposQueryPattern not match with query" )
239223 }
240224 }
241225
242- if len (repoIDs ) == 0 {
243- repoIDs = userRepoIDs
244- }
245-
246- counts , err := models .CountMilestonesByRepoIDs (userRepoIDs , isShowClosed )
226+ counts , err := models .CountMilestones (userRepoCond , isShowClosed )
247227 if err != nil {
248228 ctx .ServerError ("CountMilestonesByRepoIDs" , err )
249229 return
250230 }
251231
252- milestones , err := models .GetMilestonesByRepoIDs ( repoIDs , page , isShowClosed , sortType )
232+ milestones , err := models .SearchMilestones ( repoCond , page , isShowClosed , sortType )
253233 if err != nil {
254234 ctx .ServerError ("GetMilestonesByRepoIDs" , err )
255235 return
256236 }
257237
258- showReposMap := make (map [int64 ]* models.Repository , len (counts ))
259- for rID := range counts {
260- if rID == - 1 {
261- break
262- }
263- repo , err := models .GetRepositoryByID (rID )
264- if err != nil {
265- if models .IsErrRepoNotExist (err ) {
266- ctx .NotFound ("GetRepositoryByID" , err )
267- return
268- } else if err != nil {
269- ctx .ServerError ("GetRepositoryByID" , fmt .Errorf ("[%d]%v" , rID , err ))
270- return
271- }
272- }
273- showReposMap [rID ] = repo
274- }
275-
276- showRepos := models .RepositoryListOfMap (showReposMap )
277- sort .Sort (showRepos )
278- if err = showRepos .LoadAttributes (); err != nil {
279- ctx .ServerError ("LoadAttributes" , err )
238+ showRepos , _ , err := models .SearchRepositoryByCondition (& repoOpts , userRepoCond , false )
239+ if err != nil {
240+ ctx .ServerError ("SearchRepositoryByCondition" , err )
280241 return
281242 }
243+ sort .Sort (showRepos )
244+
245+ for i := 0 ; i < len (milestones ); {
246+ for _ , repo := range showRepos {
247+ if milestones [i ].RepoID == repo .ID {
248+ milestones [i ].Repo = repo
249+ break
250+ }
251+ }
252+ if milestones [i ].Repo == nil {
253+ log .Warn ("Cannot find milestone %d 's repository %d" , milestones [i ].ID , milestones [i ].RepoID )
254+ milestones = append (milestones [:i ], milestones [i + 1 :]... )
255+ continue
256+ }
282257
283- for _ , m := range milestones {
284- m .Repo = showReposMap [m .RepoID ]
285- m .RenderedContent = string (markdown .Render ([]byte (m .Content ), m .Repo .Link (), m .Repo .ComposeMetas ()))
286- if m .Repo .IsTimetrackerEnabled () {
287- err := m .LoadTotalTrackedTime ()
258+ milestones [i ].RenderedContent = string (markdown .Render ([]byte (milestones [i ].Content ), milestones [i ].Repo .Link (), milestones [i ].Repo .ComposeMetas ()))
259+ if milestones [i ].Repo .IsTimetrackerEnabled () {
260+ err := milestones [i ].LoadTotalTrackedTime ()
288261 if err != nil {
289262 ctx .ServerError ("LoadTotalTrackedTime" , err )
290263 return
291264 }
292265 }
266+ i ++
293267 }
294268
295- milestoneStats , err := models .GetMilestonesStats (repoIDs )
269+ milestoneStats , err := models .GetMilestonesStats (repoCond )
296270 if err != nil {
297271 ctx .ServerError ("GetMilestoneStats" , err )
298272 return
299273 }
300274
301- totalMilestoneStats , err := models .GetMilestonesStats (userRepoIDs )
302- if err != nil {
303- ctx .ServerError ("GetMilestoneStats" , err )
304- return
275+ var totalMilestoneStats * models.MilestonesStats
276+ if len (repoIDs ) == 0 {
277+ totalMilestoneStats = milestoneStats
278+ } else {
279+ totalMilestoneStats , err = models .GetMilestonesStats (userRepoCond )
280+ if err != nil {
281+ ctx .ServerError ("GetMilestoneStats" , err )
282+ return
283+ }
305284 }
306285
307286 var pagerCount int
@@ -320,7 +299,7 @@ func Milestones(ctx *context.Context) {
320299 ctx .Data ["Counts" ] = counts
321300 ctx .Data ["MilestoneStats" ] = milestoneStats
322301 ctx .Data ["SortType" ] = sortType
323- if len ( repoIDs ) != len ( userRepoIDs ) {
302+ if milestoneStats . Total ( ) != totalMilestoneStats . Total ( ) {
324303 ctx .Data ["RepoIDs" ] = repoIDs
325304 }
326305 ctx .Data ["IsShowClosed" ] = isShowClosed
0 commit comments