From 21c91b7dff29107eeadfeec9ed6305fd43fa49b4 Mon Sep 17 00:00:00 2001
From: Jason Song <i@wolfogre.com>
Date: Tue, 17 Jan 2023 23:00:19 +0800
Subject: [PATCH] Set disable_gravatar/enable_federated_avatar when offline
 mode is true (#22479)

When offline mode is true, we should set `disable_gravatar` to `true`
and `enable_federated_avatar` to `false` in system settings.
---
 models/system/setting.go    | 10 ++++++++++
 routers/web/admin/config.go | 27 +++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/models/system/setting.go b/models/system/setting.go
index 0701c4bf48..50fe17498e 100644
--- a/models/system/setting.go
+++ b/models/system/setting.go
@@ -268,6 +268,16 @@ func Init() error {
 	if setting_module.OfflineMode {
 		disableGravatar = true
 		enableFederatedAvatar = false
+		if !GetSettingBool(KeyPictureDisableGravatar) {
+			if err := SetSettingNoVersion(KeyPictureDisableGravatar, "true"); err != nil {
+				return fmt.Errorf("Failed to set setting %q: %w", KeyPictureDisableGravatar, err)
+			}
+		}
+		if GetSettingBool(KeyPictureEnableFederatedAvatar) {
+			if err := SetSettingNoVersion(KeyPictureEnableFederatedAvatar, "false"); err != nil {
+				return fmt.Errorf("Failed to set setting %q: %w", KeyPictureEnableFederatedAvatar, err)
+			}
+		}
 	}
 
 	if enableFederatedAvatar || !disableGravatar {
diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go
index eaa02588ca..1f71e81785 100644
--- a/routers/web/admin/config.go
+++ b/routers/web/admin/config.go
@@ -5,9 +5,11 @@
 package admin
 
 import (
+	"fmt"
 	"net/http"
 	"net/url"
 	"os"
+	"strconv"
 	"strings"
 
 	system_model "code.gitea.io/gitea/models/system"
@@ -201,6 +203,16 @@ func ChangeConfig(ctx *context.Context) {
 	value := ctx.FormString("value")
 	version := ctx.FormInt("version")
 
+	if check, ok := changeConfigChecks[key]; ok {
+		if err := check(ctx, value); err != nil {
+			log.Warn("refused to set setting: %v", err)
+			ctx.JSON(http.StatusOK, map[string]string{
+				"err": ctx.Tr("admin.config.set_setting_failed", key),
+			})
+			return
+		}
+	}
+
 	if err := system_model.SetSetting(&system_model.Setting{
 		SettingKey:   key,
 		SettingValue: value,
@@ -217,3 +229,18 @@ func ChangeConfig(ctx *context.Context) {
 		"version": version + 1,
 	})
 }
+
+var changeConfigChecks = map[string]func(ctx *context.Context, newValue string) error{
+	system_model.KeyPictureDisableGravatar: func(_ *context.Context, newValue string) error {
+		if v, _ := strconv.ParseBool(newValue); setting.OfflineMode && !v {
+			return fmt.Errorf("%q should be true when OFFLINE_MODE is true", system_model.KeyPictureDisableGravatar)
+		}
+		return nil
+	},
+	system_model.KeyPictureEnableFederatedAvatar: func(_ *context.Context, newValue string) error {
+		if v, _ := strconv.ParseBool(newValue); setting.OfflineMode && v {
+			return fmt.Errorf("%q cannot be false when OFFLINE_MODE is true", system_model.KeyPictureEnableFederatedAvatar)
+		}
+		return nil
+	},
+}