mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 22:28:05 +01:00 
			
		
		
		
	Hide the "Details" link of commit status when the user cannot access actions (#30156)
Fix #26685 If a commit status comes from Gitea Actions and the user cannot access the repo's actions unit (the user does not have the permission or the actions unit is disabled), a 404 page will occur after clicking the "Details" link. We should hide the "Details" link in this case. <img src="https://github.com/go-gitea/gitea/assets/15528715/68361714-b784-4bb5-baab-efde4221f466" width="400px" />
This commit is contained in:
		
							parent
							
								
									aa36989bd0
								
							
						
					
					
						commit
						7dec8de914
					
				| @ -171,13 +171,17 @@ func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (in | ||||
| 	return newIdx, nil | ||||
| } | ||||
| 
 | ||||
| func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) { | ||||
| func (status *CommitStatus) loadRepository(ctx context.Context) (err error) { | ||||
| 	if status.Repo == nil { | ||||
| 		status.Repo, err = repo_model.GetRepositoryByID(ctx, status.RepoID) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("getRepositoryByID [%d]: %w", status.RepoID, err) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (status *CommitStatus) loadCreator(ctx context.Context) (err error) { | ||||
| 	if status.Creator == nil && status.CreatorID > 0 { | ||||
| 		status.Creator, err = user_model.GetUserByID(ctx, status.CreatorID) | ||||
| 		if err != nil { | ||||
| @ -187,6 +191,13 @@ func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) { | ||||
| 	if err := status.loadRepository(ctx); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return status.loadCreator(ctx) | ||||
| } | ||||
| 
 | ||||
| // APIURL returns the absolute APIURL to this commit-status. | ||||
| func (status *CommitStatus) APIURL(ctx context.Context) string { | ||||
| 	_ = status.loadAttributes(ctx) | ||||
| @ -198,6 +209,21 @@ func (status *CommitStatus) LocaleString(lang translation.Locale) string { | ||||
| 	return lang.TrString("repo.commitstatus." + status.State.String()) | ||||
| } | ||||
| 
 | ||||
| // HideActionsURL set `TargetURL` to an empty string if the status comes from Gitea Actions | ||||
| func (status *CommitStatus) HideActionsURL(ctx context.Context) { | ||||
| 	if status.Repo == nil { | ||||
| 		if err := status.loadRepository(ctx); err != nil { | ||||
| 			log.Error("loadRepository: %v", err) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	prefix := fmt.Sprintf("%s/actions", status.Repo.Link()) | ||||
| 	if strings.HasPrefix(status.TargetURL, prefix) { | ||||
| 		status.TargetURL = "" | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // CalcCommitStatus returns commit status state via some status, the commit statues should order by id desc | ||||
| func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus { | ||||
| 	var lastStatus *CommitStatus | ||||
| @ -506,3 +532,15 @@ func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo | ||||
| 		repo, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| // CommitStatusesHideActionsURL hide Gitea Actions urls | ||||
| func CommitStatusesHideActionsURL(ctx context.Context, statuses []*CommitStatus) { | ||||
| 	idToRepos := make(map[int64]*repo_model.Repository) | ||||
| 	for _, status := range statuses { | ||||
| 		if status.Repo == nil { | ||||
| 			status.Repo = idToRepos[status.RepoID] | ||||
| 		} | ||||
| 		status.HideActionsURL(ctx) | ||||
| 		idToRepos[status.RepoID] = status.Repo | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -4,9 +4,11 @@ | ||||
| package git_test | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	actions_model "code.gitea.io/gitea/models/actions" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	git_model "code.gitea.io/gitea/models/git" | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| @ -231,3 +233,26 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) { | ||||
| 		assert.Equal(t, "compliance/lint-backend", contexts[0]) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestCommitStatusesHideActionsURL(t *testing.T) { | ||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||
| 
 | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) | ||||
| 	run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: 791, RepoID: repo.ID}) | ||||
| 	assert.NoError(t, run.LoadAttributes(db.DefaultContext)) | ||||
| 
 | ||||
| 	statuses := []*git_model.CommitStatus{ | ||||
| 		{ | ||||
| 			RepoID:    repo.ID, | ||||
| 			TargetURL: fmt.Sprintf("%s/jobs/%d", run.Link(), run.Index), | ||||
| 		}, | ||||
| 		{ | ||||
| 			RepoID:    repo.ID, | ||||
| 			TargetURL: "https://mycicd.org/1", | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	git_model.CommitStatusesHideActionsURL(db.DefaultContext, statuses) | ||||
| 	assert.Empty(t, statuses[0].TargetURL) | ||||
| 	assert.Equal(t, "https://mycicd.org/1", statuses[1].TargetURL) | ||||
| } | ||||
|  | ||||
| @ -70,6 +70,11 @@ func Branches(ctx *context.Context) { | ||||
| 		ctx.ServerError("LoadBranches", err) | ||||
| 		return | ||||
| 	} | ||||
| 	if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 		for key := range commitStatuses { | ||||
| 			git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key]) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	commitStatus := make(map[string]*git_model.CommitStatus) | ||||
| 	for commitID, cs := range commitStatuses { | ||||
|  | ||||
| @ -16,6 +16,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	git_model "code.gitea.io/gitea/models/git" | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	unit_model "code.gitea.io/gitea/models/unit" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/charset" | ||||
| @ -81,7 +82,7 @@ func Commits(ctx *context.Context) { | ||||
| 		ctx.ServerError("CommitsByRange", err) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository) | ||||
| 	ctx.Data["Commits"] = processGitCommits(ctx, commits) | ||||
| 
 | ||||
| 	ctx.Data["Username"] = ctx.Repo.Owner.Name | ||||
| 	ctx.Data["Reponame"] = ctx.Repo.Repository.Name | ||||
| @ -199,7 +200,7 @@ func SearchCommits(ctx *context.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["CommitCount"] = len(commits) | ||||
| 	ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository) | ||||
| 	ctx.Data["Commits"] = processGitCommits(ctx, commits) | ||||
| 
 | ||||
| 	ctx.Data["Keyword"] = query | ||||
| 	if all { | ||||
| @ -242,7 +243,7 @@ func FileHistory(ctx *context.Context) { | ||||
| 		ctx.ServerError("CommitsByFileAndRange", err) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository) | ||||
| 	ctx.Data["Commits"] = processGitCommits(ctx, commits) | ||||
| 
 | ||||
| 	ctx.Data["Username"] = ctx.Repo.Owner.Name | ||||
| 	ctx.Data["Reponame"] = ctx.Repo.Repository.Name | ||||
| @ -353,6 +354,9 @@ func Diff(ctx *context.Context) { | ||||
| 	if err != nil { | ||||
| 		log.Error("GetLatestCommitStatus: %v", err) | ||||
| 	} | ||||
| 	if !ctx.Repo.CanRead(unit_model.TypeActions) { | ||||
| 		git_model.CommitStatusesHideActionsURL(ctx, statuses) | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["CommitStatus"] = git_model.CalcCommitStatus(statuses) | ||||
| 	ctx.Data["CommitStatuses"] = statuses | ||||
| @ -433,3 +437,14 @@ func RawDiff(ctx *context.Context) { | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func processGitCommits(ctx *context.Context, gitCommits []*git.Commit) []*git_model.SignCommitWithStatuses { | ||||
| 	commits := git_model.ConvertFromGitCommit(ctx, gitCommits, ctx.Repo.Repository) | ||||
| 	if !ctx.Repo.CanRead(unit_model.TypeActions) { | ||||
| 		for _, commit := range commits { | ||||
| 			commit.Status.HideActionsURL(ctx) | ||||
| 			git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses) | ||||
| 		} | ||||
| 	} | ||||
| 	return commits | ||||
| } | ||||
|  | ||||
| @ -643,7 +643,7 @@ func PrepareCompareDiff( | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	commits := git_model.ConvertFromGitCommit(ctx, ci.CompareInfo.Commits, ci.HeadRepo) | ||||
| 	commits := processGitCommits(ctx, ci.CompareInfo.Commits) | ||||
| 	ctx.Data["Commits"] = commits | ||||
| 	ctx.Data["CommitCount"] = len(commits) | ||||
| 
 | ||||
|  | ||||
| @ -339,6 +339,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt | ||||
| 		ctx.ServerError("GetIssuesAllCommitStatus", err) | ||||
| 		return | ||||
| 	} | ||||
| 	if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 		for key := range commitStatuses { | ||||
| 			git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key]) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err := issues.LoadAttributes(ctx); err != nil { | ||||
| 		ctx.ServerError("issues.LoadAttributes", err) | ||||
| @ -1757,6 +1762,12 @@ func ViewIssue(ctx *context.Context) { | ||||
| 				ctx.ServerError("LoadPushCommits", err) | ||||
| 				return | ||||
| 			} | ||||
| 			if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 				for _, commit := range comment.Commits { | ||||
| 					commit.Status.HideActionsURL(ctx) | ||||
| 					git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses) | ||||
| 				} | ||||
| 			} | ||||
| 		} else if comment.Type == issues_model.CommentTypeAddTimeManual || | ||||
| 			comment.Type == issues_model.CommentTypeStopTracking || | ||||
| 			comment.Type == issues_model.CommentTypeDeleteTimeManual { | ||||
|  | ||||
| @ -283,6 +283,10 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) | ||||
| 			ctx.ServerError("GetLatestCommitStatus", err) | ||||
| 			return nil | ||||
| 		} | ||||
| 		if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 			git_model.CommitStatusesHideActionsURL(ctx, commitStatuses) | ||||
| 		} | ||||
| 
 | ||||
| 		if len(commitStatuses) != 0 { | ||||
| 			ctx.Data["LatestCommitStatuses"] = commitStatuses | ||||
| 			ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses) | ||||
| @ -345,6 +349,10 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C | ||||
| 			ctx.ServerError("GetLatestCommitStatus", err) | ||||
| 			return nil | ||||
| 		} | ||||
| 		if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 			git_model.CommitStatusesHideActionsURL(ctx, commitStatuses) | ||||
| 		} | ||||
| 
 | ||||
| 		if len(commitStatuses) > 0 { | ||||
| 			ctx.Data["LatestCommitStatuses"] = commitStatuses | ||||
| 			ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses) | ||||
| @ -437,6 +445,10 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C | ||||
| 		ctx.ServerError("GetLatestCommitStatus", err) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 		git_model.CommitStatusesHideActionsURL(ctx, commitStatuses) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(commitStatuses) > 0 { | ||||
| 		ctx.Data["LatestCommitStatuses"] = commitStatuses | ||||
| 		ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses) | ||||
| @ -603,7 +615,7 @@ func ViewPullCommits(ctx *context.Context) { | ||||
| 	ctx.Data["Username"] = ctx.Repo.Owner.Name | ||||
| 	ctx.Data["Reponame"] = ctx.Repo.Repository.Name | ||||
| 
 | ||||
| 	commits := git_model.ConvertFromGitCommit(ctx, prInfo.Commits, ctx.Repo.Repository) | ||||
| 	commits := processGitCommits(ctx, prInfo.Commits) | ||||
| 	ctx.Data["Commits"] = commits | ||||
| 	ctx.Data["CommitCount"] = len(commits) | ||||
| 
 | ||||
|  | ||||
| @ -656,6 +656,9 @@ func SearchRepo(ctx *context.Context) { | ||||
| 		ctx.JSON(http.StatusInternalServerError, nil) | ||||
| 		return | ||||
| 	} | ||||
| 	if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 		git_model.CommitStatusesHideActionsURL(ctx, latestCommitStatuses) | ||||
| 	} | ||||
| 
 | ||||
| 	results := make([]*repo_service.WebSearchRepository, len(repos)) | ||||
| 	for i, repo := range repos { | ||||
|  | ||||
| @ -363,6 +363,9 @@ func loadLatestCommitData(ctx *context.Context, latestCommit *git.Commit) bool { | ||||
| 		if err != nil { | ||||
| 			log.Error("GetLatestCommitStatus: %v", err) | ||||
| 		} | ||||
| 		if !ctx.Repo.CanRead(unit_model.TypeActions) { | ||||
| 			git_model.CommitStatusesHideActionsURL(ctx, statuses) | ||||
| 		} | ||||
| 
 | ||||
| 		ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses) | ||||
| 		ctx.Data["LatestCommitStatuses"] = statuses | ||||
|  | ||||
| @ -17,6 +17,7 @@ import ( | ||||
| 	activities_model "code.gitea.io/gitea/models/activities" | ||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	git_model "code.gitea.io/gitea/models/git" | ||||
| 	issues_model "code.gitea.io/gitea/models/issues" | ||||
| 	"code.gitea.io/gitea/models/organization" | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| @ -568,6 +569,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { | ||||
| 		ctx.ServerError("GetIssuesLastCommitStatus", err) | ||||
| 		return | ||||
| 	} | ||||
| 	if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 		for key := range commitStatuses { | ||||
| 			git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key]) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// ------------------------------- | ||||
| 	// Fill stats to post to ctx.Data. | ||||
|  | ||||
| @ -13,8 +13,10 @@ import ( | ||||
| 
 | ||||
| 	activities_model "code.gitea.io/gitea/models/activities" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	git_model "code.gitea.io/gitea/models/git" | ||||
| 	issues_model "code.gitea.io/gitea/models/issues" | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/models/unit" | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| @ -303,6 +305,11 @@ func NotificationSubscriptions(ctx *context.Context) { | ||||
| 		ctx.ServerError("GetIssuesAllCommitStatus", err) | ||||
| 		return | ||||
| 	} | ||||
| 	if !ctx.Repo.CanRead(unit.TypeActions) { | ||||
| 		for key := range commitStatuses { | ||||
| 			git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key]) | ||||
| 		} | ||||
| 	} | ||||
| 	ctx.Data["CommitLastStatus"] = lastStatus | ||||
| 	ctx.Data["CommitStatuses"] = commitStatuses | ||||
| 	ctx.Data["Issues"] = issues | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user