code.gitea.io/gitea@v1.22.3/services/user/email.go (about)

     1  // Copyright 2024 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package user
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  	"strings"
    10  
    11  	"code.gitea.io/gitea/models/db"
    12  	user_model "code.gitea.io/gitea/models/user"
    13  	"code.gitea.io/gitea/modules/setting"
    14  	"code.gitea.io/gitea/modules/util"
    15  )
    16  
    17  // AdminAddOrSetPrimaryEmailAddress is used by admins to add or set a user's primary email address
    18  func AdminAddOrSetPrimaryEmailAddress(ctx context.Context, u *user_model.User, emailStr string) error {
    19  	if strings.EqualFold(u.Email, emailStr) {
    20  		return nil
    21  	}
    22  
    23  	if err := user_model.ValidateEmailForAdmin(emailStr); err != nil {
    24  		return err
    25  	}
    26  
    27  	// Check if address exists already
    28  	email, err := user_model.GetEmailAddressByEmail(ctx, emailStr)
    29  	if err != nil && !errors.Is(err, util.ErrNotExist) {
    30  		return err
    31  	}
    32  	if email != nil && email.UID != u.ID {
    33  		return user_model.ErrEmailAlreadyUsed{Email: emailStr}
    34  	}
    35  
    36  	// Update old primary address
    37  	primary, err := user_model.GetPrimaryEmailAddressOfUser(ctx, u.ID)
    38  	if err != nil {
    39  		return err
    40  	}
    41  
    42  	primary.IsPrimary = false
    43  	if err := user_model.UpdateEmailAddress(ctx, primary); err != nil {
    44  		return err
    45  	}
    46  
    47  	// Insert new or update existing address
    48  	if email != nil {
    49  		email.IsPrimary = true
    50  		email.IsActivated = true
    51  		if err := user_model.UpdateEmailAddress(ctx, email); err != nil {
    52  			return err
    53  		}
    54  	} else {
    55  		email = &user_model.EmailAddress{
    56  			UID:         u.ID,
    57  			Email:       emailStr,
    58  			IsActivated: true,
    59  			IsPrimary:   true,
    60  		}
    61  		if _, err := user_model.InsertEmailAddress(ctx, email); err != nil {
    62  			return err
    63  		}
    64  	}
    65  
    66  	u.Email = emailStr
    67  
    68  	return user_model.UpdateUserCols(ctx, u, "email")
    69  }
    70  
    71  func ReplacePrimaryEmailAddress(ctx context.Context, u *user_model.User, emailStr string) error {
    72  	if strings.EqualFold(u.Email, emailStr) {
    73  		return nil
    74  	}
    75  
    76  	if err := user_model.ValidateEmail(emailStr); err != nil {
    77  		return err
    78  	}
    79  
    80  	if !u.IsOrganization() {
    81  		// Check if address exists already
    82  		email, err := user_model.GetEmailAddressByEmail(ctx, emailStr)
    83  		if err != nil && !errors.Is(err, util.ErrNotExist) {
    84  			return err
    85  		}
    86  		if email != nil {
    87  			if email.IsPrimary && email.UID == u.ID {
    88  				return nil
    89  			}
    90  			return user_model.ErrEmailAlreadyUsed{Email: emailStr}
    91  		}
    92  
    93  		// Remove old primary address
    94  		primary, err := user_model.GetPrimaryEmailAddressOfUser(ctx, u.ID)
    95  		if err != nil {
    96  			return err
    97  		}
    98  		if _, err := db.DeleteByID[user_model.EmailAddress](ctx, primary.ID); err != nil {
    99  			return err
   100  		}
   101  
   102  		// Insert new primary address
   103  		email = &user_model.EmailAddress{
   104  			UID:         u.ID,
   105  			Email:       emailStr,
   106  			IsActivated: true,
   107  			IsPrimary:   true,
   108  		}
   109  		if _, err := user_model.InsertEmailAddress(ctx, email); err != nil {
   110  			return err
   111  		}
   112  	}
   113  
   114  	u.Email = emailStr
   115  
   116  	return user_model.UpdateUserCols(ctx, u, "email")
   117  }
   118  
   119  func AddEmailAddresses(ctx context.Context, u *user_model.User, emails []string) error {
   120  	for _, emailStr := range emails {
   121  		if err := user_model.ValidateEmail(emailStr); err != nil {
   122  			return err
   123  		}
   124  
   125  		// Check if address exists already
   126  		email, err := user_model.GetEmailAddressByEmail(ctx, emailStr)
   127  		if err != nil && !errors.Is(err, util.ErrNotExist) {
   128  			return err
   129  		}
   130  		if email != nil {
   131  			return user_model.ErrEmailAlreadyUsed{Email: emailStr}
   132  		}
   133  
   134  		// Insert new address
   135  		email = &user_model.EmailAddress{
   136  			UID:         u.ID,
   137  			Email:       emailStr,
   138  			IsActivated: !setting.Service.RegisterEmailConfirm,
   139  			IsPrimary:   false,
   140  		}
   141  		if _, err := user_model.InsertEmailAddress(ctx, email); err != nil {
   142  			return err
   143  		}
   144  	}
   145  
   146  	return nil
   147  }
   148  
   149  func DeleteEmailAddresses(ctx context.Context, u *user_model.User, emails []string) error {
   150  	for _, emailStr := range emails {
   151  		// Check if address exists
   152  		email, err := user_model.GetEmailAddressOfUser(ctx, emailStr, u.ID)
   153  		if err != nil {
   154  			return err
   155  		}
   156  		if email.IsPrimary {
   157  			return user_model.ErrPrimaryEmailCannotDelete{Email: emailStr}
   158  		}
   159  
   160  		// Remove address
   161  		if _, err := db.DeleteByID[user_model.EmailAddress](ctx, email.ID); err != nil {
   162  			return err
   163  		}
   164  	}
   165  
   166  	return nil
   167  }