From 0e7bec1849d2d7a87713abe494b4d3ef416180d4 Mon Sep 17 00:00:00 2001
From: Yarden Shoham <hrsi88@gmail.com>
Date: Mon, 27 Feb 2023 18:26:13 +0200
Subject: [PATCH] Add InsecureSkipVerify to Minio Client for Storage (#23166)

Allows using Minio with untrusted certificates

Closes #23128

Signed-off-by: Yarden Shoham <hrsi88@gmail.com>
---
 custom/conf/app.example.ini                   |  6 +++++
 .../doc/advanced/config-cheat-sheet.en-us.md  |  6 +++++
 .../doc/advanced/config-cheat-sheet.zh-cn.md  |  2 ++
 modules/setting/storage.go                    |  1 +
 modules/storage/minio.go                      | 22 +++++++++++--------
 5 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index b478785a07..b7875c12dd 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -1871,6 +1871,9 @@ ROUTER = console
 ;;
 ;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
 ;MINIO_USE_SSL = false
+;;
+;; Minio skip SSL verification available when STORAGE_TYPE is `minio`
+;MINIO_INSECURE_SKIP_VERIFY = false
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2552,6 +2555,9 @@ ROUTER = console
 ;;
 ;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
 ;MINIO_USE_SSL = false
+;;
+;; Minio skip SSL verification available when STORAGE_TYPE is `minio`
+;MINIO_INSECURE_SKIP_VERIFY = false
 
 ;[proxy]
 ;; Enable the proxy, all requests to external via HTTP will be affected
diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
index 462556c9b6..c4ff8bafb9 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -854,6 +854,7 @@ Default templates for project boards:
 - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when STORAGE_TYPE is `minio`
 - `MINIO_BASE_PATH`: **attachments/**: Minio base path on the bucket only available when STORAGE_TYPE is `minio`
 - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when STORAGE_TYPE is `minio`
+- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
 
 ## Log (`log`)
 
@@ -1268,6 +1269,7 @@ is `data/lfs` and the default of `MINIO_BASE_PATH` is `lfs/`.
 - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio`
 - `MINIO_BASE_PATH`: **lfs/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio`
 - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
+- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
 
 ## Storage (`storage`)
 
@@ -1280,6 +1282,7 @@ Default storage configuration for attachments, lfs, avatars and etc.
 - `MINIO_BUCKET`: **gitea**: Minio bucket to store the data only available when `STORAGE_TYPE` is `minio`
 - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio`
 - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
+- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
 
 And you can also define a customize storage like below:
 
@@ -1298,6 +1301,8 @@ MINIO_BUCKET = gitea
 MINIO_LOCATION = us-east-1
 ; Minio enabled ssl only available when STORAGE_TYPE is `minio`
 MINIO_USE_SSL = false
+; Minio skip SSL verification available when STORAGE_TYPE is `minio`
+MINIO_INSECURE_SKIP_VERIFY = false
 ```
 
 And used by `[attachment]`, `[lfs]` and etc. as `STORAGE_TYPE`.
@@ -1318,6 +1323,7 @@ is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`.
 - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio`
 - `MINIO_BASE_PATH`: **repo-archive/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio`
 - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
+- `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio`
 
 ## Proxy (`proxy`)
 
diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md
index 2598f16a14..aae64d97ba 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md
@@ -431,6 +431,8 @@ MINIO_BUCKET = gitea
 MINIO_LOCATION = us-east-1
 ; Minio enabled ssl only available when STORAGE_TYPE is `minio`
 MINIO_USE_SSL = false
+; Minio skip SSL verification available when STORAGE_TYPE is `minio`
+MINIO_INSECURE_SKIP_VERIFY = false
 ```
 
 然后你在 `[attachment]`, `[lfs]` 等中可以把这个名字用作 `STORAGE_TYPE` 的值。
diff --git a/modules/setting/storage.go b/modules/setting/storage.go
index 9197c5f8bb..4d401614e4 100644
--- a/modules/setting/storage.go
+++ b/modules/setting/storage.go
@@ -41,6 +41,7 @@ func getStorage(rootCfg ConfigProvider, name, typ string, targetSec *ini.Section
 	sec.Key("MINIO_BUCKET").MustString("gitea")
 	sec.Key("MINIO_LOCATION").MustString("us-east-1")
 	sec.Key("MINIO_USE_SSL").MustBool(false)
+	sec.Key("MINIO_INSECURE_SKIP_VERIFY").MustBool(false)
 
 	if targetSec == nil {
 		targetSec, _ = rootCfg.NewSection(name)
diff --git a/modules/storage/minio.go b/modules/storage/minio.go
index 912f820ede..c427d8d7e3 100644
--- a/modules/storage/minio.go
+++ b/modules/storage/minio.go
@@ -5,7 +5,9 @@ package storage
 
 import (
 	"context"
+	"crypto/tls"
 	"io"
+	"net/http"
 	"net/url"
 	"os"
 	"path"
@@ -42,13 +44,14 @@ const MinioStorageType Type = "minio"
 
 // MinioStorageConfig represents the configuration for a minio storage
 type MinioStorageConfig struct {
-	Endpoint        string `ini:"MINIO_ENDPOINT"`
-	AccessKeyID     string `ini:"MINIO_ACCESS_KEY_ID"`
-	SecretAccessKey string `ini:"MINIO_SECRET_ACCESS_KEY"`
-	Bucket          string `ini:"MINIO_BUCKET"`
-	Location        string `ini:"MINIO_LOCATION"`
-	BasePath        string `ini:"MINIO_BASE_PATH"`
-	UseSSL          bool   `ini:"MINIO_USE_SSL"`
+	Endpoint           string `ini:"MINIO_ENDPOINT"`
+	AccessKeyID        string `ini:"MINIO_ACCESS_KEY_ID"`
+	SecretAccessKey    string `ini:"MINIO_SECRET_ACCESS_KEY"`
+	Bucket             string `ini:"MINIO_BUCKET"`
+	Location           string `ini:"MINIO_LOCATION"`
+	BasePath           string `ini:"MINIO_BASE_PATH"`
+	UseSSL             bool   `ini:"MINIO_USE_SSL"`
+	InsecureSkipVerify bool   `ini:"MINIO_INSECURE_SKIP_VERIFY"`
 }
 
 // MinioStorage returns a minio bucket storage
@@ -90,8 +93,9 @@ func NewMinioStorage(ctx context.Context, cfg interface{}) (ObjectStorage, error
 	log.Info("Creating Minio storage at %s:%s with base path %s", config.Endpoint, config.Bucket, config.BasePath)
 
 	minioClient, err := minio.New(config.Endpoint, &minio.Options{
-		Creds:  credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""),
-		Secure: config.UseSSL,
+		Creds:     credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""),
+		Secure:    config.UseSSL,
+		Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}},
 	})
 	if err != nil {
 		return nil, convertMinioErr(err)