36147f580c
Repositories displaying an "Add more..." tab on the header is a neat way to let people discover they can enable more units. However, displaying it all the time for repository owners, even when they deliberately do not want to enable more units gets noisy very fast. As such, this patch introduces a new setting which lets people disable this hint under the appearance settings. Fixes #2378. Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
219 lines
5.9 KiB
Go
219 lines
5.9 KiB
Go
// Copyright 2024 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package user
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"code.gitea.io/gitea/models"
|
|
auth_model "code.gitea.io/gitea/models/auth"
|
|
user_model "code.gitea.io/gitea/models/user"
|
|
password_module "code.gitea.io/gitea/modules/auth/password"
|
|
"code.gitea.io/gitea/modules/optional"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/modules/structs"
|
|
)
|
|
|
|
type UpdateOptions struct {
|
|
KeepEmailPrivate optional.Option[bool]
|
|
FullName optional.Option[string]
|
|
Website optional.Option[string]
|
|
Location optional.Option[string]
|
|
Description optional.Option[string]
|
|
AllowGitHook optional.Option[bool]
|
|
AllowImportLocal optional.Option[bool]
|
|
MaxRepoCreation optional.Option[int]
|
|
IsRestricted optional.Option[bool]
|
|
Visibility optional.Option[structs.VisibleType]
|
|
KeepActivityPrivate optional.Option[bool]
|
|
Language optional.Option[string]
|
|
Theme optional.Option[string]
|
|
DiffViewStyle optional.Option[string]
|
|
AllowCreateOrganization optional.Option[bool]
|
|
IsActive optional.Option[bool]
|
|
IsAdmin optional.Option[bool]
|
|
EmailNotificationsPreference optional.Option[string]
|
|
SetLastLogin bool
|
|
RepoAdminChangeTeamAccess optional.Option[bool]
|
|
EnableRepoUnitHints optional.Option[bool]
|
|
}
|
|
|
|
func UpdateUser(ctx context.Context, u *user_model.User, opts *UpdateOptions) error {
|
|
cols := make([]string, 0, 20)
|
|
|
|
if opts.KeepEmailPrivate.Has() {
|
|
u.KeepEmailPrivate = opts.KeepEmailPrivate.Value()
|
|
|
|
cols = append(cols, "keep_email_private")
|
|
}
|
|
|
|
if opts.FullName.Has() {
|
|
u.FullName = opts.FullName.Value()
|
|
|
|
cols = append(cols, "full_name")
|
|
}
|
|
if opts.Website.Has() {
|
|
u.Website = opts.Website.Value()
|
|
|
|
cols = append(cols, "website")
|
|
}
|
|
if opts.Location.Has() {
|
|
u.Location = opts.Location.Value()
|
|
|
|
cols = append(cols, "location")
|
|
}
|
|
if opts.Description.Has() {
|
|
u.Description = opts.Description.Value()
|
|
|
|
cols = append(cols, "description")
|
|
}
|
|
if opts.Language.Has() {
|
|
u.Language = opts.Language.Value()
|
|
|
|
cols = append(cols, "language")
|
|
}
|
|
if opts.Theme.Has() {
|
|
u.Theme = opts.Theme.Value()
|
|
|
|
cols = append(cols, "theme")
|
|
}
|
|
if opts.DiffViewStyle.Has() {
|
|
u.DiffViewStyle = opts.DiffViewStyle.Value()
|
|
|
|
cols = append(cols, "diff_view_style")
|
|
}
|
|
if opts.EnableRepoUnitHints.Has() {
|
|
u.EnableRepoUnitHints = opts.EnableRepoUnitHints.Value()
|
|
|
|
cols = append(cols, "enable_repo_unit_hints")
|
|
}
|
|
|
|
if opts.AllowGitHook.Has() {
|
|
u.AllowGitHook = opts.AllowGitHook.Value()
|
|
|
|
cols = append(cols, "allow_git_hook")
|
|
}
|
|
if opts.AllowImportLocal.Has() {
|
|
u.AllowImportLocal = opts.AllowImportLocal.Value()
|
|
|
|
cols = append(cols, "allow_import_local")
|
|
}
|
|
|
|
if opts.MaxRepoCreation.Has() {
|
|
u.MaxRepoCreation = opts.MaxRepoCreation.Value()
|
|
|
|
cols = append(cols, "max_repo_creation")
|
|
}
|
|
|
|
if opts.IsActive.Has() {
|
|
u.IsActive = opts.IsActive.Value()
|
|
|
|
cols = append(cols, "is_active")
|
|
}
|
|
if opts.IsRestricted.Has() {
|
|
u.IsRestricted = opts.IsRestricted.Value()
|
|
|
|
cols = append(cols, "is_restricted")
|
|
}
|
|
if opts.IsAdmin.Has() {
|
|
if !opts.IsAdmin.Value() && user_model.IsLastAdminUser(ctx, u) {
|
|
return models.ErrDeleteLastAdminUser{UID: u.ID}
|
|
}
|
|
|
|
u.IsAdmin = opts.IsAdmin.Value()
|
|
|
|
cols = append(cols, "is_admin")
|
|
}
|
|
|
|
if opts.Visibility.Has() {
|
|
if !u.IsOrganization() && !setting.Service.AllowedUserVisibilityModesSlice.IsAllowedVisibility(opts.Visibility.Value()) {
|
|
return fmt.Errorf("visibility mode not allowed: %s", opts.Visibility.Value().String())
|
|
}
|
|
u.Visibility = opts.Visibility.Value()
|
|
|
|
cols = append(cols, "visibility")
|
|
}
|
|
if opts.KeepActivityPrivate.Has() {
|
|
u.KeepActivityPrivate = opts.KeepActivityPrivate.Value()
|
|
|
|
cols = append(cols, "keep_activity_private")
|
|
}
|
|
|
|
if opts.AllowCreateOrganization.Has() {
|
|
u.AllowCreateOrganization = opts.AllowCreateOrganization.Value()
|
|
|
|
cols = append(cols, "allow_create_organization")
|
|
}
|
|
if opts.RepoAdminChangeTeamAccess.Has() {
|
|
u.RepoAdminChangeTeamAccess = opts.RepoAdminChangeTeamAccess.Value()
|
|
|
|
cols = append(cols, "repo_admin_change_team_access")
|
|
}
|
|
|
|
if opts.EmailNotificationsPreference.Has() {
|
|
u.EmailNotificationsPreference = opts.EmailNotificationsPreference.Value()
|
|
|
|
cols = append(cols, "email_notifications_preference")
|
|
}
|
|
|
|
if opts.SetLastLogin {
|
|
u.SetLastLogin()
|
|
|
|
cols = append(cols, "last_login_unix")
|
|
}
|
|
|
|
return user_model.UpdateUserCols(ctx, u, cols...)
|
|
}
|
|
|
|
type UpdateAuthOptions struct {
|
|
LoginSource optional.Option[int64]
|
|
LoginName optional.Option[string]
|
|
Password optional.Option[string]
|
|
MustChangePassword optional.Option[bool]
|
|
ProhibitLogin optional.Option[bool]
|
|
}
|
|
|
|
func UpdateAuth(ctx context.Context, u *user_model.User, opts *UpdateAuthOptions) error {
|
|
if opts.LoginSource.Has() {
|
|
source, err := auth_model.GetSourceByID(ctx, opts.LoginSource.Value())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
u.LoginType = source.Type
|
|
u.LoginSource = source.ID
|
|
}
|
|
if opts.LoginName.Has() {
|
|
u.LoginName = opts.LoginName.Value()
|
|
}
|
|
|
|
if opts.Password.Has() && (u.IsLocal() || u.IsOAuth2()) {
|
|
password := opts.Password.Value()
|
|
|
|
if len(password) < setting.MinPasswordLength {
|
|
return password_module.ErrMinLength
|
|
}
|
|
if !password_module.IsComplexEnough(password) {
|
|
return password_module.ErrComplexity
|
|
}
|
|
if err := password_module.IsPwned(ctx, password); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := u.SetPassword(password); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if opts.MustChangePassword.Has() {
|
|
u.MustChangePassword = opts.MustChangePassword.Value()
|
|
}
|
|
if opts.ProhibitLogin.Has() {
|
|
u.ProhibitLogin = opts.ProhibitLogin.Value()
|
|
}
|
|
|
|
return user_model.UpdateUserCols(ctx, u, "login_type", "login_source", "login_name", "passwd", "passwd_hash_algo", "salt", "must_change_password", "prohibit_login")
|
|
}
|