44package integration
55
66import (
7+ "bytes"
78 "encoding/hex"
89 "fmt"
910 "io"
1011 mathRand "math/rand/v2"
1112 "net/http"
1213 "net/url"
1314 "os"
15+ "os/exec"
1416 "path"
1517 "path/filepath"
1618 "strconv"
@@ -30,6 +32,7 @@ import (
3032 api "code.gitea.io/gitea/modules/structs"
3133 "code.gitea.io/gitea/tests"
3234
35+ "github.com/kballard/go-shellquote"
3336 "github.com/stretchr/testify/assert"
3437 "github.com/stretchr/testify/require"
3538)
@@ -105,7 +108,11 @@ func testGitGeneral(t *testing.T, u *url.URL) {
105108
106109 // Setup key the user ssh key
107110 withKeyFile (t , keyname , func (keyFile string ) {
108- t .Run ("CreateUserKey" , doAPICreateUserKey (sshContext , "test-key" , keyFile ))
111+ var keyID int64
112+ t .Run ("CreateUserKey" , doAPICreateUserKey (sshContext , "test-key" , keyFile , func (t * testing.T , key api.PublicKey ) {
113+ keyID = key .ID
114+ }))
115+ assert .Greater (t , keyID , int64 (0 ))
109116
110117 // Setup remote link
111118 // TODO: get url from api
@@ -132,10 +139,34 @@ func testGitGeneral(t *testing.T, u *url.URL) {
132139 })
133140
134141 t .Run ("PushCreate" , doPushCreate (sshContext , sshURL ))
142+ t .Run ("LFSUploadTest" , doLFSUploadTest (sshContext , keyID ))
135143 })
136144 })
137145}
138146
147+ func doLFSUploadTest (ctx APITestContext , keyID int64 ) func (* testing.T ) {
148+ return func (t * testing.T ) {
149+ // This is set in withKeyFile and ensure correctly
150+ sshCommand := os .Getenv ("GIT_SSH_COMMAND" )
151+
152+ // We really have to split on the arguments and pass them individually.
153+ sshOptions , err := shellquote .Split (sshCommand )
154+ assert .NoError (t , err )
155+
156+ sshOptions = append (sshOptions , "-p " + strconv .Itoa (setting .SSH .ListenPort ), "git@" + setting .SSH .ListenHost )
157+ // user2's key upload lfs file to user5/repo4
158+ sshOptions = append (sshOptions , "git-lfs-authenticate" , "user5/repo4.git" , "upload" )
159+
160+ cmd := exec .CommandContext (t .Context (), sshOptions [0 ], sshOptions [1 :]... )
161+ stderr := bytes.Buffer {}
162+ cmd .Stderr = & stderr
163+ err = cmd .Run ()
164+
165+ assert .ErrorContains (t , err , "exit status 1" )
166+ assert .Contains (t , stderr .String (), fmt .Sprintf ("User: 2:user2 with Key: %d:test-key is not authorized to write to user5/repo4." , keyID ))
167+ }
168+ }
169+
139170func ensureAnonymousClone (t * testing.T , u * url.URL ) {
140171 dstLocalPath := t .TempDir ()
141172 t .Run ("CloneAnonymous" , doGitClone (dstLocalPath , u ))
0 commit comments