0
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-12-09 00:21:31 +01:00

Merge 65d051eedb6c507176a2f8a783312afaa7333de7 into c287a8cdb589172bbba8969357a671dabc6596bd

This commit is contained in:
Lunny Xiao 2025-12-05 11:33:32 +01:00 committed by GitHub
commit d47582dd29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 325 additions and 179 deletions

View File

@ -849,13 +849,16 @@ LEVEL = Info
;; ;;
;; Default value for KeepEmailPrivate ;; Default value for KeepEmailPrivate
;; Each new user will get the value of this setting copied into their profile ;; Each new user will get the value of this setting copied into their profile
;; Deprecated: Moved to database based configuration which can be set from UI
;DEFAULT_KEEP_EMAIL_PRIVATE = false ;DEFAULT_KEEP_EMAIL_PRIVATE = false
;; ;;
;; Default value for AllowCreateOrganization ;; Default value for AllowCreateOrganization
;; Every new user will have rights set to create organizations depending on this setting ;; Every new user will have rights set to create organizations depending on this setting
;; Deprecated: Moved to database based configuration which can be set from UI
;DEFAULT_ALLOW_CREATE_ORGANIZATION = true ;DEFAULT_ALLOW_CREATE_ORGANIZATION = true
;; Default value for IsRestricted ;; Default value for IsRestricted
;; Every new user will have restricted permissions depending on this setting ;; Every new user will have restricted permissions depending on this setting
;; Deprecated: Moved to database based configuration which can be set from UI
;DEFAULT_USER_IS_RESTRICTED = false ;DEFAULT_USER_IS_RESTRICTED = false
;; ;;
;; Either "public", "limited" or "private", default is "public" ;; Either "public", "limited" or "private", default is "public"
@ -875,13 +878,16 @@ LEVEL = Info
;; ;;
;; Default value for DefaultOrgMemberVisible ;; Default value for DefaultOrgMemberVisible
;; True will make the membership of the users visible when added to the organisation ;; True will make the membership of the users visible when added to the organisation
;; Deprecated: Moved to database based configuration which can be set from UI
;DEFAULT_ORG_MEMBER_VISIBLE = false ;DEFAULT_ORG_MEMBER_VISIBLE = false
;; ;;
;; Default value for EnableDependencies ;; Default value for EnableDependencies
;; Repositories will use dependencies by default depending on this setting ;; Repositories will use dependencies by default depending on this setting
;; Deprecated: Moved to database based configuration which can be set from UI
;DEFAULT_ENABLE_DEPENDENCIES = true ;DEFAULT_ENABLE_DEPENDENCIES = true
;; ;;
;; Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting. ;; Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting.
;; Deprecated: Moved to database based configuration which can be set from UI
;ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true ;ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true
;; ;;
;; Default map service. No external API support has been included. A service has to allow ;; Default map service. No external API support has been included. A service has to allow
@ -894,17 +900,21 @@ LEVEL = Info
; USER_LOCATION_MAP_URL = ; USER_LOCATION_MAP_URL =
;; ;;
;; Enable heatmap on users profiles. ;; Enable heatmap on users profiles.
;; Deprecated: Moved to database based configuration which can be set from UI
;ENABLE_USER_HEATMAP = true ;ENABLE_USER_HEATMAP = true
;; ;;
;; Enable Timetracking ;; Enable Timetracking
;; Deprecated: Moved to database based configuration which can be set from UI
;ENABLE_TIMETRACKING = true ;ENABLE_TIMETRACKING = true
;; ;;
;; Default value for EnableTimetracking ;; Default value for EnableTimetracking
;; Repositories will use timetracking by default depending on this setting ;; Repositories will use timetracking by default depending on this setting
;; Deprecated: Moved to database based configuration which can be set from UI
;DEFAULT_ENABLE_TIMETRACKING = true ;DEFAULT_ENABLE_TIMETRACKING = true
;; ;;
;; Default value for AllowOnlyContributorsToTrackTime ;; Default value for AllowOnlyContributorsToTrackTime
;; Only users with write permissions can track time if this is true ;; Only users with write permissions can track time if this is true
;; Deprecated: Moved to database based configuration which can be set from UI
;DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME = true ;DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME = true
;; ;;
;; Value for the domain part of the user's email address in the git log if user ;; Value for the domain part of the user's email address in the git log if user
@ -923,10 +933,12 @@ LEVEL = Info
;; Default value for AutoWatchNewRepos ;; Default value for AutoWatchNewRepos
;; When adding a repo to a team or creating a new repo all team members will watch the ;; When adding a repo to a team or creating a new repo all team members will watch the
;; repo automatically if enabled ;; repo automatically if enabled
;; Deprecated: Moved to database based configuration which can be set from UI
;AUTO_WATCH_NEW_REPOS = true ;AUTO_WATCH_NEW_REPOS = true
;; ;;
;; Default value for AutoWatchOnChanges ;; Default value for AutoWatchOnChanges
;; Make the user watch a repository When they commit for the first time ;; Make the user watch a repository When they commit for the first time
;; Deprecated: Moved to database based configuration which can be set from UI
;AUTO_WATCH_ON_CHANGES = false ;AUTO_WATCH_ON_CHANGES = false
;; ;;
;; Minimum amount of time a user must exist before comments are kept when the user is deleted. ;; Minimum amount of time a user must exist before comments are kept when the user is deleted.

View File

@ -7,8 +7,10 @@ import (
"testing" "testing"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -32,7 +34,11 @@ func TestIssueList_LoadRepositories(t *testing.T) {
func TestIssueList_LoadAttributes(t *testing.T) { func TestIssueList_LoadAttributes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
setting.Service.EnableTimetracking = true system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.EnableTimeTracking.DynKey(): "true",
})
config.GetDynGetter().InvalidateCache()
issueList := issues_model.IssueList{ issueList := issues_model.IssueList{
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}), unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}),
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}), unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}),

View File

@ -14,9 +14,11 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"xorm.io/builder" "xorm.io/builder"
@ -390,7 +392,10 @@ func TestCountIssues(t *testing.T) {
func TestIssueLoadAttributes(t *testing.T) { func TestIssueLoadAttributes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
setting.Service.EnableTimetracking = true system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.EnableTimeTracking.DynKey(): "true",
})
config.GetDynGetter().InvalidateCache()
issueList := issues_model.IssueList{ issueList := issues_model.IssueList{
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}), unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}),

View File

