Added the ability to create a team with SSO services and added the ability to turn off email sign up.
Этот коммит содержится в:
@@ -23,7 +23,7 @@ type GitLabUser struct {
|
||||
|
||||
func UserFromGitLabUser(glu *GitLabUser) *User {
|
||||
user := &User{}
|
||||
user.Username = glu.Username
|
||||
user.Username = CleanUsername(glu.Username)
|
||||
splitName := strings.Split(glu.Name, " ")
|
||||
if len(splitName) == 2 {
|
||||
user.FirstName = splitName[0]
|
||||
|
||||
@@ -23,11 +23,6 @@ type GoogleUser struct {
|
||||
|
||||
func UserFromGoogleUser(gu *GoogleUser) *User {
|
||||
user := &User{}
|
||||
if len(gu.Nickname) > 0 {
|
||||
user.Username = gu.Nickname
|
||||
} else {
|
||||
user.Username = strings.ToLower(strings.Replace(gu.DisplayName, " ", "", -1))
|
||||
}
|
||||
user.FirstName = gu.Names["givenName"]
|
||||
user.LastName = gu.Names["familyName"]
|
||||
user.Nickname = gu.Nickname
|
||||
@@ -35,6 +30,7 @@ func UserFromGoogleUser(gu *GoogleUser) *User {
|
||||
for _, e := range gu.Emails {
|
||||
if e["type"] == "account" {
|
||||
user.Email = e["value"]
|
||||
user.Username = CleanUsername(strings.Split(user.Email, "@")[0])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -93,7 +96,7 @@ func (o *Team) IsValid() *AppError {
|
||||
return NewAppError("Team.IsValid", "Invalid email", "id="+o.Id)
|
||||
}
|
||||
|
||||
if !IsValidEmail(o.Email) {
|
||||
if len(o.Email) > 0 && !IsValidEmail(o.Email) {
|
||||
return NewAppError("Team.IsValid", "Invalid email", "id="+o.Id)
|
||||
}
|
||||
|
||||
@@ -140,3 +143,57 @@ func (o *Team) PreSave() {
|
||||
func (o *Team) PreUpdate() {
|
||||
o.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
func IsReservedTeamName(s string) bool {
|
||||
s = strings.ToLower(s)
|
||||
|
||||
for _, value := range reservedName {
|
||||
if strings.Index(s, value) == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsValidTeamName(s string) bool {
|
||||
|
||||
if !IsValidAlphaNum(s) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(s) <= 3 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
var validTeamNameCharacter = regexp.MustCompile(`^[a-z0-9-]$`)
|
||||
|
||||
func CleanTeamName(s string) string {
|
||||
s = strings.ToLower(strings.Replace(s, " ", "-", -1))
|
||||
|
||||
for _, value := range reservedName {
|
||||
if strings.Index(s, value) == 0 {
|
||||
s = strings.Replace(s, value, "", -1)
|
||||
}
|
||||
}
|
||||
|
||||
s = strings.TrimSpace(s)
|
||||
|
||||
for _, c := range s {
|
||||
char := fmt.Sprintf("%c", c)
|
||||
if !validTeamNameCharacter.MatchString(char) {
|
||||
s = strings.Replace(s, char, "", -1)
|
||||
}
|
||||
}
|
||||
|
||||
s = strings.Trim(s, "-")
|
||||
|
||||
if !IsValidTeamName(s) {
|
||||
s = NewId()
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -74,3 +74,62 @@ func TestTeamPreUpdate(t *testing.T) {
|
||||
o := Team{DisplayName: "test"}
|
||||
o.PreUpdate()
|
||||
}
|
||||
|
||||
var domains = []struct {
|
||||
value string
|
||||
expected bool
|
||||
}{
|
||||
{"spin-punch", true},
|
||||
{"-spin-punch", false},
|
||||
{"spin-punch-", false},
|
||||
{"spin_punch", false},
|
||||
{"a", false},
|
||||
{"aa", false},
|
||||
{"aaa", false},
|
||||
{"aaa-999b", true},
|
||||
{"b00b", true},
|
||||
{"b))b", false},
|
||||
{"test", true},
|
||||
}
|
||||
|
||||
func TestValidTeamName(t *testing.T) {
|
||||
for _, v := range domains {
|
||||
if IsValidTeamName(v.value) != v.expected {
|
||||
t.Errorf("expect %v as %v", v.value, v.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tReservedDomains = []struct {
|
||||
value string
|
||||
expected bool
|
||||
}{
|
||||
{"test-hello", true},
|
||||
{"test", true},
|
||||
{"admin", true},
|
||||
{"Admin-punch", true},
|
||||
{"spin-punch-admin", false},
|
||||
}
|
||||
|
||||
func TestReservedTeamName(t *testing.T) {
|
||||
for _, v := range tReservedDomains {
|
||||
if IsReservedTeamName(v.value) != v.expected {
|
||||
t.Errorf("expect %v as %v", v.value, v.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanTeamName(t *testing.T) {
|
||||
if CleanTeamName("Jimbo's Team") != "jimbos-team" {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
if len(CleanTeamName("Test")) != 26 {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
if CleanTeamName("Team Really cool") != "really-cool" {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
if CleanTeamName("super-duper-guys") != "super-duper-guys" {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ package model
|
||||
import (
|
||||
"code.google.com/p/go.crypto/bcrypt"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -72,13 +73,7 @@ func (u *User) IsValid() *AppError {
|
||||
return NewAppError("User.IsValid", "Invalid team id", "")
|
||||
}
|
||||
|
||||
if len(u.Username) == 0 || len(u.Username) > 64 {
|
||||
return NewAppError("User.IsValid", "Invalid username", "user_id="+u.Id)
|
||||
}
|
||||
|
||||
validChars, _ := regexp.Compile("^[a-z0-9\\.\\-\\_]+$")
|
||||
|
||||
if !validChars.MatchString(u.Username) {
|
||||
if !IsValidUsername(u.Username) {
|
||||
return NewAppError("User.IsValid", "Invalid username", "user_id="+u.Id)
|
||||
}
|
||||
|
||||
@@ -332,17 +327,58 @@ func ComparePassword(hash string, password string) bool {
|
||||
|
||||
func IsUsernameValid(username string) bool {
|
||||
|
||||
var restrictedUsernames = []string{
|
||||
BOT_USERNAME,
|
||||
"all",
|
||||
"channel",
|
||||
return true
|
||||
}
|
||||
|
||||
var validUsernameChars = regexp.MustCompile(`^[a-z0-9\.\-_]+$`)
|
||||
|
||||
var restrictedUsernames = []string{
|
||||
BOT_USERNAME,
|
||||
"all",
|
||||
"channel",
|
||||
}
|
||||
|
||||
func IsValidUsername(s string) bool {
|
||||
if len(s) == 0 || len(s) > 64 {
|
||||
return false
|
||||
}
|
||||
|
||||
if !validUsernameChars.MatchString(s) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, restrictedUsername := range restrictedUsernames {
|
||||
if username == restrictedUsername {
|
||||
if s == restrictedUsername {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func CleanUsername(s string) string {
|
||||
s = strings.ToLower(strings.Replace(s, " ", "-", -1))
|
||||
|
||||
for _, value := range reservedName {
|
||||
if s == value {
|
||||
s = strings.Replace(s, value, "", -1)
|
||||
}
|
||||
}
|
||||
|
||||
s = strings.TrimSpace(s)
|
||||
|
||||
for _, c := range s {
|
||||
char := fmt.Sprintf("%c", c)
|
||||
if !validUsernameChars.MatchString(char) {
|
||||
s = strings.Replace(s, char, "-", -1)
|
||||
}
|
||||
}
|
||||
|
||||
s = strings.Trim(s, "-")
|
||||
|
||||
if !IsValidUsername(s) {
|
||||
s = "a" + NewId()
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -150,3 +150,45 @@ func TestUserGetDisplayName(t *testing.T) {
|
||||
t.Fatal("Display name should be nickname")
|
||||
}
|
||||
}
|
||||
|
||||
var usernames = []struct {
|
||||
value string
|
||||
expected bool
|
||||
}{
|
||||
{"spin-punch", true},
|
||||
{"Spin-punch", false},
|
||||
{"spin punch-", false},
|
||||
{"spin_punch", true},
|
||||
{"spin", true},
|
||||
{"PUNCH", false},
|
||||
{"spin.punch", true},
|
||||
{"spin'punch", false},
|
||||
{"spin*punch", false},
|
||||
{"all", false},
|
||||
}
|
||||
|
||||
func TestValidUsername(t *testing.T) {
|
||||
for _, v := range usernames {
|
||||
if IsValidUsername(v.value) != v.expected {
|
||||
t.Errorf("expect %v as %v", v.value, v.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanUsername(t *testing.T) {
|
||||
if CleanUsername("Spin-punch") != "spin-punch" {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
if CleanUsername("PUNCH") != "punch" {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
if CleanUsername("spin'punch") != "spin-punch" {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
if CleanUsername("spin") != "spin" {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
if len(CleanUsername("all")) != 27 {
|
||||
t.Fatal("didn't clean name properly")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,31 +168,6 @@ var reservedName = []string{
|
||||
"api",
|
||||
}
|
||||
|
||||
func IsReservedTeamName(s string) bool {
|
||||
s = strings.ToLower(s)
|
||||
|
||||
for _, value := range reservedName {
|
||||
if strings.Index(s, value) == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsValidTeamName(s string) bool {
|
||||
|
||||
if !IsValidAlphaNum(s) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(s) <= 3 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
var wwwStart = regexp.MustCompile(`^www`)
|
||||
var betaStart = regexp.MustCompile(`^beta`)
|
||||
var ciStart = regexp.MustCompile(`^ci`)
|
||||
|
||||
@@ -66,50 +66,6 @@ func TestValidLower(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var domains = []struct {
|
||||
value string
|
||||
expected bool
|
||||
}{
|
||||
{"spin-punch", true},
|
||||
{"-spin-punch", false},
|
||||
{"spin-punch-", false},
|
||||
{"spin_punch", false},
|
||||
{"a", false},
|
||||
{"aa", false},
|
||||
{"aaa", false},
|
||||
{"aaa-999b", true},
|
||||
{"b00b", true},
|
||||
{"b))b", false},
|
||||
{"test", true},
|
||||
}
|
||||
|
||||
func TestValidTeamName(t *testing.T) {
|
||||
for _, v := range domains {
|
||||
if IsValidTeamName(v.value) != v.expected {
|
||||
t.Errorf("expect %v as %v", v.value, v.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tReservedDomains = []struct {
|
||||
value string
|
||||
expected bool
|
||||
}{
|
||||
{"test-hello", true},
|
||||
{"test", true},
|
||||
{"admin", true},
|
||||
{"Admin-punch", true},
|
||||
{"spin-punch-admin", false},
|
||||
}
|
||||
|
||||
func TestReservedTeamName(t *testing.T) {
|
||||
for _, v := range tReservedDomains {
|
||||
if IsReservedTeamName(v.value) != v.expected {
|
||||
t.Errorf("expect %v as %v", v.value, v.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtag(t *testing.T) {
|
||||
etag := Etag("hello", 24)
|
||||
if len(etag) <= 0 {
|
||||
|
||||
Ссылка в новой задаче
Block a user