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