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.

136 lines
3.4 KiB

  1. /*
  2. * Copyright © 2018-2019, 2021 A Bunch Tell LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. package writefreely
  11. import (
  12. "time"
  13. "github.com/guregu/null/zero"
  14. "github.com/writeas/web-core/data"
  15. "github.com/writeas/web-core/log"
  16. "github.com/writefreely/writefreely/key"
  17. )
  18. type UserStatus int
  19. const (
  20. UserActive = iota
  21. UserSilenced
  22. )
  23. type (
  24. userCredentials struct {
  25. Alias string `json:"alias" schema:"alias"`
  26. Pass string `json:"pass" schema:"pass"`
  27. Email string `json:"email" schema:"email"`
  28. Web bool `json:"web" schema:"-"`
  29. To string `json:"-" schema:"to"`
  30. EmailLogin bool `json:"via_email" schema:"via_email"`
  31. }
  32. userRegistration struct {
  33. userCredentials
  34. InviteCode string `json:"invite_code" schema:"invite_code"`
  35. Honeypot string `json:"fullname" schema:"fullname"`
  36. Normalize bool `json:"normalize" schema:"normalize"`
  37. Signup bool `json:"signup" schema:"signup"`
  38. // Feature fields
  39. Description string `json:"description" schema:"description"`
  40. Monetization string `json:"monetization" schema:"monetization"`
  41. }
  42. // AuthUser contains information for a newly authenticated user (either
  43. // from signing up or logging in).
  44. AuthUser struct {
  45. AccessToken string `json:"access_token,omitempty"`
  46. Password string `json:"password,omitempty"`
  47. User *User `json:"user"`
  48. // Verbose user data
  49. Posts *[]PublicPost `json:"posts,omitempty"`
  50. Collections *[]Collection `json:"collections,omitempty"`
  51. }
  52. // User is a consistent user object in the database and all contexts (auth
  53. // and non-auth) in the API.
  54. User struct {
  55. ID int64 `json:"-"`
  56. Username string `json:"username"`
  57. HashedPass []byte `json:"-"`
  58. HasPass bool `json:"has_pass"`
  59. Email zero.String `json:"email"`
  60. Created time.Time `json:"created"`
  61. Status UserStatus `json:"status"`
  62. clearEmail string `json:"email"`
  63. }
  64. userMeStats struct {
  65. TotalCollections, TotalArticles, CollectionPosts uint64
  66. }
  67. ExportUser struct {
  68. *User
  69. Collections *[]CollectionObj `json:"collections"`
  70. AnonymousPosts []PublicPost `json:"posts"`
  71. }
  72. PublicUser struct {
  73. Username string `json:"username"`
  74. }
  75. )
  76. // EmailClear decrypts and returns the user's email, caching it in the user
  77. // object.
  78. func (u *User) EmailClear(keys *key.Keychain) string {
  79. if u.clearEmail != "" {
  80. return u.clearEmail
  81. }
  82. if u.Email.Valid && u.Email.String != "" {
  83. email, err := data.Decrypt(keys.EmailKey, []byte(u.Email.String))
  84. if err != nil {
  85. log.Error("Error decrypting user email: %v", err)
  86. } else {
  87. u.clearEmail = string(email)
  88. return u.clearEmail
  89. }
  90. }
  91. return ""
  92. }
  93. func (u User) CreatedFriendly() string {
  94. /*
  95. // TODO: accept a locale in this method and use that for the format
  96. var loc monday.Locale = monday.LocaleEnUS
  97. return monday.Format(u.Created, monday.DateTimeFormatsByLocale[loc], loc)
  98. */
  99. return u.Created.Format("January 2, 2006, 3:04 PM")
  100. }
  101. // Cookie strips down an AuthUser to contain only information necessary for
  102. // cookies.
  103. func (u User) Cookie() *User {
  104. u.HashedPass = []byte{}
  105. return &u
  106. }
  107. func (u *User) IsAdmin() bool {
  108. // TODO: get this from database
  109. return u.ID == 1
  110. }
  111. func (u *User) IsSilenced() bool {
  112. return u.Status&UserSilenced != 0
  113. }