forked from go-gitea/gitea
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'upstream/main'
* upstream/main: [skip ci] Updated translations via Crowdin Check for valid user token in integration tests (go-gitea#21520) Ignore error when retrieving changed PR review files (go-gitea#21487) move invite by mail to services package (go-gitea#21513) Enable Monaco automaticLayout (go-gitea#21515) Update macOS install command (go-gitea#21507) [skip ci] Updated translations via Crowdin Suppress `ExternalLoginUserNotExist` error (go-gitea#21504) Revert increased width on pull pages (go-gitea#21470) Add team member invite by email (go-gitea#20307) Disable the 'Add File' button when not able to edit repo (go-gitea#21503) Remove vitest globals (go-gitea#21505) Fix branch dropdown shifting on page load (go-gitea#21428)
- Loading branch information
Showing
64 changed files
with
738 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2022 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package migrations | ||
|
||
import ( | ||
"code.gitea.io/gitea/modules/timeutil" | ||
|
||
"xorm.io/xorm" | ||
) | ||
|
||
func addTeamInviteTable(x *xorm.Engine) error { | ||
type TeamInvite struct { | ||
ID int64 `xorm:"pk autoincr"` | ||
Token string `xorm:"UNIQUE(token) INDEX NOT NULL DEFAULT ''"` | ||
InviterID int64 `xorm:"NOT NULL DEFAULT 0"` | ||
OrgID int64 `xorm:"INDEX NOT NULL DEFAULT 0"` | ||
TeamID int64 `xorm:"UNIQUE(team_mail) INDEX NOT NULL DEFAULT 0"` | ||
Email string `xorm:"UNIQUE(team_mail) NOT NULL DEFAULT ''"` | ||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||
} | ||
|
||
return x.Sync2(new(TeamInvite)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
// Copyright 2022 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package organization | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"code.gitea.io/gitea/models/db" | ||
user_model "code.gitea.io/gitea/models/user" | ||
"code.gitea.io/gitea/modules/timeutil" | ||
"code.gitea.io/gitea/modules/util" | ||
|
||
"xorm.io/builder" | ||
) | ||
|
||
type ErrTeamInviteAlreadyExist struct { | ||
TeamID int64 | ||
Email string | ||
} | ||
|
||
func IsErrTeamInviteAlreadyExist(err error) bool { | ||
_, ok := err.(ErrTeamInviteAlreadyExist) | ||
return ok | ||
} | ||
|
||
func (err ErrTeamInviteAlreadyExist) Error() string { | ||
return fmt.Sprintf("team invite already exists [team_id: %d, email: %s]", err.TeamID, err.Email) | ||
} | ||
|
||
func (err ErrTeamInviteAlreadyExist) Unwrap() error { | ||
return util.ErrAlreadyExist | ||
} | ||
|
||
type ErrTeamInviteNotFound struct { | ||
Token string | ||
} | ||
|
||
func IsErrTeamInviteNotFound(err error) bool { | ||
_, ok := err.(ErrTeamInviteNotFound) | ||
return ok | ||
} | ||
|
||
func (err ErrTeamInviteNotFound) Error() string { | ||
return fmt.Sprintf("team invite was not found [token: %s]", err.Token) | ||
} | ||
|
||
func (err ErrTeamInviteNotFound) Unwrap() error { | ||
return util.ErrNotExist | ||
} | ||
|
||
// ErrUserEmailAlreadyAdded represents a "user by email already added to team" error. | ||
type ErrUserEmailAlreadyAdded struct { | ||
Email string | ||
} | ||
|
||
// IsErrUserEmailAlreadyAdded checks if an error is a ErrUserEmailAlreadyAdded. | ||
func IsErrUserEmailAlreadyAdded(err error) bool { | ||
_, ok := err.(ErrUserEmailAlreadyAdded) | ||
return ok | ||
} | ||
|
||
func (err ErrUserEmailAlreadyAdded) Error() string { | ||
return fmt.Sprintf("user with email already added [email: %s]", err.Email) | ||
} | ||
|
||
func (err ErrUserEmailAlreadyAdded) Unwrap() error { | ||
return util.ErrAlreadyExist | ||
} | ||
|
||
// TeamInvite represents an invite to a team | ||
type TeamInvite struct { | ||
ID int64 `xorm:"pk autoincr"` | ||
Token string `xorm:"UNIQUE(token) INDEX NOT NULL DEFAULT ''"` | ||
InviterID int64 `xorm:"NOT NULL DEFAULT 0"` | ||
OrgID int64 `xorm:"INDEX NOT NULL DEFAULT 0"` | ||
TeamID int64 `xorm:"UNIQUE(team_mail) INDEX NOT NULL DEFAULT 0"` | ||
Email string `xorm:"UNIQUE(team_mail) NOT NULL DEFAULT ''"` | ||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||
} | ||
|
||
func CreateTeamInvite(ctx context.Context, doer *user_model.User, team *Team, email string) (*TeamInvite, error) { | ||
has, err := db.GetEngine(ctx).Exist(&TeamInvite{ | ||
TeamID: team.ID, | ||
Email: email, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if has { | ||
return nil, ErrTeamInviteAlreadyExist{ | ||
TeamID: team.ID, | ||
Email: email, | ||
} | ||
} | ||
|
||
// check if the user is already a team member by email | ||
exist, err := db.GetEngine(ctx). | ||
Where(builder.Eq{ | ||
"team_user.org_id": team.OrgID, | ||
"team_user.team_id": team.ID, | ||
"`user`.email": email, | ||
}). | ||
Join("INNER", "`user`", "`user`.id = team_user.uid"). | ||
Table("team_user"). | ||
Exist() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if exist { | ||
return nil, ErrUserEmailAlreadyAdded{ | ||
Email: email, | ||
} | ||
} | ||
|
||
token, err := util.CryptoRandomString(25) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
invite := &TeamInvite{ | ||
Token: token, | ||
InviterID: doer.ID, | ||
OrgID: team.OrgID, | ||
TeamID: team.ID, | ||
Email: email, | ||
} | ||
|
||
return invite, db.Insert(ctx, invite) | ||
} | ||
|
||
func RemoveInviteByID(ctx context.Context, inviteID, teamID int64) error { | ||
_, err := db.DeleteByBean(ctx, &TeamInvite{ | ||
ID: inviteID, | ||
TeamID: teamID, | ||
}) | ||
return err | ||
} | ||
|
||
func GetInvitesByTeamID(ctx context.Context, teamID int64) ([]*TeamInvite, error) { | ||
invites := make([]*TeamInvite, 0, 10) | ||
return invites, db.GetEngine(ctx). | ||
Where("team_id=?", teamID). | ||
Find(&invites) | ||
} | ||
|
||
func GetInviteByToken(ctx context.Context, token string) (*TeamInvite, error) { | ||
invite := &TeamInvite{} | ||
|
||
has, err := db.GetEngine(ctx).Where("token=?", token).Get(invite) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if !has { | ||
return nil, ErrTeamInviteNotFound{Token: token} | ||
} | ||
return invite, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright 2022 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package organization_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"code.gitea.io/gitea/models/db" | ||
"code.gitea.io/gitea/models/organization" | ||
"code.gitea.io/gitea/models/unittest" | ||
user_model "code.gitea.io/gitea/models/user" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestTeamInvite(t *testing.T) { | ||
assert.NoError(t, unittest.PrepareTestDatabase()) | ||
|
||
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) | ||
|
||
t.Run("MailExistsInTeam", func(t *testing.T) { | ||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||
|
||
// user 2 already added to team 2, should result in error | ||
_, err := organization.CreateTeamInvite(db.DefaultContext, user2, team, user2.Email) | ||
assert.Error(t, err) | ||
}) | ||
|
||
t.Run("CreateAndRemove", func(t *testing.T) { | ||
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | ||
|
||
invite, err := organization.CreateTeamInvite(db.DefaultContext, user1, team, "user3@example.com") | ||
assert.NotNil(t, invite) | ||
assert.NoError(t, err) | ||
|
||
// Shouldn't allow duplicate invite | ||
_, err = organization.CreateTeamInvite(db.DefaultContext, user1, team, "user3@example.com") | ||
assert.Error(t, err) | ||
|
||
// should remove invite | ||
assert.NoError(t, organization.RemoveInviteByID(db.DefaultContext, invite.ID, invite.TeamID)) | ||
|
||
// invite should not exist | ||
_, err = organization.GetInviteByToken(db.DefaultContext, invite.Token) | ||
assert.Error(t, err) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -261,6 +261,7 @@ register_success=Успешна регистрация | |
|
||
|
||
|
||
|
||
[modal] | ||
yes=Да | ||
no=Не | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.