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.

team_invite.go 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package organization
  4. import (
  5. "context"
  6. "fmt"
  7. "code.gitea.io/gitea/models/db"
  8. user_model "code.gitea.io/gitea/models/user"
  9. "code.gitea.io/gitea/modules/timeutil"
  10. "code.gitea.io/gitea/modules/util"
  11. "xorm.io/builder"
  12. )
  13. type ErrTeamInviteAlreadyExist struct {
  14. TeamID int64
  15. Email string
  16. }
  17. func IsErrTeamInviteAlreadyExist(err error) bool {
  18. _, ok := err.(ErrTeamInviteAlreadyExist)
  19. return ok
  20. }
  21. func (err ErrTeamInviteAlreadyExist) Error() string {
  22. return fmt.Sprintf("team invite already exists [team_id: %d, email: %s]", err.TeamID, err.Email)
  23. }
  24. func (err ErrTeamInviteAlreadyExist) Unwrap() error {
  25. return util.ErrAlreadyExist
  26. }
  27. type ErrTeamInviteNotFound struct {
  28. Token string
  29. }
  30. func IsErrTeamInviteNotFound(err error) bool {
  31. _, ok := err.(ErrTeamInviteNotFound)
  32. return ok
  33. }
  34. func (err ErrTeamInviteNotFound) Error() string {
  35. return fmt.Sprintf("team invite was not found [token: %s]", err.Token)
  36. }
  37. func (err ErrTeamInviteNotFound) Unwrap() error {
  38. return util.ErrNotExist
  39. }
  40. // ErrUserEmailAlreadyAdded represents a "user by email already added to team" error.
  41. type ErrUserEmailAlreadyAdded struct {
  42. Email string
  43. }
  44. // IsErrUserEmailAlreadyAdded checks if an error is a ErrUserEmailAlreadyAdded.
  45. func IsErrUserEmailAlreadyAdded(err error) bool {
  46. _, ok := err.(ErrUserEmailAlreadyAdded)
  47. return ok
  48. }
  49. func (err ErrUserEmailAlreadyAdded) Error() string {
  50. return fmt.Sprintf("user with email already added [email: %s]", err.Email)
  51. }
  52. func (err ErrUserEmailAlreadyAdded) Unwrap() error {
  53. return util.ErrAlreadyExist
  54. }
  55. // TeamInvite represents an invite to a team
  56. type TeamInvite struct {
  57. ID int64 `xorm:"pk autoincr"`
  58. Token string `xorm:"UNIQUE(token) INDEX NOT NULL DEFAULT ''"`
  59. InviterID int64 `xorm:"NOT NULL DEFAULT 0"`
  60. OrgID int64 `xorm:"INDEX NOT NULL DEFAULT 0"`
  61. TeamID int64 `xorm:"UNIQUE(team_mail) INDEX NOT NULL DEFAULT 0"`
  62. Email string `xorm:"UNIQUE(team_mail) NOT NULL DEFAULT ''"`
  63. CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
  64. UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
  65. }
  66. func CreateTeamInvite(ctx context.Context, doer *user_model.User, team *Team, email string) (*TeamInvite, error) {
  67. has, err := db.GetEngine(ctx).Exist(&TeamInvite{
  68. TeamID: team.ID,
  69. Email: email,
  70. })
  71. if err != nil {
  72. return nil, err
  73. }
  74. if has {
  75. return nil, ErrTeamInviteAlreadyExist{
  76. TeamID: team.ID,
  77. Email: email,
  78. }
  79. }
  80. // check if the user is already a team member by email
  81. exist, err := db.GetEngine(ctx).
  82. Where(builder.Eq{
  83. "team_user.org_id": team.OrgID,
  84. "team_user.team_id": team.ID,
  85. "`user`.email": email,
  86. }).
  87. Join("INNER", "`user`", "`user`.id = team_user.uid").
  88. Table("team_user").
  89. Exist()
  90. if err != nil {
  91. return nil, err
  92. }
  93. if exist {
  94. return nil, ErrUserEmailAlreadyAdded{
  95. Email: email,
  96. }
  97. }
  98. token, err := util.CryptoRandomString(25)
  99. if err != nil {
  100. return nil, err
  101. }
  102. invite := &TeamInvite{
  103. Token: token,
  104. InviterID: doer.ID,
  105. OrgID: team.OrgID,
  106. TeamID: team.ID,
  107. Email: email,
  108. }
  109. return invite, db.Insert(ctx, invite)
  110. }
  111. func RemoveInviteByID(ctx context.Context, inviteID, teamID int64) error {
  112. _, err := db.DeleteByBean(ctx, &TeamInvite{
  113. ID: inviteID,
  114. TeamID: teamID,
  115. })
  116. return err
  117. }
  118. func GetInvitesByTeamID(ctx context.Context, teamID int64) ([]*TeamInvite, error) {
  119. invites := make([]*TeamInvite, 0, 10)
  120. return invites, db.GetEngine(ctx).
  121. Where("team_id=?", teamID).
  122. Find(&invites)
  123. }
  124. func GetInviteByToken(ctx context.Context, token string) (*TeamInvite, error) {
  125. invite := &TeamInvite{}
  126. has, err := db.GetEngine(ctx).Where("token=?", token).Get(invite)
  127. if err != nil {
  128. return nil, err
  129. }
  130. if !has {
  131. return nil, ErrTeamInviteNotFound{Token: token}
  132. }
  133. return invite, nil
  134. }