mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 14:31:02 +00:00 
			
		
		
		
	chore: add clone credential unit test
Verify it still works and the askpass file implementation is employed by Git.
This commit is contained in:
		
					parent
					
						
							
								f7f7d086e4
							
						
					
				
			
			
				commit
				
					
						900ea0ce5a
					
				
			
		
					 1 changed files with 85 additions and 0 deletions
				
			
		|  | @ -4,7 +4,15 @@ | |||
| package git | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/base64" | ||||
| 	"io/fs" | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
|  | @ -54,3 +62,80 @@ func TestRepoGetDivergingCommits(t *testing.T) { | |||
| 		Behind: 2, | ||||
| 	}, do) | ||||
| } | ||||
| 
 | ||||
| func TestCloneCredentials(t *testing.T) { | ||||
| 	calledWithoutPassword := false | ||||
| 	askpassFile := "" | ||||
| 	credentialsFile := "" | ||||
| 
 | ||||
| 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { | ||||
| 		if req.URL.Path != "/info/refs" { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		// Get basic authorization. | ||||
| 		auth, ok := strings.CutPrefix(req.Header.Get("Authorization"), "Basic ") | ||||
| 		if !ok { | ||||
| 			w.Header().Set("WWW-Authenticate", `Basic realm="Forgejo"`) | ||||
| 			http.Error(w, "require credentials", http.StatusUnauthorized) | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		rawAuth, err := base64.StdEncoding.DecodeString(auth) | ||||
| 		require.NoError(t, err) | ||||
| 
 | ||||
| 		user, password, ok := bytes.Cut(rawAuth, []byte{':'}) | ||||
| 		assert.True(t, ok) | ||||
| 
 | ||||
| 		// First time around Git tries without password (that's specified in the clone URL). | ||||
| 		// It demonstrates it doesn't immediately uses askpass. | ||||
| 		if len(password) == 0 { | ||||
| 			assert.EqualValues(t, "oauth2", user) | ||||
| 			calledWithoutPassword = true | ||||
| 
 | ||||
| 			w.Header().Set("WWW-Authenticate", `Basic realm="Forgejo"`) | ||||
| 			http.Error(w, "require credentials", http.StatusUnauthorized) | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		assert.EqualValues(t, "oauth2", user) | ||||
| 		assert.EqualValues(t, "some_token", password) | ||||
| 
 | ||||
| 		tmpDir := os.TempDir() | ||||
| 
 | ||||
| 		// Verify that the askpass implementation was used. | ||||
| 		files, err := fs.Glob(os.DirFS(tmpDir), "forgejo-askpass*") | ||||
| 		require.NoError(t, err) | ||||
| 		for _, fileName := range files { | ||||
| 			fileContent, err := os.ReadFile(filepath.Join(tmpDir, fileName)) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 			credentialsPath, ok := bytes.CutPrefix(fileContent, []byte(`exec cat `)) | ||||
| 			assert.True(t, ok) | ||||
| 
 | ||||
| 			fileContent, err = os.ReadFile(string(credentialsPath)) | ||||
| 			require.NoError(t, err) | ||||
| 			assert.EqualValues(t, "some_token", fileContent) | ||||
| 
 | ||||
| 			askpassFile = filepath.Join(tmpDir, fileName) | ||||
| 			credentialsFile = string(credentialsPath) | ||||
| 		} | ||||
| 	})) | ||||
| 
 | ||||
| 	serverURL, err := url.Parse(server.URL) | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	serverURL.User = url.UserPassword("oauth2", "some_token") | ||||
| 
 | ||||
| 	require.NoError(t, Clone(t.Context(), serverURL.String(), t.TempDir(), CloneRepoOptions{})) | ||||
| 
 | ||||
| 	assert.True(t, calledWithoutPassword) | ||||
| 	assert.NotEmpty(t, askpassFile) | ||||
| 	assert.NotEmpty(t, credentialsFile) | ||||
| 
 | ||||
| 	// Check that the helper files are gone. | ||||
| 	_, err = os.Stat(askpassFile) | ||||
| 	require.ErrorIs(t, err, fs.ErrNotExist) | ||||
| 	_, err = os.Stat(credentialsFile) | ||||
| 	require.ErrorIs(t, err, fs.ErrNotExist) | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue