From 795b75ee6934556149da632c7fb496dc3e42efcd Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Tue, 6 Oct 2020 20:13:52 +0200 Subject: [PATCH 01/11] Parameter DISABLE_LOCAL_USER_MANAGEMENT added Added parameter DISABLE_LOCAL_USER_MANAGEMENT (false by default) in app.ini [service] section; when true disables local modifications of username, fullname and e-mail fields in user Settings. Author-Change-Id: IB#1105051 --- custom/conf/app.example.ini | 2 ++ .../doc/advanced/config-cheat-sheet.en-us.md | 1 + models/user.go | 18 ++++++++++++++++++ modules/auth/user_form.go | 1 + modules/setting/service.go | 2 ++ routers/user/setting/profile.go | 4 +++- templates/user/settings/profile.tmpl | 10 +++++----- 7 files changed, 32 insertions(+), 6 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index b3b9fd96cc708..385bf6ccb02e8 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -569,6 +569,8 @@ EMAIL_DOMAIN_WHITELIST= DISABLE_REGISTRATION = false ; Allow registration only using third-party services, it works only when DISABLE_REGISTRATION is false ALLOW_ONLY_EXTERNAL_REGISTRATION = false +; Disable local user management (i.e. when user data and password comes from LDAP and should not be changed locally in gitea). +DISABLE_LOCAL_USER_MANAGEMENT = false ; User must sign in to view anything. REQUIRE_SIGNIN_VIEW = false ; Mail notification 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 673eeac79ddae..784e15f3f84ba 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -409,6 +409,7 @@ set name for unique queues. Individual queues will default to - `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private". - `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation. - `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services. +- `DISABLE_LOCAL_USER_MANAGEMENT`: **false** Set to true to disable local user management in gitea (i.e. when users are managed in LDAP). - `NO_REPLY_ADDRESS`: **DOMAIN** Default value for the domain part of the user's email address in the git log if he has set KeepEmailPrivate to true. The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS. diff --git a/models/user.go b/models/user.go index 650d5a803aa9a..3688087782127 100644 --- a/models/user.go +++ b/models/user.go @@ -1148,6 +1148,24 @@ func updateUserCols(e Engine, u *User, cols ...string) error { // UpdateUserSetting updates user's settings. func UpdateUserSetting(u *User) error { + + // Don't allow username, fullname nor email changes if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + if currUser, err := GetUserByID(u.ID); err == nil { + if currUser.Name != u.Name { + return fmt.Errorf("cannot change %s username; local user management disabled", u.Name) + } + if currUser.FullName != u.FullName { + return fmt.Errorf("cannot change %s full name; local user management disabled", u.Name) + } + if currUser.Email != u.Email { + return fmt.Errorf("cannot change %s e-mail; local user management disabled", u.Name) + } + } else { + return err + } + } + if !u.IsOrganization() { if err := checkDupEmail(x, u); err != nil { return err diff --git a/modules/auth/user_form.go b/modules/auth/user_form.go index 999d4cd74df69..fe9b7bfbf511d 100644 --- a/modules/auth/user_form.go +++ b/modules/auth/user_form.go @@ -51,6 +51,7 @@ type InstallForm struct { EnableOpenIDSignUp bool DisableRegistration bool AllowOnlyExternalRegistration bool + DisableLocalUserManagement bool EnableCaptcha bool RequireSignInView bool DefaultKeepEmailPrivate bool diff --git a/modules/setting/service.go b/modules/setting/service.go index c463b0a9d5d0d..5dd33ff1e4a77 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -20,6 +20,7 @@ var Service struct { EmailDomainWhitelist []string DisableRegistration bool AllowOnlyExternalRegistration bool + DisableLocalUserManagement bool ShowRegistrationButton bool ShowMilestonesDashboardPage bool RequireSignInView bool @@ -61,6 +62,7 @@ func newService() { Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180) Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool() Service.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool() + Service.DisableLocalUserManagement = sec.Key("DISABLE_LOCAL_USER_MANAGEMENT").MustBool() Service.EmailDomainWhitelist = sec.Key("EMAIL_DOMAIN_WHITELIST").Strings(",") Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration)) Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true) diff --git a/routers/user/setting/profile.go b/routers/user/setting/profile.go index fe0506946ad68..98f852d87a3ab 100644 --- a/routers/user/setting/profile.go +++ b/routers/user/setting/profile.go @@ -34,13 +34,14 @@ const ( func Profile(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsProfile"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.HTML(200, tplSettingsProfile) } func handleUsernameChange(ctx *context.Context, newName string) { // Non-local users are not allowed to change their username. - if len(newName) == 0 || !ctx.User.IsLocal() { + if len(newName) == 0 || !ctx.User.IsLocal() || setting.Service.DisableLocalUserManagement { return } @@ -80,6 +81,7 @@ func handleUsernameChange(ctx *context.Context, newName string) { func ProfilePost(ctx *context.Context, form auth.UpdateProfileForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsProfile"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement if ctx.HasError() { ctx.HTML(200, tplSettingsProfile) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 1f34e24585d6d..dd55de94695c0 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -10,20 +10,20 @@

{{.i18n.Tr "settings.profile_desc"}}

{{.CsrfTokenHtml}} -
+
- + {{if not .SignedUser.IsLocal}}

{{$.i18n.Tr "settings.password_username_disabled"}}