@ -4,6 +4,7 @@
package v1_6 package v1_6
import ( import (
"context"
"fmt" "fmt"
"time" "time"
@ -99,7 +100,7 @@ func AddIssueDependencies(x *xorm.Engine) (err error) {
unit.Config = make(map[string]any) unit.Config = make(map[string]any)
} }
if _, ok := unit.Config["EnableDependencies"]; !ok { if _, ok := unit.Config["EnableDependencies"]; !ok {
unit.Config["EnableDependencies"] = setting.Service.DefaultEnableDependencies unit.Config["EnableDependencies"] = setting.Config().Service.DefaultEnableDependencies.Value(context.Background())
} }
if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil { if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil {
return err return err

View File

@ -326,7 +326,7 @@ func CreateOrganization(ctx context.Context, org *Organization, owner *user_mode
if err = db.Insert(ctx, &OrgUser{ if err = db.Insert(ctx, &OrgUser{
UID: owner.ID, UID: owner.ID,
OrgID: org.ID, OrgID: org.ID,
IsPublic: setting.Service.DefaultOrgMemberVisible, IsPublic: setting.Config().Service.DefaultOrgMemberVisible.Value(ctx),
}); err != nil { }); err != nil {
return fmt.Errorf("insert org-user relation: %w", err) return fmt.Errorf("insert org-user relation: %w", err)
} }
@ -508,7 +508,7 @@ func AddOrgUser(ctx context.Context, orgID, uid int64) error {
ou := &OrgUser{ ou := &OrgUser{
UID: uid, UID: uid,
OrgID: orgID, OrgID: orgID,
IsPublic: setting.Service.DefaultOrgMemberVisible, IsPublic: setting.Config().Service.DefaultOrgMemberVisible.Value(ctx),
} }
if err := db.Insert(ctx, ou); err != nil { if err := db.Insert(ctx, ou); err != nil {

View File

@ -8,9 +8,11 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -141,12 +143,19 @@ func TestAddOrgUser(t *testing.T) {
assert.Equal(t, expectedNumMembers, org.NumMembers) assert.Equal(t, expectedNumMembers, org.NumMembers)
} }
setting.Service.DefaultOrgMemberVisible = false system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.DefaultOrgMemberVisible.DynKey(): "false",
})
config.GetDynGetter().InvalidateCache()
testSuccess(3, 5, false) testSuccess(3, 5, false)
testSuccess(3, 5, false) testSuccess(3, 5, false)
testSuccess(6, 2, false) testSuccess(6, 2, false)
setting.Service.DefaultOrgMemberVisible = true system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.DefaultOrgMemberVisible.DynKey(): "true",
})
config.GetDynGetter().InvalidateCache()
testSuccess(6, 3, true) testSuccess(6, 3, true)
unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{}) unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{})

View File

@ -11,29 +11,22 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
// ___________.__ ___________ __
// \__ ___/|__| _____ ___\__ ___/___________ ____ | | __ ___________
// | | | |/ \_/ __ \| | \_ __ \__ \ _/ ___\| |/ // __ \_ __ \
// | | | | Y Y \ ___/| | | | \// __ \\ \___| <\ ___/| | \/
// |____| |__|__|_| /\___ >____| |__| (____ /\___ >__|_ \\___ >__|
// \/ \/ \/ \/ \/ \/
// CanEnableTimetracker returns true when the server admin enabled time tracking // CanEnableTimetracker returns true when the server admin enabled time tracking
// This overrules IsTimetrackerEnabled // This overrules IsTimetrackerEnabled
func (repo *Repository) CanEnableTimetracker() bool { func (repo *Repository) CanEnableTimetracker(ctx context.Context) bool {
return setting.Service.EnableTimetracking return setting.Config().Service.EnableTimeTracking.Value(ctx)
} }
// IsTimetrackerEnabled returns whether or not the timetracker is enabled. It returns the default value from config if an error occurs. // IsTimetrackerEnabled returns whether or not the timetracker is enabled. It returns the default value from config if an error occurs.
func (repo *Repository) IsTimetrackerEnabled(ctx context.Context) bool { func (repo *Repository) IsTimetrackerEnabled(ctx context.Context) bool {
if !setting.Service.EnableTimetracking { if !setting.Config().Service.EnableTimeTracking.Value(ctx) {
return false return false
} }
var u *RepoUnit var u *RepoUnit
var err error var err error
if u, err = repo.GetUnit(ctx, unit.TypeIssues); err != nil { if u, err = repo.GetUnit(ctx, unit.TypeIssues); err != nil {
return setting.Service.DefaultEnableTimetracking return setting.Config().Service.DefaultEnableTimeTracking.Value(ctx)
} }
return u.IssuesConfig().EnableTimetracker return u.IssuesConfig().EnableTimetracker
} }
@ -43,7 +36,7 @@ func (repo *Repository) AllowOnlyContributorsToTrackTime(ctx context.Context) bo
var u *RepoUnit var u *RepoUnit
var err error var err error
if u, err = repo.GetUnit(ctx, unit.TypeIssues); err != nil { if u, err = repo.GetUnit(ctx, unit.TypeIssues); err != nil {
return setting.Service.DefaultAllowOnlyContributorsToTrackTime return setting.Config().Service.DefaultAllowOnlyContributorsToTrackTime.Value(ctx)
} }
return u.IssuesConfig().AllowOnlyContributorsToTrackTime return u.IssuesConfig().AllowOnlyContributorsToTrackTime
} }
@ -54,7 +47,7 @@ func (repo *Repository) IsDependenciesEnabled(ctx context.Context) bool {
var err error var err error
if u, err = repo.GetUnit(ctx, unit.TypeIssues); err != nil { if u, err = repo.GetUnit(ctx, unit.TypeIssues); err != nil {
log.Trace("IsDependenciesEnabled: %v", err) log.Trace("IsDependenciesEnabled: %v", err)
return setting.Service.DefaultEnableDependencies return setting.Config().Service.DefaultEnableDependencies.Value(ctx)
} }
return u.IssuesConfig().EnableDependencies return u.IssuesConfig().EnableDependencies
} }

View File

@ -164,7 +164,7 @@ func GetRepoWatchers(ctx context.Context, repoID int64, opts db.ListOptions) ([]
// WatchIfAuto subscribes to repo if AutoWatchOnChanges is set // WatchIfAuto subscribes to repo if AutoWatchOnChanges is set
func WatchIfAuto(ctx context.Context, userID, repoID int64, isWrite bool) error { func WatchIfAuto(ctx context.Context, userID, repoID int64, isWrite bool) error {
if !isWrite || !setting.Service.AutoWatchOnChanges { if !isWrite || !setting.Config().Service.AutoWatchOnChanges.Value(ctx) {
return nil return nil
} }
watch, err := GetWatch(ctx, userID, repoID) watch, err := GetWatch(ctx, userID, repoID)

View File

@ -8,9 +8,11 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -71,7 +73,10 @@ func TestWatchIfAuto(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, watchers, repo.NumWatches) assert.Len(t, watchers, repo.NumWatches)
setting.Service.AutoWatchOnChanges = false assert.NoError(t, system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.AutoWatchOnChanges.DynKey(): "false",
}))
config.GetDynGetter().InvalidateCache()
prevCount := repo.NumWatches prevCount := repo.NumWatches
@ -87,7 +92,10 @@ func TestWatchIfAuto(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, watchers, prevCount) assert.Len(t, watchers, prevCount)
setting.Service.AutoWatchOnChanges = true assert.NoError(t, system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.AutoWatchOnChanges.DynKey(): "true",
}))
config.GetDynGetter().InvalidateCache()
// Must not add watch // Must not add watch
assert.NoError(t, repo_model.WatchIfAuto(t.Context(), 8, 1, true)) assert.NoError(t, repo_model.WatchIfAuto(t.Context(), 8, 1, true))

View File

