mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in NOTICE, alongside LICENSE. The header lint accepts any copyright line above the SPDX line, so it no longer demands an upstream one. Co-authored-by: Hanzo Dev <[email protected]>
119 lines
3.1 KiB
Go
119 lines
3.1 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package user
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/hanzoai/git/models/db"
|
|
user_model "github.com/hanzoai/git/models/user"
|
|
"github.com/hanzoai/git/modules/setting"
|
|
"github.com/hanzoai/git/modules/util"
|
|
)
|
|
|
|
// ReplacePrimaryEmailAddress replaces the user's primary email address with the given email address.
|
|
// It also updates the user's email field to match the new primary email address.
|
|
func ReplacePrimaryEmailAddress(ctx context.Context, u *user_model.User, emailStr string) error {
|
|
// FIXME: this check is from old logic, but it is not right, there are far more user types, not only "organization"
|
|
if u.IsOrganization() {
|
|
return util.NewInvalidArgumentErrorf("user %s is an organization", u.Name)
|
|
}
|
|
|
|
if strings.EqualFold(u.Email, emailStr) {
|
|
return nil
|
|
}
|
|
|
|
if err := user_model.ValidateEmail(emailStr); err != nil {
|
|
return err
|
|
}
|
|
|
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
|
// Check if address exists already
|
|
email, err := user_model.GetEmailAddressByEmail(ctx, emailStr)
|
|
if err != nil && !errors.Is(err, util.ErrNotExist) {
|
|
return err
|
|
}
|
|
if email != nil {
|
|
if email.IsPrimary && email.UID == u.ID {
|
|
return nil
|
|
}
|
|
return user_model.ErrEmailAlreadyUsed{Email: emailStr}
|
|
}
|
|
|
|
// Remove old primary address
|
|
primary, err := user_model.GetPrimaryEmailAddressOfUser(ctx, u.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if _, err := db.DeleteByID[user_model.EmailAddress](ctx, primary.ID); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Insert new primary address
|
|
if _, err := user_model.InsertEmailAddress(ctx, &user_model.EmailAddress{
|
|
UID: u.ID,
|
|
Email: emailStr,
|
|
IsActivated: true,
|
|
IsPrimary: true,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
|
|
u.Email = emailStr
|
|
return user_model.UpdateUserCols(ctx, u, "email")
|
|
})
|
|
}
|
|
|
|
func AddEmailAddresses(ctx context.Context, u *user_model.User, emails []string) error {
|
|
for _, emailStr := range emails {
|
|
if err := user_model.ValidateEmail(emailStr); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Check if address exists already
|
|
email, err := user_model.GetEmailAddressByEmail(ctx, emailStr)
|
|
if err != nil && !errors.Is(err, util.ErrNotExist) {
|
|
return err
|
|
}
|
|
if email != nil {
|
|
return user_model.ErrEmailAlreadyUsed{Email: emailStr}
|
|
}
|
|
|
|
// Insert new address
|
|
email = &user_model.EmailAddress{
|
|
UID: u.ID,
|
|
Email: emailStr,
|
|
IsActivated: !setting.Service.RegisterEmailConfirm,
|
|
IsPrimary: false,
|
|
}
|
|
if _, err := user_model.InsertEmailAddress(ctx, email); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func DeleteEmailAddresses(ctx context.Context, u *user_model.User, emails []string) error {
|
|
for _, emailStr := range emails {
|
|
// Check if address exists
|
|
email, err := user_model.GetEmailAddressOfUser(ctx, emailStr, u.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if email.IsPrimary {
|
|
return user_model.ErrPrimaryEmailCannotDelete{Email: emailStr}
|
|
}
|
|
|
|
// Remove address
|
|
if _, err := db.DeleteByID[user_model.EmailAddress](ctx, email.ID); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|