{{end}}
- +
-
+
- +
From eca35631ecb44cdec697301de0d373efc314491f Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Wed, 7 Oct 2020 16:43:14 +0200 Subject: [PATCH 02/11] DISABLE_LOCAL_USER_MANAGEMENT mode added This patch blocks access to local user management options that are not required and possibly problematic in scenario when users are managed in external database (like LDAP) and should not be managed separately in gitea. Options specific to gitea (like restricted users) are still managed in this app. Author-Change-Id: IB#1105051 --- models/user.go | 57 +++++++++++++++++++--------- routers/admin/admin.go | 4 ++ routers/admin/auths.go | 30 +++++++++++++++ routers/admin/emails.go | 13 +++++++ routers/admin/hooks.go | 1 + routers/admin/notice.go | 1 + routers/admin/orgs.go | 1 + routers/admin/repos.go | 1 + routers/admin/users.go | 21 ++++++++++ routers/user/setting/account.go | 35 +++++++++++++++++ routers/user/setting/profile.go | 5 ++- templates/admin/navbar.tmpl | 2 + templates/admin/user/edit.tmpl | 20 +++++----- templates/admin/user/list.tmpl | 2 + templates/user/settings/account.tmpl | 13 ++++++- 15 files changed, 175 insertions(+), 31 deletions(-) diff --git a/models/user.go b/models/user.go index 3688087782127..ab8681bfff571 100644 --- a/models/user.go +++ b/models/user.go @@ -1126,7 +1126,43 @@ func checkDupEmail(e Engine, u *User) error { return nil } +// updateUserAllowed is used to block updating selected user fields when local user managemement is disabled. +func updateUserAllowed(u *User) error { + // Don't allow changes of selected user fields if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + if currUser, err := GetUserByID(u.ID); err == nil { + if currUser.Name != u.Name { + return fmt.Errorf("cannot change user %s username; local user management disabled", u.Name) + } + if (currUser.LoginSource != u.LoginSource) || (currUser.LoginName != u.LoginName) { + return fmt.Errorf("cannot change user %s login; local user management disabled", u.Name) + } + if currUser.FullName != u.FullName { + return fmt.Errorf("cannot change user %s full name; local user management disabled", u.Name) + } + if currUser.Email != u.Email { + return fmt.Errorf("cannot change user %s e-mail; local user management disabled", u.Name) + } + if (currUser.Passwd != u.Passwd) || (currUser.PasswdHashAlgo != u.PasswdHashAlgo) { + return fmt.Errorf("cannot change user %s password; local user management disabled", u.Name) + } + if currUser.IsActive != u.IsActive { + return fmt.Errorf("cannot change user %s activity; local user management disabled", u.Name) + } + if currUser.IsAdmin != u.IsAdmin { + return fmt.Errorf("cannot change user %s admin permission; local user management disabled", u.Name) + } + } else { + return err + } + } + return nil +} + func updateUser(e Engine, u *User) error { + if err := updateUserAllowed(u); err != nil { + return err + } _, err := e.ID(u.ID).AllCols().Update(u) return err } @@ -1142,30 +1178,15 @@ func UpdateUserCols(u *User, cols ...string) error { } func updateUserCols(e Engine, u *User, cols ...string) error { + if err := updateUserAllowed(u); err != nil { + return err + } _, err := e.ID(u.ID).Cols(cols...).Update(u) return err } // UpdateUserSetting updates user's settings. func UpdateUserSetting(u *User) error { - - // Don't allow username, fullname nor email changes if local user management is disabled. - if setting.Service.DisableLocalUserManagement { - if currUser, err := GetUserByID(u.ID); err == nil { - if currUser.Name != u.Name { - return fmt.Errorf("cannot change %s username; local user management disabled", u.Name) - } - if currUser.FullName != u.FullName { - return fmt.Errorf("cannot change %s full name; local user management disabled", u.Name) - } - if currUser.Email != u.Email { - return fmt.Errorf("cannot change %s e-mail; local user management disabled", u.Name) - } - } else { - return err - } - } - if !u.IsOrganization() { if err := checkDupEmail(x, u); err != nil { return err diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 5dbc321e9db2e..446a150cabc64 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -127,6 +127,7 @@ func Dashboard(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.dashboard") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminDashboard"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.Data["Stats"] = models.GetStatistic() // FIXME: update periodically updateSystemStatus() @@ -139,6 +140,7 @@ func DashboardPost(ctx *context.Context, form auth.AdminDashboardForm) { ctx.Data["Title"] = ctx.Tr("admin.dashboard") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminDashboard"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.Data["Stats"] = models.GetStatistic() updateSystemStatus() ctx.Data["SysStatus"] = sysStatus @@ -235,6 +237,7 @@ func Config(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.config") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminConfig"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.Data["CustomConf"] = setting.CustomConf ctx.Data["AppUrl"] = setting.AppURL @@ -325,6 +328,7 @@ func Monitor(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.monitor") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminMonitor"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.Data["Processes"] = process.GetManager().Processes() ctx.Data["Entries"] = cron.ListTasks() ctx.Data["Queues"] = queue.GetManager().ManagedQueues() diff --git a/routers/admin/auths.go b/routers/admin/auths.go index 98f6e25b1f938..e1066c90ac8e4 100644 --- a/routers/admin/auths.go +++ b/routers/admin/auths.go @@ -40,6 +40,12 @@ func Authentications(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminAuthentications"] = true + // No access to this page if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("Authentications", fmt.Errorf("access to /admin/auths page denied; local user management disabled")) + return + } + var err error ctx.Data["Sources"], err = models.LoginSources() if err != nil { @@ -96,6 +102,12 @@ func NewAuthSource(ctx *context.Context) { ctx.Data["SSPISeparatorReplacement"] = "_" ctx.Data["SSPIDefaultLanguage"] = "" + // No access to this page if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("NewAuthSource", fmt.Errorf("access to /admin/auths/new page denied; local user management disabled")) + return + } + // only the first as default for key := range models.OAuth2Providers { ctx.Data["oauth2_provider"] = key @@ -218,6 +230,12 @@ func NewAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) { ctx.Data["SSPISeparatorReplacement"] = "_" ctx.Data["SSPIDefaultLanguage"] = "" + // Don't allow to create auth source if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("NewAuthSourcePost", fmt.Errorf("cannot create auth source; local user management disabled")) + return + } + hasTLS := false var config convert.Conversion switch models.LoginType(form.Type) { @@ -290,6 +308,12 @@ func EditAuthSource(ctx *context.Context) { ctx.Data["OAuth2Providers"] = models.OAuth2Providers ctx.Data["OAuth2DefaultCustomURLMappings"] = models.OAuth2DefaultCustomURLMappings + // No access to this page if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("EditAuthSource", fmt.Errorf("access to /admin/auths page denied; local user management disabled")) + return + } + source, err := models.GetLoginSourceByID(ctx.ParamsInt64(":authid")) if err != nil { ctx.ServerError("GetLoginSourceByID", err) @@ -314,6 +338,12 @@ func EditAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) { ctx.Data["OAuth2Providers"] = models.OAuth2Providers ctx.Data["OAuth2DefaultCustomURLMappings"] = models.OAuth2DefaultCustomURLMappings + // Don't allow to update auth source if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("EditAuthSourcePost", fmt.Errorf("cannot update auth source; local user management disabled")) + return + } + source, err := models.GetLoginSourceByID(ctx.ParamsInt64(":authid")) if err != nil { ctx.ServerError("GetLoginSourceByID", err) diff --git a/routers/admin/emails.go b/routers/admin/emails.go index f0b14ce5e59dc..2001f148130be 100644 --- a/routers/admin/emails.go +++ b/routers/admin/emails.go @@ -6,6 +6,7 @@ package admin import ( "bytes" + "fmt" "net/url" "code.gitea.io/gitea/models" @@ -28,6 +29,12 @@ func Emails(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminEmails"] = true + // No access to this page if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("Emails", fmt.Errorf("access to /admin/emails page denied; local user management disabled")) + return + } + opts := &models.SearchEmailOptions{ ListOptions: models.ListOptions{ PageSize: setting.UI.Admin.UserPagingNum, @@ -112,6 +119,12 @@ func isKeywordValid(keyword string) bool { // ActivateEmail serves a POST request for activating/deactivating a user's email func ActivateEmail(ctx *context.Context) { + // Don't allow to activate/deactivate emails if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("ActivateEmail", fmt.Errorf("cannot activate email; local user management disabled")) + return + } + truefalse := map[string]bool{"1": true, "0": false} uid := com.StrTo(ctx.Query("uid")).MustInt64() diff --git a/routers/admin/hooks.go b/routers/admin/hooks.go index 4697c4d933f5a..b677fda0e6572 100644 --- a/routers/admin/hooks.go +++ b/routers/admin/hooks.go @@ -20,6 +20,7 @@ const ( func DefaultOrSystemWebhooks(ctx *context.Context) { var ws []*models.Webhook var err error + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement // Are we looking at default webhooks? if ctx.Params(":configType") == "hooks" { diff --git a/routers/admin/notice.go b/routers/admin/notice.go index ad2bad21630ca..b5029d8edbe5a 100644 --- a/routers/admin/notice.go +++ b/routers/admin/notice.go @@ -24,6 +24,7 @@ func Notices(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.notices") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminNotices"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement total := models.CountNotices() page := ctx.QueryInt("page") diff --git a/routers/admin/orgs.go b/routers/admin/orgs.go index 627f56eaecdfc..9945e305a7b85 100644 --- a/routers/admin/orgs.go +++ b/routers/admin/orgs.go @@ -23,6 +23,7 @@ func Organizations(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.organizations") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminOrganizations"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement routers.RenderUserSearch(ctx, &models.SearchUserOptions{ Type: models.UserTypeOrganization, diff --git a/routers/admin/repos.go b/routers/admin/repos.go index 10abaf9547ad1..4d433d53dce5c 100644 --- a/routers/admin/repos.go +++ b/routers/admin/repos.go @@ -28,6 +28,7 @@ func Repos(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.repositories") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminRepositories"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement routers.RenderRepoSearch(ctx, &routers.RepoSearchOptions{ Private: true, diff --git a/routers/admin/users.go b/routers/admin/users.go index 531f81b8b51e4..0d180237099d3 100644 --- a/routers/admin/users.go +++ b/routers/admin/users.go @@ -6,6 +6,7 @@ package admin import ( + "fmt" "strings" "code.gitea.io/gitea/models" @@ -32,6 +33,7 @@ func Users(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.users") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement routers.RenderUserSearch(ctx, &models.SearchUserOptions{ Type: models.UserTypeIndividual, @@ -50,6 +52,12 @@ func NewUser(ctx *context.Context) { ctx.Data["login_type"] = "0-0" + // No access to this page if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("NewUser", fmt.Errorf("access to /admin/users/new page denied; local user management disabled")) + return + } + sources, err := models.LoginSources() if err != nil { ctx.ServerError("LoginSources", err) @@ -67,6 +75,12 @@ func NewUserPost(ctx *context.Context, form auth.AdminCreateUserForm) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true + // Don't allow to create users if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("NewUserPost", fmt.Errorf("cannot create new user; local user management disabled")) + return + } + sources, err := models.LoginSources() if err != nil { ctx.ServerError("LoginSources", err) @@ -188,6 +202,7 @@ func EditUser(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true ctx.Data["DisableRegularOrgCreation"] = setting.Admin.DisableRegularOrgCreation + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement prepareUserInfo(ctx) if ctx.Written() { @@ -202,6 +217,7 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { ctx.Data["Title"] = ctx.Tr("admin.users.edit_account") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement u := prepareUserInfo(ctx) if ctx.Written() { @@ -226,6 +242,11 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { if len(form.Password) > 0 { var err error + // Don't allow password changes if local user management is disabled. + //if setting.Service.DisableLocalUserManagement { + //ctx.ServerError("UpdateUser", fmt.Errorf("cannot change %s password; local user management disabled", u.Name)) + //return + //} if len(form.Password) < setting.MinPasswordLength { ctx.Data["Err_Password"] = true ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplUserEdit, &form) diff --git a/routers/user/setting/account.go b/routers/user/setting/account.go index 99e20177bc986..eb5d0d6bdecce 100644 --- a/routers/user/setting/account.go +++ b/routers/user/setting/account.go @@ -7,6 +7,7 @@ package setting import ( "errors" + "fmt" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth" @@ -28,6 +29,7 @@ func Account(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true ctx.Data["Email"] = ctx.User.Email + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement loadAccountData(ctx) @@ -38,6 +40,7 @@ func Account(ctx *context.Context) { func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement if ctx.HasError() { loadAccountData(ctx) @@ -83,9 +86,16 @@ func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) { func EmailPost(ctx *context.Context, form auth.AddEmailForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement // Make emailaddress primary. if ctx.Query("_method") == "PRIMARY" { + // No access to this function if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("MakeEmailPrimary", fmt.Errorf("access to /user/settings/account/email MakeEmailPrimary function denied; local user management disabled")) + return + } + if err := models.MakeEmailPrimary(&models.EmailAddress{ID: ctx.QueryInt64("id")}); err != nil { ctx.ServerError("MakeEmailPrimary", err) return @@ -97,6 +107,11 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) { } // Send activation Email if ctx.Query("_method") == "SENDACTIVATION" { + // No access to this function if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("SendActivation", fmt.Errorf("access to /user/settings/account/email SendActivation function denied; local user management disabled")) + return + } var address string if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) { log.Error("Send activation: activation still pending") @@ -161,6 +176,12 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) { return } + // No access to this function if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("AddEmailAddress", fmt.Errorf("access to /user/settings/account/email AddEmailAddress function denied; local user management disabled")) + return + } + if ctx.HasError() { loadAccountData(ctx) @@ -201,6 +222,13 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) { // DeleteEmail response for delete user's email func DeleteEmail(ctx *context.Context) { + + // No access to this function if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("DeleteEmail", fmt.Errorf("access to /user/settings/account/email DeleteEmail function denied; local user management disabled")) + return + } + if err := models.DeleteEmailAddress(&models.EmailAddress{ID: ctx.QueryInt64("id"), UID: ctx.User.ID}); err != nil { ctx.ServerError("DeleteEmail", err) return @@ -215,6 +243,12 @@ func DeleteEmail(ctx *context.Context) { // DeleteAccount render user suicide page and response for delete user himself func DeleteAccount(ctx *context.Context) { + // No access to this page if local user management is disabled. + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("DeleteAccount", fmt.Errorf("access to /user/settings/account/delete page denied; local user management disabled")) + return + } + ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true @@ -251,6 +285,7 @@ func UpdateUIThemePost(ctx *context.Context, form auth.UpdateThemeForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true + ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement if ctx.HasError() { ctx.Redirect(setting.AppSubURL + "/user/settings/account") diff --git a/routers/user/setting/profile.go b/routers/user/setting/profile.go index 98f852d87a3ab..a230ae8b61113 100644 --- a/routers/user/setting/profile.go +++ b/routers/user/setting/profile.go @@ -41,12 +41,15 @@ func Profile(ctx *context.Context) { func handleUsernameChange(ctx *context.Context, newName string) { // Non-local users are not allowed to change their username. - if len(newName) == 0 || !ctx.User.IsLocal() || setting.Service.DisableLocalUserManagement { + if len(newName) == 0 || !ctx.User.IsLocal() { return } // Check if user name has been changed if ctx.User.LowerName != strings.ToLower(newName) { + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("ChangeUserName", fmt.Errorf("cannot change user %s username; local user management disabled", ctx.User.Name)) + } if err := models.ChangeUserName(ctx.User, newName); err != nil { switch { case models.IsErrUserAlreadyExist(err): diff --git a/templates/admin/navbar.tmpl b/templates/admin/navbar.tmpl index 6d81d7557f607..0c17fc71ded22 100644 --- a/templates/admin/navbar.tmpl +++ b/templates/admin/navbar.tmpl @@ -17,12 +17,14 @@ {{.i18n.Tr "admin.systemhooks"}} +{{if not .DisableLocalUserManagement}} {{.i18n.Tr "admin.authentication"}} {{.i18n.Tr "admin.emails"}} +{{end}} {{.i18n.Tr "admin.config"}} diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index 042c09954a2c3..d6177435f4085 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -14,7 +14,7 @@ {{.User.Name}}
-
+
-
+
- +
- +
-
+
- +
-
+

{{.i18n.Tr "admin.users.password_helper"}}

@@ -68,19 +68,19 @@
- +
- +
- +
diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl index d6dd7d5c03969..3f6fb7e98ec72 100644 --- a/templates/admin/user/list.tmpl +++ b/templates/admin/user/list.tmpl @@ -5,9 +5,11 @@ {{template "base/alert" .}}

{{.i18n.Tr "admin.users.user_manage_panel"}} ({{.i18n.Tr "admin.total" .Total}}) +{{if not .DisableLocalUserManagement}} +{{end}}

{{template "admin/base/search" .}} diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl index b2cff8618878a..7230c6a6eabb7 100644 --- a/templates/user/settings/account.tmpl +++ b/templates/user/settings/account.tmpl @@ -3,6 +3,7 @@ {{template "user/settings/navbar" .}}
{{template "base/alert" .}} +{{if not .DisableLocalUserManagement}}

{{.i18n.Tr "settings.password"}}

@@ -36,7 +37,7 @@
{{end}}
- +{{end}}

{{.i18n.Tr "settings.manage_emails"}}

@@ -70,6 +71,7 @@
{{range .Emails}}
+{{if not $.DisableLocalUserManagement}} {{if not .IsPrimary}}
{{end}} +{{end}}
{{.Email}} +{{if not $.DisableLocalUserManagement}} + {{if .IsPrimary}}
{{$.i18n.Tr "settings.primary"}}
{{end}} @@ -111,11 +116,13 @@ {{else}}
{{$.i18n.Tr "settings.requires_activation"}}
{{end}} +{{end}}
{{end}}
+{{if not .DisableLocalUserManagement}}
{{.CsrfTokenHtml}} @@ -128,7 +135,7 @@
- +{{end}}

{{.i18n.Tr "settings.manage_themes"}}

@@ -167,6 +174,7 @@
+{{if not .DisableLocalUserManagement}}

{{.i18n.Tr "settings.delete_account"}}