@ -663,13 +663,13 @@ func createUser(ctx context.Context, u *User, meta *Meta, createdByAdmin bool, o
} }
// set system defaults // set system defaults
u.KeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate u.KeepEmailPrivate = setting.Config().Service.DefaultKeepEmailPrivate.Value(ctx)
u.Visibility = setting.Service.DefaultUserVisibilityMode u.Visibility = setting.Service.DefaultUserVisibilityMode
u.AllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization && !setting.Admin.DisableRegularOrgCreation u.AllowCreateOrganization = setting.Config().Service.DefaultAllowCreateOrganization.Value(ctx) && !setting.Admin.DisableRegularOrgCreation
u.EmailNotificationsPreference = setting.Admin.DefaultEmailNotification u.EmailNotificationsPreference = setting.Admin.DefaultEmailNotification
u.MaxRepoCreation = -1 u.MaxRepoCreation = -1
u.Theme = setting.UI.DefaultTheme u.Theme = setting.UI.DefaultTheme
u.IsRestricted = setting.Service.DefaultUserIsRestricted u.IsRestricted = setting.Config().Service.DefaultUserIsRestricted.Value(ctx)
u.IsActive = !(setting.Service.RegisterEmailConfirm || setting.Service.RegisterManualConfirm) u.IsActive = !(setting.Service.RegisterEmailConfirm || setting.Service.RegisterManualConfirm)
// Ensure consistency of the dates. // Ensure consistency of the dates.

View File

@ -83,7 +83,7 @@ loop:
} }
then = now then = now
if setting.Service.EnableTimetracking { if setting.Config().Service.EnableTimeTracking.Value(ctx) {
usersStopwatches, err := issues_model.GetUIDsAndStopwatch(ctx) usersStopwatches, err := issues_model.GetUIDsAndStopwatch(ctx)
if err != nil { if err != nil {
log.Error("Unable to get GetUIDsAndStopwatch: %v", err) log.Error("Unable to get GetUIDsAndStopwatch: %v", err)

View File

@ -52,9 +52,25 @@ type RepositoryStruct struct {
GitGuideRemoteName *config.Value[string] GitGuideRemoteName *config.Value[string]
} }
type ServiceStruct struct {
DefaultKeepEmailPrivate *config.Value[bool]
DefaultAllowCreateOrganization *config.Value[bool]
DefaultUserIsRestricted *config.Value[bool]
EnableTimeTracking *config.Value[bool]
DefaultEnableTimeTracking *config.Value[bool]
DefaultEnableDependencies *config.Value[bool]
AllowCrossRepositoryDependencies *config.Value[bool]
DefaultAllowOnlyContributorsToTrackTime *config.Value[bool]
EnableUserHeatmap *config.Value[bool]
AutoWatchNewRepos *config.Value[bool]
AutoWatchOnChanges *config.Value[bool]
DefaultOrgMemberVisible *config.Value[bool]
}
type ConfigStruct struct { type ConfigStruct struct {
Picture *PictureStruct Picture *PictureStruct
Repository *RepositoryStruct Repository *RepositoryStruct
Service *ServiceStruct
} }
var ( var (
@ -73,6 +89,20 @@ func initDefaultConfig() {
OpenWithEditorApps: config.ValueJSON[OpenWithEditorAppsType]("repository.open-with.editor-apps"), OpenWithEditorApps: config.ValueJSON[OpenWithEditorAppsType]("repository.open-with.editor-apps"),
GitGuideRemoteName: config.ValueJSON[string]("repository.git-guide-remote-name").WithDefault("origin"), GitGuideRemoteName: config.ValueJSON[string]("repository.git-guide-remote-name").WithDefault("origin"),
}, },
Service: &ServiceStruct{
DefaultKeepEmailPrivate: config.ValueJSON[bool]("service.default_keep_email_private").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "DEFAULT_KEEP_EMAIL_PRIVATE"}).WithDefault(false),
DefaultAllowCreateOrganization: config.ValueJSON[bool]("service.default_allow_create_organization").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "DEFAULT_ALLOW_CREATE_ORGANIZATION"}).WithDefault(true),
DefaultUserIsRestricted: config.ValueJSON[bool]("service.default_user_is_restricted").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "DEFAULT_USER_IS_RESTRICTED"}).WithDefault(false),
EnableTimeTracking: config.ValueJSON[bool]("service.enable_time_tracking").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "ENABLE_TIMETRACKING"}).WithDefault(true),
DefaultEnableTimeTracking: config.ValueJSON[bool]("service.default_enable_time_tracking").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "DEFAULT_ENABLE_TIMETRACKING"}).WithDefault(true),
DefaultEnableDependencies: config.ValueJSON[bool]("service.default_enable_dependencies").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "DEFAULT_ENABLE_DEPENDENCIES"}).WithDefault(true),
AllowCrossRepositoryDependencies: config.ValueJSON[bool]("service.allow_cross_repository_dependencies").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "ALLOW_CROSS_REPOSITORY_DEPENDENCIES"}).WithDefault(true),
DefaultAllowOnlyContributorsToTrackTime: config.ValueJSON[bool]("service.default_allow_only_contributors_to_track_time").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME"}).WithDefault(true),
EnableUserHeatmap: config.ValueJSON[bool]("service.enable_user_heatmap").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "ENABLE_USER_HEATMAP"}).WithDefault(true),
AutoWatchNewRepos: config.ValueJSON[bool]("service.auto_watch_new_repos").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "AUTO_WATCH_NEW_REPOS"}).WithDefault(true),
AutoWatchOnChanges: config.ValueJSON[bool]("service.auto_watch_on_changes").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "AUTO_WATCH_ON_CHANGES"}).WithDefault(false),
DefaultOrgMemberVisible: config.ValueJSON[bool]("service.default_org_member_visible").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "DEFAULT_ORG_MEMBER_VISIBLE"}).WithDefault(false),
},
} }
} }

View File

