summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/team.go86
-rw-r--r--app/team_test.go173
2 files changed, 208 insertions, 51 deletions
diff --git a/app/team.go b/app/team.go
index 8d1331823..dd372a99a 100644
--- a/app/team.go
+++ b/app/team.go
@@ -44,7 +44,7 @@ func (a *App) CreateTeamWithUser(team *model.Team, userId string) (*model.Team,
team.Email = user.Email
}
- if !a.isTeamEmailAllowed(user) {
+ if !a.isTeamEmailAllowed(user, team) {
return nil, model.NewAppError("isTeamEmailAllowed", "api.team.is_team_creation_allowed.domain.app_error", nil, "", http.StatusBadRequest)
}
@@ -60,35 +60,43 @@ func (a *App) CreateTeamWithUser(team *model.Team, userId string) (*model.Team,
return rteam, nil
}
-func (a *App) isTeamEmailAddressAllowed(email string) bool {
- email = strings.ToLower(email)
+func (a *App) normalizeDomains(domains string) []string {
// commas and @ signs are optional
// can be in the form of "@corp.mattermost.com, mattermost.com mattermost.org" -> corp.mattermost.com mattermost.com mattermost.org
- domains := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(a.Config().TeamSettings.RestrictCreationToDomains, "@", " ", -1), ",", " ", -1))))
+ return strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(domains, "@", " ", -1), ",", " ", -1))))
+}
- matched := false
- for _, d := range domains {
- if strings.HasSuffix(email, "@"+d) {
- matched = true
- break
+func (a *App) isTeamEmailAddressAllowed(email string, allowedDomains string) bool {
+ email = strings.ToLower(email)
+ // First check per team allowedDomains, then app wide restrictions
+ for _, restriction := range []string{allowedDomains, a.Config().TeamSettings.RestrictCreationToDomains} {
+ domains := a.normalizeDomains(restriction)
+ if len(domains) <= 0 {
+ continue
+ }
+ matched := false
+ for _, d := range domains {
+ if strings.HasSuffix(email, "@"+d) {
+ matched = true
+ break
+ }
+ }
+ if !matched {
+ return false
}
- }
-
- if len(a.Config().TeamSettings.RestrictCreationToDomains) > 0 && !matched {
- return false
}
return true
}
-func (a *App) isTeamEmailAllowed(user *model.User) bool {
+func (a *App) isTeamEmailAllowed(user *model.User, team *model.Team) bool {
email := strings.ToLower(user.Email)
if len(user.AuthService) > 0 && len(*user.AuthData) > 0 {
return true
}
- return a.isTeamEmailAddressAllowed(email)
+ return a.isTeamEmailAddressAllowed(email, team.AllowedDomains)
}
func (a *App) UpdateTeam(team *model.Team) (*model.Team, *model.AppError) {
@@ -98,6 +106,23 @@ func (a *App) UpdateTeam(team *model.Team) (*model.Team, *model.AppError) {
return nil, err
}
+ validDomains := a.normalizeDomains(a.Config().TeamSettings.RestrictCreationToDomains)
+ if len(validDomains) > 0 {
+ for _, domain := range a.normalizeDomains(team.AllowedDomains) {
+ matched := false
+ for _, d := range validDomains {
+ if domain == d {
+ matched = true
+ break
+ }
+ }
+ if !matched {
+ err := model.NewAppError("UpdateTeam", "api.team.update_restricted_domains.mismatch.app_error", map[string]interface{}{"Domain": domain}, "", http.StatusBadRequest)
+ return nil, err
+ }
+ }
+ }
+
oldTeam.DisplayName = team.DisplayName
oldTeam.Description = team.Description
oldTeam.InviteId = team.InviteId
@@ -430,6 +455,9 @@ func (a *App) joinUserToTeam(team *model.Team, user *model.User) (*model.TeamMem
}
func (a *App) JoinUserToTeam(team *model.Team, user *model.User, userRequestorId string) *model.AppError {
+ if !a.isTeamEmailAllowed(user, team) {
+ return model.NewAppError("JoinUserToTeam", "api.team.join_user_to_team.allowed_domains.app_error", nil, "", http.StatusBadRequest)
+ }
tm, alreadyAdded, err := a.joinUserToTeam(team, user)
if err != nil {
return err
@@ -843,20 +871,6 @@ func (a *App) InviteNewUsersToTeam(emailList []string, teamId, senderId string)
return err
}
- var invalidEmailList []string
-
- for _, email := range emailList {
- if !a.isTeamEmailAddressAllowed(email) {
- invalidEmailList = append(invalidEmailList, email)
- }
- }
-
- if len(invalidEmailList) > 0 {
- s := strings.Join(invalidEmailList, ", ")
- err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.invalid_email.app_error", map[string]interface{}{"Addresses": s}, "", http.StatusBadRequest)
- return err
- }
-
tchan := a.Srv.Store.Team().Get(teamId)
uchan := a.Srv.Store.User().Get(senderId)
@@ -874,6 +888,20 @@ func (a *App) InviteNewUsersToTeam(emailList []string, teamId, senderId string)
user = result.Data.(*model.User)
}
+ var invalidEmailList []string
+
+ for _, email := range emailList {
+ if !a.isTeamEmailAddressAllowed(email, team.AllowedDomains) {
+ invalidEmailList = append(invalidEmailList, email)
+ }
+ }
+
+ if len(invalidEmailList) > 0 {
+ s := strings.Join(invalidEmailList, ", ")
+ err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.invalid_email.app_error", map[string]interface{}{"Addresses": s}, "", http.StatusBadRequest)
+ return err
+ }
+
nameFormat := *a.Config().TeamSettings.TeammateNameDisplay
a.SendInviteEmails(team, user.GetDisplayName(nameFormat), user.Id, emailList, a.GetSiteURL())
diff --git a/app/team_test.go b/app/team_test.go
index 429e07931..1f2dd5318 100644
--- a/app/team_test.go
+++ b/app/team_test.go
@@ -73,13 +73,99 @@ func TestAddUserToTeam(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()
- user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
- ruser, _ := th.App.CreateUser(&user)
+ t.Run("add user", func(t *testing.T) {
+ user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
- if _, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, ""); err != nil {
- t.Log(err)
- t.Fatal("Should add user to the team")
- }
+ if _, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, ""); err != nil {
+ t.Log(err)
+ t.Fatal("Should add user to the team")
+ }
+ })
+
+ t.Run("allow user by domain", func(t *testing.T) {
+ th.BasicTeam.AllowedDomains = "example.com"
+ if _, err := th.App.UpdateTeam(th.BasicTeam); err != nil {
+ t.Log(err)
+ t.Fatal("Should update the team")
+ }
+
+ user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
+
+ if _, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, ""); err != nil {
+ t.Log(err)
+ t.Fatal("Should have allowed whitelisted user")
+ }
+ })
+
+ t.Run("block user by domain", func(t *testing.T) {
+ th.BasicTeam.AllowedDomains = "example.com"
+ if _, err := th.App.UpdateTeam(th.BasicTeam); err != nil {
+ t.Log(err)
+ t.Fatal("Should update the team")
+ }
+
+ user := model.User{Email: strings.ToLower(model.NewId()) + "test@invalid.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
+
+ if _, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, ""); err == nil || err.Where != "JoinUserToTeam" {
+ t.Log(err)
+ t.Fatal("Should not add restricted user")
+ }
+ })
+
+ t.Run("block user with subdomain", func(t *testing.T) {
+ th.BasicTeam.AllowedDomains = "example.com"
+ if _, err := th.App.UpdateTeam(th.BasicTeam); err != nil {
+ t.Log(err)
+ t.Fatal("Should update the team")
+ }
+
+ user := model.User{Email: strings.ToLower(model.NewId()) + "test@invalid.example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
+
+ if _, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser.Id, ""); err == nil || err.Where != "JoinUserToTeam" {
+ t.Log(err)
+ t.Fatal("Should not add restricted user")
+ }
+ })
+
+ t.Run("allow users by multiple domains", func(t *testing.T) {
+ th.BasicTeam.AllowedDomains = "foo.com, bar.com"
+ if _, err := th.App.UpdateTeam(th.BasicTeam); err != nil {
+ t.Log(err)
+ t.Fatal("Should update the team")
+ }
+
+ user1 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@foo.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser1, _ := th.App.CreateUser(&user1)
+ user2 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@bar.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser2, _ := th.App.CreateUser(&user2)
+ user3 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@invalid.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser3, _ := th.App.CreateUser(&user3)
+ defer th.App.PermanentDeleteUser(&user1)
+ defer th.App.PermanentDeleteUser(&user2)
+ defer th.App.PermanentDeleteUser(&user3)
+
+ if _, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser1.Id, ""); err != nil {
+ t.Log(err)
+ t.Fatal("Should have allowed whitelisted user1")
+ }
+ if _, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser2.Id, ""); err != nil {
+ t.Log(err)
+ t.Fatal("Should have allowed whitelisted user2")
+ }
+ if _, err := th.App.AddUserToTeam(th.BasicTeam.Id, ruser3.Id, ""); err == nil || err.Where != "JoinUserToTeam" {
+ t.Log(err)
+ t.Fatal("Should not have allowed restricted user3")
+ }
+
+ })
}
func TestAddUserToTeamByToken(t *testing.T) {
@@ -158,19 +244,62 @@ func TestAddUserToTeamByToken(t *testing.T) {
t.Fatal("The token must be deleted after be used")
}
})
+
+ t.Run("block user", func(t *testing.T) {
+ th.BasicTeam.AllowedDomains = "example.com"
+ if _, err := th.App.UpdateTeam(th.BasicTeam); err != nil {
+ t.Log(err)
+ t.Fatal("Should update the team")
+ }
+
+ user := model.User{Email: strings.ToLower(model.NewId()) + "test@invalid.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
+
+ token := model.NewToken(
+ TOKEN_TYPE_TEAM_INVITATION,
+ model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id}),
+ )
+ <-th.App.Srv.Store.Token().Save(token)
+
+ if _, err := th.App.AddUserToTeamByToken(ruser.Id, token.Token); err == nil || err.Where != "JoinUserToTeam" {
+ t.Log(err)
+ t.Fatal("Should not add restricted user")
+ }
+ })
}
func TestAddUserToTeamByTeamId(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()
- user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
- ruser, _ := th.App.CreateUser(&user)
+ t.Run("add user", func(t *testing.T) {
+ user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+
+ if err := th.App.AddUserToTeamByTeamId(th.BasicTeam.Id, ruser); err != nil {
+ t.Log(err)
+ t.Fatal("Should add user to the team")
+ }
+ })
+
+ t.Run("block user", func(t *testing.T) {
+ th.BasicTeam.AllowedDomains = "example.com"
+ if _, err := th.App.UpdateTeam(th.BasicTeam); err != nil {
+ t.Log(err)
+ t.Fatal("Should update the team")
+ }
+
+ user := model.User{Email: strings.ToLower(model.NewId()) + "test@invalid.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
+
+ if err := th.App.AddUserToTeamByTeamId(th.BasicTeam.Id, ruser); err == nil || err.Where != "JoinUserToTeam" {
+ t.Log(err)
+ t.Fatal("Should not add restricted user")
+ }
+ })
- if err := th.App.AddUserToTeamByTeamId(th.BasicTeam.Id, ruser); err != nil {
- t.Log(err)
- t.Fatal("Should add user to the team")
- }
}
func TestPermanentDeleteTeam(t *testing.T) {
@@ -264,7 +393,7 @@ func TestSanitizeTeam(t *testing.T) {
}
sanitized := th.App.SanitizeTeam(session, copyTeam())
- if sanitized.Email != "" && sanitized.AllowedDomains != "" {
+ if sanitized.Email != "" {
t.Fatal("should've sanitized team")
}
})
@@ -283,7 +412,7 @@ func TestSanitizeTeam(t *testing.T) {
}
sanitized := th.App.SanitizeTeam(session, copyTeam())
- if sanitized.Email != "" && sanitized.AllowedDomains != "" {
+ if sanitized.Email != "" {
t.Fatal("should've sanitized team")
}
})
@@ -302,7 +431,7 @@ func TestSanitizeTeam(t *testing.T) {
}
sanitized := th.App.SanitizeTeam(session, copyTeam())
- if sanitized.Email == "" && sanitized.AllowedDomains == "" {
+ if sanitized.Email == "" {
t.Fatal("shouldn't have sanitized team")
}
})
@@ -321,7 +450,7 @@ func TestSanitizeTeam(t *testing.T) {
}
sanitized := th.App.SanitizeTeam(session, copyTeam())
- if sanitized.Email != "" && sanitized.AllowedDomains != "" {
+ if sanitized.Email != "" {
t.Fatal("should've sanitized team")
}
})
@@ -340,7 +469,7 @@ func TestSanitizeTeam(t *testing.T) {
}
sanitized := th.App.SanitizeTeam(session, copyTeam())
- if sanitized.Email == "" && sanitized.AllowedDomains == "" {
+ if sanitized.Email == "" {
t.Fatal("shouldn't have sanitized team")
}
})
@@ -359,7 +488,7 @@ func TestSanitizeTeam(t *testing.T) {
}
sanitized := th.App.SanitizeTeam(session, copyTeam())
- if sanitized.Email == "" && sanitized.AllowedDomains == "" {
+ if sanitized.Email == "" {
t.Fatal("shouldn't have sanitized team")
}
})
@@ -402,11 +531,11 @@ func TestSanitizeTeams(t *testing.T) {
sanitized := th.App.SanitizeTeams(session, teams)
- if sanitized[0].Email != "" && sanitized[0].AllowedDomains != "" {
+ if sanitized[0].Email != "" {
t.Fatal("should've sanitized first team")
}
- if sanitized[1].Email == "" && sanitized[1].AllowedDomains == "" {
+ if sanitized[1].Email == "" {
t.Fatal("shouldn't have sanitized second team")
}
})
@@ -439,11 +568,11 @@ func TestSanitizeTeams(t *testing.T) {
sanitized := th.App.SanitizeTeams(session, teams)
- if sanitized[0].Email == "" && sanitized[0].AllowedDomains == "" {
+ if sanitized[0].Email == "" {
t.Fatal("shouldn't have sanitized first team")
}
- if sanitized[1].Email == "" && sanitized[1].AllowedDomains == "" {
+ if sanitized[1].Email == "" {
t.Fatal("shouldn't have sanitized second team")
}
})