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.
This commit is contained in:
parent
d01f2f3c22
commit
99599c099f
2 changed files with 42 additions and 9 deletions
|
@ -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 {
|
||||||
|
|
Reference in a new issue