@ -25,65 +25,53 @@ const (
// Service settings // Service settings
var Service = struct { var Service = struct {
DefaultUserVisibility string DefaultUserVisibility string
DefaultUserVisibilityMode structs.VisibleType DefaultUserVisibilityMode structs.VisibleType
AllowedUserVisibilityModes []string AllowedUserVisibilityModes []string
AllowedUserVisibilityModesSlice AllowedVisibility `ini:"-"` AllowedUserVisibilityModesSlice AllowedVisibility `ini:"-"`
DefaultOrgVisibility string DefaultOrgVisibility string
DefaultOrgVisibilityMode structs.VisibleType DefaultOrgVisibilityMode structs.VisibleType
ActiveCodeLives int ActiveCodeLives int
ResetPwdCodeLives int ResetPwdCodeLives int
RegisterEmailConfirm bool RegisterEmailConfirm bool
RegisterManualConfirm bool RegisterManualConfirm bool
EmailDomainAllowList []glob.Glob EmailDomainAllowList []glob.Glob
EmailDomainBlockList []glob.Glob EmailDomainBlockList []glob.Glob
DisableRegistration bool DisableRegistration bool
AllowOnlyInternalRegistration bool AllowOnlyInternalRegistration bool
AllowOnlyExternalRegistration bool AllowOnlyExternalRegistration bool
ShowRegistrationButton bool ShowRegistrationButton bool
EnablePasswordSignInForm bool EnablePasswordSignInForm bool
ShowMilestonesDashboardPage bool ShowMilestonesDashboardPage bool
RequireSignInViewStrict bool RequireSignInViewStrict bool
BlockAnonymousAccessExpensive bool BlockAnonymousAccessExpensive bool
EnableNotifyMail bool EnableNotifyMail bool
EnableBasicAuth bool EnableBasicAuth bool
EnablePasskeyAuth bool EnablePasskeyAuth bool
EnableReverseProxyAuth bool EnableReverseProxyAuth bool
EnableReverseProxyAuthAPI bool EnableReverseProxyAuthAPI bool
EnableReverseProxyAutoRegister bool EnableReverseProxyAutoRegister bool
EnableReverseProxyEmail bool EnableReverseProxyEmail bool
EnableReverseProxyFullName bool EnableReverseProxyFullName bool
EnableCaptcha bool EnableCaptcha bool
RequireCaptchaForLogin bool RequireCaptchaForLogin bool
RequireExternalRegistrationCaptcha bool RequireExternalRegistrationCaptcha bool
RequireExternalRegistrationPassword bool RequireExternalRegistrationPassword bool
CaptchaType string CaptchaType string
RecaptchaSecret string RecaptchaSecret string
RecaptchaSitekey string RecaptchaSitekey string
RecaptchaURL string RecaptchaURL string
CfTurnstileSecret string CfTurnstileSecret string
CfTurnstileSitekey string CfTurnstileSitekey string
HcaptchaSecret string HcaptchaSecret string
HcaptchaSitekey string HcaptchaSitekey string
McaptchaSecret string McaptchaSecret string
McaptchaSitekey string McaptchaSitekey string
McaptchaURL string McaptchaURL string
DefaultKeepEmailPrivate bool NoReplyAddress string
DefaultAllowCreateOrganization bool UserLocationMapURL string
DefaultUserIsRestricted bool UserDeleteWithCommentsMaxTime time.Duration
EnableTimetracking bool ValidSiteURLSchemes []string
DefaultEnableTimetracking bool
DefaultEnableDependencies bool
AllowCrossRepositoryDependencies bool
DefaultAllowOnlyContributorsToTrackTime bool
NoReplyAddress string
UserLocationMapURL string
EnableUserHeatmap bool
AutoWatchNewRepos bool
AutoWatchOnChanges bool
DefaultOrgMemberVisible bool
UserDeleteWithCommentsMaxTime time.Duration
ValidSiteURLSchemes []string
// OpenID settings // OpenID settings
EnableOpenIDSignIn bool EnableOpenIDSignIn bool
@ -202,21 +190,9 @@ func loadServiceFrom(rootCfg ConfigProvider) {
Service.McaptchaURL = sec.Key("MCAPTCHA_URL").MustString("https://demo.mcaptcha.org/") Service.McaptchaURL = sec.Key("MCAPTCHA_URL").MustString("https://demo.mcaptcha.org/")
Service.McaptchaSecret = sec.Key("MCAPTCHA_SECRET").MustString("") Service.McaptchaSecret = sec.Key("MCAPTCHA_SECRET").MustString("")
Service.McaptchaSitekey = sec.Key("MCAPTCHA_SITEKEY").MustString("") Service.McaptchaSitekey = sec.Key("MCAPTCHA_SITEKEY").MustString("")
Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true)
Service.DefaultUserIsRestricted = sec.Key("DEFAULT_USER_IS_RESTRICTED").MustBool(false)
Service.EnableTimetracking = sec.Key("ENABLE_TIMETRACKING").MustBool(true)
if Service.EnableTimetracking {
Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true)
}
Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true)
Service.AllowCrossRepositoryDependencies = sec.Key("ALLOW_CROSS_REPOSITORY_DEPENDENCIES").MustBool(true)
Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true)
Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply." + Domain) Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply." + Domain)
Service.UserLocationMapURL = sec.Key("USER_LOCATION_MAP_URL").String() Service.UserLocationMapURL = sec.Key("USER_LOCATION_MAP_URL").String()
Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true)
Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true)
Service.AutoWatchOnChanges = sec.Key("AUTO_WATCH_ON_CHANGES").MustBool(false)
modes := sec.Key("ALLOWED_USER_VISIBILITY_MODES").Strings(",") modes := sec.Key("ALLOWED_USER_VISIBILITY_MODES").Strings(",")
if len(modes) != 0 { if len(modes) != 0 {
Service.AllowedUserVisibilityModes = []string{} Service.AllowedUserVisibilityModes = []string{}
@ -246,7 +222,6 @@ func loadServiceFrom(rootCfg ConfigProvider) {
Service.DefaultUserVisibilityMode = structs.VisibilityModes[Service.DefaultUserVisibility] Service.DefaultUserVisibilityMode = structs.VisibilityModes[Service.DefaultUserVisibility]
Service.DefaultOrgVisibility = sec.Key("DEFAULT_ORG_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes)) Service.DefaultOrgVisibility = sec.Key("DEFAULT_ORG_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes))
Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility] Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility]
Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool()
Service.UserDeleteWithCommentsMaxTime = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_TIME").MustDuration(0) Service.UserDeleteWithCommentsMaxTime = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_TIME").MustDuration(0)
sec.Key("VALID_SITE_URL_SCHEMES").MustString("http,https") sec.Key("VALID_SITE_URL_SCHEMES").MustString("http,https")
Service.ValidSiteURLSchemes = sec.Key("VALID_SITE_URL_SCHEMES").Strings(",") Service.ValidSiteURLSchemes = sec.Key("VALID_SITE_URL_SCHEMES").Strings(",")

View File

