2016-07-16 05:08:04 +03:00
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
2016-12-15 11:49:06 +03:00
"errors"
2016-07-16 05:08:04 +03:00
"fmt"
"strings"
)
2016-12-15 11:49:06 +03:00
var (
// ErrEmailAddressNotExist email address not exist
ErrEmailAddressNotExist = errors . New ( "Email address does not exist" )
)
2016-11-26 03:03:06 +03:00
// EmailAddress is the list of all email addresses of a user. Can contain the
2016-07-16 05:08:04 +03:00
// primary email address, but is not obligatory.
type EmailAddress struct {
ID int64 ` xorm:"pk autoincr" `
UID int64 ` xorm:"INDEX NOT NULL" `
Email string ` xorm:"UNIQUE NOT NULL" `
IsActivated bool
IsPrimary bool ` xorm:"-" `
}
// GetEmailAddresses returns all email addresses belongs to given user.
func GetEmailAddresses ( uid int64 ) ( [ ] * EmailAddress , error ) {
emails := make ( [ ] * EmailAddress , 0 , 5 )
2016-11-10 18:16:32 +03:00
if err := x .
Where ( "uid=?" , uid ) .
Find ( & emails ) ; err != nil {
2016-07-16 05:08:04 +03:00
return nil , err
}
u , err := GetUserByID ( uid )
if err != nil {
return nil , err
}
isPrimaryFound := false
for _ , email := range emails {
if email . Email == u . Email {
isPrimaryFound = true
email . IsPrimary = true
} else {
email . IsPrimary = false
}
}
2017-01-05 03:50:34 +03:00
// We always want the primary email address displayed, even if it's not in
// the email address table (yet).
2016-07-16 05:08:04 +03:00
if ! isPrimaryFound {
emails = append ( emails , & EmailAddress {
Email : u . Email ,
IsActivated : true ,
IsPrimary : true ,
} )
}
return emails , nil
}
func isEmailUsed ( e Engine , email string ) ( bool , error ) {
if len ( email ) == 0 {
return true , nil
}
return e . Get ( & EmailAddress { Email : email } )
}
// IsEmailUsed returns true if the email has been used.
func IsEmailUsed ( email string ) ( bool , error ) {
return isEmailUsed ( x , email )
}
func addEmailAddress ( e Engine , email * EmailAddress ) error {
email . Email = strings . ToLower ( strings . TrimSpace ( email . Email ) )
used , err := isEmailUsed ( e , email . Email )
if err != nil {
return err
} else if used {
return ErrEmailAlreadyUsed { email . Email }
}
_ , err = e . Insert ( email )
return err
}
2016-11-27 14:59:12 +03:00
// AddEmailAddress adds an email address to given user.
2016-07-16 05:08:04 +03:00
func AddEmailAddress ( email * EmailAddress ) error {
return addEmailAddress ( x , email )
}
2016-11-27 14:59:12 +03:00
// AddEmailAddresses adds an email address to given user.
2016-07-16 05:08:04 +03:00
func AddEmailAddresses ( emails [ ] * EmailAddress ) error {
if len ( emails ) == 0 {
return nil
}
// Check if any of them has been used
for i := range emails {
emails [ i ] . Email = strings . ToLower ( strings . TrimSpace ( emails [ i ] . Email ) )
used , err := IsEmailUsed ( emails [ i ] . Email )
if err != nil {
return err
} else if used {
return ErrEmailAlreadyUsed { emails [ i ] . Email }
}
}
if _ , err := x . Insert ( emails ) ; err != nil {
return fmt . Errorf ( "Insert: %v" , err )
}
return nil
}
2016-11-27 14:59:12 +03:00
// Activate activates the email address to given user.
2016-07-16 05:08:04 +03:00
func ( email * EmailAddress ) Activate ( ) error {
user , err := GetUserByID ( email . UID )
if err != nil {
return err
}
2016-12-20 15:32:02 +03:00
if user . Rands , err = GetUserSalt ( ) ; err != nil {
return err
}
2016-07-16 05:08:04 +03:00
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2016-07-16 05:08:04 +03:00
if err = sess . Begin ( ) ; err != nil {
return err
}
email . IsActivated = true
2016-11-10 18:16:32 +03:00
if _ , err := sess .
Id ( email . ID ) .
2017-09-25 07:59:27 +03:00
Cols ( "is_activated" ) .
2016-11-10 18:16:32 +03:00
Update ( email ) ; err != nil {
2016-07-16 05:08:04 +03:00
return err
2017-09-25 07:59:27 +03:00
} else if err = updateUserCols ( sess , user , "rands" ) ; err != nil {
2016-07-16 05:08:04 +03:00
return err
}
return sess . Commit ( )
}
2016-11-27 14:59:12 +03:00
// DeleteEmailAddress deletes an email address of given user.
2016-07-16 05:08:04 +03:00
func DeleteEmailAddress ( email * EmailAddress ) ( err error ) {
2016-12-15 11:49:06 +03:00
var deleted int64
// ask to check UID
var address = EmailAddress {
UID : email . UID ,
}
2016-07-16 05:08:04 +03:00
if email . ID > 0 {
2017-10-05 07:43:04 +03:00
deleted , err = x . ID ( email . ID ) . Delete ( & address )
2016-07-16 05:08:04 +03:00
} else {
2016-12-15 11:49:06 +03:00
deleted , err = x .
2016-11-10 18:16:32 +03:00
Where ( "email=?" , email . Email ) .
2016-12-15 11:49:06 +03:00
Delete ( & address )
2016-07-16 05:08:04 +03:00
}
2016-12-15 11:49:06 +03:00
if err != nil {
return err
} else if deleted != 1 {
return ErrEmailAddressNotExist
}
return nil
2016-07-16 05:08:04 +03:00
}
2016-11-27 14:59:12 +03:00
// DeleteEmailAddresses deletes multiple email addresses
2016-07-16 05:08:04 +03:00
func DeleteEmailAddresses ( emails [ ] * EmailAddress ) ( err error ) {
for i := range emails {
if err = DeleteEmailAddress ( emails [ i ] ) ; err != nil {
return err
}
}
return nil
}
2016-11-27 14:59:12 +03:00
// MakeEmailPrimary sets primary email address of given user.
2016-07-16 05:08:04 +03:00
func MakeEmailPrimary ( email * EmailAddress ) error {
has , err := x . Get ( email )
if err != nil {
return err
} else if ! has {
return ErrEmailNotExist
}
if ! email . IsActivated {
return ErrEmailNotActivated
}
2016-07-23 20:08:22 +03:00
user := & User { ID : email . UID }
2016-07-16 05:08:04 +03:00
has , err = x . Get ( user )
if err != nil {
return err
} else if ! has {
2016-11-12 02:01:09 +03:00
return ErrUserNotExist { email . UID , "" , 0 }
2016-07-16 05:08:04 +03:00
}
// Make sure the former primary email doesn't disappear.
formerPrimaryEmail := & EmailAddress { Email : user . Email }
has , err = x . Get ( formerPrimaryEmail )
if err != nil {
return err
}
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2016-07-16 05:08:04 +03:00
if err = sess . Begin ( ) ; err != nil {
return err
}
if ! has {
2016-07-23 20:08:22 +03:00
formerPrimaryEmail . UID = user . ID
2016-07-16 05:08:04 +03:00
formerPrimaryEmail . IsActivated = user . IsActive
if _ , err = sess . Insert ( formerPrimaryEmail ) ; err != nil {
return err
}
}
user . Email = email . Email
2017-10-05 07:43:04 +03:00
if _ , err = sess . ID ( user . ID ) . Cols ( "email" ) . Update ( user ) ; err != nil {
2016-07-16 05:08:04 +03:00
return err
}
return sess . Commit ( )
}