From 742d357d946307216a070803a970663f10fa55ed Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Thu, 10 Sep 2020 19:59:33 +0100 Subject: [PATCH 1/9] Provide configuration to allow camo-media proxying Fix #916 Signed-off-by: Andrew Thornton --- custom/conf/app.example.ini | 4 +++ .../doc/advanced/config-cheat-sheet.en-us.md | 2 ++ modules/markup/camo.go | 35 +++++++++++++++++++ modules/markup/html.go | 9 +++++ modules/setting/setting.go | 4 +++ 5 files changed, 54 insertions(+) create mode 100644 modules/markup/camo.go diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index af3418f70c9b0..886569c17f4ed 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -514,6 +514,10 @@ PASSWORD_HASH_ALGO = argon2 CSRF_COOKIE_HTTP_ONLY = true ; Validate against https://haveibeenpwned.com/Passwords to see if a password has been exposed PASSWORD_CHECK_PWN = false +; Use a camo image proxy - leave empty to not use +CAMO_SERVER_URL = +; HMAC to encode urls with +CAMO_HMAC_KEY = [openid] ; 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 7f969add2c902..e7d144d803acf 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -345,6 +345,8 @@ set name for unique queues. Individual queues will default to - spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~`` - off - do not check password complexity - `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed. +- `CAMO_SERVER_URL`: ****: If you would like to use a camo proxy to proxy images from rendered content, set the camo server url here +- `CAMO_HMAC_KEY`: ****: Provide the HMAC key for encoding urls ## OpenID (`openid`) diff --git a/modules/markup/camo.go b/modules/markup/camo.go new file mode 100644 index 0000000000000..a75a27069d6c0 --- /dev/null +++ b/modules/markup/camo.go @@ -0,0 +1,35 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package markup + +import ( + "bytes" + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "strings" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" +) + +// CamoEncode encodes a lnk to fit with the go-camo and camo proxy links +func CamoEncode(link []byte) []byte { + if bytes.HasPrefix(link, []byte(setting.CamoServerURL)) || len(setting.CamoHMACKey) == 0 { + return link + } + + hmacKey := []byte(setting.CamoHMACKey) + mac := hmac.New(sha1.New, hmacKey) + _, _ = mac.Write(link) // hmac does not return errors + macSum := b64encode(mac.Sum(nil)) + encodedURL := b64encode(link) + + return []byte(util.URLJoin(setting.CamoServerURL, macSum, encodedURL)) +} + +func b64encode(data []byte) string { + return strings.TrimRight(base64.URLEncoding.EncodeToString(data), "=") +} diff --git a/modules/markup/html.go b/modules/markup/html.go index bef6269a69157..93c818a7a422a 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -377,8 +377,17 @@ func (ctx *postProcessCtx) visitNode(node *html.Node, visitText bool) { lnk := string(link) lnk = util.URLJoin(prefix, lnk) + link = []byte(lnk) } + if setting.CamoServerURL != "" { + lnk := string(link) + lnkURL, _ := url.Parse(lnk) + if lnkURL.IsAbs() && !strings.HasPrefix(lnk, setting.AppURL) { + // We should camo this url + link = CamoEncode(link) + } + } node.Attr[idx].Val = string(link) } } else if node.Data == "a" { diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 7d7eacba6f93b..c28ed98321c7e 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -147,6 +147,8 @@ var ( PasswordComplexity []string PasswordHashAlgo string PasswordCheckPwn bool + CamoServerURL string + CamoHMACKey string // UI settings UI = struct { @@ -746,6 +748,8 @@ func NewContext() { PasswordHashAlgo = sec.Key("PASSWORD_HASH_ALGO").MustString("argon2") CSRFCookieHTTPOnly = sec.Key("CSRF_COOKIE_HTTP_ONLY").MustBool(true) PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false) + CamoServerURL = sec.Key("CAMO_SERVER_URL").MustString("") + CamoHMACKey = sec.Key("CAMO_HMAC_KEY").MustString("") InternalToken = loadInternalToken(sec) From e62e675efe2b731460d402c97e567d0465a6844b Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Mar 2022 03:15:17 +0200 Subject: [PATCH 2/9] fix --- modules/markup/camo.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/markup/camo.go b/modules/markup/camo.go index a75a27069d6c0..cdd6c4a81d3e0 100644 --- a/modules/markup/camo.go +++ b/modules/markup/camo.go @@ -5,7 +5,6 @@ package markup import ( - "bytes" "crypto/hmac" "crypto/sha1" "encoding/base64" @@ -16,18 +15,17 @@ import ( ) // CamoEncode encodes a lnk to fit with the go-camo and camo proxy links -func CamoEncode(link []byte) []byte { - if bytes.HasPrefix(link, []byte(setting.CamoServerURL)) || len(setting.CamoHMACKey) == 0 { +func CamoEncode(link string) string { + if strings.HasPrefix(link, setting.CamoServerURL) || len(setting.CamoHMACKey) == 0 { return link } - hmacKey := []byte(setting.CamoHMACKey) - mac := hmac.New(sha1.New, hmacKey) - _, _ = mac.Write(link) // hmac does not return errors + mac := hmac.New(sha1.New, []byte(setting.CamoHMACKey)) + _, _ = mac.Write([]byte(link)) // hmac does not return errors macSum := b64encode(mac.Sum(nil)) - encodedURL := b64encode(link) + encodedURL := b64encode([]byte(link)) - return []byte(util.URLJoin(setting.CamoServerURL, macSum, encodedURL)) + return util.URLJoin(setting.CamoServerURL, macSum, encodedURL) } func b64encode(data []byte) string { From f9d6790e642fc40ebdf536f14ad211a59268daf1 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Mar 2022 03:32:46 +0200 Subject: [PATCH 3/9] address review and add option --- custom/conf/app.example.ini | 2 ++ docs/content/doc/advanced/config-cheat-sheet.en-us.md | 1 + modules/markup/camo.go | 4 ++-- modules/markup/html.go | 6 +++--- modules/setting/setting.go | 9 ++++++++- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 85d30cbc3827d..5ffd854adfa92 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -428,6 +428,8 @@ INTERNAL_TOKEN= ;CAMO_SERVER_URL = ;; HMAC to encode urls with ;CAMO_HMAC_KEY = +;; Set to true to use camo for https too lese only non https urls are proxyed +;CAMO_ALLWAYS = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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 d48110e39ef79..a035ae5a2b0d3 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -516,6 +516,7 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o - `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**: Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security. - `CAMO_SERVER_URL`: ****: If you would like to use a camo proxy to proxy images from rendered content, set the camo server url here - `CAMO_HMAC_KEY`: ****: Provide the HMAC key for encoding urls +- `CAMO_ALLWAYS`: **false**: Set to true to use camo for https too lese only non https urls are proxyed ## OpenID (`openid`) diff --git a/modules/markup/camo.go b/modules/markup/camo.go index cdd6c4a81d3e0..019ec93d2a238 100644 --- a/modules/markup/camo.go +++ b/modules/markup/camo.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. +// Copyright 2022 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -16,7 +16,7 @@ import ( // CamoEncode encodes a lnk to fit with the go-camo and camo proxy links func CamoEncode(link string) string { - if strings.HasPrefix(link, setting.CamoServerURL) || len(setting.CamoHMACKey) == 0 { + if strings.HasPrefix(link, setting.CamoServerURL) { return link } diff --git a/modules/markup/html.go b/modules/markup/html.go index 44fe91fe620ba..8068fe51b4664 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -387,9 +387,9 @@ func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node attr.Val = util.URLJoin(prefix, attr.Val) } if setting.CamoServerURL != "" { - lnkURL, _ := url.Parse(attr.Val) - if lnkURL.IsAbs() && !strings.HasPrefix(attr.Val, setting.AppURL) { - // We should camo this url + lnkURL, err := url.Parse(attr.Val) + if err != nil && lnkURL.IsAbs() && !strings.HasPrefix(attr.Val, setting.AppURL) && + (setting.CamoAllways || lnkURL.Scheme != "https") { attr.Val = CamoEncode(attr.Val) } } diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 103758d8a0c55..9fdfaaf79df7c 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -198,6 +198,7 @@ var ( SuccessfulTokensCacheSize int CamoServerURL string CamoHMACKey string + CamoAllways bool // UI settings UI = struct { @@ -914,9 +915,15 @@ func loadFromConf(allowEmpty bool, extraConfig string) { PasswordHashAlgo = sec.Key("PASSWORD_HASH_ALGO").MustString("pbkdf2") CSRFCookieHTTPOnly = sec.Key("CSRF_COOKIE_HTTP_ONLY").MustBool(true) PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false) + SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20) + CamoServerURL = sec.Key("CAMO_SERVER_URL").MustString("") CamoHMACKey = sec.Key("CAMO_HMAC_KEY").MustString("") - SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20) + CamoAllways = sec.Key("CAMO_ALLWAYS").MustBool(false) + if CamoServerURL != "" && CamoHMACKey == "" { + log.Error("CAMO_SERVER_URL is set but CAMO_HMAC_KEY is empty, skip media proxy settings") + CamoServerURL = "" + } InternalToken = loadInternalToken(sec) if InstallLock && InternalToken == "" { From 19bd41ec80cfe6db86772e1874fe4951b5b18932 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Mar 2022 03:35:39 +0200 Subject: [PATCH 4/9] compare setting once --- modules/markup/html.go | 2 +- modules/setting/setting.go | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 8068fe51b4664..ba08d534776e2 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -386,7 +386,7 @@ func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node attr.Val = util.URLJoin(prefix, attr.Val) } - if setting.CamoServerURL != "" { + if setting.CamoEnabled { lnkURL, err := url.Parse(attr.Val) if err != nil && lnkURL.IsAbs() && !strings.HasPrefix(attr.Val, setting.AppURL) && (setting.CamoAllways || lnkURL.Scheme != "https") { diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 9fdfaaf79df7c..33f6796decc70 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -196,6 +196,7 @@ var ( PasswordHashAlgo string PasswordCheckPwn bool SuccessfulTokensCacheSize int + CamoEnabled bool CamoServerURL string CamoHMACKey string CamoAllways bool @@ -920,9 +921,12 @@ func loadFromConf(allowEmpty bool, extraConfig string) { CamoServerURL = sec.Key("CAMO_SERVER_URL").MustString("") CamoHMACKey = sec.Key("CAMO_HMAC_KEY").MustString("") CamoAllways = sec.Key("CAMO_ALLWAYS").MustBool(false) - if CamoServerURL != "" && CamoHMACKey == "" { - log.Error("CAMO_SERVER_URL is set but CAMO_HMAC_KEY is empty, skip media proxy settings") - CamoServerURL = "" + if CamoServerURL != "" { + if CamoHMACKey == "" { + log.Error("CAMO_SERVER_URL is set but CAMO_HMAC_KEY is empty, skip media proxy settings") + } else { + CamoEnabled = true + } } InternalToken = loadInternalToken(sec) From 664b16d56a7407e589c7fabf77bb3d5fdc9f60ba Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Mar 2022 04:04:31 +0200 Subject: [PATCH 5/9] be able to unit test --- modules/markup/camo.go | 12 ++++++++++ modules/markup/camo_test.go | 44 +++++++++++++++++++++++++++++++++++++ modules/markup/html.go | 8 +------ 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 modules/markup/camo_test.go diff --git a/modules/markup/camo.go b/modules/markup/camo.go index 019ec93d2a238..3a97b380f9fc4 100644 --- a/modules/markup/camo.go +++ b/modules/markup/camo.go @@ -8,6 +8,7 @@ import ( "crypto/hmac" "crypto/sha1" "encoding/base64" + "net/url" "strings" "code.gitea.io/gitea/modules/setting" @@ -31,3 +32,14 @@ func CamoEncode(link string) string { func b64encode(data []byte) string { return strings.TrimRight(base64.URLEncoding.EncodeToString(data), "=") } + +func camoHandleLink(link string) string { + if setting.CamoEnabled { + lnkURL, err := url.Parse(link) + if err == nil && lnkURL.IsAbs() && !strings.HasPrefix(link, setting.AppURL) && + (setting.CamoAllways || lnkURL.Scheme != "https") { + return CamoEncode(link) + } + } + return link +} diff --git a/modules/markup/camo_test.go b/modules/markup/camo_test.go new file mode 100644 index 0000000000000..e4641d46fe7f4 --- /dev/null +++ b/modules/markup/camo_test.go @@ -0,0 +1,44 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package markup + +import ( + "testing" + + "code.gitea.io/gitea/modules/setting" + "github.com/stretchr/testify/assert" +) + +func TestCamoHandleLink(t *testing.T) { + setting.AppURL = "https://gitea.com" + // Test media proxy + setting.CamoEnabled = true + setting.CamoServerURL = "https://image.proxy" + setting.CamoHMACKey = "geheim" + + assert.Equal(t, + "https://gitea.com/img.jpg", + camoHandleLink("https://gitea.com/img.jpg")) + assert.Equal(t, + "https://testimages.org/img.jpg", + camoHandleLink("https://testimages.org/img.jpg")) + assert.Equal(t, + "https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc", + camoHandleLink("http://testimages.org/img.jpg")) + + setting.CamoAllways = true + assert.Equal(t, + "https://gitea.com/img.jpg", + camoHandleLink("https://gitea.com/img.jpg")) + assert.Equal(t, + "https://image.proxy/tkdlvmqpbIr7SjONfHNgEU622y0/aHR0cHM6Ly90ZXN0aW1hZ2VzLm9yZy9pbWcuanBn", + camoHandleLink("https://testimages.org/img.jpg")) + assert.Equal(t, + "https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc", + camoHandleLink("http://testimages.org/img.jpg")) + + // Restore previous settings + setting.CamoEnabled = false +} diff --git a/modules/markup/html.go b/modules/markup/html.go index ba08d534776e2..af6ae3bf16822 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -386,13 +386,7 @@ func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node attr.Val = util.URLJoin(prefix, attr.Val) } - if setting.CamoEnabled { - lnkURL, err := url.Parse(attr.Val) - if err != nil && lnkURL.IsAbs() && !strings.HasPrefix(attr.Val, setting.AppURL) && - (setting.CamoAllways || lnkURL.Scheme != "https") { - attr.Val = CamoEncode(attr.Val) - } - } + attr.Val = camoHandleLink(attr.Val) node.Attr[i] = attr } } else if node.Data == "a" { From 7cd58ec1afdafc82d9fc008408b425b28ea7937d Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Mar 2022 05:10:09 +0200 Subject: [PATCH 6/9] own settings section --- custom/conf/app.example.ini | 19 ++++++++---- .../doc/advanced/config-cheat-sheet.en-us.md | 10 +++++-- modules/markup/camo.go | 10 +++---- modules/markup/camo_test.go | 1 + modules/setting/setting.go | 30 +++++++++---------- 5 files changed, 41 insertions(+), 29 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 5ffd854adfa92..39f2a5a1e6a7f 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -423,13 +423,20 @@ INTERNAL_TOKEN= ;; Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. ;; This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security. ;SUCCESSFUL_TOKENS_CACHE_SIZE = 20 -;; -;; Use a camo image proxy - leave empty to not use -;CAMO_SERVER_URL = -;; HMAC to encode urls with -;CAMO_HMAC_KEY = + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[camo] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; if the camo is enabled +;ENABLED = false +;; url to a camo image proxy, it **is required** if camo is enabled. +;SERVER_URL = +;; HMAC to encode urls with, it **is required** if camo is enabled. +;HMAC_KEY = ;; Set to true to use camo for https too lese only non https urls are proxyed -;CAMO_ALLWAYS = false +;ALLWAYS = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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 a035ae5a2b0d3..5135bfd163960 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -514,9 +514,13 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o - off - do not check password complexity - `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed. - `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**: Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security. -- `CAMO_SERVER_URL`: ****: If you would like to use a camo proxy to proxy images from rendered content, set the camo server url here -- `CAMO_HMAC_KEY`: ****: Provide the HMAC key for encoding urls -- `CAMO_ALLWAYS`: **false**: Set to true to use camo for https too lese only non https urls are proxyed + +## Camo (`camo`) + +- `ENABLED`: **false**: If camo is enabled +- `SERVER_URL`: ****: url of camo server, it **is required** if camo is enabled. +- `HMAC_KEY`: ****: Provide the HMAC key for encoding urls, it **is required** if camo is enabled. +- `ALLWAYS`: **false**: Set to true to use camo for https too lese only non https urls are proxyed ## OpenID (`openid`) diff --git a/modules/markup/camo.go b/modules/markup/camo.go index 3a97b380f9fc4..71572c07be9b3 100644 --- a/modules/markup/camo.go +++ b/modules/markup/camo.go @@ -17,16 +17,16 @@ import ( // CamoEncode encodes a lnk to fit with the go-camo and camo proxy links func CamoEncode(link string) string { - if strings.HasPrefix(link, setting.CamoServerURL) { + if strings.HasPrefix(link, setting.Camo.ServerURL) { return link } - mac := hmac.New(sha1.New, []byte(setting.CamoHMACKey)) + mac := hmac.New(sha1.New, []byte(setting.Camo.HMACKey)) _, _ = mac.Write([]byte(link)) // hmac does not return errors macSum := b64encode(mac.Sum(nil)) encodedURL := b64encode([]byte(link)) - return util.URLJoin(setting.CamoServerURL, macSum, encodedURL) + return util.URLJoin(setting.Camo.ServerURL, macSum, encodedURL) } func b64encode(data []byte) string { @@ -34,10 +34,10 @@ func b64encode(data []byte) string { } func camoHandleLink(link string) string { - if setting.CamoEnabled { + if setting.Camo.Enabled { lnkURL, err := url.Parse(link) if err == nil && lnkURL.IsAbs() && !strings.HasPrefix(link, setting.AppURL) && - (setting.CamoAllways || lnkURL.Scheme != "https") { + (setting.Camo.Allways || lnkURL.Scheme != "https") { return CamoEncode(link) } } diff --git a/modules/markup/camo_test.go b/modules/markup/camo_test.go index e4641d46fe7f4..a00002764ab9d 100644 --- a/modules/markup/camo_test.go +++ b/modules/markup/camo_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/modules/setting" + "github.com/stretchr/testify/assert" ) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 33f6796decc70..c80fc3d2040ec 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -196,10 +196,13 @@ var ( PasswordHashAlgo string PasswordCheckPwn bool SuccessfulTokensCacheSize int - CamoEnabled bool - CamoServerURL string - CamoHMACKey string - CamoAllways bool + + Camo = struct { + Enabled bool + ServerURL string `ini:"SERVER_URL"` + HMACKey string `ini:"HMAC_KEY"` + Allways bool + }{} // UI settings UI = struct { @@ -918,17 +921,6 @@ func loadFromConf(allowEmpty bool, extraConfig string) { PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false) SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20) - CamoServerURL = sec.Key("CAMO_SERVER_URL").MustString("") - CamoHMACKey = sec.Key("CAMO_HMAC_KEY").MustString("") - CamoAllways = sec.Key("CAMO_ALLWAYS").MustBool(false) - if CamoServerURL != "" { - if CamoHMACKey == "" { - log.Error("CAMO_SERVER_URL is set but CAMO_HMAC_KEY is empty, skip media proxy settings") - } else { - CamoEnabled = true - } - } - InternalToken = loadInternalToken(sec) if InstallLock && InternalToken == "" { // if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate @@ -1034,6 +1026,14 @@ func loadFromConf(allowEmpty bool, extraConfig string) { log.Fatal("Failed to map API settings: %v", err) } else if err = Cfg.Section("metrics").MapTo(&Metrics); err != nil { log.Fatal("Failed to map Metrics settings: %v", err) + } else if err = Cfg.Section("camo").MapTo(&Camo); err != nil { + log.Fatal("Failed to map Camo settings: %v", err) + } + + if Camo.Enabled { + if Camo.ServerURL == "" || Camo.HMACKey == "" { + log.Fatal(`Camo settings require "SERVER_URL" and HMAC_KEY`) + } } u := *appURL From dc6d0bde73a3f6d87df4679838e4ddd877def7dd Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Mar 2022 05:14:32 +0200 Subject: [PATCH 7/9] add content type comments --- custom/conf/app.example.ini | 3 +++ docs/content/doc/advanced/config-cheat-sheet.en-us.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 39f2a5a1e6a7f..516d61452e492 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -429,6 +429,9 @@ INTERNAL_TOKEN= [camo] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; At the moment we only support images +;; ;; if the camo is enabled ;ENABLED = false ;; url to a camo image proxy, it **is required** if camo is enabled. 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 5135bfd163960..ae40e0954b583 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -517,7 +517,7 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o ## Camo (`camo`) -- `ENABLED`: **false**: If camo is enabled +- `ENABLED`: **false**: Enable media proxy, we support images only at the moment. - `SERVER_URL`: ****: url of camo server, it **is required** if camo is enabled. - `HMAC_KEY`: ****: Provide the HMAC key for encoding urls, it **is required** if camo is enabled. - `ALLWAYS`: **false**: Set to true to use camo for https too lese only non https urls are proxyed From 40cd0d0c5dcbdcf1fb69a29ef891cc65b1dc76ac Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 29 Mar 2022 15:27:55 +0800 Subject: [PATCH 8/9] Add comments for camo-proxy to describe the purposes. --- modules/markup/camo.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/markup/camo.go b/modules/markup/camo.go index 71572c07be9b3..f804447f2def3 100644 --- a/modules/markup/camo.go +++ b/modules/markup/camo.go @@ -15,7 +15,9 @@ import ( "code.gitea.io/gitea/modules/util" ) -// CamoEncode encodes a lnk to fit with the go-camo and camo proxy links +// CamoEncode encodes a lnk to fit with the go-camo and camo proxy links. The purposes of camo-proxy are: +// 1. Allow accessing "http://" images on a HTTPS site by using the "https://" URLs provided by camo-proxy. +// 2. Hide the visitor's real IP (protect privacy) when accessing external images. func CamoEncode(link string) string { if strings.HasPrefix(link, setting.Camo.ServerURL) { return link From 6a68631589fa3a1a9afe918c2aaffb82ab9d8fc8 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 29 Mar 2022 15:42:46 +0800 Subject: [PATCH 9/9] fix unit test --- modules/markup/camo_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/markup/camo_test.go b/modules/markup/camo_test.go index a00002764ab9d..cc917039d8ee7 100644 --- a/modules/markup/camo_test.go +++ b/modules/markup/camo_test.go @@ -15,9 +15,9 @@ import ( func TestCamoHandleLink(t *testing.T) { setting.AppURL = "https://gitea.com" // Test media proxy - setting.CamoEnabled = true - setting.CamoServerURL = "https://image.proxy" - setting.CamoHMACKey = "geheim" + setting.Camo.Enabled = true + setting.Camo.ServerURL = "https://image.proxy" + setting.Camo.HMACKey = "geheim" assert.Equal(t, "https://gitea.com/img.jpg", @@ -29,7 +29,7 @@ func TestCamoHandleLink(t *testing.T) { "https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc", camoHandleLink("http://testimages.org/img.jpg")) - setting.CamoAllways = true + setting.Camo.Allways = true assert.Equal(t, "https://gitea.com/img.jpg", camoHandleLink("https://gitea.com/img.jpg")) @@ -41,5 +41,5 @@ func TestCamoHandleLink(t *testing.T) { camoHandleLink("http://testimages.org/img.jpg")) // Restore previous settings - setting.CamoEnabled = false + setting.Camo.Enabled = false }