@@ -189,6 +197,7 @@
+{{end}}
From f92d339e4684a2ecfe5786112d88e3e46781ee35 Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Wed, 7 Oct 2020 19:43:39 +0200 Subject: [PATCH 03/11] Fixed external user syncing when local user management is disabled This fixes external user syncing when local user management is disabled. Fixes: eca35631ecb44cdec697301de0d373efc314491f Author-Change-Id: IB#1105051 --- cmd/admin.go | 2 +- models/login_source.go | 4 ++-- models/repo.go | 2 +- models/user.go | 22 ++++++++++++---------- models/user_mail.go | 4 ++-- modules/auth/sso/sso.go | 2 +- routers/api/v1/org/org.go | 2 +- routers/user/auth.go | 16 ++++++++-------- routers/user/auth_openid.go | 2 +- routers/user/setting/account.go | 2 +- routers/user/setting/profile.go | 2 +- 11 files changed, 31 insertions(+), 29 deletions(-) diff --git a/cmd/admin.go b/cmd/admin.go index 9f81f5284dd6d..813b92a3d0f7a 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -283,7 +283,7 @@ func runChangePassword(c *cli.Context) error { } user.HashPassword(c.String("password")) - if err := models.UpdateUserCols(user, "passwd", "salt"); err != nil { + if err := models.UpdateUserCols(user, false, "passwd", "salt"); err != nil { return err } diff --git a/models/login_source.go b/models/login_source.go index 1de24a9cf70b5..55efa3c0c62c5 100644 --- a/models/login_source.go +++ b/models/login_source.go @@ -488,7 +488,7 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource) (*Use cols = append(cols, "is_restricted") } if len(cols) > 0 { - err = UpdateUserCols(user, cols...) + err = UpdateUserCols(user, false, cols...) if err != nil { return nil, err } @@ -768,7 +768,7 @@ func UserSignIn(username, password string) (*User, error) { // Update password hash if server password hash algorithm have changed if user.PasswdHashAlgo != setting.PasswordHashAlgo { user.HashPassword(password) - if err := UpdateUserCols(user, "passwd", "passwd_hash_algo"); err != nil { + if err := UpdateUserCols(user, false, "passwd", "passwd_hash_algo"); err != nil { return nil, err } } diff --git a/models/repo.go b/models/repo.go index 46f91fc7df658..20822ff14c405 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1190,7 +1190,7 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, overwriteO // Remember visibility preference. u.LastRepoVisibility = repo.IsPrivate - if err = updateUserCols(ctx.e, u, "last_repo_visibility"); err != nil { + if err = updateUserCols(ctx.e, u, false, "last_repo_visibility"); err != nil { return fmt.Errorf("updateUser: %v", err) } diff --git a/models/user.go b/models/user.go index ab8681bfff571..966dc1e023411 100644 --- a/models/user.go +++ b/models/user.go @@ -220,13 +220,13 @@ func (u *User) SetLastLogin() { // UpdateDiffViewStyle updates the users diff view style func (u *User) UpdateDiffViewStyle(style string) error { u.DiffViewStyle = style - return UpdateUserCols(u, "diff_view_style") + return UpdateUserCols(u, false, "diff_view_style") } // UpdateTheme updates a users' theme irrespective of the site wide theme func (u *User) UpdateTheme(themeName string) error { u.Theme = themeName - return UpdateUserCols(u, "theme") + return UpdateUserCols(u, false, "theme") } // GetEmail returns an noreply email, if the user has set to keep his @@ -824,7 +824,7 @@ func (u *User) EmailNotifications() string { // SetEmailNotifications sets the user's email notification preference func (u *User) SetEmailNotifications(set string) error { u.EmailNotificationsPreference = set - if err := UpdateUserCols(u, "email_notifications_preference"); err != nil { + if err := UpdateUserCols(u, false, "email_notifications_preference"); err != nil { log.Error("SetEmailNotifications: %v", err) return err } @@ -1173,13 +1173,15 @@ func UpdateUser(u *User) error { } // UpdateUserCols update user according special columns -func UpdateUserCols(u *User, cols ...string) error { - return updateUserCols(x, u, cols...) +func UpdateUserCols(u *User, force bool, cols ...string) error { + return updateUserCols(x, u, force, cols...) } -func updateUserCols(e Engine, u *User, cols ...string) error { - if err := updateUserAllowed(u); err != nil { - return err +func updateUserCols(e Engine, u *User, force bool, cols ...string) error { + if !force { + if err := updateUserAllowed(u); err != nil { + return err + } } _, err := e.ID(u.ID).Cols(cols...).Update(u) return err @@ -2021,7 +2023,7 @@ func SyncExternalUsers(ctx context.Context, updateExisting bool) error { } usr.IsActive = true - err = UpdateUserCols(usr, "full_name", "email", "is_admin", "is_restricted", "is_active") + err = UpdateUserCols(usr, true, "full_name", "email", "is_admin", "is_restricted", "is_active") if err != nil { log.Error("SyncExternalUsers[%s]: Error updating user %s: %v", s.Name, usr.Name, err) } @@ -2058,7 +2060,7 @@ func SyncExternalUsers(ctx context.Context, updateExisting bool) error { log.Trace("SyncExternalUsers[%s]: Deactivating user %s", s.Name, usr.Name) usr.IsActive = false - err = UpdateUserCols(usr, "is_active") + err = UpdateUserCols(usr, true, "is_active") if err != nil { log.Error("SyncExternalUsers[%s]: Error deactivating user %s: %v", s.Name, usr.Name, err) } diff --git a/models/user_mail.go b/models/user_mail.go index 60354e23ffb22..390e60f9fa16d 100644 --- a/models/user_mail.go +++ b/models/user_mail.go @@ -201,7 +201,7 @@ func (email *EmailAddress) updateActivation(e Engine, activate bool) error { if _, err := e.ID(email.ID).Cols("is_activated").Update(email); err != nil { return err } - return updateUserCols(e, user, "rands") + return updateUserCols(e, user, false, "rands") } // DeleteEmailAddress deletes an email address of given user. @@ -448,7 +448,7 @@ func ActivateUserEmail(userID int64, email string, primary, activate bool) (err if user.Rands, err = GetUserSalt(); err != nil { return fmt.Errorf("generate salt: %v", err) } - if err = updateUserCols(sess, &user, "is_active", "rands"); err != nil { + if err = updateUserCols(sess, &user, false, "is_active", "rands"); err != nil { return fmt.Errorf("updateUserCols(): %v", err) } } else { diff --git a/modules/auth/sso/sso.go b/modules/auth/sso/sso.go index c2e36f3f5ebf2..f8d999ee891b7 100644 --- a/modules/auth/sso/sso.go +++ b/modules/auth/sso/sso.go @@ -133,7 +133,7 @@ func handleSignIn(ctx *macaron.Context, sess session.Store, user *models.User) { // If the user does not have a locale set, we save the current one. if len(user.Language) == 0 { user.Language = ctx.Locale.Language() - if err := models.UpdateUserCols(user, "language"); err != nil { + if err := models.UpdateUserCols(user, false, "language"); err != nil { log.Error(fmt.Sprintf("Error updating user language [user: %d, locale: %s]", user.ID, user.Language)) return } diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index 987f141078088..4759c8ede1667 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -253,7 +253,7 @@ func Edit(ctx *context.APIContext, form api.EditOrgOption) { if form.Visibility != "" { org.Visibility = api.VisibilityModes[form.Visibility] } - if err := models.UpdateUserCols(org, "full_name", "description", "website", "location", "visibility"); err != nil { + if err := models.UpdateUserCols(org, false, "full_name", "description", "website", "location", "visibility"); err != nil { ctx.Error(http.StatusInternalServerError, "EditOrganization", err) return } diff --git a/routers/user/auth.go b/routers/user/auth.go index 96a73c9dd4632..9eb8cd1359454 100644 --- a/routers/user/auth.go +++ b/routers/user/auth.go @@ -519,7 +519,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR // If the user does not have a locale set, we save the current one. if len(u.Language) == 0 { u.Language = ctx.Locale.Language() - if err := models.UpdateUserCols(u, "language"); err != nil { + if err := models.UpdateUserCols(u, false, "language"); err != nil { log.Error(fmt.Sprintf("Error updating user language [user: %d, locale: %s]", u.ID, u.Language)) return setting.AppSubURL + "/" } @@ -532,7 +532,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR // Register last login u.SetLastLogin() - if err := models.UpdateUserCols(u, "last_login_unix"); err != nil { + if err := models.UpdateUserCols(u, false, "last_login_unix"); err != nil { ctx.ServerError("UpdateUserCols", err) return setting.AppSubURL + "/" } @@ -639,7 +639,7 @@ func handleOAuth2SignIn(u *models.User, gothUser goth.User, ctx *context.Context // Register last login u.SetLastLogin() - if err := models.UpdateUserCols(u, "last_login_unix"); err != nil { + if err := models.UpdateUserCols(u, false, "last_login_unix"); err != nil { ctx.ServerError("UpdateUserCols", err) return } @@ -978,7 +978,7 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au u.IsAdmin = true u.IsActive = true u.SetLastLogin() - if err := models.UpdateUserCols(u, "is_admin", "is_active", "last_login_unix"); err != nil { + if err := models.UpdateUserCols(u, false, "is_admin", "is_active", "last_login_unix"); err != nil { ctx.ServerError("UpdateUser", err) return } @@ -1154,7 +1154,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo u.IsAdmin = true u.IsActive = true u.SetLastLogin() - if err := models.UpdateUserCols(u, "is_admin", "is_active", "last_login_unix"); err != nil { + if err := models.UpdateUserCols(u, false, "is_admin", "is_active", "last_login_unix"); err != nil { ctx.ServerError("UpdateUser", err) return } @@ -1215,7 +1215,7 @@ func Activate(ctx *context.Context) { ctx.ServerError("UpdateUser", err) return } - if err := models.UpdateUserCols(user, "is_active", "rands"); err != nil { + if err := models.UpdateUserCols(user, false, "is_active", "rands"); err != nil { if models.IsErrUserNotExist(err) { ctx.Error(404) } else { @@ -1475,7 +1475,7 @@ func ResetPasswdPost(ctx *context.Context) { } u.HashPassword(passwd) u.MustChangePassword = false - if err := models.UpdateUserCols(u, "must_change_password", "passwd", "rands", "salt"); err != nil { + if err := models.UpdateUserCols(u, false, "must_change_password", "passwd", "rands", "salt"); err != nil { ctx.ServerError("UpdateUser", err) return } @@ -1551,7 +1551,7 @@ func MustChangePasswordPost(ctx *context.Context, cpt *captcha.Captcha, form aut u.HashPassword(form.Password) u.MustChangePassword = false - if err := models.UpdateUserCols(u, "must_change_password", "passwd", "salt"); err != nil { + if err := models.UpdateUserCols(u, false, "must_change_password", "passwd", "salt"); err != nil { ctx.ServerError("UpdateUser", err) return } diff --git a/routers/user/auth_openid.go b/routers/user/auth_openid.go index ba2c8be8c24cb..258691522874a 100644 --- a/routers/user/auth_openid.go +++ b/routers/user/auth_openid.go @@ -443,7 +443,7 @@ func RegisterOpenIDPost(ctx *context.Context, cpt *captcha.Captcha, form auth.Si u.IsAdmin = true u.IsActive = true u.SetLastLogin() - if err := models.UpdateUserCols(u, "is_admin", "is_active", "last_login_unix"); err != nil { + if err := models.UpdateUserCols(u, false, "is_admin", "is_active", "last_login_unix"); err != nil { ctx.ServerError("UpdateUser", err) return } diff --git a/routers/user/setting/account.go b/routers/user/setting/account.go index eb5d0d6bdecce..a956e04a037c2 100644 --- a/routers/user/setting/account.go +++ b/routers/user/setting/account.go @@ -71,7 +71,7 @@ func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) { return } ctx.User.HashPassword(form.Password) - if err := models.UpdateUserCols(ctx.User, "salt", "passwd"); err != nil { + if err := models.UpdateUserCols(ctx.User, false, "salt", "passwd"); err != nil { ctx.ServerError("UpdateUser", err) return } diff --git a/routers/user/setting/profile.go b/routers/user/setting/profile.go index a230ae8b61113..0207296fc887e 100644 --- a/routers/user/setting/profile.go +++ b/routers/user/setting/profile.go @@ -160,7 +160,7 @@ func UpdateAvatarSetting(ctx *context.Context, form auth.AvatarForm, ctxUser *mo } } - if err := models.UpdateUserCols(ctxUser, "avatar", "avatar_email", "use_custom_avatar"); err != nil { + if err := models.UpdateUserCols(ctxUser, false, "avatar", "avatar_email", "use_custom_avatar"); err != nil { return fmt.Errorf("UpdateUser: %v", err) } From 70672ee67fbdb8b9a4d14e7b9814f912608cdb6e Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Wed, 7 Oct 2020 20:42:28 +0200 Subject: [PATCH 04/11] Hide message about changing username Hide message about changing username when local user modifications are disabled. Author-Change-Id: IB#1105051 --- templates/user/settings/profile.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index dd55de94695c0..28af65ab25ea5 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -13,7 +13,7 @@
- {{if not .SignedUser.IsLocal}} + {{if not (or (.SignedUser.IsLocal) (.DisableLocalUserManagement))}}

