Add alternative email addresses to the model
A new struct is created named EmailAddress that contains alternative email addresses for users. Also the email related methods; IsEmailUsed and GetUserByEmail are updated. DeleteUser deletes the extra email addresses and DeleteInactivateUsers also deletes inactive accounts. This could be factored out, but should do it for now.release/v1.15
parent
d01f2f3c22
commit
99599c099f
|
@ -45,7 +45,7 @@ func init() {
|
||||||
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
|
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
|
||||||
new(Mirror), new(Release), new(LoginSource), new(Webhook),
|
new(Mirror), new(Release), new(LoginSource), new(Webhook),
|
||||||
new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
|
new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
|
||||||
new(Notice))
|
new(Notice), new(EmailAddress))
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadModelsConfig() {
|
func LoadModelsConfig() {
|
||||||
|
|
|
@ -54,6 +54,7 @@ type User struct {
|
||||||
LowerName string `xorm:"UNIQUE NOT NULL"`
|
LowerName string `xorm:"UNIQUE NOT NULL"`
|
||||||
Name string `xorm:"UNIQUE NOT NULL"`
|
Name string `xorm:"UNIQUE NOT NULL"`
|
||||||
FullName string
|
FullName string
|
||||||
|
// Email is the primary email address (to be used for communication).
|
||||||
Email string `xorm:"UNIQUE(s) NOT NULL"`
|
Email string `xorm:"UNIQUE(s) NOT NULL"`
|
||||||
Passwd string `xorm:"NOT NULL"`
|
Passwd string `xorm:"NOT NULL"`
|
||||||
LoginType LoginType
|
LoginType LoginType
|
||||||
|
@ -93,6 +94,15 @@ type User struct {
|
||||||
Members []*User `xorm:"-"`
|
Members []*User `xorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EmailAdresses is the list of all email addresses of a user. Can contain the
|
||||||
|
// primary email address, but is not obligatory
|
||||||
|
type EmailAddress struct {
|
||||||
|
Id int64
|
||||||
|
OwnerId int64 `xorm:"INDEX NOT NULL"`
|
||||||
|
Email string `xorm:"UNIQUE NOT NULL"`
|
||||||
|
IsActivated bool
|
||||||
|
}
|
||||||
|
|
||||||
// DashboardLink returns the user dashboard page link.
|
// DashboardLink returns the user dashboard page link.
|
||||||
func (u *User) DashboardLink() string {
|
func (u *User) DashboardLink() string {
|
||||||
if u.IsOrganization() {
|
if u.IsOrganization() {
|
||||||
|
@ -248,6 +258,9 @@ func IsEmailUsed(email string) (bool, error) {
|
||||||
if len(email) == 0 {
|
if len(email) == 0 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
if used, err := x.Get(&EmailAddress{Email: email}); used || err != nil {
|
||||||
|
return used, err
|
||||||
|
}
|
||||||
return x.Get(&User{Email: email})
|
return x.Get(&User{Email: email})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,6 +501,10 @@ func DeleteUser(u *User) error {
|
||||||
if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil {
|
if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// Delete all alternative email addresses
|
||||||
|
if _, err = x.Delete(&EmailAddress{OwnerId: u.Id}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// Delete all SSH keys.
|
// Delete all SSH keys.
|
||||||
keys := make([]*PublicKey, 0, 10)
|
keys := make([]*PublicKey, 0, 10)
|
||||||
if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
|
if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
|
||||||
|
@ -508,9 +525,12 @@ func DeleteUser(u *User) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteInactivateUsers deletes all inactivate users.
|
// DeleteInactivateUsers deletes all inactivate users and email addresses.
|
||||||
func DeleteInactivateUsers() error {
|
func DeleteInactivateUsers() error {
|
||||||
_, err := x.Where("is_active=?", false).Delete(new(User))
|
_, err := x.Where("is_active=?", false).Delete(new(User))
|
||||||
|
if err == nil {
|
||||||
|
_, err = x.Delete(&EmailAddress{IsActivated: false})
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,16 +649,29 @@ func GetUserByEmail(email string) (*User, error) {
|
||||||
if len(email) == 0 {
|
if len(email) == 0 {
|
||||||
return nil, ErrUserNotExist
|
return nil, ErrUserNotExist
|
||||||
}
|
}
|
||||||
|
// First try to find the user by primary email
|
||||||
user := &User{Email: strings.ToLower(email)}
|
user := &User{Email: strings.ToLower(email)}
|
||||||
has, err := x.Get(user)
|
has, err := x.Get(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
|
||||||
return nil, ErrUserNotExist
|
|
||||||
}
|
}
|
||||||
|
if has {
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Otherwise, check in alternative list for activated email addresses
|
||||||
|
emailAddress := &EmailAddress{Email: strings.ToLower(email), IsActivated: true}
|
||||||
|
has, err = x.Get(emailAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if has {
|
||||||
|
return GetUserById(emailAddress.OwnerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, ErrUserNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// SearchUserByName returns given number of users whose name contains keyword.
|
// SearchUserByName returns given number of users whose name contains keyword.
|
||||||
func SearchUserByName(opt SearchOption) (us []*User, err error) {
|
func SearchUserByName(opt SearchOption) (us []*User, err error) {
|
||||||
if len(opt.Keyword) == 0 {
|
if len(opt.Keyword) == 0 {
|
||||||
|
|
Loading…
Reference in New Issue