mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 15:04:00 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			204 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2023 The Gitea Authors. All rights reserved.
 | 
						|
// SPDX-License-Identifier: MIT
 | 
						|
 | 
						|
package storage
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"net/http"
 | 
						|
	"net/http/httptest"
 | 
						|
	"os"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"code.gitea.io/gitea/modules/setting"
 | 
						|
 | 
						|
	"github.com/minio/minio-go/v7"
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
)
 | 
						|
 | 
						|
func TestMinioStorageIterator(t *testing.T) {
 | 
						|
	if os.Getenv("CI") == "" {
 | 
						|
		t.Skip("minioStorage not present outside of CI")
 | 
						|
		return
 | 
						|
	}
 | 
						|
	testStorageIterator(t, setting.MinioStorageType, &setting.Storage{
 | 
						|
		MinioConfig: setting.MinioStorageConfig{
 | 
						|
			Endpoint:        "minio:9000",
 | 
						|
			AccessKeyID:     "123456",
 | 
						|
			SecretAccessKey: "12345678",
 | 
						|
			Bucket:          "gitea",
 | 
						|
			Location:        "us-east-1",
 | 
						|
		},
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func TestMinioStoragePath(t *testing.T) {
 | 
						|
	m := &MinioStorage{basePath: ""}
 | 
						|
	assert.Empty(t, m.buildMinioPath("/"))
 | 
						|
	assert.Empty(t, m.buildMinioPath("."))
 | 
						|
	assert.Equal(t, "a", m.buildMinioPath("/a"))
 | 
						|
	assert.Equal(t, "a/b", m.buildMinioPath("/a/b/"))
 | 
						|
	assert.Empty(t, m.buildMinioDirPrefix(""))
 | 
						|
	assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/"))
 | 
						|
 | 
						|
	m = &MinioStorage{basePath: "/"}
 | 
						|
	assert.Empty(t, m.buildMinioPath("/"))
 | 
						|
	assert.Empty(t, m.buildMinioPath("."))
 | 
						|
	assert.Equal(t, "a", m.buildMinioPath("/a"))
 | 
						|
	assert.Equal(t, "a/b", m.buildMinioPath("/a/b/"))
 | 
						|
	assert.Empty(t, m.buildMinioDirPrefix(""))
 | 
						|
	assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/"))
 | 
						|
 | 
						|
	m = &MinioStorage{basePath: "/base"}
 | 
						|
	assert.Equal(t, "base", m.buildMinioPath("/"))
 | 
						|
	assert.Equal(t, "base", m.buildMinioPath("."))
 | 
						|
	assert.Equal(t, "base/a", m.buildMinioPath("/a"))
 | 
						|
	assert.Equal(t, "base/a/b", m.buildMinioPath("/a/b/"))
 | 
						|
	assert.Equal(t, "base/", m.buildMinioDirPrefix(""))
 | 
						|
	assert.Equal(t, "base/a/", m.buildMinioDirPrefix("/a/"))
 | 
						|
 | 
						|
	m = &MinioStorage{basePath: "/base/"}
 | 
						|
	assert.Equal(t, "base", m.buildMinioPath("/"))
 | 
						|
	assert.Equal(t, "base", m.buildMinioPath("."))
 | 
						|
	assert.Equal(t, "base/a", m.buildMinioPath("/a"))
 | 
						|
	assert.Equal(t, "base/a/b", m.buildMinioPath("/a/b/"))
 | 
						|
	assert.Equal(t, "base/", m.buildMinioDirPrefix(""))
 | 
						|
	assert.Equal(t, "base/a/", m.buildMinioDirPrefix("/a/"))
 | 
						|
}
 | 
						|
 | 
						|
func TestS3StorageBadRequest(t *testing.T) {
 | 
						|
	if os.Getenv("CI") == "" {
 | 
						|
		t.Skip("S3Storage not present outside of CI")
 | 
						|
		return
 | 
						|
	}
 | 
						|
	cfg := &setting.Storage{
 | 
						|
		MinioConfig: setting.MinioStorageConfig{
 | 
						|
			Endpoint:        "minio:9000",
 | 
						|
			AccessKeyID:     "123456",
 | 
						|
			SecretAccessKey: "12345678",
 | 
						|
			Bucket:          "bucket",
 | 
						|
			Location:        "us-east-1",
 | 
						|
		},
 | 
						|
	}
 | 
						|
	message := "ERROR"
 | 
						|
	old := getBucketVersioning
 | 
						|
	defer func() { getBucketVersioning = old }()
 | 
						|
	getBucketVersioning = func(ctx context.Context, minioClient *minio.Client, bucket string) error {
 | 
						|
		return minio.ErrorResponse{
 | 
						|
			StatusCode: http.StatusBadRequest,
 | 
						|
			Code:       "FixtureError",
 | 
						|
			Message:    message,
 | 
						|
		}
 | 
						|
	}
 | 
						|
	_, err := NewStorage(setting.MinioStorageType, cfg)
 | 
						|
	assert.ErrorContains(t, err, message)
 | 
						|
}
 | 
						|
 | 
						|
func TestMinioCredentials(t *testing.T) {
 | 
						|
	const (
 | 
						|
		ExpectedAccessKey       = "ExampleAccessKeyID"
 | 
						|
		ExpectedSecretAccessKey = "ExampleSecretAccessKeyID"
 | 
						|
		// Use a FakeEndpoint for IAM credentials to avoid logging any
 | 
						|
		// potential real IAM credentials when running in EC2.
 | 
						|
		FakeEndpoint = "http://localhost"
 | 
						|
	)
 | 
						|
 | 
						|
	t.Run("Static Credentials", func(t *testing.T) {
 | 
						|
		cfg := setting.MinioStorageConfig{
 | 
						|
			AccessKeyID:     ExpectedAccessKey,
 | 
						|
			SecretAccessKey: ExpectedSecretAccessKey,
 | 
						|
			IamEndpoint:     FakeEndpoint,
 | 
						|
		}
 | 
						|
		creds := buildMinioCredentials(cfg)
 | 
						|
		v, err := creds.Get()
 | 
						|
 | 
						|
		assert.NoError(t, err)
 | 
						|
		assert.Equal(t, ExpectedAccessKey, v.AccessKeyID)
 | 
						|
		assert.Equal(t, ExpectedSecretAccessKey, v.SecretAccessKey)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("Chain", func(t *testing.T) {
 | 
						|
		cfg := setting.MinioStorageConfig{
 | 
						|
			IamEndpoint: FakeEndpoint,
 | 
						|
		}
 | 
						|
 | 
						|
		t.Run("EnvMinio", func(t *testing.T) {
 | 
						|
			t.Setenv("MINIO_ACCESS_KEY", ExpectedAccessKey+"Minio")
 | 
						|
			t.Setenv("MINIO_SECRET_KEY", ExpectedSecretAccessKey+"Minio")
 | 
						|
 | 
						|
			creds := buildMinioCredentials(cfg)
 | 
						|
			v, err := creds.Get()
 | 
						|
 | 
						|
			assert.NoError(t, err)
 | 
						|
			assert.Equal(t, ExpectedAccessKey+"Minio", v.AccessKeyID)
 | 
						|
			assert.Equal(t, ExpectedSecretAccessKey+"Minio", v.SecretAccessKey)
 | 
						|
		})
 | 
						|
 | 
						|
		t.Run("EnvAWS", func(t *testing.T) {
 | 
						|
			t.Setenv("AWS_ACCESS_KEY", ExpectedAccessKey+"AWS")
 | 
						|
			t.Setenv("AWS_SECRET_KEY", ExpectedSecretAccessKey+"AWS")
 | 
						|
 | 
						|
			creds := buildMinioCredentials(cfg)
 | 
						|
			v, err := creds.Get()
 | 
						|
 | 
						|
			assert.NoError(t, err)
 | 
						|
			assert.Equal(t, ExpectedAccessKey+"AWS", v.AccessKeyID)
 | 
						|
			assert.Equal(t, ExpectedSecretAccessKey+"AWS", v.SecretAccessKey)
 | 
						|
		})
 | 
						|
 | 
						|
		t.Run("FileMinio", func(t *testing.T) {
 | 
						|
			// prevent loading any actual credentials files from the user
 | 
						|
			t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/minio.json")
 | 
						|
			t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/fake")
 | 
						|
 | 
						|
			creds := buildMinioCredentials(cfg)
 | 
						|
			v, err := creds.Get()
 | 
						|
 | 
						|
			assert.NoError(t, err)
 | 
						|
			assert.Equal(t, ExpectedAccessKey+"MinioFile", v.AccessKeyID)
 | 
						|
			assert.Equal(t, ExpectedSecretAccessKey+"MinioFile", v.SecretAccessKey)
 | 
						|
		})
 | 
						|
 | 
						|
		t.Run("FileAWS", func(t *testing.T) {
 | 
						|
			// prevent loading any actual credentials files from the user
 | 
						|
			t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/fake.json")
 | 
						|
			t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/aws_credentials")
 | 
						|
 | 
						|
			creds := buildMinioCredentials(cfg)
 | 
						|
			v, err := creds.Get()
 | 
						|
 | 
						|
			assert.NoError(t, err)
 | 
						|
			assert.Equal(t, ExpectedAccessKey+"AWSFile", v.AccessKeyID)
 | 
						|
			assert.Equal(t, ExpectedSecretAccessKey+"AWSFile", v.SecretAccessKey)
 | 
						|
		})
 | 
						|
 | 
						|
		t.Run("IAM", func(t *testing.T) {
 | 
						|
			// prevent loading any actual credentials files from the user
 | 
						|
			t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/fake.json")
 | 
						|
			t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/fake")
 | 
						|
 | 
						|
			// Spawn a server to emulate the EC2 Instance Metadata
 | 
						|
			server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
						|
				// The client will actually make 3 requests here,
 | 
						|
				// first will be to get the IMDSv2 token, second to
 | 
						|
				// get the role, and third for the actual
 | 
						|
				// credentials. However, we can return credentials
 | 
						|
				// every request since we're not emulating a full
 | 
						|
				// IMDSv2 flow.
 | 
						|
				w.Write([]byte(`{"Code":"Success","AccessKeyId":"ExampleAccessKeyIDIAM","SecretAccessKey":"ExampleSecretAccessKeyIDIAM"}`))
 | 
						|
			}))
 | 
						|
			defer server.Close()
 | 
						|
 | 
						|
			// Use the provided EC2 Instance Metadata server
 | 
						|
			creds := buildMinioCredentials(setting.MinioStorageConfig{
 | 
						|
				IamEndpoint: server.URL,
 | 
						|
			})
 | 
						|
			v, err := creds.Get()
 | 
						|
 | 
						|
			assert.NoError(t, err)
 | 
						|
			assert.Equal(t, ExpectedAccessKey+"IAM", v.AccessKeyID)
 | 
						|
			assert.Equal(t, ExpectedSecretAccessKey+"IAM", v.SecretAccessKey)
 | 
						|
		})
 | 
						|
	})
 | 
						|
}
 |