@ -5,6 +5,7 @@
package templates package templates
import ( import (
"context"
"fmt" "fmt"
"html/template" "html/template"
"net/url" "net/url"
@ -122,8 +123,8 @@ func NewFuncMap() template.FuncMap {
"MetaKeywords": func() string { "MetaKeywords": func() string {
return setting.UI.Meta.Keywords return setting.UI.Meta.Keywords
}, },
"EnableTimetracking": func() bool { "EnableTimeTracking": func(ctx context.Context) bool {
return setting.Service.EnableTimetracking return setting.Config().Service.EnableTimeTracking.Value(ctx)
}, },
"DisableWebhooks": func() bool { "DisableWebhooks": func() bool {
return setting.DisableWebhooks return setting.DisableWebhooks

View File

@ -351,12 +351,6 @@ secret_key_failed = Failed to generate secret key: %v
save_config_failed = Failed to save configuration: %v save_config_failed = Failed to save configuration: %v
invalid_admin_setting = Administrator account setting is invalid: %v invalid_admin_setting = Administrator account setting is invalid: %v
invalid_log_root_path = The log path is invalid: %v invalid_log_root_path = The log path is invalid: %v
default_keep_email_private = Hide Email Addresses by Default
default_keep_email_private_popup = Hide email addresses of new user accounts by default.
default_allow_create_organization = Allow Creation of Organizations by Default
default_allow_create_organization_popup = Allow new user accounts to create organizations by default.
default_enable_timetracking = Enable Time Tracking by Default
default_enable_timetracking_popup = Enable time tracking for new repositories by default.
no_reply_address = Hidden Email Domain no_reply_address = Hidden Email Domain
no_reply_address_helper = Domain name for users with a hidden email address. For example, the username 'joe' will be logged in Git as 'joe@noreply.example.org' if the hidden email domain is set to 'noreply.example.org'. no_reply_address_helper = Domain name for users with a hidden email address. For example, the username 'joe' will be logged in Git as 'joe@noreply.example.org' if the hidden email domain is set to 'noreply.example.org'.
password_algorithm = Password Hash Algorithm password_algorithm = Password Hash Algorithm
@ -3385,14 +3379,31 @@ config.enable_captcha = Enable CAPTCHA
config.active_code_lives = Active Code Lives config.active_code_lives = Active Code Lives
config.reset_password_code_lives = Recover Account Code Expiry Time config.reset_password_code_lives = Recover Account Code Expiry Time
config.default_keep_email_private = Hide Email Addresses by Default config.default_keep_email_private = Hide Email Addresses by Default
config.default_keep_email_private_desc = Each new user will get the value of this setting copied into their profile
config.default_allow_create_organization = Allow Creation of Organizations by Default config.default_allow_create_organization = Allow Creation of Organizations by Default
config.enable_timetracking = Enable Time Tracking config.default_allow_create_organization_desc = Every new user will have rights set to create organizations depending on this setting
config.default_enable_timetracking = Enable Time Tracking by Default config.default_user_is_restricted = New user will be restricted by default
config.default_user_is_restricted_desc = Every new user will have restricted permissions depending on this setting
config.enable_time_tracking = Enable Time Tracking
config.enable_time_tracking_desc = Allow users to track time on issues and pull requests
config.default_enable_time_tracking = Enable Time Tracking by Default
config.default_enable_time_tracking_desc = Repositories will use time tracking by default depending on this setting
config.default_allow_only_contributors_to_track_time = Let Only Contributors Track Time config.default_allow_only_contributors_to_track_time = Let Only Contributors Track Time
config.default_allow_only_contributors_to_track_time_desc = Only users with write permissions can track time if this is true
config.default_enable_dependencies = Enable Issue Dependencies by Default
config.default_enable_dependencies_desc = Repositories will use dependencies by default depending on this setting
config.allow_cross_repository_dependencies = Allow Cross Repository Issue Dependencies
config.allow_cross_repository_dependencies_desc = Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting.
config.enable_user_heatmap = Enable User Heatmap
config.enable_user_heatmap_desc = Show a heatmap of user activity on user profiles
config.auto_watch_new_repos = Enable Auto Watch for New Repositories
config.auto_watch_new_repos_desc = When adding a repo to a team or creating a new repo all team members will watch the repo automatically if enabled
config.auto_watch_on_changes = Enable Auto Watch for Repositories Push
config.auto_watch_on_changes_desc = Make the user watch a repository When they commit for the first time
config.default_org_member_visible = Default Organization Member Visibility
config.default_org_member_visible_desc = True will make the membership of the users visible when added to the organisation
config.no_reply_address = Hidden Email Domain config.no_reply_address = Hidden Email Domain
config.default_visibility_organization = Default visibility for new Organizations config.default_visibility_organization = Default visibility for new Organizations
config.default_enable_dependencies = Enable Issue Dependencies by Default
config.webhook_config = Webhook Configuration config.webhook_config = Webhook Configuration
config.queue_length = Queue Length config.queue_length = Queue Length
config.deliver_timeout = Deliver Timeout config.deliver_timeout = Deliver Timeout

View File

@ -996,7 +996,7 @@ func Routes() *web.Router {
m.Group("/{username}", func() { m.Group("/{username}", func() {
m.Get("", reqExploreSignIn(), user.GetInfo) m.Get("", reqExploreSignIn(), user.GetInfo)
if setting.Service.EnableUserHeatmap { if setting.Config().Service.EnableUserHeatmap.Value(gocontext.Background()) {
m.Get("/heatmap", user.GetUserHeatmapData) m.Get("/heatmap", user.GetUserHeatmapData)
} }

View File

@ -509,7 +509,7 @@ func getParamsIssue(ctx *context.APIContext) *issues_model.Issue {
func getFormIssue(ctx *context.APIContext, form *api.IssueMeta) *issues_model.Issue { func getFormIssue(ctx *context.APIContext, form *api.IssueMeta) *issues_model.Issue {
var repo *repo_model.Repository var repo *repo_model.Repository
if form.Owner != ctx.Repo.Repository.OwnerName || form.Name != ctx.Repo.Repository.Name { if form.Owner != ctx.Repo.Repository.OwnerName || form.Name != ctx.Repo.Repository.Name {
if !setting.Service.AllowCrossRepositoryDependencies { if !setting.Config().Service.AllowCrossRepositoryDependencies.Value(ctx) {
ctx.JSON(http.StatusBadRequest, "CrossRepositoryDependencies not enabled") ctx.JSON(http.StatusBadRequest, "CrossRepositoryDependencies not enabled")
return nil return nil
} }

View File

@ -62,7 +62,7 @@ func GetGeneralRepoSettings(ctx *context.APIContext) {
HTTPGitDisabled: setting.Repository.DisableHTTPGit, HTTPGitDisabled: setting.Repository.DisableHTTPGit,
MigrationsDisabled: setting.Repository.DisableMigrations, MigrationsDisabled: setting.Repository.DisableMigrations,
StarsDisabled: setting.Repository.DisableStars, StarsDisabled: setting.Repository.DisableStars,
TimeTrackingDisabled: !setting.Service.EnableTimetracking, TimeTrackingDisabled: !setting.Config().Service.EnableTimeTracking.Value(ctx),
LFSDisabled: !setting.LFS.StartServer, LFSDisabled: !setting.LFS.StartServer,
}) })
} }

View File

@ -145,9 +145,9 @@ func Install(ctx *context.Context) {
form.AllowOnlyExternalRegistration = setting.Service.AllowOnlyExternalRegistration form.AllowOnlyExternalRegistration = setting.Service.AllowOnlyExternalRegistration
form.EnableCaptcha = setting.Service.EnableCaptcha form.EnableCaptcha = setting.Service.EnableCaptcha
form.RequireSignInView = setting.Service.RequireSignInViewStrict form.RequireSignInView = setting.Service.RequireSignInViewStrict
form.DefaultKeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate form.DefaultKeepEmailPrivate = setting.Config().Service.DefaultKeepEmailPrivate.Value(ctx)
form.DefaultAllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization form.DefaultAllowCreateOrganization = setting.Config().Service.DefaultAllowCreateOrganization.Value(ctx)
form.DefaultEnableTimetracking = setting.Service.DefaultEnableTimetracking form.DefaultEnableTimetracking = setting.Config().Service.DefaultEnableTimeTracking.Value(ctx)
form.NoReplyAddress = setting.Service.NoReplyAddress form.NoReplyAddress = setting.Service.NoReplyAddress
form.PasswordAlgorithm = hash.ConfigHashAlgorithm(setting.PasswordHashAlgo) form.PasswordAlgorithm = hash.ConfigHashAlgorithm(setting.PasswordHashAlgo)
@ -440,9 +440,6 @@ func SubmitInstall(ctx *context.Context) {
cfg.Section("service").Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").SetValue(strconv.FormatBool(form.AllowOnlyExternalRegistration)) cfg.Section("service").Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").SetValue(strconv.FormatBool(form.AllowOnlyExternalRegistration))
cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(strconv.FormatBool(form.EnableCaptcha)) cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(strconv.FormatBool(form.EnableCaptcha))
cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(strconv.FormatBool(form.RequireSignInView)) cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(strconv.FormatBool(form.RequireSignInView))
cfg.Section("service").Key("DEFAULT_KEEP_EMAIL_PRIVATE").SetValue(strconv.FormatBool(form.DefaultKeepEmailPrivate))
cfg.Section("service").Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").SetValue(strconv.FormatBool(form.DefaultAllowCreateOrganization))
cfg.Section("service").Key("DEFAULT_ENABLE_TIMETRACKING").SetValue(strconv.FormatBool(form.DefaultEnableTimetracking))
cfg.Section("service").Key("NO_REPLY_ADDRESS").SetValue(form.NoReplyAddress) cfg.Section("service").Key("NO_REPLY_ADDRESS").SetValue(form.NoReplyAddress)
cfg.Section("cron.update_checker").Key("ENABLED").SetValue(strconv.FormatBool(form.EnableUpdateChecker)) cfg.Section("cron.update_checker").Key("ENABLED").SetValue(strconv.FormatBool(form.EnableUpdateChecker))

View File

@ -233,6 +233,20 @@ func ChangeConfig(ctx *context.Context) {
marshallers := map[string]func(string) ([]byte, error){ marshallers := map[string]func(string) ([]byte, error){
cfg.Picture.DisableGravatar.DynKey(): marshalBool, cfg.Picture.DisableGravatar.DynKey(): marshalBool,
cfg.Picture.EnableFederatedAvatar.DynKey(): marshalBool, cfg.Picture.EnableFederatedAvatar.DynKey(): marshalBool,
cfg.Service.DefaultKeepEmailPrivate.DynKey(): marshalBool,
cfg.Service.DefaultAllowCreateOrganization.DynKey(): marshalBool,
cfg.Service.DefaultUserIsRestricted.DynKey(): marshalBool,
cfg.Service.EnableTimeTracking.DynKey(): marshalBool,
cfg.Service.DefaultEnableTimeTracking.DynKey(): marshalBool,
cfg.Service.DefaultEnableDependencies.DynKey(): marshalBool,
cfg.Service.AllowCrossRepositoryDependencies.DynKey(): marshalBool,
cfg.Service.DefaultAllowOnlyContributorsToTrackTime.DynKey(): marshalBool,
cfg.Service.EnableUserHeatmap.DynKey(): marshalBool,
cfg.Service.AutoWatchNewRepos.DynKey(): marshalBool,
cfg.Service.AutoWatchOnChanges.DynKey(): marshalBool,
cfg.Service.DefaultOrgMemberVisible.DynKey(): marshalBool,
cfg.Repository.OpenWithEditorApps.DynKey(): marshalOpenWithApps, cfg.Repository.OpenWithEditorApps.DynKey(): marshalOpenWithApps,
cfg.Repository.GitGuideRemoteName.DynKey(): marshalString(cfg.Repository.GitGuideRemoteName.DefaultValue()), cfg.Repository.GitGuideRemoteName.DynKey(): marshalString(cfg.Repository.GitGuideRemoteName.DefaultValue()),
} }

View File

@ -191,7 +191,7 @@ func SignInOAuthCallback(ctx *context.Context) {
isAdmin, isRestricted := getUserAdminAndRestrictedFromGroupClaims(source, &gothUser) isAdmin, isRestricted := getUserAdminAndRestrictedFromGroupClaims(source, &gothUser)
u.IsAdmin = isAdmin.ValueOrDefault(user_service.UpdateOptionField[bool]{FieldValue: false}).FieldValue u.IsAdmin = isAdmin.ValueOrDefault(user_service.UpdateOptionField[bool]{FieldValue: false}).FieldValue
u.IsRestricted = isRestricted.ValueOrDefault(setting.Service.DefaultUserIsRestricted) u.IsRestricted = isRestricted.ValueOrDefault(setting.Config().Service.DefaultUserIsRestricted.Value(ctx))
linkAccountData := &LinkAccountData{authSource.ID, gothUser} linkAccountData := &LinkAccountData{authSource.ID, gothUser}
if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingDisabled { if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingDisabled {

View File

@ -46,7 +46,7 @@ func AddDependency(ctx *context.Context) {
// Check if both issues are in the same repo if cross repository dependencies is not enabled // Check if both issues are in the same repo if cross repository dependencies is not enabled
if issue.RepoID != dep.RepoID { if issue.RepoID != dep.RepoID {
if !setting.Service.AllowCrossRepositoryDependencies { if !setting.Config().Service.AllowCrossRepositoryDependencies.Value(ctx) {
ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_same_repo")) ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_same_repo"))
return return
} }

View File

@ -466,7 +466,7 @@ func prepareIssueViewSidebarDependency(ctx *context.Context, issue *issues_model
ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx, ctx.Doer, issue.IsPull) ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx, ctx.Doer, issue.IsPull)
// check if dependencies can be created across repositories // check if dependencies can be created across repositories
ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies ctx.Data["AllowCrossRepositoryDependencies"] = setting.Config().Service.AllowCrossRepositoryDependencies.Value(ctx)
// Get Dependencies // Get Dependencies
blockedBy, err := issue.BlockedByDependencies(ctx, db.ListOptions{}) blockedBy, err := issue.BlockedByDependencies(ctx, db.ListOptions{})

View File

@ -109,7 +109,7 @@ func Dashboard(ctx *context.Context) {
"uid": uid, "uid": uid,
} }
if setting.Service.EnableUserHeatmap { if setting.Config().Service.EnableUserHeatmap.Value(ctx) {
data, err := activities_model.GetUserHeatmapDataByUserTeam(ctx, ctxUser, ctx.Org.Team, ctx.Doer) data, err := activities_model.GetUserHeatmapDataByUserTeam(ctx, ctxUser, ctx.Org.Team, ctx.Doer)
if err != nil { if err != nil {
ctx.ServerError("GetUserHeatmapDataByUserTeam", err) ctx.ServerError("GetUserHeatmapDataByUserTeam", err)

View File

@ -162,7 +162,7 @@ func prepareUserProfileTabData(ctx *context.Context, profileDbRepo *repo_model.R
total = int(numFollowing) total = int(numFollowing)
case "activity": case "activity":
// prepare heatmap data // prepare heatmap data
if setting.Service.EnableUserHeatmap { if setting.Config().Service.EnableUserHeatmap.Value(ctx) {
data, err := activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer) data, err := activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer)
if err != nil { if err != nil {
ctx.ServerError("GetUserHeatmapDataByUser", err) ctx.ServerError("GetUserHeatmapDataByUser", err)

View File

@ -251,7 +251,7 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode
// this behaviour may spend much time so run it in a goroutine // this behaviour may spend much time so run it in a goroutine
// FIXME: Update watch repos batchly // FIXME: Update watch repos batchly
if setting.Service.AutoWatchNewRepos { if setting.Config().Service.AutoWatchNewRepos.Value(ctx) {
// Get team and its repositories. // Get team and its repositories.
repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{
TeamID: team.ID, TeamID: team.ID,

View File

@ -376,9 +376,9 @@ func createRepositoryInDB(ctx context.Context, doer, u *user_model.User, repo *r
RepoID: repo.ID, RepoID: repo.ID,
Type: tp, Type: tp,
Config: &repo_model.IssuesConfig{ Config: &repo_model.IssuesConfig{
EnableTimetracker: setting.Service.DefaultEnableTimetracking, EnableTimetracker: setting.Config().Service.DefaultEnableTimeTracking.Value(ctx),
AllowOnlyContributorsToTrackTime: setting.Service.DefaultAllowOnlyContributorsToTrackTime, AllowOnlyContributorsToTrackTime: setting.Config().Service.DefaultAllowOnlyContributorsToTrackTime.Value(ctx),
EnableDependencies: setting.Service.DefaultEnableDependencies, EnableDependencies: setting.Config().Service.DefaultEnableDependencies.Value(ctx),
}, },
}) })
case unit.TypePullRequests: case unit.TypePullRequests:
@ -447,7 +447,7 @@ func createRepositoryInDB(ctx context.Context, doer, u *user_model.User, repo *r
return fmt.Errorf("RecalculateAccesses: %w", err) return fmt.Errorf("RecalculateAccesses: %w", err)
} }
if setting.Service.AutoWatchNewRepos { if setting.Config().Service.AutoWatchNewRepos.Value(ctx) {
if err = repo_model.WatchRepo(ctx, doer, repo, true); err != nil { if err = repo_model.WatchRepo(ctx, doer, repo, true); err != nil {
return fmt.Errorf("WatchRepo: %w", err) return fmt.Errorf("WatchRepo: %w", err)
} }

View File

@ -45,7 +45,7 @@ func addRepositoryToTeam(ctx context.Context, t *organization.Team, repo *repo_m
} }
// Make all team members watch this repo if enabled in global settings // Make all team members watch this repo if enabled in global settings
if setting.Service.AutoWatchNewRepos { if setting.Config().Service.AutoWatchNewRepos.Value(ctx) {
if err = t.LoadMembers(ctx); err != nil { if err = t.LoadMembers(ctx); err != nil {
return fmt.Errorf("getMembers: %w", err) return fmt.Errorf("getMembers: %w", err)
} }

View File

@ -13,9 +13,11 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
org_service "code.gitea.io/gitea/services/org" org_service "code.gitea.io/gitea/services/org"
@ -179,7 +181,10 @@ func TestCreateUser_Issue5882(t *testing.T) {
{&user_model.User{Name: "GiteaBot2", Email: "GiteaBot2@gitea.io", Passwd: passwd, MustChangePassword: false}, true}, {&user_model.User{Name: "GiteaBot2", Email: "GiteaBot2@gitea.io", Passwd: passwd, MustChangePassword: false}, true},
} }
setting.Service.DefaultAllowCreateOrganization = true system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.DefaultAllowCreateOrganization.DynKey(): "true",
})
config.GetDynGetter().InvalidateCache()
for _, v := range tt { for _, v := range tt {
setting.Admin.DisableRegularOrgCreation = v.disableOrgCreation setting.Admin.DisableRegularOrgCreation = v.disableOrgCreation

View File

@ -149,25 +149,10 @@
<dd>{{svg (Iif .Service.EnableNotifyMail "octicon-check" "octicon-x")}}</dd> <dd>{{svg (Iif .Service.EnableNotifyMail "octicon-check" "octicon-x")}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.enable_captcha"}}</dt> <dt>{{ctx.Locale.Tr "admin.config.enable_captcha"}}</dt>
<dd>{{svg (Iif .Service.EnableCaptcha "octicon-check" "octicon-x")}}</dd> <dd>{{svg (Iif .Service.EnableCaptcha "octicon-check" "octicon-x")}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.default_keep_email_private"}}</dt>
<dd>{{svg (Iif .Service.DefaultKeepEmailPrivate "octicon-check" "octicon-x")}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.default_allow_create_organization"}}</dt>
<dd>{{svg (Iif .Service.DefaultAllowCreateOrganization "octicon-check" "octicon-x")}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.enable_timetracking"}}</dt>
<dd>{{svg (Iif .Service.EnableTimetracking "octicon-check" "octicon-x")}}</dd>
{{if .Service.EnableTimetracking}}
<dt>{{ctx.Locale.Tr "admin.config.default_enable_timetracking"}}</dt>
<dd>{{svg (Iif .Service.DefaultEnableTimetracking "octicon-check" "octicon-x")}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.default_allow_only_contributors_to_track_time"}}</dt>
<dd>{{svg (Iif .Service.DefaultAllowOnlyContributorsToTrackTime "octicon-check" "octicon-x")}}</dd>
{{end}}
<dt>{{ctx.Locale.Tr "admin.config.default_visibility_organization"}}</dt> <dt>{{ctx.Locale.Tr "admin.config.default_visibility_organization"}}</dt>
<dd>{{.Service.DefaultOrgVisibility}}</dd> <dd>{{.Service.DefaultOrgVisibility}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.no_reply_address"}}</dt> <dt>{{ctx.Locale.Tr "admin.config.no_reply_address"}}</dt>
<dd>{{if .Service.NoReplyAddress}}{{.Service.NoReplyAddress}}{{else}}-{{end}}</dd> <dd>{{if .Service.NoReplyAddress}}{{.Service.NoReplyAddress}}{{else}}-{{end}}</dd>
<dt>{{ctx.Locale.Tr "admin.config.default_enable_dependencies"}}</dt>
<dd>{{svg (Iif .Service.DefaultEnableDependencies "octicon-check" "octicon-x")}}</dd>
<div class="divider"></div> <div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.active_code_lives"}}</dt> <dt>{{ctx.Locale.Tr "admin.config.active_code_lives"}}</dt>
<dd>{{.Service.ActiveCodeLives}} {{ctx.Locale.Tr "tool.raw_minutes"}}</dd> <dd>{{.Service.ActiveCodeLives}} {{ctx.Locale.Tr "tool.raw_minutes"}}</dd>

View File

@ -4,4 +4,6 @@
{{template "admin/config_settings/repository" .}} {{template "admin/config_settings/repository" .}}
{{template "admin/config_settings/service" .}}
{{template "admin/layout_footer" .}} {{template "admin/layout_footer" .}}

View File

@ -0,0 +1,104 @@
<h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.config.service_config"}}
</h4>
<div class="ui attached table segment">
<form class="ui form">
<dl class="admin-dl-horizontal">
<dt>{{ctx.Locale.Tr "admin.config.default_keep_email_private"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.default_keep_email_private" {{if .SystemConfig.Service.DefaultKeepEmailPrivate.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.default_keep_email_private_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.default_allow_create_organization"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.default_allow_create_organization" {{if .SystemConfig.Service.DefaultAllowCreateOrganization.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.default_allow_create_organization_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.default_user_is_restricted"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.default_user_is_restricted" {{if .SystemConfig.Service.DefaultUserIsRestricted.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.default_user_is_restricted_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.enable_time_tracking"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.enable_time_tracking" {{if .SystemConfig.Service.EnableTimeTracking.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.enable_time_tracking_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.default_enable_time_tracking"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.default_enable_time_tracking" {{if .SystemConfig.Service.DefaultEnableTimeTracking.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.default_enable_time_tracking_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.default_allow_only_contributors_to_track_time"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.default_allow_only_contributors_to_track_time" {{if .SystemConfig.Service.DefaultAllowOnlyContributorsToTrackTime.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.default_allow_only_contributors_to_track_time_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.default_enable_dependencies"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.default_enable_dependencies" {{if .SystemConfig.Service.DefaultEnableDependencies.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.default_enable_dependencies_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.allow_cross_repository_dependencies"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.allow_cross_repository_dependencies" {{if .SystemConfig.Service.AllowCrossRepositoryDependencies.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.allow_cross_repository_dependencies_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.enable_user_heatmap"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.enable_user_heatmap" {{if .SystemConfig.Service.EnableUserHeatmap.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.enable_user_heatmap_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.auto_watch_new_repos"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.auto_watch_new_repos" {{if .SystemConfig.Service.AutoWatchNewRepos.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.auto_watch_new_repos_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.auto_watch_on_changes"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.auto_watch_on_changes" {{if .SystemConfig.Service.AutoWatchOnChanges.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.auto_watch_on_changes_desc"}}</p></div>
<div class="divider"></div>
<dt>{{ctx.Locale.Tr "admin.config.default_org_member_visible"}}</dt>
<dd>
<div class="ui toggle checkbox">
<input type="checkbox" data-config-dyn-key="service.default_org_member_visible" {{if .SystemConfig.Service.DefaultOrgMemberVisible.Value ctx}}checked{{end}}><label></label>
</div>
</dd>
<div><p class="help">{{ctx.Locale.Tr "admin.config.default_org_member_visible_desc"}}</p></div>
</dl>
</form>
</div>

View File

@ -16,7 +16,7 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
csrfToken: '{{.CsrfToken}}', csrfToken: '{{.CsrfToken}}',
pageData: {{.PageData}}, pageData: {{.PageData}},
notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}} notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}}
enableTimeTracking: {{EnableTimetracking}}, enableTimeTracking: {{EnableTimeTracking ctx}},
{{if or .Participants .Assignees .MentionableTeams}} {{if or .Participants .Assignees .MentionableTeams}}
mentionValues: Array.from(new Map([ mentionValues: Array.from(new Map([
{{- range .Participants -}} {{- range .Participants -}}

View File

@ -257,24 +257,6 @@
<input name="require_sign_in_view" type="checkbox" {{if .require_sign_in_view}}checked{{end}}> <input name="require_sign_in_view" type="checkbox" {{if .require_sign_in_view}}checked{{end}}>
</div> </div>
</div> </div>
<div class="inline field">
<div class="ui checkbox">
<label data-tooltip-content="{{ctx.Locale.Tr "install.default_keep_email_private_popup"}}">{{ctx.Locale.Tr "install.default_keep_email_private"}}</label>
<input name="default_keep_email_private" type="checkbox" {{if .default_keep_email_private}}checked{{end}}>
</div>
</div>
<div class="inline field">
<div class="ui checkbox">
<label data-tooltip-content="{{ctx.Locale.Tr "install.default_allow_create_organization_popup"}}">{{ctx.Locale.Tr "install.default_allow_create_organization"}}</label>
<input name="default_allow_create_organization" type="checkbox" {{if .default_allow_create_organization}}checked{{end}}>
</div>
</div>
<div class="inline field">
<div class="ui checkbox">
<label data-tooltip-content="{{ctx.Locale.Tr "install.default_enable_timetracking_popup"}}">{{ctx.Locale.Tr "install.default_enable_timetracking"}}</label>
<input name="default_enable_timetracking" type="checkbox" {{if .default_enable_timetracking}}checked{{end}}>
</div>
</div>
<div class="inline field"> <div class="inline field">
<label for="no_reply_address">{{ctx.Locale.Tr "install.no_reply_address"}}</label> <label for="no_reply_address">{{ctx.Locale.Tr "install.no_reply_address"}}</label>
<input id="_no_reply_address" name="no_reply_address" value="{{.no_reply_address}}"> <input id="_no_reply_address" name="no_reply_address" value="{{.no_reply_address}}">

View File

@ -44,7 +44,7 @@
{{end}} {{end}}
</a> </a>
{{end}} {{end}}
{{if and EnableTimetracking .IsOrganizationOwner}} {{if and (EnableTimeTracking ctx) .IsOrganizationOwner}}
<a class="{{if $.PageIsOrgTimes}}active{{end}} item" href="{{$.OrgLink}}/worktime"> <a class="{{if $.PageIsOrgTimes}}active{{end}} item" href="{{$.OrgLink}}/worktime">
{{svg "octicon-clock"}} {{ctx.Locale.Tr "org.worktime"}} {{svg "octicon-clock"}} {{ctx.Locale.Tr "org.worktime"}}
</a> </a>

View File

@ -372,7 +372,7 @@
</div> </div>
</div> </div>
<div class="field tw-pl-4 {{if (.Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeExternalTracker)}}disabled{{end}}" id="internal_issue_box"> <div class="field tw-pl-4 {{if (.Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeExternalTracker)}}disabled{{end}}" id="internal_issue_box">
{{if .Repository.CanEnableTimetracker}} {{if .Repository.CanEnableTimetracker ctx}}
<div class="field"> <div class="field">
<div class="ui checkbox"> <div class="ui checkbox">
<input name="enable_timetracker" class="enable-system" data-target="#only_contributors" type="checkbox" {{if .Repository.IsTimetrackerEnabled ctx}}checked{{end}}> <input name="enable_timetracker" class="enable-system" data-target="#only_contributors" type="checkbox" {{if .Repository.IsTimetrackerEnabled ctx}}checked{{end}}>

View File

@ -8,14 +8,23 @@ import (
"testing" "testing"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"github.com/stretchr/testify/assert"
) )
func TestRepoWatch(t *testing.T) { func TestRepoWatch(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
// Test round-trip auto-watch // Test round-trip auto-watch
setting.Service.AutoWatchOnChanges = true
assert.NoError(t, system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.AutoWatchOnChanges.DynKey(): "true",
}))
config.GetDynGetter().InvalidateCache()
session := loginUser(t, "user2") session := loginUser(t, "user2")
unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 2, RepoID: 3}) unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 2, RepoID: 3})
testEditFile(t, session, "org3", "repo3", "master", "README.md", "Hello, World (Edited for watch)\n") testEditFile(t, session, "org3", "repo3", "master", "README.md", "Hello, World (Edited for watch)\n")

View File

@ -10,9 +10,11 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/translation"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
@ -40,7 +42,10 @@ func TestSignup(t *testing.T) {
func TestSignupAsRestricted(t *testing.T) { func TestSignupAsRestricted(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
defer test.MockVariableValue(&setting.Service.EnableCaptcha, false)() defer test.MockVariableValue(&setting.Service.EnableCaptcha, false)()
defer test.MockVariableValue(&setting.Service.DefaultUserIsRestricted, true)() system.SetSettings(t.Context(), map[string]string{
setting.Config().Service.DefaultUserIsRestricted.DynKey(): "true",
})
config.GetDynGetter().InvalidateCache()
req := NewRequestWithValues(t, "POST", "/user/sign_up", map[string]string{ req := NewRequestWithValues(t, "POST", "/user/sign_up", map[string]string{
"user_name": "restrictedUser", "user_name": "restrictedUser",

View File

@ -68,8 +68,6 @@ REGISTER_MANUAL_CONFIRM = false
DISABLE_REGISTRATION = false DISABLE_REGISTRATION = false
ENABLE_CAPTCHA = false ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = false REQUIRE_SIGNIN_VIEW = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
NO_REPLY_ADDRESS = noreply.example.org NO_REPLY_ADDRESS = noreply.example.org
ENABLE_NOTIFY_MAIL = true ENABLE_NOTIFY_MAIL = true

View File

@ -71,8 +71,6 @@ REGISTER_MANUAL_CONFIRM = false
DISABLE_REGISTRATION = false DISABLE_REGISTRATION = false
ENABLE_CAPTCHA = false ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = false REQUIRE_SIGNIN_VIEW = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
NO_REPLY_ADDRESS = noreply.example.org NO_REPLY_ADDRESS = noreply.example.org
ENABLE_NOTIFY_MAIL = true ENABLE_NOTIFY_MAIL = true

View File

@ -69,8 +69,6 @@ REGISTER_MANUAL_CONFIRM = false
DISABLE_REGISTRATION = false DISABLE_REGISTRATION = false
ENABLE_CAPTCHA = false ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = false REQUIRE_SIGNIN_VIEW = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
NO_REPLY_ADDRESS = noreply.example.org NO_REPLY_ADDRESS = noreply.example.org
ENABLE_NOTIFY_MAIL = true ENABLE_NOTIFY_MAIL = true

View File

@ -69,8 +69,6 @@ ENABLE_NOTIFY_MAIL = true
DISABLE_REGISTRATION = false DISABLE_REGISTRATION = false
ENABLE_CAPTCHA = false ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = false REQUIRE_SIGNIN_VIEW = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
NO_REPLY_ADDRESS = noreply.example.org NO_REPLY_ADDRESS = noreply.example.org
[picture] [picture]