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