{{$.i18n.Tr "settings.password_username_disabled"}}

{{end}}
From d97a8ea9a07a1d37ceba05b2aba5befac25c68d2 Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Tue, 20 Oct 2020 23:12:05 +0200 Subject: [PATCH 05/11] Fixed DISABLE_LOCAL_USER_MANAGEMENT mode Adopted repos screens didn't hide menu tabs. This mod fixes it and simplifies configuration for templates. It also removes unnecessarry comment. Author-Change-Id: IB#1105051 Fixes: eca35631ecb44cdec697301de0d373efc314491f --- modules/templates/helper.go | 3 +++ routers/admin/admin.go | 4 ---- routers/admin/hooks.go | 1 - routers/admin/notice.go | 1 - routers/admin/orgs.go | 1 - routers/admin/repos.go | 1 - routers/admin/users.go | 11 ++++------- routers/user/setting/account.go | 4 ---- routers/user/setting/profile.go | 2 -- templates/admin/navbar.tmpl | 2 +- templates/admin/user/edit.tmpl | 20 ++++++++++---------- templates/admin/user/list.tmpl | 2 +- templates/user/settings/account.tmpl | 10 +++++----- templates/user/settings/profile.tmpl | 12 ++++++------ 14 files changed, 30 insertions(+), 44 deletions(-) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 63be27d98735a..13a185eb50d40 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -228,6 +228,9 @@ func NewFuncMap() []template.FuncMap { "DisableImportLocal": func() bool { return !setting.ImportLocalPaths }, + "DisableLocalUserManagement": func() bool { + return setting.Service.DisableLocalUserManagement + }, "TrN": TrN, "Dict": func(values ...interface{}) (map[string]interface{}, error) { if len(values)%2 != 0 { diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 446a150cabc64..5dbc321e9db2e 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -127,7 +127,6 @@ func Dashboard(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.dashboard") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminDashboard"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.Data["Stats"] = models.GetStatistic() // FIXME: update periodically updateSystemStatus() @@ -140,7 +139,6 @@ func DashboardPost(ctx *context.Context, form auth.AdminDashboardForm) { ctx.Data["Title"] = ctx.Tr("admin.dashboard") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminDashboard"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.Data["Stats"] = models.GetStatistic() updateSystemStatus() ctx.Data["SysStatus"] = sysStatus @@ -237,7 +235,6 @@ func Config(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.config") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminConfig"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.Data["CustomConf"] = setting.CustomConf ctx.Data["AppUrl"] = setting.AppURL @@ -328,7 +325,6 @@ func Monitor(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.monitor") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminMonitor"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.Data["Processes"] = process.GetManager().Processes() ctx.Data["Entries"] = cron.ListTasks() ctx.Data["Queues"] = queue.GetManager().ManagedQueues() diff --git a/routers/admin/hooks.go b/routers/admin/hooks.go index b677fda0e6572..4697c4d933f5a 100644 --- a/routers/admin/hooks.go +++ b/routers/admin/hooks.go @@ -20,7 +20,6 @@ const ( func DefaultOrSystemWebhooks(ctx *context.Context) { var ws []*models.Webhook var err error - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement // Are we looking at default webhooks? if ctx.Params(":configType") == "hooks" { diff --git a/routers/admin/notice.go b/routers/admin/notice.go index b5029d8edbe5a..ad2bad21630ca 100644 --- a/routers/admin/notice.go +++ b/routers/admin/notice.go @@ -24,7 +24,6 @@ func Notices(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.notices") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminNotices"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement total := models.CountNotices() page := ctx.QueryInt("page") diff --git a/routers/admin/orgs.go b/routers/admin/orgs.go index 9945e305a7b85..627f56eaecdfc 100644 --- a/routers/admin/orgs.go +++ b/routers/admin/orgs.go @@ -23,7 +23,6 @@ func Organizations(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.organizations") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminOrganizations"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement routers.RenderUserSearch(ctx, &models.SearchUserOptions{ Type: models.UserTypeOrganization, diff --git a/routers/admin/repos.go b/routers/admin/repos.go index 4d433d53dce5c..10abaf9547ad1 100644 --- a/routers/admin/repos.go +++ b/routers/admin/repos.go @@ -28,7 +28,6 @@ func Repos(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.repositories") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminRepositories"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement routers.RenderRepoSearch(ctx, &routers.RepoSearchOptions{ Private: true, diff --git a/routers/admin/users.go b/routers/admin/users.go index 0d180237099d3..dc21921da143f 100644 --- a/routers/admin/users.go +++ b/routers/admin/users.go @@ -33,7 +33,6 @@ func Users(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.users") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement routers.RenderUserSearch(ctx, &models.SearchUserOptions{ Type: models.UserTypeIndividual, @@ -202,7 +201,6 @@ func EditUser(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true ctx.Data["DisableRegularOrgCreation"] = setting.Admin.DisableRegularOrgCreation - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement prepareUserInfo(ctx) if ctx.Written() { @@ -217,7 +215,6 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { ctx.Data["Title"] = ctx.Tr("admin.users.edit_account") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement u := prepareUserInfo(ctx) if ctx.Written() { @@ -243,10 +240,10 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { if len(form.Password) > 0 { var err error // Don't allow password changes if local user management is disabled. - //if setting.Service.DisableLocalUserManagement { - //ctx.ServerError("UpdateUser", fmt.Errorf("cannot change %s password; local user management disabled", u.Name)) - //return - //} + if setting.Service.DisableLocalUserManagement { + ctx.ServerError("UpdateUser", fmt.Errorf("cannot change %s password; local user management disabled", u.Name)) + return + } if len(form.Password) < setting.MinPasswordLength { ctx.Data["Err_Password"] = true ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplUserEdit, &form) diff --git a/routers/user/setting/account.go b/routers/user/setting/account.go index a956e04a037c2..f9fe5c00fc4c6 100644 --- a/routers/user/setting/account.go +++ b/routers/user/setting/account.go @@ -29,7 +29,6 @@ func Account(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true ctx.Data["Email"] = ctx.User.Email - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement loadAccountData(ctx) @@ -40,7 +39,6 @@ func Account(ctx *context.Context) { func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement if ctx.HasError() { loadAccountData(ctx) @@ -86,7 +84,6 @@ func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) { func EmailPost(ctx *context.Context, form auth.AddEmailForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement // Make emailaddress primary. if ctx.Query("_method") == "PRIMARY" { @@ -285,7 +282,6 @@ func UpdateUIThemePost(ctx *context.Context, form auth.UpdateThemeForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement if ctx.HasError() { ctx.Redirect(setting.AppSubURL + "/user/settings/account") diff --git a/routers/user/setting/profile.go b/routers/user/setting/profile.go index 0207296fc887e..de80f013a62e5 100644 --- a/routers/user/setting/profile.go +++ b/routers/user/setting/profile.go @@ -34,7 +34,6 @@ const ( func Profile(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsProfile"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement ctx.HTML(200, tplSettingsProfile) } @@ -84,7 +83,6 @@ func handleUsernameChange(ctx *context.Context, newName string) { func ProfilePost(ctx *context.Context, form auth.UpdateProfileForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsProfile"] = true - ctx.Data["DisableLocalUserManagement"] = setting.Service.DisableLocalUserManagement if ctx.HasError() { ctx.HTML(200, tplSettingsProfile) diff --git a/templates/admin/navbar.tmpl b/templates/admin/navbar.tmpl index 0c17fc71ded22..eba96209c0966 100644 --- a/templates/admin/navbar.tmpl +++ b/templates/admin/navbar.tmpl @@ -17,7 +17,7 @@ {{.i18n.Tr "admin.systemhooks"}} -{{if not .DisableLocalUserManagement}} +{{if not DisableLocalUserManagement}} {{.i18n.Tr "admin.authentication"}} diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index d6177435f4085..6031f6895098a 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -14,7 +14,7 @@ {{.User.Name}} -
+
-
+
- +
- +
-
+
- +
-
+

