summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/mattermost-server/v5/model/utils.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mattermost/mattermost-server/v5/model/utils.go')
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/utils.go726
1 files changed, 0 insertions, 726 deletions
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/utils.go b/vendor/github.com/mattermost/mattermost-server/v5/model/utils.go
deleted file mode 100644
index 0c5a272c..00000000
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/utils.go
+++ /dev/null
@@ -1,726 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See LICENSE.txt for license information.
-
-package model
-
-import (
- "bytes"
- "crypto/rand"
- "encoding/base32"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "net/http"
- "net/mail"
- "net/url"
- "regexp"
- "strconv"
- "strings"
- "sync"
- "time"
- "unicode"
-
- "github.com/mattermost/mattermost-server/v5/shared/i18n"
- "github.com/pborman/uuid"
-)
-
-const (
- LOWERCASE_LETTERS = "abcdefghijklmnopqrstuvwxyz"
- UPPERCASE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- NUMBERS = "0123456789"
- SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~"
- MB = 1 << 20
-)
-
-type StringInterface map[string]interface{}
-type StringArray []string
-
-func (sa StringArray) Remove(input string) StringArray {
- for index := range sa {
- if sa[index] == input {
- ret := make(StringArray, 0, len(sa)-1)
- ret = append(ret, sa[:index]...)
- return append(ret, sa[index+1:]...)
- }
- }
- return sa
-}
-
-func (sa StringArray) Contains(input string) bool {
- for index := range sa {
- if sa[index] == input {
- return true
- }
- }
-
- return false
-}
-func (sa StringArray) Equals(input StringArray) bool {
-
- if len(sa) != len(input) {
- return false
- }
-
- for index := range sa {
-
- if sa[index] != input[index] {
- return false
- }
- }
-
- return true
-}
-
-var translateFunc i18n.TranslateFunc
-var translateFuncOnce sync.Once
-
-func AppErrorInit(t i18n.TranslateFunc) {
- translateFuncOnce.Do(func() {
- translateFunc = t
- })
-}
-
-type AppError struct {
- Id string `json:"id"`
- Message string `json:"message"` // Message to be display to the end user without debugging information
- DetailedError string `json:"detailed_error"` // Internal error string to help the developer
- RequestId string `json:"request_id,omitempty"` // The RequestId that's also set in the header
- StatusCode int `json:"status_code,omitempty"` // The http status code
- Where string `json:"-"` // The function where it happened in the form of Struct.Func
- IsOAuth bool `json:"is_oauth,omitempty"` // Whether the error is OAuth specific
- params map[string]interface{}
-}
-
-func (er *AppError) Error() string {
- return er.Where + ": " + er.Message + ", " + er.DetailedError
-}
-
-func (er *AppError) Translate(T i18n.TranslateFunc) {
- if T == nil {
- er.Message = er.Id
- return
- }
-
- if er.params == nil {
- er.Message = T(er.Id)
- } else {
- er.Message = T(er.Id, er.params)
- }
-}
-
-func (er *AppError) SystemMessage(T i18n.TranslateFunc) string {
- if er.params == nil {
- return T(er.Id)
- }
- return T(er.Id, er.params)
-}
-
-func (er *AppError) ToJson() string {
- b, _ := json.Marshal(er)
- return string(b)
-}
-
-// AppErrorFromJson will decode the input and return an AppError
-func AppErrorFromJson(data io.Reader) *AppError {
- str := ""
- bytes, rerr := ioutil.ReadAll(data)
- if rerr != nil {
- str = rerr.Error()
- } else {
- str = string(bytes)
- }
-
- decoder := json.NewDecoder(strings.NewReader(str))
- var er AppError
- err := decoder.Decode(&er)
- if err != nil {
- return NewAppError("AppErrorFromJson", "model.utils.decode_json.app_error", nil, "body: "+str, http.StatusInternalServerError)
- }
- return &er
-}
-
-func NewAppError(where string, id string, params map[string]interface{}, details string, status int) *AppError {
- ap := &AppError{}
- ap.Id = id
- ap.params = params
- ap.Message = id
- ap.Where = where
- ap.DetailedError = details
- ap.StatusCode = status
- ap.IsOAuth = false
- ap.Translate(translateFunc)
- return ap
-}
-
-var encoding = base32.NewEncoding("ybndrfg8ejkmcpqxot1uwisza345h769")
-
-// NewId is a globally unique identifier. It is a [A-Z0-9] string 26
-// characters long. It is a UUID version 4 Guid that is zbased32 encoded
-// with the padding stripped off.
-func NewId() string {
- var b bytes.Buffer
- encoder := base32.NewEncoder(encoding, &b)
- encoder.Write(uuid.NewRandom())
- encoder.Close()
- b.Truncate(26) // removes the '==' padding
- return b.String()
-}
-
-// NewRandomTeamName is a NewId that will be a valid team name.
-func NewRandomTeamName() string {
- teamName := NewId()
- for IsReservedTeamName(teamName) {
- teamName = NewId()
- }
- return teamName
-}
-
-// NewRandomString returns a random string of the given length.
-// The resulting entropy will be (5 * length) bits.
-func NewRandomString(length int) string {
- data := make([]byte, 1+(length*5/8))
- rand.Read(data)
- return encoding.EncodeToString(data)[:length]
-}
-
-// GetMillis is a convenience method to get milliseconds since epoch.
-func GetMillis() int64 {
- return time.Now().UnixNano() / int64(time.Millisecond)
-}
-
-// GetMillisForTime is a convenience method to get milliseconds since epoch for provided Time.
-func GetMillisForTime(thisTime time.Time) int64 {
- return thisTime.UnixNano() / int64(time.Millisecond)
-}
-
-// GetTimeForMillis is a convenience method to get time.Time for milliseconds since epoch.
-func GetTimeForMillis(millis int64) time.Time {
- return time.Unix(0, millis*int64(time.Millisecond))
-}
-
-// PadDateStringZeros is a convenience method to pad 2 digit date parts with zeros to meet ISO 8601 format
-func PadDateStringZeros(dateString string) string {
- parts := strings.Split(dateString, "-")
- for index, part := range parts {
- if len(part) == 1 {
- parts[index] = "0" + part
- }
- }
- dateString = strings.Join(parts[:], "-")
- return dateString
-}
-
-// GetStartOfDayMillis is a convenience method to get milliseconds since epoch for provided date's start of day
-func GetStartOfDayMillis(thisTime time.Time, timeZoneOffset int) int64 {
- localSearchTimeZone := time.FixedZone("Local Search Time Zone", timeZoneOffset)
- resultTime := time.Date(thisTime.Year(), thisTime.Month(), thisTime.Day(), 0, 0, 0, 0, localSearchTimeZone)
- return GetMillisForTime(resultTime)
-}
-
-// GetEndOfDayMillis is a convenience method to get milliseconds since epoch for provided date's end of day
-func GetEndOfDayMillis(thisTime time.Time, timeZoneOffset int) int64 {
- localSearchTimeZone := time.FixedZone("Local Search Time Zone", timeZoneOffset)
- resultTime := time.Date(thisTime.Year(), thisTime.Month(), thisTime.Day(), 23, 59, 59, 999999999, localSearchTimeZone)
- return GetMillisForTime(resultTime)
-}
-
-func CopyStringMap(originalMap map[string]string) map[string]string {
- copyMap := make(map[string]string)
- for k, v := range originalMap {
- copyMap[k] = v
- }
- return copyMap
-}
-
-// MapToJson converts a map to a json string
-func MapToJson(objmap map[string]string) string {
- b, _ := json.Marshal(objmap)
- return string(b)
-}
-
-// MapBoolToJson converts a map to a json string
-func MapBoolToJson(objmap map[string]bool) string {
- b, _ := json.Marshal(objmap)
- return string(b)
-}
-
-// MapFromJson will decode the key/value pair map
-func MapFromJson(data io.Reader) map[string]string {
- decoder := json.NewDecoder(data)
-
- var objmap map[string]string
- if err := decoder.Decode(&objmap); err != nil {
- return make(map[string]string)
- }
- return objmap
-}
-
-// MapFromJson will decode the key/value pair map
-func MapBoolFromJson(data io.Reader) map[string]bool {
- decoder := json.NewDecoder(data)
-
- var objmap map[string]bool
- if err := decoder.Decode(&objmap); err != nil {
- return make(map[string]bool)
- }
- return objmap
-}
-
-func ArrayToJson(objmap []string) string {
- b, _ := json.Marshal(objmap)
- return string(b)
-}
-
-func ArrayFromJson(data io.Reader) []string {
- decoder := json.NewDecoder(data)
-
- var objmap []string
- if err := decoder.Decode(&objmap); err != nil {
- return make([]string, 0)
- }
- return objmap
-}
-
-func ArrayFromInterface(data interface{}) []string {
- stringArray := []string{}
-
- dataArray, ok := data.([]interface{})
- if !ok {
- return stringArray
- }
-
- for _, v := range dataArray {
- if str, ok := v.(string); ok {
- stringArray = append(stringArray, str)
- }
- }
-
- return stringArray
-}
-
-func StringInterfaceToJson(objmap map[string]interface{}) string {
- b, _ := json.Marshal(objmap)
- return string(b)
-}
-
-func StringInterfaceFromJson(data io.Reader) map[string]interface{} {
- decoder := json.NewDecoder(data)
-
- var objmap map[string]interface{}
- if err := decoder.Decode(&objmap); err != nil {
- return make(map[string]interface{})
- }
- return objmap
-}
-
-func StringToJson(s string) string {
- b, _ := json.Marshal(s)
- return string(b)
-}
-
-func StringFromJson(data io.Reader) string {
- decoder := json.NewDecoder(data)
-
- var s string
- if err := decoder.Decode(&s); err != nil {
- return ""
- }
- return s
-}
-
-// ToJson serializes an arbitrary data type to JSON, discarding the error.
-func ToJson(v interface{}) []byte {
- b, _ := json.Marshal(v)
- return b
-}
-
-func GetServerIpAddress(iface string) string {
- var addrs []net.Addr
- if iface == "" {
- var err error
- addrs, err = net.InterfaceAddrs()
- if err != nil {
- return ""
- }
- } else {
- interfaces, err := net.Interfaces()
- if err != nil {
- return ""
- }
- for _, i := range interfaces {
- if i.Name == iface {
- addrs, err = i.Addrs()
- if err != nil {
- return ""
- }
- break
- }
- }
- }
-
- for _, addr := range addrs {
-
- if ip, ok := addr.(*net.IPNet); ok && !ip.IP.IsLoopback() && !ip.IP.IsLinkLocalUnicast() && !ip.IP.IsLinkLocalMulticast() {
- if ip.IP.To4() != nil {
- return ip.IP.String()
- }
- }
- }
-
- return ""
-}
-
-func IsLower(s string) bool {
- return strings.ToLower(s) == s
-}
-
-func IsValidEmail(email string) bool {
- if !IsLower(email) {
- return false
- }
-
- if addr, err := mail.ParseAddress(email); err != nil {
- return false
- } else if addr.Name != "" {
- // mail.ParseAddress accepts input of the form "Billy Bob <billy@example.com>" which we don't allow
- return false
- }
-
- return true
-}
-
-var reservedName = []string{
- "admin",
- "api",
- "channel",
- "claim",
- "error",
- "files",
- "help",
- "landing",
- "login",
- "mfa",
- "oauth",
- "plug",
- "plugins",
- "post",
- "signup",
-}
-
-func IsValidChannelIdentifier(s string) bool {
-
- if !IsValidAlphaNumHyphenUnderscore(s, true) {
- return false
- }
-
- if len(s) < CHANNEL_NAME_MIN_LENGTH {
- return false
- }
-
- return true
-}
-
-func IsValidAlphaNum(s string) bool {
- validAlphaNum := regexp.MustCompile(`^[a-z0-9]+([a-z\-0-9]+|(__)?)[a-z0-9]+$`)
-
- return validAlphaNum.MatchString(s)
-}
-
-func IsValidAlphaNumHyphenUnderscore(s string, withFormat bool) bool {
- if withFormat {
- validAlphaNumHyphenUnderscore := regexp.MustCompile(`^[a-z0-9]+([a-z\-\_0-9]+|(__)?)[a-z0-9]+$`)
- return validAlphaNumHyphenUnderscore.MatchString(s)
- }
-
- validSimpleAlphaNumHyphenUnderscore := regexp.MustCompile(`^[a-zA-Z0-9\-_]+$`)
- return validSimpleAlphaNumHyphenUnderscore.MatchString(s)
-}
-
-func IsValidAlphaNumHyphenUnderscorePlus(s string) bool {
-
- validSimpleAlphaNumHyphenUnderscorePlus := regexp.MustCompile(`^[a-zA-Z0-9+_-]+$`)
- return validSimpleAlphaNumHyphenUnderscorePlus.MatchString(s)
-}
-
-func Etag(parts ...interface{}) string {
-
- etag := CurrentVersion
-
- for _, part := range parts {
- etag += fmt.Sprintf(".%v", part)
- }
-
- return etag
-}
-
-var validHashtag = regexp.MustCompile(`^(#\pL[\pL\d\-_.]*[\pL\d])$`)
-var puncStart = regexp.MustCompile(`^[^\pL\d\s#]+`)
-var hashtagStart = regexp.MustCompile(`^#{2,}`)
-var puncEnd = regexp.MustCompile(`[^\pL\d\s]+$`)
-
-func ParseHashtags(text string) (string, string) {
- words := strings.Fields(text)
-
- hashtagString := ""
- plainString := ""
- for _, word := range words {
- // trim off surrounding punctuation
- word = puncStart.ReplaceAllString(word, "")
- word = puncEnd.ReplaceAllString(word, "")
-
- // and remove extra pound #s
- word = hashtagStart.ReplaceAllString(word, "#")
-
- if validHashtag.MatchString(word) {
- hashtagString += " " + word
- } else {
- plainString += " " + word
- }
- }
-
- if len(hashtagString) > 1000 {
- hashtagString = hashtagString[:999]
- lastSpace := strings.LastIndex(hashtagString, " ")
- if lastSpace > -1 {
- hashtagString = hashtagString[:lastSpace]
- } else {
- hashtagString = ""
- }
- }
-
- return strings.TrimSpace(hashtagString), strings.TrimSpace(plainString)
-}
-
-func ClearMentionTags(post string) string {
- post = strings.Replace(post, "<mention>", "", -1)
- post = strings.Replace(post, "</mention>", "", -1)
- return post
-}
-
-func IsValidHttpUrl(rawUrl string) bool {
- if strings.Index(rawUrl, "http://") != 0 && strings.Index(rawUrl, "https://") != 0 {
- return false
- }
-
- if u, err := url.ParseRequestURI(rawUrl); err != nil || u.Scheme == "" || u.Host == "" {
- return false
- }
-
- return true
-}
-
-func IsValidTurnOrStunServer(rawUri string) bool {
- if strings.Index(rawUri, "turn:") != 0 && strings.Index(rawUri, "stun:") != 0 {
- return false
- }
-
- if _, err := url.ParseRequestURI(rawUri); err != nil {
- return false
- }
-
- return true
-}
-
-func IsSafeLink(link *string) bool {
- if link != nil {
- if IsValidHttpUrl(*link) {
- return true
- } else if strings.HasPrefix(*link, "/") {
- return true
- } else {
- return false
- }
- }
-
- return true
-}
-
-func IsValidWebsocketUrl(rawUrl string) bool {
- if strings.Index(rawUrl, "ws://") != 0 && strings.Index(rawUrl, "wss://") != 0 {
- return false
- }
-
- if _, err := url.ParseRequestURI(rawUrl); err != nil {
- return false
- }
-
- return true
-}
-
-func IsValidTrueOrFalseString(value string) bool {
- return value == "true" || value == "false"
-}
-
-func IsValidNumberString(value string) bool {
- if _, err := strconv.Atoi(value); err != nil {
- return false
- }
-
- return true
-}
-
-func IsValidId(value string) bool {
- if len(value) != 26 {
- return false
- }
-
- for _, r := range value {
- if !unicode.IsLetter(r) && !unicode.IsNumber(r) {
- return false
- }
- }
-
- return true
-}
-
-// Copied from https://golang.org/src/net/dnsclient.go#L119
-func IsDomainName(s string) bool {
- // See RFC 1035, RFC 3696.
- // Presentation format has dots before every label except the first, and the
- // terminal empty label is optional here because we assume fully-qualified
- // (absolute) input. We must therefore reserve space for the first and last
- // labels' length octets in wire format, where they are necessary and the
- // maximum total length is 255.
- // So our _effective_ maximum is 253, but 254 is not rejected if the last
- // character is a dot.
- l := len(s)
- if l == 0 || l > 254 || l == 254 && s[l-1] != '.' {
- return false
- }
-
- last := byte('.')
- ok := false // Ok once we've seen a letter.
- partlen := 0
- for i := 0; i < len(s); i++ {
- c := s[i]
- switch {
- default:
- return false
- case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_':
- ok = true
- partlen++
- case '0' <= c && c <= '9':
- // fine
- partlen++
- case c == '-':
- // Byte before dash cannot be dot.
- if last == '.' {
- return false
- }
- partlen++
- case c == '.':
- // Byte before dot cannot be dot, dash.
- if last == '.' || last == '-' {
- return false
- }
- if partlen > 63 || partlen == 0 {
- return false
- }
- partlen = 0
- }
- last = c
- }
- if last == '-' || partlen > 63 {
- return false
- }
-
- return ok
-}
-
-func RemoveDuplicateStrings(in []string) []string {
- out := []string{}
- seen := make(map[string]bool, len(in))
-
- for _, item := range in {
- if !seen[item] {
- out = append(out, item)
-
- seen[item] = true
- }
- }
-
- return out
-}
-
-func GetPreferredTimezone(timezone StringMap) string {
- if timezone["useAutomaticTimezone"] == "true" {
- return timezone["automaticTimezone"]
- }
-
- return timezone["manualTimezone"]
-}
-
-// IsSamlFile checks if filename is a SAML file.
-func IsSamlFile(saml *SamlSettings, filename string) bool {
- return filename == *saml.PublicCertificateFile || filename == *saml.PrivateKeyFile || filename == *saml.IdpCertificateFile
-}
-
-func AsStringBoolMap(list []string) map[string]bool {
- listMap := map[string]bool{}
- for _, p := range list {
- listMap[p] = true
- }
- return listMap
-}
-
-// SanitizeUnicode will remove undesirable Unicode characters from a string.
-func SanitizeUnicode(s string) string {
- return strings.Map(filterBlocklist, s)
-}
-
-// filterBlocklist returns `r` if it is not in the blocklist, otherwise drop (-1).
-// Blocklist is taken from https://www.w3.org/TR/unicode-xml/#Charlist
-func filterBlocklist(r rune) rune {
- const drop = -1
- switch r {
- case '\u0340', '\u0341': // clones of grave and acute; deprecated in Unicode
- return drop
- case '\u17A3', '\u17D3': // obsolete characters for Khmer; deprecated in Unicode
- return drop
- case '\u2028', '\u2029': // line and paragraph separator
- return drop
- case '\u202A', '\u202B', '\u202C', '\u202D', '\u202E': // BIDI embedding controls
- return drop
- case '\u206A', '\u206B': // activate/inhibit symmetric swapping; deprecated in Unicode
- return drop
- case '\u206C', '\u206D': // activate/inhibit Arabic form shaping; deprecated in Unicode
- return drop
- case '\u206E', '\u206F': // activate/inhibit national digit shapes; deprecated in Unicode
- return drop
- case '\uFFF9', '\uFFFA', '\uFFFB': // interlinear annotation characters
- return drop
- case '\uFEFF': // byte order mark
- return drop
- case '\uFFFC': // object replacement character
- return drop
- }
-
- // Scoping for musical notation
- if r >= 0x0001D173 && r <= 0x0001D17A {
- return drop
- }
-
- // Language tag code points
- if r >= 0x000E0000 && r <= 0x000E007F {
- return drop
- }
-
- return r
-}
-
-// UniqueStrings returns a unique subset of the string slice provided.
-func UniqueStrings(input []string) []string {
- u := make([]string, 0, len(input))
- m := make(map[string]bool)
-
- for _, val := range input {
- if _, ok := m[val]; !ok {
- m[val] = true
- u = append(u, val)
- }
- }
-
- return u
-}