本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
4.9KB

  1. // Copyright 2016 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package models
  5. import (
  6. "errors"
  7. "fmt"
  8. "strings"
  9. )
  10. var (
  11. // ErrEmailAddressNotExist email address not exist
  12. ErrEmailAddressNotExist = errors.New("Email address does not exist")
  13. )
  14. // EmailAddress is the list of all email addresses of a user. Can contain the
  15. // primary email address, but is not obligatory.
  16. type EmailAddress struct {
  17. ID int64 `xorm:"pk autoincr"`
  18. UID int64 `xorm:"INDEX NOT NULL"`
  19. Email string `xorm:"UNIQUE NOT NULL"`
  20. IsActivated bool
  21. IsPrimary bool `xorm:"-"`
  22. }
  23. // GetEmailAddresses returns all email addresses belongs to given user.
  24. func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
  25. emails := make([]*EmailAddress, 0, 5)
  26. if err := x.
  27. Where("uid=?", uid).
  28. Find(&emails); err != nil {
  29. return nil, err
  30. }
  31. u, err := GetUserByID(uid)
  32. if err != nil {
  33. return nil, err
  34. }
  35. isPrimaryFound := false
  36. for _, email := range emails {
  37. if email.Email == u.Email {
  38. isPrimaryFound = true
  39. email.IsPrimary = true
  40. } else {
  41. email.IsPrimary = false
  42. }
  43. }
  44. // We always want the primary email address displayed, even if it's not in
  45. // the email address table (yet).
  46. if !isPrimaryFound {
  47. emails = append(emails, &EmailAddress{
  48. Email: u.Email,
  49. IsActivated: true,
  50. IsPrimary: true,
  51. })
  52. }
  53. return emails, nil
  54. }
  55. func isEmailUsed(e Engine, email string) (bool, error) {
  56. if len(email) == 0 {
  57. return true, nil
  58. }
  59. return e.Get(&EmailAddress{Email: email})
  60. }
  61. // IsEmailUsed returns true if the email has been used.
  62. func IsEmailUsed(email string) (bool, error) {
  63. return isEmailUsed(x, email)
  64. }
  65. func addEmailAddress(e Engine, email *EmailAddress) error {
  66. email.Email = strings.ToLower(strings.TrimSpace(email.Email))
  67. used, err := isEmailUsed(e, email.Email)
  68. if err != nil {
  69. return err
  70. } else if used {
  71. return ErrEmailAlreadyUsed{email.Email}
  72. }
  73. _, err = e.Insert(email)
  74. return err
  75. }
  76. // AddEmailAddress adds an email address to given user.
  77. func AddEmailAddress(email *EmailAddress) error {
  78. return addEmailAddress(x, email)
  79. }
  80. // AddEmailAddresses adds an email address to given user.
  81. func AddEmailAddresses(emails []*EmailAddress) error {
  82. if len(emails) == 0 {
  83. return nil
  84. }
  85. // Check if any of them has been used
  86. for i := range emails {
  87. emails[i].Email = strings.ToLower(strings.TrimSpace(emails[i].Email))
  88. used, err := IsEmailUsed(emails[i].Email)
  89. if err != nil {
  90. return err
  91. } else if used {
  92. return ErrEmailAlreadyUsed{emails[i].Email}
  93. }
  94. }
  95. if _, err := x.Insert(emails); err != nil {
  96. return fmt.Errorf("Insert: %v", err)
  97. }
  98. return nil
  99. }
  100. // Activate activates the email address to given user.
  101. func (email *EmailAddress) Activate() error {
  102. user, err := GetUserByID(email.UID)
  103. if err != nil {
  104. return err
  105. }
  106. if user.Rands, err = GetUserSalt(); err != nil {
  107. return err
  108. }
  109. sess := x.NewSession()
  110. defer sess.Close()
  111. if err = sess.Begin(); err != nil {
  112. return err
  113. }
  114. email.IsActivated = true
  115. if _, err := sess.
  116. ID(email.ID).
  117. Cols("is_activated").
  118. Update(email); err != nil {
  119. return err
  120. } else if err = updateUserCols(sess, user, "rands"); err != nil {
  121. return err
  122. }
  123. return sess.Commit()
  124. }
  125. // DeleteEmailAddress deletes an email address of given user.
  126. func DeleteEmailAddress(email *EmailAddress) (err error) {
  127. var deleted int64
  128. // ask to check UID
  129. var address = EmailAddress{
  130. UID: email.UID,
  131. }
  132. if email.ID > 0 {
  133. deleted, err = x.ID(email.ID).Delete(&address)
  134. } else {
  135. deleted, err = x.
  136. Where("email=?", email.Email).
  137. Delete(&address)
  138. }
  139. if err != nil {
  140. return err
  141. } else if deleted != 1 {
  142. return ErrEmailAddressNotExist
  143. }
  144. return nil
  145. }
  146. // DeleteEmailAddresses deletes multiple email addresses
  147. func DeleteEmailAddresses(emails []*EmailAddress) (err error) {
  148. for i := range emails {
  149. if err = DeleteEmailAddress(emails[i]); err != nil {
  150. return err
  151. }
  152. }
  153. return nil
  154. }
  155. // MakeEmailPrimary sets primary email address of given user.
  156. func MakeEmailPrimary(email *EmailAddress) error {
  157. has, err := x.Get(email)
  158. if err != nil {
  159. return err
  160. } else if !has {
  161. return ErrEmailNotExist
  162. }
  163. if !email.IsActivated {
  164. return ErrEmailNotActivated
  165. }
  166. user := &User{ID: email.UID}
  167. has, err = x.Get(user)
  168. if err != nil {
  169. return err
  170. } else if !has {
  171. return ErrUserNotExist{email.UID, "", 0}
  172. }
  173. // Make sure the former primary email doesn't disappear.
  174. formerPrimaryEmail := &EmailAddress{Email: user.Email}
  175. has, err = x.Get(formerPrimaryEmail)
  176. if err != nil {
  177. return err
  178. }
  179. sess := x.NewSession()
  180. defer sess.Close()
  181. if err = sess.Begin(); err != nil {
  182. return err
  183. }
  184. if !has {
  185. formerPrimaryEmail.UID = user.ID
  186. formerPrimaryEmail.IsActivated = user.IsActive
  187. if _, err = sess.Insert(formerPrimaryEmail); err != nil {
  188. return err
  189. }
  190. }
  191. user.Email = email.Email
  192. if _, err = sess.ID(user.ID).Cols("email").Update(user); err != nil {
  193. return err
  194. }
  195. return sess.Commit()
  196. }
上海开阖软件有限公司 沪ICP备12045867号-1