{{.i18n.Tr "admin.users.password_helper"}}

@@ -68,19 +68,19 @@
- +
- +
- +
diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl index 3f6fb7e98ec72..0363501bbeb0f 100644 --- a/templates/admin/user/list.tmpl +++ b/templates/admin/user/list.tmpl @@ -5,7 +5,7 @@ {{template "base/alert" .}}

{{.i18n.Tr "admin.users.user_manage_panel"}} ({{.i18n.Tr "admin.total" .Total}}) -{{if not .DisableLocalUserManagement}} +{{if not DisableLocalUserManagement}} diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl index 7230c6a6eabb7..584974cc9b1bb 100644 --- a/templates/user/settings/account.tmpl +++ b/templates/user/settings/account.tmpl @@ -3,7 +3,7 @@ {{template "user/settings/navbar" .}}
{{template "base/alert" .}} -{{if not .DisableLocalUserManagement}} +{{if not DisableLocalUserManagement}}

{{.i18n.Tr "settings.password"}}

@@ -71,7 +71,7 @@
{{range .Emails}}
-{{if not $.DisableLocalUserManagement}} +{{if not DisableLocalUserManagement}} {{if not .IsPrimary}}
-{{if not .DisableLocalUserManagement}} +{{if not DisableLocalUserManagement}}
{{.CsrfTokenHtml}} @@ -174,7 +174,7 @@
-{{if not .DisableLocalUserManagement}} +{{if not DisableLocalUserManagement}}

{{.i18n.Tr "settings.delete_account"}}

diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 28af65ab25ea5..2748eb45f89be 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -10,20 +10,20 @@

{{.i18n.Tr "settings.profile_desc"}}

{{.CsrfTokenHtml}} -
+
- - {{if not (or (.SignedUser.IsLocal) (.DisableLocalUserManagement))}} + + {{if not (or .SignedUser.IsLocal DisableLocalUserManagement)}}

{{$.i18n.Tr "settings.password_username_disabled"}}

