github.com/spline-fu/mattermost-server@v4.10.10+incompatible/model/team.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package model
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  	"io"
    10  	"net/http"
    11  	"regexp"
    12  	"strings"
    13  	"unicode/utf8"
    14  )
    15  
    16  const (
    17  	TEAM_OPEN                       = "O"
    18  	TEAM_INVITE                     = "I"
    19  	TEAM_ALLOWED_DOMAINS_MAX_LENGTH = 500
    20  	TEAM_COMPANY_NAME_MAX_LENGTH    = 64
    21  	TEAM_DESCRIPTION_MAX_LENGTH     = 255
    22  	TEAM_DISPLAY_NAME_MAX_RUNES     = 64
    23  	TEAM_EMAIL_MAX_LENGTH           = 128
    24  	TEAM_NAME_MAX_LENGTH            = 64
    25  	TEAM_NAME_MIN_LENGTH            = 2
    26  )
    27  
    28  type Team struct {
    29  	Id                 string `json:"id"`
    30  	CreateAt           int64  `json:"create_at"`
    31  	UpdateAt           int64  `json:"update_at"`
    32  	DeleteAt           int64  `json:"delete_at"`
    33  	DisplayName        string `json:"display_name"`
    34  	Name               string `json:"name"`
    35  	Description        string `json:"description"`
    36  	Email              string `json:"email"`
    37  	Type               string `json:"type"`
    38  	CompanyName        string `json:"company_name"`
    39  	AllowedDomains     string `json:"allowed_domains"`
    40  	InviteId           string `json:"invite_id"`
    41  	AllowOpenInvite    bool   `json:"allow_open_invite"`
    42  	LastTeamIconUpdate int64  `json:"last_team_icon_update,omitempty"`
    43  }
    44  
    45  type TeamPatch struct {
    46  	DisplayName     *string `json:"display_name"`
    47  	Description     *string `json:"description"`
    48  	CompanyName     *string `json:"company_name"`
    49  	InviteId        *string `json:"invite_id"`
    50  	AllowOpenInvite *bool   `json:"allow_open_invite"`
    51  }
    52  
    53  type Invites struct {
    54  	Invites []map[string]string `json:"invites"`
    55  }
    56  
    57  func InvitesFromJson(data io.Reader) *Invites {
    58  	var o *Invites
    59  	json.NewDecoder(data).Decode(&o)
    60  	return o
    61  }
    62  
    63  func (o *Invites) ToEmailList() []string {
    64  	emailList := make([]string, len(o.Invites))
    65  	for _, invite := range o.Invites {
    66  		emailList = append(emailList, invite["email"])
    67  	}
    68  	return emailList
    69  }
    70  
    71  func (o *Invites) ToJson() string {
    72  	b, _ := json.Marshal(o)
    73  	return string(b)
    74  }
    75  
    76  func (o *Team) ToJson() string {
    77  	b, _ := json.Marshal(o)
    78  	return string(b)
    79  }
    80  
    81  func TeamFromJson(data io.Reader) *Team {
    82  	var o *Team
    83  	json.NewDecoder(data).Decode(&o)
    84  	return o
    85  }
    86  
    87  func TeamMapToJson(u map[string]*Team) string {
    88  	b, _ := json.Marshal(u)
    89  	return string(b)
    90  }
    91  
    92  func TeamMapFromJson(data io.Reader) map[string]*Team {
    93  	var teams map[string]*Team
    94  	json.NewDecoder(data).Decode(&teams)
    95  	return teams
    96  }
    97  
    98  func TeamListToJson(t []*Team) string {
    99  	b, _ := json.Marshal(t)
   100  	return string(b)
   101  }
   102  
   103  func TeamListFromJson(data io.Reader) []*Team {
   104  	var teams []*Team
   105  	json.NewDecoder(data).Decode(&teams)
   106  	return teams
   107  }
   108  
   109  func (o *Team) Etag() string {
   110  	return Etag(o.Id, o.UpdateAt)
   111  }
   112  
   113  func (o *Team) IsValid() *AppError {
   114  
   115  	if len(o.Id) != 26 {
   116  		return NewAppError("Team.IsValid", "model.team.is_valid.id.app_error", nil, "", http.StatusBadRequest)
   117  	}
   118  
   119  	if o.CreateAt == 0 {
   120  		return NewAppError("Team.IsValid", "model.team.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   121  	}
   122  
   123  	if o.UpdateAt == 0 {
   124  		return NewAppError("Team.IsValid", "model.team.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   125  	}
   126  
   127  	if len(o.Email) > TEAM_EMAIL_MAX_LENGTH {
   128  		return NewAppError("Team.IsValid", "model.team.is_valid.email.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   129  	}
   130  
   131  	if len(o.Email) > 0 && !IsValidEmail(o.Email) {
   132  		return NewAppError("Team.IsValid", "model.team.is_valid.email.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   133  	}
   134  
   135  	if utf8.RuneCountInString(o.DisplayName) == 0 || utf8.RuneCountInString(o.DisplayName) > TEAM_DISPLAY_NAME_MAX_RUNES {
   136  		return NewAppError("Team.IsValid", "model.team.is_valid.name.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   137  	}
   138  
   139  	if len(o.Name) > TEAM_NAME_MAX_LENGTH {
   140  		return NewAppError("Team.IsValid", "model.team.is_valid.url.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   141  	}
   142  
   143  	if len(o.Description) > TEAM_DESCRIPTION_MAX_LENGTH {
   144  		return NewAppError("Team.IsValid", "model.team.is_valid.description.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   145  	}
   146  
   147  	if IsReservedTeamName(o.Name) {
   148  		return NewAppError("Team.IsValid", "model.team.is_valid.reserved.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   149  	}
   150  
   151  	if !IsValidTeamName(o.Name) {
   152  		return NewAppError("Team.IsValid", "model.team.is_valid.characters.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   153  	}
   154  
   155  	if !(o.Type == TEAM_OPEN || o.Type == TEAM_INVITE) {
   156  		return NewAppError("Team.IsValid", "model.team.is_valid.type.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   157  	}
   158  
   159  	if len(o.CompanyName) > TEAM_COMPANY_NAME_MAX_LENGTH {
   160  		return NewAppError("Team.IsValid", "model.team.is_valid.company.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   161  	}
   162  
   163  	if len(o.AllowedDomains) > TEAM_ALLOWED_DOMAINS_MAX_LENGTH {
   164  		return NewAppError("Team.IsValid", "model.team.is_valid.domains.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  func (o *Team) PreSave() {
   171  	if o.Id == "" {
   172  		o.Id = NewId()
   173  	}
   174  
   175  	o.CreateAt = GetMillis()
   176  	o.UpdateAt = o.CreateAt
   177  
   178  	if len(o.InviteId) == 0 {
   179  		o.InviteId = NewId()
   180  	}
   181  }
   182  
   183  func (o *Team) PreUpdate() {
   184  	o.UpdateAt = GetMillis()
   185  }
   186  
   187  func IsReservedTeamName(s string) bool {
   188  	s = strings.ToLower(s)
   189  
   190  	for _, value := range reservedName {
   191  		if strings.Index(s, value) == 0 {
   192  			return true
   193  		}
   194  	}
   195  
   196  	return false
   197  }
   198  
   199  func IsValidTeamName(s string) bool {
   200  
   201  	if !IsValidAlphaNum(s) {
   202  		return false
   203  	}
   204  
   205  	if len(s) < TEAM_NAME_MIN_LENGTH {
   206  		return false
   207  	}
   208  
   209  	return true
   210  }
   211  
   212  var validTeamNameCharacter = regexp.MustCompile(`^[a-z0-9-]$`)
   213  
   214  func CleanTeamName(s string) string {
   215  	s = strings.ToLower(strings.Replace(s, " ", "-", -1))
   216  
   217  	for _, value := range reservedName {
   218  		if strings.Index(s, value) == 0 {
   219  			s = strings.Replace(s, value, "", -1)
   220  		}
   221  	}
   222  
   223  	s = strings.TrimSpace(s)
   224  
   225  	for _, c := range s {
   226  		char := fmt.Sprintf("%c", c)
   227  		if !validTeamNameCharacter.MatchString(char) {
   228  			s = strings.Replace(s, char, "", -1)
   229  		}
   230  	}
   231  
   232  	s = strings.Trim(s, "-")
   233  
   234  	if !IsValidTeamName(s) {
   235  		s = NewId()
   236  	}
   237  
   238  	return s
   239  }
   240  
   241  func (o *Team) Sanitize() {
   242  	o.Email = ""
   243  	o.AllowedDomains = ""
   244  }
   245  
   246  func (t *Team) Patch(patch *TeamPatch) {
   247  	if patch.DisplayName != nil {
   248  		t.DisplayName = *patch.DisplayName
   249  	}
   250  
   251  	if patch.Description != nil {
   252  		t.Description = *patch.Description
   253  	}
   254  
   255  	if patch.CompanyName != nil {
   256  		t.CompanyName = *patch.CompanyName
   257  	}
   258  
   259  	if patch.InviteId != nil {
   260  		t.InviteId = *patch.InviteId
   261  	}
   262  
   263  	if patch.AllowOpenInvite != nil {
   264  		t.AllowOpenInvite = *patch.AllowOpenInvite
   265  	}
   266  }
   267  
   268  func (t *TeamPatch) ToJson() string {
   269  	b, err := json.Marshal(t)
   270  	if err != nil {
   271  		return ""
   272  	}
   273  
   274  	return string(b)
   275  }
   276  
   277  func TeamPatchFromJson(data io.Reader) *TeamPatch {
   278  	decoder := json.NewDecoder(data)
   279  	var team TeamPatch
   280  	err := decoder.Decode(&team)
   281  	if err != nil {
   282  		return nil
   283  	}
   284  
   285  	return &team
   286  }