From fe7caa05ccafe3182db0ceb48dd36e2629f6807c Mon Sep 17 00:00:00 2001
From: Giteabot <teabot@gitea.io>
Date: Sun, 2 Apr 2023 16:30:33 -0400
Subject: [PATCH] Check `IsActionsToken` for LFS authentication (#23841)
 (#23875)

Backport #23841 by @Zettat123

Close #23824

Actions cannot fetch LFS objects from private repos because we don't
check if the user is the `ActionUser`.

Co-authored-by: Zettat123 <zettat123@gmail.com>
---
 services/lfs/server.go | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/services/lfs/server.go b/services/lfs/server.go
index 320c8e7281..758f4ebfe0 100644
--- a/services/lfs/server.go
+++ b/services/lfs/server.go
@@ -18,6 +18,7 @@ import (
 	"strconv"
 	"strings"
 
+	actions_model "code.gitea.io/gitea/models/actions"
 	git_model "code.gitea.io/gitea/models/git"
 	"code.gitea.io/gitea/models/perm"
 	access_model "code.gitea.io/gitea/models/perm/access"
@@ -495,10 +496,27 @@ func authenticate(ctx *context.Context, repository *repo_model.Repository, autho
 		accessMode = perm.AccessModeWrite
 	}
 
+	if ctx.Data["IsActionsToken"] == true {
+		taskID := ctx.Data["ActionsTaskID"].(int64)
+		task, err := actions_model.GetTaskByID(ctx, taskID)
+		if err != nil {
+			log.Error("Unable to GetTaskByID for task[%d] Error: %v", taskID, err)
+			return false
+		}
+		if task.RepoID != repository.ID {
+			return false
+		}
+
+		if task.IsForkPullRequest {
+			return accessMode <= perm.AccessModeRead
+		}
+		return accessMode <= perm.AccessModeWrite
+	}
+
 	// ctx.IsSigned is unnecessary here, this will be checked in perm.CanAccess
 	perm, err := access_model.GetUserRepoPermission(ctx, repository, ctx.Doer)
 	if err != nil {
-		log.Error("Unable to GetUserRepoPermission for user %-v in repo %-v Error: %v", ctx.Doer, repository)
+		log.Error("Unable to GetUserRepoPermission for user %-v in repo %-v Error: %v", ctx.Doer, repository, err)
 		return false
 	}