{{end}}
- +
-
+
- +
From fe6ae270f1e7bbb9cfd28c618f69c985168cb9bb Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Tue, 23 Mar 2021 12:27:17 +0100 Subject: [PATCH 06/11] Allow org name change in DISABLE_LOCAL_USER_MANAGEMENT mode Fixes 500 on organization name change in DISABLE_LOCAL_USER_MANAGEMENT mode. Fixes: eca35631ecb44cdec697301de0d373efc314491f Author-Change-Id: IB#1105051 --- models/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/user.go b/models/user.go index 966dc1e023411..064e47b296ead 100644 --- a/models/user.go +++ b/models/user.go @@ -1129,7 +1129,7 @@ func checkDupEmail(e Engine, u *User) error { // updateUserAllowed is used to block updating selected user fields when local user managemement is disabled. func updateUserAllowed(u *User) error { // Don't allow changes of selected user fields if local user management is disabled. - if setting.Service.DisableLocalUserManagement { + if setting.Service.DisableLocalUserManagement && (u.Type == UserTypeIndividual) { if currUser, err := GetUserByID(u.ID); err == nil { if currUser.Name != u.Name { return fmt.Errorf("cannot change user %s username; local user management disabled", u.Name) From cda4a8a21624587690a932206362d4f6a6d9bc30 Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Tue, 1 Feb 2022 12:04:52 +0100 Subject: [PATCH 07/11] Separate function for forced update added Fixes: f92d339e4684a2ecfe5786112d88e3e46781ee35 Related: https://github.com/go-gitea/gitea/pull/18466#discussion_r796044064 Author-Change-Id: IB#1105051 --- cmd/admin.go | 2 +- models/repo.go | 2 +- models/user/email_address.go | 4 ++-- models/user/user.go | 19 ++++++++++++------- routers/api/v1/org/org.go | 2 +- routers/web/auth/auth.go | 10 +++++----- routers/web/auth/oauth.go | 4 ++-- routers/web/auth/password.go | 4 ++-- routers/web/user/setting/account.go | 2 +- routers/web/user/setting/profile.go | 2 +- services/auth/auth.go | 2 +- services/auth/source/db/authenticate.go | 2 +- .../auth/source/ldap/source_authenticate.go | 2 +- services/auth/source/ldap/source_sync.go | 4 ++-- services/user/user.go | 2 +- 15 files changed, 34 insertions(+), 29 deletions(-) diff --git a/cmd/admin.go b/cmd/admin.go index e3c0922680794..3c7f7c8a7c5df 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -471,7 +471,7 @@ func runChangePassword(c *cli.Context) error { return err } - if err = user_model.UpdateUserCols(db.DefaultContext, user, false, "passwd", "passwd_hash_algo", "salt"); err != nil { + if err = user_model.UpdateUserCols(db.DefaultContext, user, "passwd", "passwd_hash_algo", "salt"); err != nil { return err } diff --git a/models/repo.go b/models/repo.go index d48ba23e05ff5..83031c508cdce 100644 --- a/models/repo.go +++ b/models/repo.go @@ -508,7 +508,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_ // Remember visibility preference. u.LastRepoVisibility = repo.IsPrivate - if err = user_model.UpdateUserColsEngine(db.GetEngine(ctx), u, false, "last_repo_visibility"); err != nil { + if err = user_model.UpdateUserColsEngine(db.GetEngine(ctx), u, "last_repo_visibility"); err != nil { return fmt.Errorf("updateUser: %v", err) } diff --git a/models/user/email_address.go b/models/user/email_address.go index 096f120fcf657..0ff62fb6a8056 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -303,7 +303,7 @@ func updateActivation(e db.Engine, email *EmailAddress, activate bool) error { if _, err := e.ID(email.ID).Cols("is_activated").Update(email); err != nil { return err } - return UpdateUserColsEngine(e, user, false, "rands") + return UpdateUserColsEngine(e, user, "rands") } // MakeEmailPrimary sets primary email address of given user. @@ -513,7 +513,7 @@ func ActivateUserEmail(userID int64, email string, activate bool) (err error) { if user.Rands, err = GetUserSalt(); err != nil { return fmt.Errorf("unable to generate salt: %v", err) } - if err = UpdateUserColsEngine(sess, &user, false, "is_active", "rands"); err != nil { + if err = UpdateUserColsEngine(sess, &user, "is_active", "rands"); err != nil { return fmt.Errorf("unable to updateUserCols() for user ID: %d: %v", userID, err) } } diff --git a/models/user/user.go b/models/user/user.go index 0c739f758f9b2..037584f1a7af9 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -206,13 +206,13 @@ func (u *User) SetLastLogin() { // UpdateUserDiffViewStyle updates the users diff view style func UpdateUserDiffViewStyle(u *User, style string) error { u.DiffViewStyle = style - return UpdateUserCols(db.DefaultContext, u, false, "diff_view_style") + return UpdateUserCols(db.DefaultContext, u, "diff_view_style") } // UpdateUserTheme updates a users' theme irrespective of the site wide theme func UpdateUserTheme(u *User, themeName string) error { u.Theme = themeName - return UpdateUserCols(db.DefaultContext, u, false, "theme") + return UpdateUserCols(db.DefaultContext, u, "theme") } // GetEmail returns an noreply email, if the user has set to keep his @@ -502,7 +502,7 @@ func (u *User) EmailNotifications() string { // SetEmailNotifications sets the user's email notification preference func SetEmailNotifications(u *User, set string) error { u.EmailNotificationsPreference = set - if err := UpdateUserCols(db.DefaultContext, u, false, "email_notifications_preference"); err != nil { + if err := UpdateUserCols(db.DefaultContext, u, "email_notifications_preference"); err != nil { log.Error("SetEmailNotifications: %v", err) return err } @@ -908,13 +908,18 @@ func UpdateUser(u *User, emailChanged bool) error { } // UpdateUserCols update user according special columns -func UpdateUserCols(ctx context.Context, u *User, force bool, cols ...string) error { - return updateUserCols(db.GetEngine(ctx), u, force, cols...) +func UpdateUserCols(ctx context.Context, u *User, cols ...string) error { + return updateUserCols(db.GetEngine(ctx), u, false, cols...) +} + +// UpdateForceUserCols force update user according special columns. +func UpdateForceUserCols(ctx context.Context, u *User, cols ...string) error { + return updateUserCols(db.GetEngine(ctx), u, true, cols...) } // UpdateUserColsEngine update user according special columns -func UpdateUserColsEngine(e db.Engine, u *User, force bool, cols ...string) error { - return updateUserCols(e, u, force, cols...) +func UpdateUserColsEngine(e db.Engine, u *User, cols ...string) error { + return updateUserCols(e, u, false, cols...) } func updateUserCols(e db.Engine, u *User, force bool, cols ...string) error { diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index beac42c4b4a80..133cce3416c5d 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -346,7 +346,7 @@ func Edit(ctx *context.APIContext) { if form.RepoAdminChangeTeamAccess != nil { org.RepoAdminChangeTeamAccess = *form.RepoAdminChangeTeamAccess } - if err := user_model.UpdateUserCols(db.DefaultContext, org.AsUser(), false, + if err := user_model.UpdateUserCols(db.DefaultContext, org.AsUser(), "full_name", "description", "website", "location", "visibility", "repo_admin_change_team_access", ); err != nil { diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index d65c8f667e886..d6b363558453e 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -107,7 +107,7 @@ func resetLocale(ctx *context.Context, u *user_model.User) error { // If the user does not have a locale set, we save the current one. if len(u.Language) == 0 { u.Language = ctx.Locale.Language() - if err := user_model.UpdateUserCols(db.DefaultContext, u, false, "language"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, u, "language"); err != nil { return err } } @@ -333,7 +333,7 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember bool, o // If the user does not have a locale set, we save the current one. if len(u.Language) == 0 { u.Language = ctx.Locale.Language() - if err := user_model.UpdateUserCols(db.DefaultContext, u, false, "language"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, u, "language"); err != nil { ctx.ServerError("UpdateUserCols Language", fmt.Errorf("Error updating user language [user: %d, locale: %s]", u.ID, u.Language)) return setting.AppSubURL + "/" } @@ -350,7 +350,7 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember bool, o // Register last login u.SetLastLogin() - if err := user_model.UpdateUserCols(db.DefaultContext, u, false, "last_login_unix"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, u, "last_login_unix"); err != nil { ctx.ServerError("UpdateUserCols", err) return setting.AppSubURL + "/" } @@ -603,7 +603,7 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth. u.IsAdmin = true u.IsActive = true u.SetLastLogin() - if err := user_model.UpdateUserCols(db.DefaultContext, u, false, "is_admin", "is_active", "last_login_unix"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, u, "is_admin", "is_active", "last_login_unix"); err != nil { ctx.ServerError("UpdateUser", err) return } @@ -724,7 +724,7 @@ func handleAccountActivation(ctx *context.Context, user *user_model.User) { ctx.ServerError("UpdateUser", err) return } - if err := user_model.UpdateUserCols(db.DefaultContext, user, false, "is_active", "rands"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, user, "is_active", "rands"); err != nil { if user_model.IsErrUserNotExist(err) { ctx.NotFound("UpdateUserCols", err) } else { diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index ebcb0609e5942..fa2b0aa65f1f8 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -1021,7 +1021,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model cols = append(cols, "is_admin", "is_restricted") } - if err := user_model.UpdateUserCols(db.DefaultContext, u, false, cols...); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, u, cols...); err != nil { ctx.ServerError("UpdateUserCols", err) return } @@ -1048,7 +1048,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model changed := setUserGroupClaims(source, u, &gothUser) if changed { - if err := user_model.UpdateUserCols(db.DefaultContext, u, false, "is_admin", "is_restricted"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, u, "is_admin", "is_restricted"); err != nil { ctx.ServerError("UpdateUserCols", err) return } diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go index 63c2572811eb8..65d5c55976eef 100644 --- a/routers/web/auth/password.go +++ b/routers/web/auth/password.go @@ -232,7 +232,7 @@ func ResetPasswdPost(ctx *context.Context) { return } u.MustChangePassword = false - if err := user_model.UpdateUserCols(db.DefaultContext, u, false, "must_change_password", "passwd", "passwd_hash_algo", "rands", "salt"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, u, "must_change_password", "passwd", "passwd_hash_algo", "rands", "salt"); err != nil { ctx.ServerError("UpdateUser", err) return } @@ -327,7 +327,7 @@ func MustChangePasswordPost(ctx *context.Context) { u.MustChangePassword = false - if err := user_model.UpdateUserCols(db.DefaultContext, u, false, "must_change_password", "passwd", "passwd_hash_algo", "salt"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, u, "must_change_password", "passwd", "passwd_hash_algo", "salt"); err != nil { ctx.ServerError("UpdateUser", err) return } diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index ab3137f53d500..c523ef6703488 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -76,7 +76,7 @@ func AccountPost(ctx *context.Context) { ctx.ServerError("UpdateUser", err) return } - if err := user_model.UpdateUserCols(db.DefaultContext, ctx.User, false, "salt", "passwd_hash_algo", "passwd"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, ctx.User, "salt", "passwd_hash_algo", "passwd"); err != nil { ctx.ServerError("UpdateUser", err) return } diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 00c91ed6c46a0..084e905567dda 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -187,7 +187,7 @@ func UpdateAvatarSetting(ctx *context.Context, form *forms.AvatarForm, ctxUser * } } - if err := user_model.UpdateUserCols(db.DefaultContext, ctxUser, false, "avatar", "avatar_email", "use_custom_avatar"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, ctxUser, "avatar", "avatar_email", "use_custom_avatar"); err != nil { return fmt.Errorf("UpdateUser: %v", err) } diff --git a/services/auth/auth.go b/services/auth/auth.go index fd6239e8ef02c..3eb7f027d2e77 100644 --- a/services/auth/auth.go +++ b/services/auth/auth.go @@ -140,7 +140,7 @@ func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore if len(user.Language) == 0 { lc := middleware.Locale(resp, req) user.Language = lc.Language() - if err := user_model.UpdateUserCols(db.DefaultContext, user, false, "language"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, user, "language"); err != nil { log.Error(fmt.Sprintf("Error updating user language [user: %d, locale: %s]", user.ID, user.Language)) return } diff --git a/services/auth/source/db/authenticate.go b/services/auth/source/db/authenticate.go index 99a52476b8d8c..f062f66ae039c 100644 --- a/services/auth/source/db/authenticate.go +++ b/services/auth/source/db/authenticate.go @@ -27,7 +27,7 @@ func Authenticate(user *user_model.User, login, password string) (*user_model.Us if err := user.SetPassword(password); err != nil { return nil, err } - if err := user_model.UpdateUserCols(db.DefaultContext, user, false, "passwd", "passwd_hash_algo", "salt"); err != nil { + if err := user_model.UpdateUserCols(db.DefaultContext, user, "passwd", "passwd_hash_algo", "salt"); err != nil { return nil, err } } diff --git a/services/auth/source/ldap/source_authenticate.go b/services/auth/source/ldap/source_authenticate.go index 9caf1c6c0331b..52971bb87e58c 100644 --- a/services/auth/source/ldap/source_authenticate.go +++ b/services/auth/source/ldap/source_authenticate.go @@ -50,7 +50,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str cols = append(cols, "is_restricted") } if len(cols) > 0 { - err = user_model.UpdateUserCols(db.DefaultContext, user, false, cols...) + err = user_model.UpdateUserCols(db.DefaultContext, user, cols...) if err != nil { return nil, err } diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go index 44dc6a12f2238..d299e09cc2c34 100644 --- a/services/auth/source/ldap/source_sync.go +++ b/services/auth/source/ldap/source_sync.go @@ -154,7 +154,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { } usr.IsActive = true - err = user_model.UpdateUserCols(db.DefaultContext, usr, true, "full_name", "email", "is_admin", "is_restricted", "is_active") + err = user_model.UpdateForceUserCols(db.DefaultContext, usr, "full_name", "email", "is_admin", "is_restricted", "is_active") if err != nil { log.Error("SyncExternalUsers[%s]: Error updating user %s: %v", source.authSource.Name, usr.Name, err) } @@ -195,7 +195,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { log.Trace("SyncExternalUsers[%s]: Deactivating user %s", source.authSource.Name, usr.Name) usr.IsActive = false - err = user_model.UpdateUserCols(db.DefaultContext, usr, true, "is_active") + err = user_model.UpdateForceUserCols(db.DefaultContext, usr, "is_active") if err != nil { log.Error("SyncExternalUsers[%s]: Error deactivating user %s: %v", source.authSource.Name, usr.Name, err) } diff --git a/services/user/user.go b/services/user/user.go index 14dbf3383f58a..21f1a74f62f62 100644 --- a/services/user/user.go +++ b/services/user/user.go @@ -139,7 +139,7 @@ func UploadAvatar(u *user_model.User, data []byte) error { // Otherwise, if any of the users delete his avatar // Other users will lose their avatars too. u.Avatar = fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%d-%x", u.ID, md5.Sum(data))))) - if err = user_model.UpdateUserCols(ctx, u, false, "use_custom_avatar", "avatar"); err != nil { + if err = user_model.UpdateUserCols(ctx, u, "use_custom_avatar", "avatar"); err != nil { return fmt.Errorf("updateUser: %v", err) } From 25673a937efd78833756f298bfd344b214158151 Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Wed, 2 Feb 2022 11:42:22 +0100 Subject: [PATCH 08/11] Code cleanup Related: https://github.com/go-gitea/gitea/pull/18466#pullrequestreview-869501363 Author-Change-Id: IB#1105051 --- models/user/user.go | 2 +- routers/web/admin/emails.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/models/user/user.go b/models/user/user.go index 037584f1a7af9..d5f17857c1229 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -830,7 +830,7 @@ func validateUser(u *User) error { // updateUserAllowed is used to block updating selected user fields when local user managemement is disabled. func updateUserAllowed(u *User) error { // Don't allow changes of selected user fields if local user management is disabled. - if setting.Service.DisableLocalUserManagement && (u.Type == UserTypeIndividual) { + if setting.Service.DisableLocalUserManagement && u.Type == UserTypeIndividual { if currUser, err := GetUserByID(u.ID); err == nil { if currUser.Name != u.Name { return fmt.Errorf("cannot change user %s username; local user management disabled", u.Name) diff --git a/routers/web/admin/emails.go b/routers/web/admin/emails.go index 73d01afc591c2..f3ac18e1834ee 100644 --- a/routers/web/admin/emails.go +++ b/routers/web/admin/emails.go @@ -118,7 +118,6 @@ func isKeywordValid(keyword string) bool { // ActivateEmail serves a POST request for activating/deactivating a user's email func ActivateEmail(ctx *context.Context) { - // Don't allow to activate/deactivate emails if local user management is disabled. if setting.Service.DisableLocalUserManagement { ctx.ServerError("ActivateEmail", fmt.Errorf("cannot activate email; local user management disabled")) From 5c8f90510a5834de402e0251bbd8636c5a11fb56 Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Thu, 3 Feb 2022 10:15:19 +0100 Subject: [PATCH 09/11] User data must be updatable from LDAP on authentication Fixes: cda4a8a21624587690a932206362d4f6a6d9bc30 Related: https://github.com/go-gitea/gitea/pull/18466 Author-Change-Id: IB#1105051 --- services/auth/source/ldap/source_authenticate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/auth/source/ldap/source_authenticate.go b/services/auth/source/ldap/source_authenticate.go index 52971bb87e58c..2d8e19af2bd94 100644 --- a/services/auth/source/ldap/source_authenticate.go +++ b/services/auth/source/ldap/source_authenticate.go @@ -50,7 +50,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str cols = append(cols, "is_restricted") } if len(cols) > 0 { - err = user_model.UpdateUserCols(db.DefaultContext, user, cols...) + err = user_model.UpdateForceUserCols(db.DefaultContext, user, cols...) if err != nil { return nil, err } From e45a831bcd2263cae509f42b3dd66ca2b1307cdb Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Fri, 4 Feb 2022 11:09:48 +0100 Subject: [PATCH 10/11] Disable login prohibition and extra e-mail list When local user management is disabled, active user login should not be prohibited. Only primary user e-mail should be available when local user management is enabled (only this mail is synchronized from LDAP). Related: https://github.com/go-gitea/gitea/pull/18466 Author-Change-Id: IB#1105051 --- services/auth/source/ldap/source_authenticate.go | 8 +++++++- services/auth/source/ldap/source_sync.go | 8 ++++++-- templates/admin/user/edit.tmpl | 4 ++-- templates/user/settings/account.tmpl | 6 ++---- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/services/auth/source/ldap/source_authenticate.go b/services/auth/source/ldap/source_authenticate.go index 2d8e19af2bd94..754c3d4871c36 100644 --- a/services/auth/source/ldap/source_authenticate.go +++ b/services/auth/source/ldap/source_authenticate.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/mailer" user_service "code.gitea.io/gitea/services/user" ) @@ -37,7 +38,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str return nil, err } } - if user != nil && !user.ProhibitLogin { + if user != nil && (!user.ProhibitLogin || setting.Service.DisableLocalUserManagement) { cols := make([]string, 0) if len(source.AdminFilter) > 0 && user.IsAdmin != sr.IsAdmin { // Change existing admin flag only if AdminFilter option is set @@ -49,6 +50,11 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str user.IsRestricted = sr.IsRestricted cols = append(cols, "is_restricted") } + if user.ProhibitLogin && setting.Service.DisableLocalUserManagement { + // When local user management is disabled, active user is allowed to login. + user.ProhibitLogin = false + cols = append(cols, "prohibit_login") + } if len(cols) > 0 { err = user_model.UpdateForceUserCols(db.DefaultContext, user, cols...) if err != nil { diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go index d299e09cc2c34..8ae81f2045459 100644 --- a/services/auth/source/ldap/source_sync.go +++ b/services/auth/source/ldap/source_sync.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" user_service "code.gitea.io/gitea/services/user" ) @@ -138,7 +139,8 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { (len(source.RestrictedFilter) > 0 && usr.IsRestricted != su.IsRestricted) || !strings.EqualFold(usr.Email, su.Mail) || usr.FullName != fullName || - !usr.IsActive { + !usr.IsActive || + usr.ProhibitLogin != (usr.ProhibitLogin && !setting.Service.DisableLocalUserManagement) { log.Trace("SyncExternalUsers[%s]: Updating user %s", source.authSource.Name, usr.Name) @@ -153,8 +155,10 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { usr.IsRestricted = su.IsRestricted } usr.IsActive = true + // When local user management is disabled, active user is allowed to login. + usr.ProhibitLogin = usr.ProhibitLogin && !setting.Service.DisableLocalUserManagement - err = user_model.UpdateForceUserCols(db.DefaultContext, usr, "full_name", "email", "is_admin", "is_restricted", "is_active") + err = user_model.UpdateForceUserCols(db.DefaultContext, usr, "full_name", "email", "is_admin", "is_restricted", "is_active", "prohibit_login") if err != nil { log.Error("SyncExternalUsers[%s]: Error updating user %s: %v", source.authSource.Name, usr.Name, err) } diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index 4f20dca8ecea1..04da6e1607dca 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -92,7 +92,7 @@
-
+
@@ -101,7 +101,7 @@
- +
diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl index 198b1b327c9d2..ea2d7eac7c13e 100644 --- a/templates/user/settings/account.tmpl +++ b/templates/user/settings/account.tmpl @@ -72,8 +72,8 @@
{{range .Emails}} + {{if not DisableLocalUserManagement}}
-{{if not DisableLocalUserManagement}} {{if not .IsPrimary}}
{{end}} -{{end}}
{{.Email}} -{{if not DisableLocalUserManagement}} {{if .IsPrimary}}
{{$.i18n.Tr "settings.primary"}}
{{end}} @@ -117,10 +115,10 @@ {{else}}
{{$.i18n.Tr "settings.requires_activation"}}
{{end}} -{{end}}
{{end}} + {{end}}
{{if not DisableLocalUserManagement}} From 38e5a4d6695aff84f6780f3e3bece625f19991d1 Mon Sep 17 00:00:00 2001 From: Pawel Boguslawski Date: Fri, 4 Feb 2022 11:25:32 +0100 Subject: [PATCH 11/11] Option hiding corrected Fixes: e45a831bcd2263cae509f42b3dd66ca2b1307cdb Related: https://github.com/go-gitea/gitea/pull/18466 Author-Change-Id: IB#1105051 --- templates/admin/user/edit.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index 04da6e1607dca..9bcf668eabd0c 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -92,13 +92,13 @@
-
+
-
+