mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-07-03 06:07:45 +00:00
Update vendor (#1265)
This commit is contained in:
2
vendor/github.com/mattermost/mattermost-server/v5/LICENSE.txt
generated
vendored
2
vendor/github.com/mattermost/mattermost-server/v5/LICENSE.txt
generated
vendored
@ -11,7 +11,7 @@ You may be licensed to use source code to create compiled versions not produced
|
||||
1. Under the Free Software Foundation’s GNU AGPL v.3.0, subject to the exceptions outlined in this policy; or
|
||||
2. Under a commercial license available from Mattermost, Inc. by contacting commercial@mattermost.com
|
||||
|
||||
You are licensed to use the source code in Admin Tools and Configuration Files (templates/, config/default.json, model/,
|
||||
You are licensed to use the source code in Admin Tools and Configuration Files (templates/, config/default.json, i18n/, model/,
|
||||
plugin/ and all subdirectories thereof) under the Apache License v2.0.
|
||||
|
||||
We promise that we will not enforce the copyleft provisions in AGPL v3.0 against you if your application (a) does not
|
||||
|
142
vendor/github.com/mattermost/mattermost-server/v5/NOTICE.txt
generated
vendored
142
vendor/github.com/mattermost/mattermost-server/v5/NOTICE.txt
generated
vendored
@ -4132,3 +4132,145 @@ A caching, resizing image proxy written in Go
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
---
|
||||
|
||||
## oov/psd
|
||||
|
||||
This product contains 'psd' by oov.
|
||||
|
||||
A PSD/PSB file reader for go
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/oov/psd
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 oov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## gopherjs
|
||||
|
||||
This product contains 'gopherjs' by Richard Musiol.
|
||||
|
||||
A Go code to javascript code compiler.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/gopherjs/gopherjs
|
||||
|
||||
* LICENSE:
|
||||
|
||||
Copyright (c) 2013 Richard Musiol. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
---
|
||||
|
||||
## semver
|
||||
|
||||
This product contains 'semver' by Masterminds.
|
||||
|
||||
The semver package provides the ability to work with Semantic Versions in Go.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/Masterminds/semver
|
||||
|
||||
* LICENSE:
|
||||
|
||||
Copyright (C) 2014-2019, Matt Butcher and Matt Farina
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## Date Constraints
|
||||
|
||||
This product contains 'dateconstraints' by Eli Yukelzon.
|
||||
|
||||
Go library to validate a date against constraints
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/reflog/dateconstraints
|
||||
|
||||
* LICENSE:
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Eli Yukelzon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
44
vendor/github.com/mattermost/mattermost-server/v5/mlog/default.go
generated
vendored
44
vendor/github.com/mattermost/mattermost-server/v5/mlog/default.go
generated
vendored
@ -4,9 +4,13 @@
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/mattermost/logr"
|
||||
)
|
||||
|
||||
// defaultLog manually encodes the log to STDERR, providing a basic, default logging implementation
|
||||
@ -49,3 +53,43 @@ func defaultCriticalLog(msg string, fields ...Field) {
|
||||
// We map critical to error in zap, so be consistent.
|
||||
defaultLog("error", msg, fields...)
|
||||
}
|
||||
|
||||
func defaultCustomLog(lvl LogLevel, msg string, fields ...Field) {
|
||||
// custom log levels are only output once log targets are configured.
|
||||
}
|
||||
|
||||
func defaultCustomMultiLog(lvl []LogLevel, msg string, fields ...Field) {
|
||||
// custom log levels are only output once log targets are configured.
|
||||
}
|
||||
|
||||
func defaultFlush(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultAdvancedConfig(cfg LogTargetCfg) error {
|
||||
// mlog.ConfigAdvancedConfig should not be called until default
|
||||
// logger is replaced with mlog.Logger instance.
|
||||
return errors.New("cannot config advanced logging on default logger")
|
||||
}
|
||||
|
||||
func defaultAdvancedShutdown(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultAddTarget(targets ...logr.Target) error {
|
||||
// mlog.AddTarget should not be called until default
|
||||
// logger is replaced with mlog.Logger instance.
|
||||
return errors.New("cannot AddTarget on default logger")
|
||||
}
|
||||
|
||||
func defaultRemoveTargets(ctx context.Context, f func(TargetInfo) bool) error {
|
||||
// mlog.RemoveTargets should not be called until default
|
||||
// logger is replaced with mlog.Logger instance.
|
||||
return errors.New("cannot RemoveTargets on default logger")
|
||||
}
|
||||
|
||||
func defaultEnableMetrics(collector logr.MetricsCollector) error {
|
||||
// mlog.EnableMetrics should not be called until default
|
||||
// logger is replaced with mlog.Logger instance.
|
||||
return errors.New("cannot EnableMetrics on default logger")
|
||||
}
|
||||
|
30
vendor/github.com/mattermost/mattermost-server/v5/mlog/errors.go
generated
vendored
Normal file
30
vendor/github.com/mattermost/mattermost-server/v5/mlog/errors.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import "github.com/mattermost/logr"
|
||||
|
||||
// onLoggerError is called when the logging system encounters an error,
|
||||
// such as a target not able to write records. The targets will keep trying
|
||||
// however the error will be logged with a dedicated level that can be output
|
||||
// to a safe/always available target for monitoring or alerting.
|
||||
func onLoggerError(err error) {
|
||||
Log(LvlLogError, "advanced logging error", Err(err))
|
||||
}
|
||||
|
||||
// onQueueFull is called when the main logger queue is full, indicating the
|
||||
// volume and frequency of log record creation is too high for the queue size
|
||||
// and/or the target latencies.
|
||||
func onQueueFull(rec *logr.LogRec, maxQueueSize int) bool {
|
||||
Log(LvlLogError, "main queue full, dropping record", Any("rec", rec))
|
||||
return true // drop record
|
||||
}
|
||||
|
||||
// onTargetQueueFull is called when the main logger queue is full, indicating the
|
||||
// volume and frequency of log record creation is too high for the target's queue size
|
||||
// and/or the target latency.
|
||||
func onTargetQueueFull(target logr.Target, rec *logr.LogRec, maxQueueSize int) bool {
|
||||
Log(LvlLogError, "target queue full, dropping record", String("target", ""), Any("rec", rec))
|
||||
return true // drop record
|
||||
}
|
53
vendor/github.com/mattermost/mattermost-server/v5/mlog/global.go
generated
vendored
53
vendor/github.com/mattermost/mattermost-server/v5/mlog/global.go
generated
vendored
@ -4,6 +4,11 @@
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/mattermost/logr"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
@ -11,6 +16,10 @@ import (
|
||||
var globalLogger *Logger
|
||||
|
||||
func InitGlobalLogger(logger *Logger) {
|
||||
// Clean up previous instance.
|
||||
if globalLogger != nil && globalLogger.logrLogger != nil {
|
||||
globalLogger.logrLogger.Logr().Shutdown()
|
||||
}
|
||||
glob := *logger
|
||||
glob.zap = glob.zap.WithOptions(zap.AddCallerSkip(1))
|
||||
globalLogger = &glob
|
||||
@ -19,13 +28,46 @@ func InitGlobalLogger(logger *Logger) {
|
||||
Warn = globalLogger.Warn
|
||||
Error = globalLogger.Error
|
||||
Critical = globalLogger.Critical
|
||||
Log = globalLogger.Log
|
||||
LogM = globalLogger.LogM
|
||||
Flush = globalLogger.Flush
|
||||
ConfigAdvancedLogging = globalLogger.ConfigAdvancedLogging
|
||||
ShutdownAdvancedLogging = globalLogger.ShutdownAdvancedLogging
|
||||
AddTarget = globalLogger.AddTarget
|
||||
RemoveTargets = globalLogger.RemoveTargets
|
||||
EnableMetrics = globalLogger.EnableMetrics
|
||||
}
|
||||
|
||||
// logWriterFunc provides access to mlog via io.Writer, so the standard logger
|
||||
// can be redirected to use mlog and whatever targets are defined.
|
||||
type logWriterFunc func([]byte) (int, error)
|
||||
|
||||
func (lw logWriterFunc) Write(p []byte) (int, error) {
|
||||
return lw(p)
|
||||
}
|
||||
|
||||
func RedirectStdLog(logger *Logger) {
|
||||
zap.RedirectStdLogAt(logger.zap.With(zap.String("source", "stdlog")).WithOptions(zap.AddCallerSkip(-2)), zapcore.ErrorLevel)
|
||||
if atomic.LoadInt32(&disableZap) == 0 {
|
||||
zap.RedirectStdLogAt(logger.zap.With(zap.String("source", "stdlog")).WithOptions(zap.AddCallerSkip(-2)), zapcore.ErrorLevel)
|
||||
return
|
||||
}
|
||||
|
||||
writer := func(p []byte) (int, error) {
|
||||
Log(LvlStdLog, string(p))
|
||||
return len(p), nil
|
||||
}
|
||||
log.SetOutput(logWriterFunc(writer))
|
||||
}
|
||||
|
||||
type LogFunc func(string, ...Field)
|
||||
type LogFuncCustom func(LogLevel, string, ...Field)
|
||||
type LogFuncCustomMulti func([]LogLevel, string, ...Field)
|
||||
type FlushFunc func(context.Context) error
|
||||
type ConfigFunc func(cfg LogTargetCfg) error
|
||||
type ShutdownFunc func(context.Context) error
|
||||
type AddTargetFunc func(...logr.Target) error
|
||||
type RemoveTargetsFunc func(context.Context, func(TargetInfo) bool) error
|
||||
type EnableMetricsFunc func(logr.MetricsCollector) error
|
||||
|
||||
// DON'T USE THIS Modify the level on the app logger
|
||||
func GloballyDisableDebugLogForTest() {
|
||||
@ -42,3 +84,12 @@ var Info LogFunc = defaultInfoLog
|
||||
var Warn LogFunc = defaultWarnLog
|
||||
var Error LogFunc = defaultErrorLog
|
||||
var Critical LogFunc = defaultCriticalLog
|
||||
var Log LogFuncCustom = defaultCustomLog
|
||||
var LogM LogFuncCustomMulti = defaultCustomMultiLog
|
||||
var Flush FlushFunc = defaultFlush
|
||||
|
||||
var ConfigAdvancedLogging ConfigFunc = defaultAdvancedConfig
|
||||
var ShutdownAdvancedLogging ShutdownFunc = defaultAdvancedShutdown
|
||||
var AddTarget AddTargetFunc = defaultAddTarget
|
||||
var RemoveTargets RemoveTargetsFunc = defaultRemoveTargets
|
||||
var EnableMetrics EnableMetricsFunc = defaultEnableMetrics
|
||||
|
39
vendor/github.com/mattermost/mattermost-server/v5/mlog/levels.go
generated
vendored
Normal file
39
vendor/github.com/mattermost/mattermost-server/v5/mlog/levels.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
// Standard levels
|
||||
var (
|
||||
LvlPanic = LogLevel{ID: 0, Name: "panic", Stacktrace: true}
|
||||
LvlFatal = LogLevel{ID: 1, Name: "fatal", Stacktrace: true}
|
||||
LvlError = LogLevel{ID: 2, Name: "error"}
|
||||
LvlWarn = LogLevel{ID: 3, Name: "warn"}
|
||||
LvlInfo = LogLevel{ID: 4, Name: "info"}
|
||||
LvlDebug = LogLevel{ID: 5, Name: "debug"}
|
||||
LvlTrace = LogLevel{ID: 6, Name: "trace"}
|
||||
// used by redirected standard logger
|
||||
LvlStdLog = LogLevel{ID: 10, Name: "stdlog"}
|
||||
// used only by the logger
|
||||
LvlLogError = LogLevel{ID: 11, Name: "logerror", Stacktrace: true}
|
||||
)
|
||||
|
||||
// Register custom (discrete) levels here.
|
||||
// !!!!! ID's must not exceed 32,768 !!!!!!
|
||||
var (
|
||||
// used by the audit system
|
||||
LvlAuditAPI = LogLevel{ID: 100, Name: "audit-api"}
|
||||
LvlAuditContent = LogLevel{ID: 101, Name: "audit-content"}
|
||||
LvlAuditPerms = LogLevel{ID: 102, Name: "audit-permissions"}
|
||||
LvlAuditCLI = LogLevel{ID: 103, Name: "audit-cli"}
|
||||
|
||||
// used by the TCP log target
|
||||
LvlTcpLogTarget = LogLevel{ID: 120, Name: "TcpLogTarget"}
|
||||
|
||||
// add more here ...
|
||||
)
|
||||
|
||||
// Combinations for LogM (log multi)
|
||||
var (
|
||||
MLvlAuditAll = []LogLevel{LvlAuditAPI, LvlAuditContent, LvlAuditPerms, LvlAuditCLI}
|
||||
)
|
161
vendor/github.com/mattermost/mattermost-server/v5/mlog/log.go
generated
vendored
161
vendor/github.com/mattermost/mattermost-server/v5/mlog/log.go
generated
vendored
@ -4,10 +4,15 @@
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/logr"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
@ -22,6 +27,19 @@ const (
|
||||
LevelWarn = "warn"
|
||||
// Errors are messages about things we know are problems
|
||||
LevelError = "error"
|
||||
|
||||
// DefaultFlushTimeout is the default amount of time mlog.Flush will wait
|
||||
// before timing out.
|
||||
DefaultFlushTimeout = time.Second * 5
|
||||
)
|
||||
|
||||
var (
|
||||
// disableZap is set when Zap should be disabled and Logr used instead.
|
||||
// This is needed for unit testing as Zap has no shutdown capabilities
|
||||
// and holds file handles until process exit. Currently unit test create
|
||||
// many server instances, and thus many Zap log files.
|
||||
// This flag will be removed when Zap is permanently replaced.
|
||||
disableZap int32
|
||||
)
|
||||
|
||||
// Type and function aliases from zap to limit the libraries scope into MM code
|
||||
@ -38,6 +56,8 @@ var NamedErr = zap.NamedError
|
||||
var Bool = zap.Bool
|
||||
var Duration = zap.Duration
|
||||
|
||||
type TargetInfo logr.TargetInfo
|
||||
|
||||
type LoggerConfiguration struct {
|
||||
EnableConsole bool
|
||||
ConsoleJson bool
|
||||
@ -52,6 +72,7 @@ type Logger struct {
|
||||
zap *zap.Logger
|
||||
consoleLevel zap.AtomicLevel
|
||||
fileLevel zap.AtomicLevel
|
||||
logrLogger *logr.Logger
|
||||
}
|
||||
|
||||
func getZapLevel(level string) zapcore.Level {
|
||||
@ -84,6 +105,7 @@ func NewLogger(config *LoggerConfiguration) *Logger {
|
||||
logger := &Logger{
|
||||
consoleLevel: zap.NewAtomicLevelAt(getZapLevel(config.ConsoleLevel)),
|
||||
fileLevel: zap.NewAtomicLevelAt(getZapLevel(config.FileLevel)),
|
||||
logrLogger: newLogr(),
|
||||
}
|
||||
|
||||
if config.EnableConsole {
|
||||
@ -93,13 +115,33 @@ func NewLogger(config *LoggerConfiguration) *Logger {
|
||||
}
|
||||
|
||||
if config.EnableFile {
|
||||
writer := zapcore.AddSync(&lumberjack.Logger{
|
||||
Filename: config.FileLocation,
|
||||
MaxSize: 100,
|
||||
Compress: true,
|
||||
})
|
||||
core := zapcore.NewCore(makeEncoder(config.FileJson), writer, logger.fileLevel)
|
||||
cores = append(cores, core)
|
||||
if atomic.LoadInt32(&disableZap) != 0 {
|
||||
t := &LogTarget{
|
||||
Type: "file",
|
||||
Format: "json",
|
||||
Levels: mlogLevelToLogrLevels(config.FileLevel),
|
||||
MaxQueueSize: DefaultMaxTargetQueue,
|
||||
Options: []byte(fmt.Sprintf(`{"Filename":"%s", "MaxSizeMB":%d, "Compress":%t}`,
|
||||
config.FileLocation, 100, true)),
|
||||
}
|
||||
if !config.FileJson {
|
||||
t.Format = "plain"
|
||||
}
|
||||
if tgt, err := NewLogrTarget("mlogFile", t); err == nil {
|
||||
logger.logrLogger.Logr().AddTarget(tgt)
|
||||
} else {
|
||||
Error("error creating mlogFile", Err(err))
|
||||
}
|
||||
} else {
|
||||
writer := zapcore.AddSync(&lumberjack.Logger{
|
||||
Filename: config.FileLocation,
|
||||
MaxSize: 100,
|
||||
Compress: true,
|
||||
})
|
||||
|
||||
core := zapcore.NewCore(makeEncoder(config.FileJson), writer, logger.fileLevel)
|
||||
cores = append(cores, core)
|
||||
}
|
||||
}
|
||||
|
||||
combinedCore := zapcore.NewTee(cores...)
|
||||
@ -107,7 +149,6 @@ func NewLogger(config *LoggerConfiguration) *Logger {
|
||||
logger.zap = zap.New(combinedCore,
|
||||
zap.AddCaller(),
|
||||
)
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
@ -123,6 +164,10 @@ func (l *Logger) SetConsoleLevel(level string) {
|
||||
func (l *Logger) With(fields ...Field) *Logger {
|
||||
newlogger := *l
|
||||
newlogger.zap = newlogger.zap.With(fields...)
|
||||
if newlogger.logrLogger != nil {
|
||||
ll := newlogger.logrLogger.WithFields(zapToLogr(fields))
|
||||
newlogger.logrLogger = &ll
|
||||
}
|
||||
return &newlogger
|
||||
}
|
||||
|
||||
@ -161,20 +206,120 @@ func (l *Logger) Sugar() *SugarLogger {
|
||||
|
||||
func (l *Logger) Debug(message string, fields ...Field) {
|
||||
l.zap.Debug(message, fields...)
|
||||
if isLevelEnabled(l.logrLogger, logr.Debug) {
|
||||
l.logrLogger.WithFields(zapToLogr(fields)).Debug(message)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Info(message string, fields ...Field) {
|
||||
l.zap.Info(message, fields...)
|
||||
if isLevelEnabled(l.logrLogger, logr.Info) {
|
||||
l.logrLogger.WithFields(zapToLogr(fields)).Info(message)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Warn(message string, fields ...Field) {
|
||||
l.zap.Warn(message, fields...)
|
||||
if isLevelEnabled(l.logrLogger, logr.Warn) {
|
||||
l.logrLogger.WithFields(zapToLogr(fields)).Warn(message)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Error(message string, fields ...Field) {
|
||||
l.zap.Error(message, fields...)
|
||||
if isLevelEnabled(l.logrLogger, logr.Error) {
|
||||
l.logrLogger.WithFields(zapToLogr(fields)).Error(message)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Critical(message string, fields ...Field) {
|
||||
l.zap.Error(message, fields...)
|
||||
if isLevelEnabled(l.logrLogger, logr.Error) {
|
||||
l.logrLogger.WithFields(zapToLogr(fields)).Error(message)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Log(level LogLevel, message string, fields ...Field) {
|
||||
l.logrLogger.WithFields(zapToLogr(fields)).Log(logr.Level(level), message)
|
||||
}
|
||||
|
||||
func (l *Logger) LogM(levels []LogLevel, message string, fields ...Field) {
|
||||
var logger *logr.Logger
|
||||
for _, lvl := range levels {
|
||||
if isLevelEnabled(l.logrLogger, logr.Level(lvl)) {
|
||||
// don't create logger with fields unless at least one level is active.
|
||||
if logger == nil {
|
||||
l := l.logrLogger.WithFields(zapToLogr(fields))
|
||||
logger = &l
|
||||
}
|
||||
logger.Log(logr.Level(lvl), message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Flush(cxt context.Context) error {
|
||||
return l.logrLogger.Logr().FlushWithTimeout(cxt)
|
||||
}
|
||||
|
||||
// ShutdownAdvancedLogging stops the logger from accepting new log records and tries to
|
||||
// flush queues within the context timeout. Once complete all targets are shutdown
|
||||
// and any resources released.
|
||||
func (l *Logger) ShutdownAdvancedLogging(cxt context.Context) error {
|
||||
err := l.logrLogger.Logr().ShutdownWithTimeout(cxt)
|
||||
l.logrLogger = newLogr()
|
||||
return err
|
||||
}
|
||||
|
||||
// ConfigAdvancedLoggingConfig (re)configures advanced logging based on the
|
||||
// specified log targets. This is the easiest way to get the advanced logger
|
||||
// configured via a config source such as file.
|
||||
func (l *Logger) ConfigAdvancedLogging(targets LogTargetCfg) error {
|
||||
if err := l.ShutdownAdvancedLogging(context.Background()); err != nil {
|
||||
Error("error shutting down previous logger", Err(err))
|
||||
}
|
||||
|
||||
err := logrAddTargets(l.logrLogger, targets)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddTarget adds one or more logr.Target to the advanced logger. This is the preferred method
|
||||
// to add custom targets or provide configuration that cannot be expressed via a
|
||||
// config source.
|
||||
func (l *Logger) AddTarget(targets ...logr.Target) error {
|
||||
return l.logrLogger.Logr().AddTarget(targets...)
|
||||
}
|
||||
|
||||
// RemoveTargets selectively removes targets that were previously added to this logger instance
|
||||
// using the passed in filter function. The filter function should return true to remove the target
|
||||
// and false to keep it.
|
||||
func (l *Logger) RemoveTargets(ctx context.Context, f func(ti TargetInfo) bool) error {
|
||||
// Use locally defined TargetInfo type so we don't spread Logr dependencies.
|
||||
fc := func(tic logr.TargetInfo) bool {
|
||||
return f(TargetInfo(tic))
|
||||
}
|
||||
return l.logrLogger.Logr().RemoveTargets(ctx, fc)
|
||||
}
|
||||
|
||||
// EnableMetrics enables metrics collection by supplying a MetricsCollector.
|
||||
// The MetricsCollector provides counters and gauges that are updated by log targets.
|
||||
func (l *Logger) EnableMetrics(collector logr.MetricsCollector) error {
|
||||
return l.logrLogger.Logr().SetMetricsCollector(collector)
|
||||
}
|
||||
|
||||
// DisableZap is called to disable Zap, and Logr will be used instead. Any Logger
|
||||
// instances created after this call will only use Logr.
|
||||
//
|
||||
// This is needed for unit testing as Zap has no shutdown capabilities
|
||||
// and holds file handles until process exit. Currently unit tests create
|
||||
// many server instances, and thus many Zap log file handles.
|
||||
//
|
||||
// This method will be removed when Zap is permanently replaced.
|
||||
func DisableZap() {
|
||||
atomic.StoreInt32(&disableZap, 1)
|
||||
}
|
||||
|
||||
// EnableZap re-enables Zap such that any Logger instances created after this
|
||||
// call will allow Zap targets.
|
||||
func EnableZap() {
|
||||
atomic.StoreInt32(&disableZap, 0)
|
||||
}
|
||||
|
247
vendor/github.com/mattermost/mattermost-server/v5/mlog/logr.go
generated
vendored
Normal file
247
vendor/github.com/mattermost/mattermost-server/v5/mlog/logr.go
generated
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/mattermost/logr"
|
||||
logrFmt "github.com/mattermost/logr/format"
|
||||
"github.com/mattermost/logr/target"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultMaxTargetQueue = 1000
|
||||
DefaultSysLogPort = 514
|
||||
)
|
||||
|
||||
type LogLevel struct {
|
||||
ID logr.LevelID
|
||||
Name string
|
||||
Stacktrace bool
|
||||
}
|
||||
|
||||
type LogTarget struct {
|
||||
Type string // one of "console", "file", "tcp", "syslog", "none".
|
||||
Format string // one of "json", "plain"
|
||||
Levels []LogLevel
|
||||
Options json.RawMessage
|
||||
MaxQueueSize int
|
||||
}
|
||||
|
||||
type LogTargetCfg map[string]*LogTarget
|
||||
type LogrCleanup func() error
|
||||
|
||||
func newLogr() *logr.Logger {
|
||||
lgr := &logr.Logr{}
|
||||
lgr.OnExit = func(int) {}
|
||||
lgr.OnPanic = func(interface{}) {}
|
||||
lgr.OnLoggerError = onLoggerError
|
||||
lgr.OnQueueFull = onQueueFull
|
||||
lgr.OnTargetQueueFull = onTargetQueueFull
|
||||
|
||||
logger := lgr.NewLogger()
|
||||
return &logger
|
||||
}
|
||||
|
||||
func logrAddTargets(logger *logr.Logger, targets LogTargetCfg) error {
|
||||
lgr := logger.Logr()
|
||||
var errs error
|
||||
for name, t := range targets {
|
||||
target, err := NewLogrTarget(name, t)
|
||||
if err != nil {
|
||||
errs = multierror.Append(err)
|
||||
continue
|
||||
}
|
||||
if target != nil {
|
||||
target.SetName(name)
|
||||
lgr.AddTarget(target)
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// NewLogrTarget creates a `logr.Target` based on a target config.
|
||||
// Can be used when parsing custom config files, or when programmatically adding
|
||||
// built-in targets. Use `mlog.AddTarget` to add custom targets.
|
||||
func NewLogrTarget(name string, t *LogTarget) (logr.Target, error) {
|
||||
formatter, err := newFormatter(name, t.Format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filter, err := newFilter(name, t.Levels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if t.MaxQueueSize == 0 {
|
||||
t.MaxQueueSize = DefaultMaxTargetQueue
|
||||
}
|
||||
|
||||
switch t.Type {
|
||||
case "console":
|
||||
return newConsoleTarget(name, t, filter, formatter)
|
||||
case "file":
|
||||
return newFileTarget(name, t, filter, formatter)
|
||||
case "syslog":
|
||||
return newSyslogTarget(name, t, filter, formatter)
|
||||
case "tcp":
|
||||
return newTCPTarget(name, t, filter, formatter)
|
||||
case "none":
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid type '%s' for target %s", t.Type, name)
|
||||
}
|
||||
|
||||
func newFilter(name string, levels []LogLevel) (logr.Filter, error) {
|
||||
filter := &logr.CustomFilter{}
|
||||
for _, lvl := range levels {
|
||||
filter.Add(logr.Level(lvl))
|
||||
}
|
||||
return filter, nil
|
||||
}
|
||||
|
||||
func newFormatter(name string, format string) (logr.Formatter, error) {
|
||||
switch format {
|
||||
case "json", "":
|
||||
return &logrFmt.JSON{}, nil
|
||||
case "plain":
|
||||
return &logrFmt.Plain{Delim: " | "}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid format '%s' for target %s", format, name)
|
||||
}
|
||||
}
|
||||
|
||||
func newConsoleTarget(name string, t *LogTarget, filter logr.Filter, formatter logr.Formatter) (logr.Target, error) {
|
||||
type consoleOptions struct {
|
||||
Out string `json:"Out"`
|
||||
}
|
||||
options := &consoleOptions{}
|
||||
if err := json.Unmarshal(t.Options, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var w io.Writer
|
||||
switch options.Out {
|
||||
case "stdout", "":
|
||||
w = os.Stdout
|
||||
case "stderr":
|
||||
w = os.Stderr
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid out '%s' for target %s", options.Out, name)
|
||||
}
|
||||
|
||||
newTarget := target.NewWriterTarget(filter, formatter, w, t.MaxQueueSize)
|
||||
return newTarget, nil
|
||||
}
|
||||
|
||||
func newFileTarget(name string, t *LogTarget, filter logr.Filter, formatter logr.Formatter) (logr.Target, error) {
|
||||
type fileOptions struct {
|
||||
Filename string `json:"Filename"`
|
||||
MaxSize int `json:"MaxSizeMB"`
|
||||
MaxAge int `json:"MaxAgeDays"`
|
||||
MaxBackups int `json:"MaxBackups"`
|
||||
Compress bool `json:"Compress"`
|
||||
}
|
||||
options := &fileOptions{}
|
||||
if err := json.Unmarshal(t.Options, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newFileTargetWithOpts(name, t, target.FileOptions(*options), filter, formatter)
|
||||
}
|
||||
|
||||
func newFileTargetWithOpts(name string, t *LogTarget, opts target.FileOptions, filter logr.Filter, formatter logr.Formatter) (logr.Target, error) {
|
||||
if opts.Filename == "" {
|
||||
return nil, fmt.Errorf("missing 'Filename' option for target %s", name)
|
||||
}
|
||||
if err := checkFileWritable(opts.Filename); err != nil {
|
||||
return nil, fmt.Errorf("error writing to 'Filename' for target %s: %w", name, err)
|
||||
}
|
||||
|
||||
newTarget := target.NewFileTarget(filter, formatter, opts, t.MaxQueueSize)
|
||||
return newTarget, nil
|
||||
}
|
||||
|
||||
func newSyslogTarget(name string, t *LogTarget, filter logr.Filter, formatter logr.Formatter) (logr.Target, error) {
|
||||
options := &SyslogParams{}
|
||||
if err := json.Unmarshal(t.Options, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if options.IP == "" {
|
||||
return nil, fmt.Errorf("missing 'IP' option for target %s", name)
|
||||
}
|
||||
if options.Port == 0 {
|
||||
options.Port = DefaultSysLogPort
|
||||
}
|
||||
return NewSyslogTarget(filter, formatter, options, t.MaxQueueSize)
|
||||
}
|
||||
|
||||
func newTCPTarget(name string, t *LogTarget, filter logr.Filter, formatter logr.Formatter) (logr.Target, error) {
|
||||
options := &TcpParams{}
|
||||
if err := json.Unmarshal(t.Options, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if options.IP == "" {
|
||||
return nil, fmt.Errorf("missing 'IP' option for target %s", name)
|
||||
}
|
||||
if options.Port == 0 {
|
||||
return nil, fmt.Errorf("missing 'Port' option for target %s", name)
|
||||
}
|
||||
return NewTcpTarget(filter, formatter, options, t.MaxQueueSize)
|
||||
}
|
||||
|
||||
func checkFileWritable(filename string) error {
|
||||
// try opening/creating the file for writing
|
||||
file, err := os.OpenFile(filename, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func isLevelEnabled(logger *logr.Logger, level logr.Level) bool {
|
||||
if logger == nil || logger.Logr() == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
status := logger.Logr().IsLevelEnabled(level)
|
||||
return status.Enabled
|
||||
}
|
||||
|
||||
// zapToLogr converts Zap fields to Logr fields.
|
||||
// This will not be needed once Logr is used for all logging.
|
||||
func zapToLogr(zapFields []Field) logr.Fields {
|
||||
encoder := zapcore.NewMapObjectEncoder()
|
||||
for _, zapField := range zapFields {
|
||||
zapField.AddTo(encoder)
|
||||
}
|
||||
return logr.Fields(encoder.Fields)
|
||||
}
|
||||
|
||||
// mlogLevelToLogrLevel converts a mlog logger level to
|
||||
// an array of discrete Logr levels.
|
||||
func mlogLevelToLogrLevels(level string) []LogLevel {
|
||||
levels := make([]LogLevel, 0)
|
||||
levels = append(levels, LvlError, LvlPanic, LvlFatal, LvlStdLog)
|
||||
|
||||
switch level {
|
||||
case LevelDebug:
|
||||
levels = append(levels, LvlDebug)
|
||||
fallthrough
|
||||
case LevelInfo:
|
||||
levels = append(levels, LvlInfo)
|
||||
fallthrough
|
||||
case LevelWarn:
|
||||
levels = append(levels, LvlWarn)
|
||||
}
|
||||
return levels
|
||||
}
|
142
vendor/github.com/mattermost/mattermost-server/v5/mlog/syslog.go
generated
vendored
Normal file
142
vendor/github.com/mattermost/mattermost-server/v5/mlog/syslog.go
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/mattermost/logr"
|
||||
"github.com/wiggin77/merror"
|
||||
syslog "github.com/wiggin77/srslog"
|
||||
)
|
||||
|
||||
// Syslog outputs log records to local or remote syslog.
|
||||
type Syslog struct {
|
||||
logr.Basic
|
||||
w *syslog.Writer
|
||||
}
|
||||
|
||||
// SyslogParams provides parameters for dialing a syslog daemon.
|
||||
type SyslogParams struct {
|
||||
IP string `json:"IP"`
|
||||
Port int `json:"Port"`
|
||||
Tag string `json:"Tag"`
|
||||
TLS bool `json:"TLS"`
|
||||
Cert string `json:"Cert"`
|
||||
Insecure bool `json:"Insecure"`
|
||||
}
|
||||
|
||||
// NewSyslogTarget creates a target capable of outputting log records to remote or local syslog, with or without TLS.
|
||||
func NewSyslogTarget(filter logr.Filter, formatter logr.Formatter, params *SyslogParams, maxQueue int) (*Syslog, error) {
|
||||
network := "tcp"
|
||||
var config *tls.Config
|
||||
|
||||
if params.TLS {
|
||||
network = "tcp+tls"
|
||||
config = &tls.Config{InsecureSkipVerify: params.Insecure}
|
||||
if params.Cert != "" {
|
||||
pool, err := getCertPool(params.Cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.RootCAs = pool
|
||||
}
|
||||
}
|
||||
raddr := fmt.Sprintf("%s:%d", params.IP, params.Port)
|
||||
|
||||
writer, err := syslog.DialWithTLSConfig(network, raddr, syslog.LOG_INFO, params.Tag, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &Syslog{w: writer}
|
||||
s.Basic.Start(s, s, filter, formatter, maxQueue)
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Shutdown stops processing log records after making best effort to flush queue.
|
||||
func (s *Syslog) Shutdown(ctx context.Context) error {
|
||||
errs := merror.New()
|
||||
|
||||
err := s.Basic.Shutdown(ctx)
|
||||
errs.Append(err)
|
||||
|
||||
err = s.w.Close()
|
||||
errs.Append(err)
|
||||
|
||||
return errs.ErrorOrNil()
|
||||
}
|
||||
|
||||
// getCertPool returns a x509.CertPool containing the cert(s)
|
||||
// from `cert`, which can be a path to a .pem or .crt file,
|
||||
// or a base64 encoded cert.
|
||||
func getCertPool(cert string) (*x509.CertPool, error) {
|
||||
if cert == "" {
|
||||
return nil, errors.New("no cert provided")
|
||||
}
|
||||
|
||||
// first treat as a file and try to read.
|
||||
serverCert, err := ioutil.ReadFile(cert)
|
||||
if err != nil {
|
||||
// maybe it's a base64 encoded cert
|
||||
serverCert, err = base64.StdEncoding.DecodeString(cert)
|
||||
if err != nil {
|
||||
return nil, errors.New("cert cannot be read")
|
||||
}
|
||||
}
|
||||
|
||||
pool := x509.NewCertPool()
|
||||
if ok := pool.AppendCertsFromPEM(serverCert); ok {
|
||||
return pool, nil
|
||||
}
|
||||
return nil, errors.New("cannot parse cert")
|
||||
}
|
||||
|
||||
// Write converts the log record to bytes, via the Formatter,
|
||||
// and outputs to syslog.
|
||||
func (s *Syslog) Write(rec *logr.LogRec) error {
|
||||
_, stacktrace := s.IsLevelEnabled(rec.Level())
|
||||
|
||||
buf := rec.Logger().Logr().BorrowBuffer()
|
||||
defer rec.Logger().Logr().ReleaseBuffer(buf)
|
||||
|
||||
buf, err := s.Formatter().Format(rec, stacktrace, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
txt := buf.String()
|
||||
|
||||
switch rec.Level() {
|
||||
case logr.Panic, logr.Fatal:
|
||||
err = s.w.Crit(txt)
|
||||
case logr.Error:
|
||||
err = s.w.Err(txt)
|
||||
case logr.Warn:
|
||||
err = s.w.Warning(txt)
|
||||
case logr.Debug, logr.Trace:
|
||||
err = s.w.Debug(txt)
|
||||
default:
|
||||
// logr.Info plus all custom levels.
|
||||
err = s.w.Info(txt)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
reporter := rec.Logger().Logr().ReportError
|
||||
reporter(fmt.Errorf("syslog write fail: %w", err))
|
||||
// syslog writer will try to reconnect.
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns a string representation of this target.
|
||||
func (s *Syslog) String() string {
|
||||
return "SyslogTarget"
|
||||
}
|
274
vendor/github.com/mattermost/mattermost-server/v5/mlog/tcp.go
generated
vendored
Normal file
274
vendor/github.com/mattermost/mattermost-server/v5/mlog/tcp.go
generated
vendored
Normal file
@ -0,0 +1,274 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/mattermost/logr"
|
||||
|
||||
_ "net/http/pprof"
|
||||
)
|
||||
|
||||
const (
|
||||
DialTimeoutSecs = 30
|
||||
WriteTimeoutSecs = 30
|
||||
RetryBackoffMillis int64 = 100
|
||||
MaxRetryBackoffMillis int64 = 30 * 1000 // 30 seconds
|
||||
)
|
||||
|
||||
// Tcp outputs log records to raw socket server.
|
||||
type Tcp struct {
|
||||
logr.Basic
|
||||
|
||||
params *TcpParams
|
||||
addy string
|
||||
|
||||
mutex sync.Mutex
|
||||
conn net.Conn
|
||||
monitor chan struct{}
|
||||
shutdown chan struct{}
|
||||
}
|
||||
|
||||
// TcpParams provides parameters for dialing a socket server.
|
||||
type TcpParams struct {
|
||||
IP string `json:"IP"`
|
||||
Port int `json:"Port"`
|
||||
TLS bool `json:"TLS"`
|
||||
Cert string `json:"Cert"`
|
||||
Insecure bool `json:"Insecure"`
|
||||
}
|
||||
|
||||
// NewTcpTarget creates a target capable of outputting log records to a raw socket, with or without TLS.
|
||||
func NewTcpTarget(filter logr.Filter, formatter logr.Formatter, params *TcpParams, maxQueue int) (*Tcp, error) {
|
||||
tcp := &Tcp{
|
||||
params: params,
|
||||
addy: fmt.Sprintf("%s:%d", params.IP, params.Port),
|
||||
monitor: make(chan struct{}),
|
||||
shutdown: make(chan struct{}),
|
||||
}
|
||||
tcp.Basic.Start(tcp, tcp, filter, formatter, maxQueue)
|
||||
|
||||
return tcp, nil
|
||||
}
|
||||
|
||||
// getConn provides a net.Conn. If a connection already exists, it is returned immediately,
|
||||
// otherwise this method blocks until a new connection is created, timeout or shutdown.
|
||||
func (tcp *Tcp) getConn() (net.Conn, error) {
|
||||
tcp.mutex.Lock()
|
||||
defer tcp.mutex.Unlock()
|
||||
|
||||
Log(LvlTcpLogTarget, "getConn enter", String("addy", tcp.addy))
|
||||
defer Log(LvlTcpLogTarget, "getConn exit", String("addy", tcp.addy))
|
||||
|
||||
if tcp.conn != nil {
|
||||
Log(LvlTcpLogTarget, "reusing existing conn", String("addy", tcp.addy)) // use "With" once Zap is removed
|
||||
return tcp.conn, nil
|
||||
}
|
||||
|
||||
type result struct {
|
||||
conn net.Conn
|
||||
err error
|
||||
}
|
||||
|
||||
connChan := make(chan result)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*DialTimeoutSecs)
|
||||
defer cancel()
|
||||
|
||||
go func(ctx context.Context, ch chan result) {
|
||||
Log(LvlTcpLogTarget, "dailing", String("addy", tcp.addy))
|
||||
conn, err := tcp.dial(ctx)
|
||||
if err == nil {
|
||||
tcp.conn = conn
|
||||
tcp.monitor = make(chan struct{})
|
||||
go monitor(tcp.conn, tcp.monitor)
|
||||
}
|
||||
connChan <- result{conn: conn, err: err}
|
||||
}(ctx, connChan)
|
||||
|
||||
select {
|
||||
case <-tcp.shutdown:
|
||||
return nil, errors.New("shutdown")
|
||||
case res := <-connChan:
|
||||
return res.conn, res.err
|
||||
}
|
||||
}
|
||||
|
||||
// dial connects to a TCP socket, and optionally performs a TLS handshake.
|
||||
// A non-nil context must be provided which can cancel the dial.
|
||||
func (tcp *Tcp) dial(ctx context.Context) (net.Conn, error) {
|
||||
var dialer net.Dialer
|
||||
dialer.Timeout = time.Second * DialTimeoutSecs
|
||||
conn, err := dialer.DialContext(ctx, "tcp", fmt.Sprintf("%s:%d", tcp.params.IP, tcp.params.Port))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !tcp.params.TLS {
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
Log(LvlTcpLogTarget, "TLS handshake", String("addy", tcp.addy))
|
||||
|
||||
tlsconfig := &tls.Config{
|
||||
ServerName: tcp.params.IP,
|
||||
InsecureSkipVerify: tcp.params.Insecure,
|
||||
}
|
||||
if tcp.params.Cert != "" {
|
||||
pool, err := getCertPool(tcp.params.Cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsconfig.RootCAs = pool
|
||||
}
|
||||
|
||||
tlsConn := tls.Client(conn, tlsconfig)
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tlsConn, nil
|
||||
}
|
||||
|
||||
func (tcp *Tcp) close() error {
|
||||
tcp.mutex.Lock()
|
||||
defer tcp.mutex.Unlock()
|
||||
|
||||
var err error
|
||||
if tcp.conn != nil {
|
||||
Log(LvlTcpLogTarget, "closing connection", String("addy", tcp.addy))
|
||||
close(tcp.monitor)
|
||||
err = tcp.conn.Close()
|
||||
tcp.conn = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Shutdown stops processing log records after making best effort to flush queue.
|
||||
func (tcp *Tcp) Shutdown(ctx context.Context) error {
|
||||
errs := &multierror.Error{}
|
||||
|
||||
Log(LvlTcpLogTarget, "shutting down", String("addy", tcp.addy))
|
||||
|
||||
if err := tcp.Basic.Shutdown(ctx); err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
|
||||
if err := tcp.close(); err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
|
||||
close(tcp.shutdown)
|
||||
return errs.ErrorOrNil()
|
||||
}
|
||||
|
||||
// Write converts the log record to bytes, via the Formatter, and outputs to the socket.
|
||||
// Called by dedicated target goroutine and will block until success or shutdown.
|
||||
func (tcp *Tcp) Write(rec *logr.LogRec) error {
|
||||
_, stacktrace := tcp.IsLevelEnabled(rec.Level())
|
||||
|
||||
buf := rec.Logger().Logr().BorrowBuffer()
|
||||
defer rec.Logger().Logr().ReleaseBuffer(buf)
|
||||
|
||||
buf, err := tcp.Formatter().Format(rec, stacktrace, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
try := 1
|
||||
backoff := RetryBackoffMillis
|
||||
for {
|
||||
select {
|
||||
case <-tcp.shutdown:
|
||||
return err
|
||||
default:
|
||||
}
|
||||
|
||||
conn, err := tcp.getConn()
|
||||
if err != nil {
|
||||
Log(LvlTcpLogTarget, "failed getting connection", String("addy", tcp.addy), Err(err))
|
||||
reporter := rec.Logger().Logr().ReportError
|
||||
reporter(fmt.Errorf("log target %s connection error: %w", tcp.String(), err))
|
||||
backoff = tcp.sleep(backoff)
|
||||
continue
|
||||
}
|
||||
|
||||
conn.SetWriteDeadline(time.Now().Add(time.Second * WriteTimeoutSecs))
|
||||
_, err = buf.WriteTo(conn)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
Log(LvlTcpLogTarget, "write error", String("addy", tcp.addy), Err(err))
|
||||
reporter := rec.Logger().Logr().ReportError
|
||||
reporter(fmt.Errorf("log target %s write error: %w", tcp.String(), err))
|
||||
|
||||
_ = tcp.close()
|
||||
|
||||
backoff = tcp.sleep(backoff)
|
||||
try++
|
||||
Log(LvlTcpLogTarget, "retrying write", String("addy", tcp.addy), Int("try", try))
|
||||
}
|
||||
}
|
||||
|
||||
// monitor continuously tries to read from the connection to detect socket close.
|
||||
// This is needed because TCP target uses a write only socket and Linux systems
|
||||
// take a long time to detect a loss of connectivity on a socket when only writing;
|
||||
// the writes simply fail without an error returned.
|
||||
func monitor(conn net.Conn, done <-chan struct{}) {
|
||||
addy := conn.RemoteAddr().String()
|
||||
defer Log(LvlTcpLogTarget, "monitor exiting", String("addy", addy))
|
||||
|
||||
buf := make([]byte, 1)
|
||||
for {
|
||||
Log(LvlTcpLogTarget, "monitor loop", String("addy", addy))
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case <-time.After(1 * time.Second):
|
||||
}
|
||||
|
||||
err := conn.SetReadDeadline(time.Now().Add(time.Second * 30))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = conn.Read(buf)
|
||||
|
||||
if errt, ok := err.(net.Error); ok && errt.Timeout() {
|
||||
// read timeout is expected, keep looping.
|
||||
continue
|
||||
}
|
||||
|
||||
// Any other error closes the connection, forcing a reconnect.
|
||||
Log(LvlTcpLogTarget, "monitor closing connection", Err(err))
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// String returns a string representation of this target.
|
||||
func (tcp *Tcp) String() string {
|
||||
return fmt.Sprintf("TcpTarget[%s:%d]", tcp.params.IP, tcp.params.Port)
|
||||
}
|
||||
|
||||
func (tcp *Tcp) sleep(backoff int64) int64 {
|
||||
select {
|
||||
case <-tcp.shutdown:
|
||||
case <-time.After(time.Millisecond * time.Duration(backoff)):
|
||||
}
|
||||
|
||||
nextBackoff := backoff + (backoff >> 1)
|
||||
if nextBackoff > MaxRetryBackoffMillis {
|
||||
nextBackoff = MaxRetryBackoffMillis
|
||||
}
|
||||
return nextBackoff
|
||||
}
|
43
vendor/github.com/mattermost/mattermost-server/v5/mlog/test-tls-client-cert.pem
generated
vendored
Normal file
43
vendor/github.com/mattermost/mattermost-server/v5/mlog/test-tls-client-cert.pem
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDjzCCAnegAwIBAgIRAPYfRSwdzKopBKxYxKqslJUwDQYJKoZIhvcNAQELBQAw
|
||||
JzElMCMGA1UEAwwcTWF0dGVybW9zdCwgSW5jLiBJbnRlcm5hbCBDQTAeFw0xOTAz
|
||||
MjIwMDE0MTVaFw0yMjAzMDYwMDE0MTVaMDsxOTA3BgNVBAMTME1hdHRlcm1vc3Qs
|
||||
IEluYy4gSW50ZXJuYWwgSW50ZXJtZWRpYXRlIEF1dGhvcml0eTCCASIwDQYJKoZI
|
||||
hvcNAQEBBQADggEPADCCAQoCggEBAMjliRdmvnNL4u/Jr/M2dPwQmTJXEBY/Vq9Q
|
||||
vAU52X3tRMCPxcaFz+x6ftuvdO2NdohXGAmtx9QU5LZcvFeTDpoVEBo9A+4jtLvD
|
||||
DZYaTNLpJmoSoJHaDbdWX+OAOqyDiWS741LuiMKWHhew9QOisat2ZINPxjmAd9wE
|
||||
xthTMgzsv7MUqnMer8U5OGQ0Qy7wAmNRc+2K3qPwkxe2RUvcte50DUFNgxEginsh
|
||||
vrkOXR383vUCZfu72qu8oggjiQpyTllu5je2Ap6JLjYLkEMiMqrYADuWor/ZHwa6
|
||||
WrFqVETxWfAV5u9Eh0wZM/KKYwRQuw9y+Nans77FmUl1tVWWNN8CAwEAAaOBoTCB
|
||||
njAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBQY4Uqswyr2hO/HetZt2RDxJdTIPjBi
|
||||
BgNVHSMEWzBZgBRFZXVg2Z5tNIsWeWjBLEy2yzKbMKErpCkwJzElMCMGA1UEAwwc
|
||||
TWF0dGVybW9zdCwgSW5jLiBJbnRlcm5hbCBDQYIUEifGUOM+bIFZo1tkjZB5YGBr
|
||||
0xEwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAEdexL30Q0zBHmPAH8
|
||||
LhdK7dbzW1CmILbxRZlKAwRN+hKRXiMW3MHIkhNuoV9Aev602Q+ja4lWsRi/ktOL
|
||||
ni1FWx5gSScgdG8JGj47dOmoT3vXKX7+umiv4rQLPDl9/DKMuv204OYJq6VT+uNU
|
||||
6C6kL157jGJEO76H4fMZ8oYsD7Sq0zjiNKtuCYii0ngH3j3gB1jACLqRgveU7MdT
|
||||
pqOV2KfY31+h8VBtkUvljNztQ9xNY8Fjmt0SMf7E3FaUcaar3ZCr70G5aU3dKbe7
|
||||
47vGOBa5tCqw4YK0jgDKid3IJQul9a3J1mSsH8Wy3to9cAV4KGZBQLnzCX15a/+v
|
||||
3yVh
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDfjCCAmagAwIBAgIUEifGUOM+bIFZo1tkjZB5YGBr0xEwDQYJKoZIhvcNAQEL
|
||||
BQAwJzElMCMGA1UEAwwcTWF0dGVybW9zdCwgSW5jLiBJbnRlcm5hbCBDQTAeFw0x
|
||||
OTAzMjEyMTI4NDNaFw0yOTAzMTgyMTI4NDNaMCcxJTAjBgNVBAMMHE1hdHRlcm1v
|
||||
c3QsIEluYy4gSW50ZXJuYWwgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQDH0Xq5rMBGpKOVWTpb5MnaJIWFP/vOtvEk+7hVrfOfe1/5x0Kk3UgAHj85
|
||||
otaEZD1Lhn/JLkEqCiE/UXMJFwJDlNcO4CkdKBSpYX4bKAqy5q/X3QwioMSNpJG1
|
||||
+YYrNGBH0sgKcKjyCaLhmqYLD0xZDVOmWIYBU9jUPyXw5U0tnsVrTqGMxVkm1xCY
|
||||
krCWN1ZoUrLvL0MCZc5qpxoPTopr9UO9cqSBSuy6BVWVuEWBZhpqHt+ul8VxhzzY
|
||||
q1k4l7r2qw+/wm1iJBedTeBVeWNag8JaVfLgu+/W7oJVlPO32Po7pnvHp8iJ3b4K
|
||||
zXyVHaTX4S6Em+6LV8855TYrShzlAgMBAAGjgaEwgZ4wHQYDVR0OBBYEFEVldWDZ
|
||||
nm00ixZ5aMEsTLbLMpswMGIGA1UdIwRbMFmAFEVldWDZnm00ixZ5aMEsTLbLMpsw
|
||||
oSukKTAnMSUwIwYDVQQDDBxNYXR0ZXJtb3N0LCBJbmMuIEludGVybmFsIENBghQS
|
||||
J8ZQ4z5sgVmjW2SNkHlgYGvTETAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAN
|
||||
BgkqhkiG9w0BAQsFAAOCAQEAPiCWFmopyAkY2T3Zyo4yaRPhX1+VOTMKJtY6EUhq
|
||||
/GHz6kzEyvCUBf0N892cibGxekrEoItY9NqO6RQRfowg+Gn5kc13z4NyL2W8/eoT
|
||||
Xy0ZvfaQbU++fQ6pVtWtMblDMU9xiYd7/MDvJpO328l1Vhcdp8kEi+lCvpy0sCRc
|
||||
PxzPhbgCMAbZEGx+4TMQd4SZKzlRxW/2fflpReh6v1Dv0VDUSYQWwsUnaLpdKHfh
|
||||
a5k0vuySYcszE4YKlY0zakeFlJfp7fBp1xTwcdW8aTfw15EicPMwTc6xxA4JJUJx
|
||||
cddu817n1nayK5u6r9Qh1oIVkr0nC9YELMMy4dpPgJ88SA==
|
||||
-----END CERTIFICATE-----
|
3
vendor/github.com/mattermost/mattermost-server/v5/mlog/testing.go
generated
vendored
3
vendor/github.com/mattermost/mattermost-server/v5/mlog/testing.go
generated
vendored
@ -32,9 +32,10 @@ func NewTestingLogger(tb testing.TB, writer io.Writer) *Logger {
|
||||
testingLogger := &Logger{
|
||||
consoleLevel: zap.NewAtomicLevelAt(getZapLevel("debug")),
|
||||
fileLevel: zap.NewAtomicLevelAt(getZapLevel("info")),
|
||||
logrLogger: newLogr(),
|
||||
}
|
||||
|
||||
logWriterCore := zapcore.NewCore(makeEncoder(true), logWriterSync, testingLogger.consoleLevel)
|
||||
logWriterCore := zapcore.NewCore(makeEncoder(true), zapcore.Lock(logWriterSync), testingLogger.consoleLevel)
|
||||
|
||||
testingLogger.zap = zap.New(logWriterCore,
|
||||
zap.AddCaller(),
|
||||
|
7
vendor/github.com/mattermost/mattermost-server/v5/model/bot.go
generated
vendored
7
vendor/github.com/mattermost/mattermost-server/v5/model/bot.go
generated
vendored
@ -13,9 +13,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
BOT_DISPLAY_NAME_MAX_RUNES = USER_FIRST_NAME_MAX_RUNES
|
||||
BOT_DESCRIPTION_MAX_RUNES = 1024
|
||||
BOT_CREATOR_ID_MAX_RUNES = KEY_VALUE_PLUGIN_ID_MAX_RUNES // UserId or PluginId
|
||||
BOT_DISPLAY_NAME_MAX_RUNES = USER_FIRST_NAME_MAX_RUNES
|
||||
BOT_DESCRIPTION_MAX_RUNES = 1024
|
||||
BOT_CREATOR_ID_MAX_RUNES = KEY_VALUE_PLUGIN_ID_MAX_RUNES // UserId or PluginId
|
||||
BOT_WARN_METRIC_BOT_USERNAME = "mattermost-advisor"
|
||||
)
|
||||
|
||||
// Bot is a special type of User meant for programmatic interactions.
|
||||
|
18
vendor/github.com/mattermost/mattermost-server/v5/model/channel.go
generated
vendored
18
vendor/github.com/mattermost/mattermost-server/v5/model/channel.go
generated
vendored
@ -120,12 +120,18 @@ type ChannelModeratedRolesPatch struct {
|
||||
// PerPage number of results per page, if paginated.
|
||||
//
|
||||
type ChannelSearchOpts struct {
|
||||
NotAssociatedToGroup string
|
||||
ExcludeDefaultChannels bool
|
||||
IncludeDeleted bool
|
||||
ExcludeChannelNames []string
|
||||
Page *int
|
||||
PerPage *int
|
||||
NotAssociatedToGroup string
|
||||
ExcludeDefaultChannels bool
|
||||
IncludeDeleted bool
|
||||
Deleted bool
|
||||
ExcludeChannelNames []string
|
||||
TeamIds []string
|
||||
GroupConstrained bool
|
||||
ExcludeGroupConstrained bool
|
||||
Public bool
|
||||
Private bool
|
||||
Page *int
|
||||
PerPage *int
|
||||
}
|
||||
|
||||
type ChannelMemberCountByGroup struct {
|
||||
|
@ -10,7 +10,8 @@ type ChannelMemberHistoryResult struct {
|
||||
LeaveTime *int64
|
||||
|
||||
// these two fields are never set in the database - when we SELECT, we join on Users to get them
|
||||
UserEmail string `db:"Email"`
|
||||
Username string
|
||||
IsBot bool
|
||||
UserEmail string `db:"Email"`
|
||||
Username string
|
||||
IsBot bool
|
||||
UserDeleteAt int64
|
||||
}
|
||||
|
17
vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go
generated
vendored
17
vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go
generated
vendored
@ -11,11 +11,18 @@ import (
|
||||
const CHANNEL_SEARCH_DEFAULT_LIMIT = 50
|
||||
|
||||
type ChannelSearch struct {
|
||||
Term string `json:"term"`
|
||||
ExcludeDefaultChannels bool `json:"exclude_default_channels"`
|
||||
NotAssociatedToGroup string `json:"not_associated_to_group"`
|
||||
Page *int `json:"page,omitempty"`
|
||||
PerPage *int `json:"per_page,omitempty"`
|
||||
Term string `json:"term"`
|
||||
ExcludeDefaultChannels bool `json:"exclude_default_channels"`
|
||||
NotAssociatedToGroup string `json:"not_associated_to_group"`
|
||||
TeamIds []string `json:"team_ids"`
|
||||
GroupConstrained bool `json:"group_constrained"`
|
||||
ExcludeGroupConstrained bool `json:"exclude_group_constrained"`
|
||||
Public bool `json:"public"`
|
||||
Private bool `json:"private"`
|
||||
IncludeDeleted bool `json:"include_deleted"`
|
||||
Deleted bool `json:"deleted"`
|
||||
Page *int `json:"page,omitempty"`
|
||||
PerPage *int `json:"per_page,omitempty"`
|
||||
}
|
||||
|
||||
// ToJson convert a Channel to a json string
|
||||
|
111
vendor/github.com/mattermost/mattermost-server/v5/model/channel_sidebar.go
generated
vendored
Normal file
111
vendor/github.com/mattermost/mattermost-server/v5/model/channel_sidebar.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type SidebarCategoryType string
|
||||
type SidebarCategorySorting string
|
||||
|
||||
const (
|
||||
// Each sidebar category has a 'type'. System categories are Channels, Favorites and DMs
|
||||
// All user-created categories will have type Custom
|
||||
SidebarCategoryChannels SidebarCategoryType = "channels"
|
||||
SidebarCategoryDirectMessages SidebarCategoryType = "direct_messages"
|
||||
SidebarCategoryFavorites SidebarCategoryType = "favorites"
|
||||
SidebarCategoryCustom SidebarCategoryType = "custom"
|
||||
// Increment to use when adding/reordering things in the sidebar
|
||||
MinimalSidebarSortDistance = 10
|
||||
// Default Sort Orders for categories
|
||||
DefaultSidebarSortOrderFavorites = 0
|
||||
DefaultSidebarSortOrderChannels = DefaultSidebarSortOrderFavorites + MinimalSidebarSortDistance
|
||||
DefaultSidebarSortOrderDMs = DefaultSidebarSortOrderChannels + MinimalSidebarSortDistance
|
||||
// Sorting modes
|
||||
// default for all categories except DMs (behaves like manual)
|
||||
SidebarCategorySortDefault SidebarCategorySorting = ""
|
||||
// sort manually
|
||||
SidebarCategorySortManual SidebarCategorySorting = "manual"
|
||||
// sort by recency (default for DMs)
|
||||
SidebarCategorySortRecent SidebarCategorySorting = "recent"
|
||||
// sort by display name alphabetically
|
||||
SidebarCategorySortAlphabetical SidebarCategorySorting = "alpha"
|
||||
)
|
||||
|
||||
// SidebarCategory represents the corresponding DB table
|
||||
// SortOrder is never returned to the user and only used for queries
|
||||
type SidebarCategory struct {
|
||||
Id string `json:"id"`
|
||||
UserId string `json:"user_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
SortOrder int64 `json:"-"`
|
||||
Sorting SidebarCategorySorting `json:"sorting"`
|
||||
Type SidebarCategoryType `json:"type"`
|
||||
DisplayName string `json:"display_name"`
|
||||
}
|
||||
|
||||
// SidebarCategoryWithChannels combines data from SidebarCategory table with the Channel IDs that belong to that category
|
||||
type SidebarCategoryWithChannels struct {
|
||||
SidebarCategory
|
||||
Channels []string `json:"channel_ids"`
|
||||
}
|
||||
|
||||
type SidebarCategoryOrder []string
|
||||
|
||||
// OrderedSidebarCategories combines categories, their channel IDs and an array of Category IDs, sorted
|
||||
type OrderedSidebarCategories struct {
|
||||
Categories SidebarCategoriesWithChannels `json:"categories"`
|
||||
Order SidebarCategoryOrder `json:"order"`
|
||||
}
|
||||
|
||||
type SidebarChannel struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
UserId string `json:"user_id"`
|
||||
CategoryId string `json:"category_id"`
|
||||
SortOrder int64 `json:"-"`
|
||||
}
|
||||
|
||||
type SidebarChannels []*SidebarChannel
|
||||
type SidebarCategoriesWithChannels []*SidebarCategoryWithChannels
|
||||
|
||||
func SidebarCategoryFromJson(data io.Reader) (*SidebarCategoryWithChannels, error) {
|
||||
var o *SidebarCategoryWithChannels
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
return o, err
|
||||
}
|
||||
|
||||
func SidebarCategoriesFromJson(data io.Reader) ([]*SidebarCategoryWithChannels, error) {
|
||||
var o []*SidebarCategoryWithChannels
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
return o, err
|
||||
}
|
||||
|
||||
func OrderedSidebarCategoriesFromJson(data io.Reader) (*OrderedSidebarCategories, error) {
|
||||
var o *OrderedSidebarCategories
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
return o, err
|
||||
}
|
||||
|
||||
func (o SidebarCategoryWithChannels) ToJson() []byte {
|
||||
b, _ := json.Marshal(o)
|
||||
return b
|
||||
}
|
||||
|
||||
func SidebarCategoriesWithChannelsToJson(o []*SidebarCategoryWithChannels) []byte {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return []byte("[]")
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func (o OrderedSidebarCategories) ToJson() []byte {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return []byte("[]")
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
573
vendor/github.com/mattermost/mattermost-server/v5/model/client4.go
generated
vendored
573
vendor/github.com/mattermost/mattermost-server/v5/model/client4.go
generated
vendored
@ -10,6 +10,7 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@ -61,6 +62,40 @@ type Client4 struct {
|
||||
AuthToken string
|
||||
AuthType string
|
||||
HttpHeader map[string]string // Headers to be copied over for each request
|
||||
|
||||
// TrueString is the string value sent to the server for true boolean query parameters.
|
||||
trueString string
|
||||
|
||||
// FalseString is the string value sent to the server for false boolean query parameters.
|
||||
falseString string
|
||||
}
|
||||
|
||||
// SetBoolString is a helper method for overriding how true and false query string parameters are
|
||||
// sent to the server.
|
||||
//
|
||||
// This method is only exposed for testing. It is never necessary to configure these values
|
||||
// in production.
|
||||
func (c *Client4) SetBoolString(value bool, valueStr string) {
|
||||
if value {
|
||||
c.trueString = valueStr
|
||||
} else {
|
||||
c.falseString = valueStr
|
||||
}
|
||||
}
|
||||
|
||||
// boolString builds the query string parameter for boolean values.
|
||||
func (c *Client4) boolString(value bool) string {
|
||||
if value && c.trueString != "" {
|
||||
return c.trueString
|
||||
} else if !value && c.falseString != "" {
|
||||
return c.falseString
|
||||
}
|
||||
|
||||
if value {
|
||||
return "true"
|
||||
} else {
|
||||
return "false"
|
||||
}
|
||||
}
|
||||
|
||||
func closeBody(r *http.Response) {
|
||||
@ -81,7 +116,21 @@ func (c *Client4) Must(result interface{}, resp *Response) interface{} {
|
||||
}
|
||||
|
||||
func NewAPIv4Client(url string) *Client4 {
|
||||
return &Client4{url, url + API_URL_SUFFIX, &http.Client{}, "", "", map[string]string{}}
|
||||
url = strings.TrimRight(url, "/")
|
||||
return &Client4{url, url + API_URL_SUFFIX, &http.Client{}, "", "", map[string]string{}, "", ""}
|
||||
}
|
||||
|
||||
func NewAPIv4SocketClient(socketPath string) *Client4 {
|
||||
tr := &http.Transport{
|
||||
Dial: func(network, addr string) (net.Conn, error) {
|
||||
return net.Dial("unix", socketPath)
|
||||
},
|
||||
}
|
||||
|
||||
client := NewAPIv4Client("http://_")
|
||||
client.HttpClient = &http.Client{Transport: tr}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
func BuildErrorResponse(r *http.Response, err *AppError) *Response {
|
||||
@ -140,6 +189,10 @@ func (c *Client4) GetUserRoute(userId string) string {
|
||||
return fmt.Sprintf(c.GetUsersRoute()+"/%v", userId)
|
||||
}
|
||||
|
||||
func (c *Client4) GetUserCategoryRoute(userID, teamID string) string {
|
||||
return c.GetUserRoute(userID) + c.GetTeamRoute(teamID) + "/channels/categories"
|
||||
}
|
||||
|
||||
func (c *Client4) GetUserAccessTokensRoute() string {
|
||||
return fmt.Sprintf(c.GetUsersRoute() + "/tokens")
|
||||
}
|
||||
@ -261,6 +314,14 @@ func (c *Client4) GetFileRoute(fileId string) string {
|
||||
return fmt.Sprintf(c.GetFilesRoute()+"/%v", fileId)
|
||||
}
|
||||
|
||||
func (c *Client4) GetUploadsRoute() string {
|
||||
return "/uploads"
|
||||
}
|
||||
|
||||
func (c *Client4) GetUploadRoute(uploadId string) string {
|
||||
return fmt.Sprintf("%s/%s", c.GetUploadsRoute(), uploadId)
|
||||
}
|
||||
|
||||
func (c *Client4) GetPluginsRoute() string {
|
||||
return "/plugins"
|
||||
}
|
||||
@ -453,6 +514,10 @@ func (c *Client4) GetGroupsRoute() string {
|
||||
return "/groups"
|
||||
}
|
||||
|
||||
func (c *Client4) GetPublishUserTypingRoute(userId string) string {
|
||||
return c.GetUserRoute(userId) + "/typing"
|
||||
}
|
||||
|
||||
func (c *Client4) GetGroupRoute(groupID string) string {
|
||||
return fmt.Sprintf("%s/%s", c.GetGroupsRoute(), groupID)
|
||||
}
|
||||
@ -650,7 +715,7 @@ func (c *Client4) LoginByLdap(loginId string, password string) (*User, *Response
|
||||
m := make(map[string]string)
|
||||
m["login_id"] = loginId
|
||||
m["password"] = password
|
||||
m["ldap_only"] = "true"
|
||||
m["ldap_only"] = c.boolString(true)
|
||||
return c.login(m)
|
||||
}
|
||||
|
||||
@ -967,6 +1032,17 @@ func (c *Client4) GetUsersWithoutTeam(page int, perPage int, etag string) ([]*Us
|
||||
return UserListFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetUsersInGroup returns a page of users in a group. Page counting starts at 0.
|
||||
func (c *Client4) GetUsersInGroup(groupID string, page int, perPage int, etag string) ([]*User, *Response) {
|
||||
query := fmt.Sprintf("?in_group=%v&page=%v&per_page=%v", groupID, page, perPage)
|
||||
r, err := c.DoApiGet(c.GetUsersRoute()+query, etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return UserListFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetUsersByIds returns a list of users based on the provided user ids.
|
||||
func (c *Client4) GetUsersByIds(userIds []string) ([]*User, *Response) {
|
||||
r, err := c.DoApiPost(c.GetUsersRoute()+"/ids", ArrayToJson(userIds))
|
||||
@ -1119,6 +1195,17 @@ func (c *Client4) UpdateUserPassword(userId, currentPassword, newPassword string
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// UpdateUserHashedPassword updates a user's password with an already-hashed password. Must be a system administrator.
|
||||
func (c *Client4) UpdateUserHashedPassword(userId, newHashedPassword string) (bool, *Response) {
|
||||
requestBody := map[string]string{"already_hashed": "true", "new_password": newHashedPassword}
|
||||
r, err := c.DoApiPut(c.GetUserRoute(userId)+"/password", MapToJson(requestBody))
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// PromoteGuestToUser convert a guest into a regular user
|
||||
func (c *Client4) PromoteGuestToUser(guestId string) (bool, *Response) {
|
||||
r, err := c.DoApiPost(c.GetUserRoute(guestId)+"/promote", "")
|
||||
@ -1173,6 +1260,50 @@ func (c *Client4) DeleteUser(userId string) (bool, *Response) {
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// PermanentDeleteUser deletes a user in the system based on the provided user id string.
|
||||
func (c *Client4) PermanentDeleteUser(userId string) (bool, *Response) {
|
||||
r, err := c.DoApiDelete(c.GetUserRoute(userId) + "?permanent=" + c.boolString(true))
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// ConvertUserToBot converts a user to a bot user.
|
||||
func (c *Client4) ConvertUserToBot(userId string) (*Bot, *Response) {
|
||||
r, err := c.DoApiPost(c.GetUserRoute(userId)+"/convert_to_bot", "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return BotFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// ConvertBotToUser converts a bot user to a user.
|
||||
func (c *Client4) ConvertBotToUser(userId string, userPatch *UserPatch, setSystemAdmin bool) (*User, *Response) {
|
||||
var query string
|
||||
if setSystemAdmin {
|
||||
query = "?set_system_admin=true"
|
||||
}
|
||||
r, err := c.DoApiPost(c.GetBotRoute(userId)+"/convert_to_user"+query, userPatch.ToJson())
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return UserFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// PermanentDeleteAll permanently deletes all users in the system. This is a local only endpoint
|
||||
func (c *Client4) PermanentDeleteAllUsers() (bool, *Response) {
|
||||
r, err := c.DoApiDelete(c.GetUsersRoute())
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// SendPasswordResetEmail will send a link for password resetting to a user with the
|
||||
// provided email.
|
||||
func (c *Client4) SendPasswordResetEmail(email string) (bool, *Response) {
|
||||
@ -1287,6 +1418,16 @@ func (c *Client4) VerifyUserEmail(token string) (bool, *Response) {
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// VerifyUserEmailWithoutToken will verify a user's email by its Id. (Requires manage system role)
|
||||
func (c *Client4) VerifyUserEmailWithoutToken(userId string) (*User, *Response) {
|
||||
r, err := c.DoApiPost(c.GetUserRoute(userId)+"/email/verify/member", "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return UserFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// SendVerificationEmail will send an email to the user with the provided email address, if
|
||||
// that user exists. The email will contain a link that can be used to verify the user's
|
||||
// email address.
|
||||
@ -1487,7 +1628,7 @@ func (c *Client4) GetBot(userId string, etag string) (*Bot, *Response) {
|
||||
|
||||
// GetBot fetches the given bot, even if it is deleted.
|
||||
func (c *Client4) GetBotIncludeDeleted(userId string, etag string) (*Bot, *Response) {
|
||||
r, err := c.DoApiGet(c.GetBotRoute(userId)+"?include_deleted=true", etag)
|
||||
r, err := c.DoApiGet(c.GetBotRoute(userId)+"?include_deleted="+c.boolString(true), etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
@ -1508,7 +1649,7 @@ func (c *Client4) GetBots(page, perPage int, etag string) ([]*Bot, *Response) {
|
||||
|
||||
// GetBotsIncludeDeleted fetches the given page of bots, including deleted.
|
||||
func (c *Client4) GetBotsIncludeDeleted(page, perPage int, etag string) ([]*Bot, *Response) {
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&include_deleted=true", page, perPage)
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&include_deleted="+c.boolString(true), page, perPage)
|
||||
r, err := c.DoApiGet(c.GetBotsRoute()+query, etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
@ -1519,7 +1660,7 @@ func (c *Client4) GetBotsIncludeDeleted(page, perPage int, etag string) ([]*Bot,
|
||||
|
||||
// GetBotsOrphaned fetches the given page of bots, only including orphanded bots.
|
||||
func (c *Client4) GetBotsOrphaned(page, perPage int, etag string) ([]*Bot, *Response) {
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&only_orphaned=true", page, perPage)
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&only_orphaned="+c.boolString(true), page, perPage)
|
||||
r, err := c.DoApiGet(c.GetBotsRoute()+query, etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
@ -1659,7 +1800,7 @@ func (c *Client4) GetAllTeams(etag string, page int, perPage int) ([]*Team, *Res
|
||||
|
||||
// GetAllTeamsWithTotalCount returns all teams based on permissions.
|
||||
func (c *Client4) GetAllTeamsWithTotalCount(etag string, page int, perPage int) ([]*Team, int64, *Response) {
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&include_total_count=true", page, perPage)
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&include_total_count="+c.boolString(true), page, perPage)
|
||||
r, err := c.DoApiGet(c.GetTeamsRoute()+query, etag)
|
||||
if err != nil {
|
||||
return nil, 0, BuildErrorResponse(r, err)
|
||||
@ -1811,7 +1952,7 @@ func (c *Client4) SoftDeleteTeam(teamId string) (bool, *Response) {
|
||||
// PermanentDeleteTeam deletes the team, should only be used when needed for
|
||||
// compliance and the like.
|
||||
func (c *Client4) PermanentDeleteTeam(teamId string) (bool, *Response) {
|
||||
r, err := c.DoApiDelete(c.GetTeamRoute(teamId) + "?permanent=true")
|
||||
r, err := c.DoApiDelete(c.GetTeamRoute(teamId) + "?permanent=" + c.boolString(true))
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
@ -1931,7 +2072,7 @@ func (c *Client4) AddTeamMembersGracefully(teamId string, userIds []string) ([]*
|
||||
members = append(members, member)
|
||||
}
|
||||
|
||||
r, err := c.DoApiPost(c.GetTeamMembersRoute(teamId)+"/batch?graceful=true", TeamMembersToJson(members))
|
||||
r, err := c.DoApiPost(c.GetTeamMembersRoute(teamId)+"/batch?graceful="+c.boolString(true), TeamMembersToJson(members))
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
@ -2049,7 +2190,7 @@ func (c *Client4) InviteGuestsToTeam(teamId string, userEmails []string, channel
|
||||
|
||||
// InviteUsersToTeam invite users by email to the team.
|
||||
func (c *Client4) InviteUsersToTeamGracefully(teamId string, userEmails []string) ([]*EmailInviteWithError, *Response) {
|
||||
r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/invite/email?graceful=true", ArrayToJson(userEmails))
|
||||
r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/invite/email?graceful="+c.boolString(true), ArrayToJson(userEmails))
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
@ -2064,7 +2205,7 @@ func (c *Client4) InviteGuestsToTeamGracefully(teamId string, userEmails []strin
|
||||
Channels: channels,
|
||||
Message: message,
|
||||
}
|
||||
r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/invite-guests/email?graceful=true", guestsInvite.ToJson())
|
||||
r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/invite-guests/email?graceful="+c.boolString(true), guestsInvite.ToJson())
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
@ -2163,7 +2304,16 @@ func (c *Client4) RemoveTeamIcon(teamId string) (bool, *Response) {
|
||||
|
||||
// GetAllChannels get all the channels. Must be a system administrator.
|
||||
func (c *Client4) GetAllChannels(page int, perPage int, etag string) (*ChannelListWithTeamData, *Response) {
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)
|
||||
return c.getAllChannels(page, perPage, etag, false)
|
||||
}
|
||||
|
||||
// GetAllChannelsIncludeDeleted get all the channels. Must be a system administrator.
|
||||
func (c *Client4) GetAllChannelsIncludeDeleted(page int, perPage int, etag string) (*ChannelListWithTeamData, *Response) {
|
||||
return c.getAllChannels(page, perPage, etag, true)
|
||||
}
|
||||
|
||||
func (c *Client4) getAllChannels(page int, perPage int, etag string, includeDeleted bool) (*ChannelListWithTeamData, *Response) {
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&include_deleted=%v", page, perPage, includeDeleted)
|
||||
r, err := c.DoApiGet(c.GetChannelsRoute()+query, etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
@ -2174,7 +2324,7 @@ func (c *Client4) GetAllChannels(page int, perPage int, etag string) (*ChannelLi
|
||||
|
||||
// GetAllChannelsWithCount get all the channels including the total count. Must be a system administrator.
|
||||
func (c *Client4) GetAllChannelsWithCount(page int, perPage int, etag string) (*ChannelListWithTeamData, int64, *Response) {
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&include_total_count=true", page, perPage)
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v&include_total_count="+c.boolString(true), page, perPage)
|
||||
r, err := c.DoApiGet(c.GetChannelsRoute()+query, etag)
|
||||
if err != nil {
|
||||
return nil, 0, BuildErrorResponse(r, err)
|
||||
@ -2307,6 +2457,17 @@ func (c *Client4) GetPinnedPosts(channelId string, etag string) (*PostList, *Res
|
||||
return PostListFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetPrivateChannelsForTeam returns a list of private channels based on the provided team id string.
|
||||
func (c *Client4) GetPrivateChannelsForTeam(teamId string, page int, perPage int, etag string) ([]*Channel, *Response) {
|
||||
query := fmt.Sprintf("/private?page=%v&per_page=%v", page, perPage)
|
||||
r, err := c.DoApiGet(c.GetChannelsForTeamRoute(teamId)+query, etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return ChannelSliceFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetPublicChannelsForTeam returns a list of public channels based on the provided team id string.
|
||||
func (c *Client4) GetPublicChannelsForTeam(teamId string, page int, perPage int, etag string) ([]*Channel, *Response) {
|
||||
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)
|
||||
@ -2349,6 +2510,18 @@ func (c *Client4) GetChannelsForTeamForUser(teamId, userId string, includeDelete
|
||||
return ChannelSliceFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetChannelsForTeamAndUserWithLastDeleteAt returns a list channels of a team for a user, additionally filtered with lastDeleteAt. This does not have any effect if includeDeleted is set to false.
|
||||
func (c *Client4) GetChannelsForTeamAndUserWithLastDeleteAt(teamId, userId string, includeDeleted bool, lastDeleteAt int, etag string) ([]*Channel, *Response) {
|
||||
route := fmt.Sprintf(c.GetUserRoute(userId) + c.GetTeamRoute(teamId) + "/channels")
|
||||
route += fmt.Sprintf("?include_deleted=%v&last_delete_at=%d", includeDeleted, lastDeleteAt)
|
||||
r, err := c.DoApiGet(route, etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return ChannelSliceFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// SearchChannels returns the channels on a team matching the provided search term.
|
||||
func (c *Client4) SearchChannels(teamId string, search *ChannelSearch) ([]*Channel, *Response) {
|
||||
r, err := c.DoApiPost(c.GetChannelsForTeamRoute(teamId)+"/search", search.ToJson())
|
||||
@ -2409,6 +2582,30 @@ func (c *Client4) DeleteChannel(channelId string) (bool, *Response) {
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// PermanentDeleteChannel deletes a channel based on the provided channel id string.
|
||||
func (c *Client4) PermanentDeleteChannel(channelId string) (bool, *Response) {
|
||||
r, err := c.DoApiDelete(c.GetChannelRoute(channelId) + "?permanent=" + c.boolString(true))
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// MoveChannel moves the channel to the destination team.
|
||||
func (c *Client4) MoveChannel(channelId, teamId string, force bool) (*Channel, *Response) {
|
||||
requestBody := map[string]interface{}{
|
||||
"team_id": teamId,
|
||||
"force": force,
|
||||
}
|
||||
r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/move", StringInterfaceToJson(requestBody))
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return ChannelFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetChannelByName returns a channel based on the provided channel name and team id strings.
|
||||
func (c *Client4) GetChannelByName(channelName, teamId string, etag string) (*Channel, *Response) {
|
||||
r, err := c.DoApiGet(c.GetChannelByNameRoute(channelName, teamId), etag)
|
||||
@ -2421,7 +2618,7 @@ func (c *Client4) GetChannelByName(channelName, teamId string, etag string) (*Ch
|
||||
|
||||
// GetChannelByNameIncludeDeleted returns a channel based on the provided channel name and team id strings. Other then GetChannelByName it will also return deleted channels.
|
||||
func (c *Client4) GetChannelByNameIncludeDeleted(channelName, teamId string, etag string) (*Channel, *Response) {
|
||||
r, err := c.DoApiGet(c.GetChannelByNameRoute(channelName, teamId)+"?include_deleted=true", etag)
|
||||
r, err := c.DoApiGet(c.GetChannelByNameRoute(channelName, teamId)+"?include_deleted="+c.boolString(true), etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
@ -2441,7 +2638,7 @@ func (c *Client4) GetChannelByNameForTeamName(channelName, teamName string, etag
|
||||
|
||||
// GetChannelByNameForTeamNameIncludeDeleted returns a channel based on the provided channel name and team name strings. Other then GetChannelByNameForTeamName it will also return deleted channels.
|
||||
func (c *Client4) GetChannelByNameForTeamNameIncludeDeleted(channelName, teamName string, etag string) (*Channel, *Response) {
|
||||
r, err := c.DoApiGet(c.GetChannelByNameForTeamNameRoute(channelName, teamName)+"?include_deleted=true", etag)
|
||||
r, err := c.DoApiGet(c.GetChannelByNameForTeamNameRoute(channelName, teamName)+"?include_deleted="+c.boolString(true), etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
@ -3059,7 +3256,7 @@ func (c *Client4) GetPing() (string, *Response) {
|
||||
// GetPingWithServerStatus will return ok if several basic server health checks
|
||||
// all pass successfully.
|
||||
func (c *Client4) GetPingWithServerStatus() (string, *Response) {
|
||||
r, err := c.DoApiGet(c.GetSystemRoute()+"/ping?get_server_status=true", "")
|
||||
r, err := c.DoApiGet(c.GetSystemRoute()+"/ping?get_server_status="+c.boolString(true), "")
|
||||
if r != nil && r.StatusCode == 500 {
|
||||
defer r.Body.Close()
|
||||
return STATUS_UNHEALTHY, BuildErrorResponse(r, err)
|
||||
@ -3187,6 +3384,19 @@ func (c *Client4) UpdateConfig(config *Config) (*Config, *Response) {
|
||||
return ConfigFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// MigrateConfig will migrate existing config to the new one.
|
||||
func (c *Client4) MigrateConfig(from, to string) (bool, *Response) {
|
||||
m := make(map[string]string, 2)
|
||||
m["from"] = from
|
||||
m["to"] = to
|
||||
r, err := c.DoApiPost(c.GetConfigRoute()+"/migrate", MapToJson(m))
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return true, BuildResponse(r)
|
||||
}
|
||||
|
||||
// UploadLicenseFile will add a license file to the system.
|
||||
func (c *Client4) UploadLicenseFile(data []byte) (bool, *Response) {
|
||||
body := &bytes.Buffer{}
|
||||
@ -3470,7 +3680,7 @@ func (c *Client4) GetSamlMetadata() (string, *Response) {
|
||||
return buf.String(), BuildResponse(r)
|
||||
}
|
||||
|
||||
func samlFileToMultipart(data []byte, filename string) ([]byte, *multipart.Writer, error) {
|
||||
func fileToMultipart(data []byte, filename string) ([]byte, *multipart.Writer, error) {
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
@ -3493,7 +3703,7 @@ func samlFileToMultipart(data []byte, filename string) ([]byte, *multipart.Write
|
||||
// UploadSamlIdpCertificate will upload an IDP certificate for SAML and set the config to use it.
|
||||
// The filename parameter is deprecated and ignored: the server will pick a hard-coded filename when writing to disk.
|
||||
func (c *Client4) UploadSamlIdpCertificate(data []byte, filename string) (bool, *Response) {
|
||||
body, writer, err := samlFileToMultipart(data, filename)
|
||||
body, writer, err := fileToMultipart(data, filename)
|
||||
if err != nil {
|
||||
return false, &Response{Error: NewAppError("UploadSamlIdpCertificate", "model.client.upload_saml_cert.app_error", nil, err.Error(), http.StatusBadRequest)}
|
||||
}
|
||||
@ -3505,7 +3715,7 @@ func (c *Client4) UploadSamlIdpCertificate(data []byte, filename string) (bool,
|
||||
// UploadSamlPublicCertificate will upload a public certificate for SAML and set the config to use it.
|
||||
// The filename parameter is deprecated and ignored: the server will pick a hard-coded filename when writing to disk.
|
||||
func (c *Client4) UploadSamlPublicCertificate(data []byte, filename string) (bool, *Response) {
|
||||
body, writer, err := samlFileToMultipart(data, filename)
|
||||
body, writer, err := fileToMultipart(data, filename)
|
||||
if err != nil {
|
||||
return false, &Response{Error: NewAppError("UploadSamlPublicCertificate", "model.client.upload_saml_cert.app_error", nil, err.Error(), http.StatusBadRequest)}
|
||||
}
|
||||
@ -3517,7 +3727,7 @@ func (c *Client4) UploadSamlPublicCertificate(data []byte, filename string) (boo
|
||||
// UploadSamlPrivateCertificate will upload a private key for SAML and set the config to use it.
|
||||
// The filename parameter is deprecated and ignored: the server will pick a hard-coded filename when writing to disk.
|
||||
func (c *Client4) UploadSamlPrivateCertificate(data []byte, filename string) (bool, *Response) {
|
||||
body, writer, err := samlFileToMultipart(data, filename)
|
||||
body, writer, err := fileToMultipart(data, filename)
|
||||
if err != nil {
|
||||
return false, &Response{Error: NewAppError("UploadSamlPrivateCertificate", "model.client.upload_saml_cert.app_error", nil, err.Error(), http.StatusBadRequest)}
|
||||
}
|
||||
@ -3685,7 +3895,19 @@ func (c *Client4) GetLdapGroups() ([]*Group, *Response) {
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
return GroupsFromJson(r.Body), BuildResponse(r)
|
||||
responseData := struct {
|
||||
Count int `json:"count"`
|
||||
Groups []*Group `json:"groups"`
|
||||
}{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&responseData); err != nil {
|
||||
appErr := NewAppError("Api4.GetLdapGroups", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
for i := range responseData.Groups {
|
||||
responseData.Groups[i].DisplayName = *responseData.Groups[i].Name
|
||||
}
|
||||
|
||||
return responseData.Groups, BuildResponse(r)
|
||||
}
|
||||
|
||||
// LinkLdapGroup creates or undeletes a Mattermost group and associates it to the given LDAP group DN.
|
||||
@ -3714,6 +3936,18 @@ func (c *Client4) UnlinkLdapGroup(dn string) (*Group, *Response) {
|
||||
return GroupFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// MigrateIdLdap migrates the LDAP enabled users to given attribute
|
||||
func (c *Client4) MigrateIdLdap(toAttribute string) (bool, *Response) {
|
||||
r, err := c.DoApiPost(c.GetLdapRoute()+"/migrateid", MapToJson(map[string]string{
|
||||
"toAttribute": toAttribute,
|
||||
}))
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetGroupsByChannel retrieves the Mattermost Groups associated with a given channel
|
||||
func (c *Client4) GetGroupsByChannel(channelId string, opts GroupSearchOpts) ([]*GroupWithSchemeAdmin, int, *Response) {
|
||||
path := fmt.Sprintf("%s/groups?q=%v&include_member_count=%v&filter_allow_reference=%v", c.GetChannelRoute(channelId), opts.Q, opts.IncludeMemberCount, opts.FilterAllowReference)
|
||||
@ -3828,6 +4062,74 @@ func (c *Client4) GetGroupsByUserId(userId string) ([]*Group, *Response) {
|
||||
return GroupsFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) MigrateAuthToLdap(fromAuthService string, matchField string, force bool) (bool, *Response) {
|
||||
r, err := c.DoApiPost(c.GetUsersRoute()+"/migrate_auth/ldap", StringInterfaceToJson(map[string]interface{}{
|
||||
"from": fromAuthService,
|
||||
"force": force,
|
||||
"match_field": matchField,
|
||||
}))
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) MigrateAuthToSaml(fromAuthService string, usersMap map[string]string, auto bool) (bool, *Response) {
|
||||
r, err := c.DoApiPost(c.GetUsersRoute()+"/migrate_auth/saml", StringInterfaceToJson(map[string]interface{}{
|
||||
"from": fromAuthService,
|
||||
"auto": auto,
|
||||
"matches": usersMap,
|
||||
}))
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// UploadLdapPublicCertificate will upload a public certificate for LDAP and set the config to use it.
|
||||
func (c *Client4) UploadLdapPublicCertificate(data []byte) (bool, *Response) {
|
||||
body, writer, err := fileToMultipart(data, LDAP_PUBIC_CERTIFICATE_NAME)
|
||||
if err != nil {
|
||||
return false, &Response{Error: NewAppError("UploadLdapPublicCertificate", "model.client.upload_ldap_cert.app_error", nil, err.Error(), http.StatusBadRequest)}
|
||||
}
|
||||
|
||||
_, resp := c.DoUploadFile(c.GetLdapRoute()+"/certificate/public", body, writer.FormDataContentType())
|
||||
return resp.Error == nil, resp
|
||||
}
|
||||
|
||||
// UploadLdapPrivateCertificate will upload a private key for LDAP and set the config to use it.
|
||||
func (c *Client4) UploadLdapPrivateCertificate(data []byte) (bool, *Response) {
|
||||
body, writer, err := fileToMultipart(data, LDAP_PRIVATE_KEY_NAME)
|
||||
if err != nil {
|
||||
return false, &Response{Error: NewAppError("UploadLdapPrivateCertificate", "model.client.upload_Ldap_cert.app_error", nil, err.Error(), http.StatusBadRequest)}
|
||||
}
|
||||
|
||||
_, resp := c.DoUploadFile(c.GetLdapRoute()+"/certificate/private", body, writer.FormDataContentType())
|
||||
return resp.Error == nil, resp
|
||||
}
|
||||
|
||||
// DeleteLdapPublicCertificate deletes the LDAP IDP certificate from the server and updates the config to not use it and disable LDAP.
|
||||
func (c *Client4) DeleteLdapPublicCertificate() (bool, *Response) {
|
||||
r, err := c.DoApiDelete(c.GetLdapRoute() + "/certificate/public")
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// DeleteLDAPPrivateCertificate deletes the LDAP IDP certificate from the server and updates the config to not use it and disable LDAP.
|
||||
func (c *Client4) DeleteLdapPrivateCertificate() (bool, *Response) {
|
||||
r, err := c.DoApiDelete(c.GetLdapRoute() + "/certificate/private")
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// Audits Section
|
||||
|
||||
// GetAudits returns a list of audits for the whole system.
|
||||
@ -4519,6 +4821,21 @@ func (c *Client4) CancelJob(jobId string) (bool, *Response) {
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// DownloadJob downloads the results of the job
|
||||
func (c *Client4) DownloadJob(jobId string) ([]byte, *Response) {
|
||||
r, appErr := c.DoApiGet(c.GetJobsRoute()+fmt.Sprintf("/%v/download", jobId), "")
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, NewAppError("GetFile", "model.client.read_job_result_file.app_error", nil, err.Error(), r.StatusCode))
|
||||
}
|
||||
return data, BuildResponse(r)
|
||||
}
|
||||
|
||||
// Roles Section
|
||||
|
||||
// GetRole gets a single role by ID.
|
||||
@ -4650,7 +4967,7 @@ func (c *Client4) uploadPlugin(file io.Reader, force bool) (*Manifest, *Response
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
if force {
|
||||
err := writer.WriteField("force", "true")
|
||||
err := writer.WriteField("force", c.boolString(true))
|
||||
if err != nil {
|
||||
return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.writer.app_error", nil, err.Error(), 0)}
|
||||
}
|
||||
@ -4693,10 +5010,7 @@ func (c *Client4) uploadPlugin(file io.Reader, force bool) (*Manifest, *Response
|
||||
}
|
||||
|
||||
func (c *Client4) InstallPluginFromUrl(downloadUrl string, force bool) (*Manifest, *Response) {
|
||||
forceStr := "false"
|
||||
if force {
|
||||
forceStr = "true"
|
||||
}
|
||||
forceStr := c.boolString(force)
|
||||
|
||||
url := fmt.Sprintf("%s?plugin_download_url=%s&force=%s", c.GetPluginsRoute()+"/install_from_url", url.QueryEscape(downloadUrl), forceStr)
|
||||
r, err := c.DoApiPost(url, "")
|
||||
@ -5074,6 +5388,16 @@ func (c *Client4) GetKnownUsers() ([]string, *Response) {
|
||||
return userIds, BuildResponse(r)
|
||||
}
|
||||
|
||||
// PublishUserTyping publishes a user is typing websocket event based on the provided TypingRequest.
|
||||
func (c *Client4) PublishUserTyping(userID string, typingRequest TypingRequest) (bool, *Response) {
|
||||
r, err := c.DoApiPost(c.GetPublishUserTypingRoute(userID), typingRequest.ToJson())
|
||||
if err != nil {
|
||||
return false, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) GetChannelMemberCountsByGroup(channelID string, includeTimezones bool, etag string) ([]*ChannelMemberCountByGroup, *Response) {
|
||||
r, err := c.DoApiGet(c.GetChannelRoute(channelID)+"/member_counts_by_group?include_timezones="+strconv.FormatBool(includeTimezones), etag)
|
||||
if err != nil {
|
||||
@ -5093,3 +5417,202 @@ func (c *Client4) RequestTrialLicense(users int) (bool, *Response) {
|
||||
defer closeBody(r)
|
||||
return CheckStatusOK(r), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetGroupStats retrieves stats for a Mattermost Group
|
||||
func (c *Client4) GetGroupStats(groupID string) (*GroupStats, *Response) {
|
||||
r, appErr := c.DoApiGet(c.GetGroupRoute(groupID)+"/stats", "")
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return GroupStatsFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) GetSidebarCategoriesForTeamForUser(userID, teamID, etag string) (*OrderedSidebarCategories, *Response) {
|
||||
route := c.GetUserCategoryRoute(userID, teamID)
|
||||
r, appErr := c.DoApiGet(route, etag)
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
cat, err := OrderedSidebarCategoriesFromJson(r.Body)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, NewAppError("Client4.GetSidebarCategoriesForTeamForUser", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
|
||||
}
|
||||
return cat, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) CreateSidebarCategoryForTeamForUser(userID, teamID string, category *SidebarCategoryWithChannels) (*SidebarCategoryWithChannels, *Response) {
|
||||
payload, _ := json.Marshal(category)
|
||||
route := c.GetUserCategoryRoute(userID, teamID)
|
||||
r, appErr := c.doApiPostBytes(route, payload)
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
defer closeBody(r)
|
||||
cat, err := SidebarCategoryFromJson(r.Body)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, NewAppError("Client4.CreateSidebarCategoryForTeamForUser", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
|
||||
}
|
||||
return cat, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) UpdateSidebarCategoriesForTeamForUser(userID, teamID string, categories []*SidebarCategoryWithChannels) ([]*SidebarCategoryWithChannels, *Response) {
|
||||
payload, _ := json.Marshal(categories)
|
||||
route := c.GetUserCategoryRoute(userID, teamID)
|
||||
|
||||
r, appErr := c.doApiPutBytes(route, payload)
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
categories, err := SidebarCategoriesFromJson(r.Body)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, NewAppError("Client4.UpdateSidebarCategoriesForTeamForUser", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
|
||||
}
|
||||
|
||||
return categories, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) GetSidebarCategoryOrderForTeamForUser(userID, teamID, etag string) ([]string, *Response) {
|
||||
route := c.GetUserCategoryRoute(userID, teamID) + "/order"
|
||||
r, err := c.DoApiGet(route, etag)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return ArrayFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) UpdateSidebarCategoryOrderForTeamForUser(userID, teamID string, order []string) ([]string, *Response) {
|
||||
payload, _ := json.Marshal(order)
|
||||
route := c.GetUserCategoryRoute(userID, teamID) + "/order"
|
||||
r, err := c.doApiPutBytes(route, payload)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return ArrayFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) GetSidebarCategoryForTeamForUser(userID, teamID, categoryID, etag string) (*SidebarCategoryWithChannels, *Response) {
|
||||
route := c.GetUserCategoryRoute(userID, teamID) + "/" + categoryID
|
||||
r, appErr := c.DoApiGet(route, etag)
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
defer closeBody(r)
|
||||
cat, err := SidebarCategoryFromJson(r.Body)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, NewAppError("Client4.UpdateSidebarCategoriesForTeamForUser", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
|
||||
}
|
||||
|
||||
return cat, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) UpdateSidebarCategoryForTeamForUser(userID, teamID, categoryID string, category *SidebarCategoryWithChannels) (*SidebarCategoryWithChannels, *Response) {
|
||||
payload, _ := json.Marshal(category)
|
||||
route := c.GetUserCategoryRoute(userID, teamID) + "/" + categoryID
|
||||
r, appErr := c.doApiPutBytes(route, payload)
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
defer closeBody(r)
|
||||
cat, err := SidebarCategoryFromJson(r.Body)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, NewAppError("Client4.UpdateSidebarCategoriesForTeamForUser", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
|
||||
}
|
||||
|
||||
return cat, BuildResponse(r)
|
||||
}
|
||||
|
||||
// CheckIntegrity performs a database integrity check.
|
||||
func (c *Client4) CheckIntegrity() ([]IntegrityCheckResult, *Response) {
|
||||
r, err := c.DoApiPost("/integrity", "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
var results []IntegrityCheckResult
|
||||
if err := json.NewDecoder(r.Body).Decode(&results); err != nil {
|
||||
appErr := NewAppError("Api4.CheckIntegrity", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
return results, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) GetNotices(lastViewed int64, teamId string, client NoticeClientType, clientVersion, locale, etag string) (NoticeMessages, *Response) {
|
||||
url := fmt.Sprintf("/system/notices/%s?lastViewed=%d&client=%s&clientVersion=%s&locale=%s", teamId, lastViewed, client, clientVersion, locale)
|
||||
r, appErr := c.DoApiGet(url, etag)
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
defer closeBody(r)
|
||||
notices, err := UnmarshalProductNoticeMessages(r.Body)
|
||||
if err != nil {
|
||||
return nil, &Response{StatusCode: http.StatusBadRequest, Error: NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), http.StatusForbidden)}
|
||||
}
|
||||
return notices, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) MarkNoticesViewed(ids []string) *Response {
|
||||
r, err := c.DoApiPut("/system/notices/view", ArrayToJson(ids))
|
||||
if err != nil {
|
||||
return BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return BuildResponse(r)
|
||||
}
|
||||
|
||||
// CreateUpload creates a new upload session.
|
||||
func (c *Client4) CreateUpload(us *UploadSession) (*UploadSession, *Response) {
|
||||
r, err := c.DoApiPost(c.GetUploadsRoute(), us.ToJson())
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return UploadSessionFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetUpload returns the upload session for the specified uploadId.
|
||||
func (c *Client4) GetUpload(uploadId string) (*UploadSession, *Response) {
|
||||
r, err := c.DoApiGet(c.GetUploadRoute(uploadId), "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return UploadSessionFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// GetUploadsForUser returns the upload sessions created by the specified
|
||||
// userId.
|
||||
func (c *Client4) GetUploadsForUser(userId string) ([]*UploadSession, *Response) {
|
||||
r, err := c.DoApiGet(c.GetUserRoute(userId)+"/uploads", "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return UploadSessionsFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
// UploadData performs an upload. On success it returns
|
||||
// a FileInfo object.
|
||||
func (c *Client4) UploadData(uploadId string, data io.Reader) (*FileInfo, *Response) {
|
||||
url := c.GetUploadRoute(uploadId)
|
||||
r, err := c.doApiRequestReader("POST", c.ApiUrl+url, data, "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return FileInfoFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) UpdatePassword(userId, currentPassword, newPassword string) *Response {
|
||||
requestBody := map[string]string{"current_password": currentPassword, "new_password": newPassword}
|
||||
r, err := c.DoApiPut(c.GetUserRoute(userId)+"/password", MapToJson(requestBody))
|
||||
if err != nil {
|
||||
return BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
return BuildResponse(r)
|
||||
}
|
||||
|
10
vendor/github.com/mattermost/mattermost-server/v5/model/cluster_message.go
generated
vendored
10
vendor/github.com/mattermost/mattermost-server/v5/model/cluster_message.go
generated
vendored
@ -43,6 +43,16 @@ const (
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE = "inv_terms_of_service"
|
||||
CLUSTER_EVENT_BUSY_STATE_CHANGED = "busy_state_change"
|
||||
|
||||
// Gossip communication
|
||||
CLUSTER_GOSSIP_EVENT_REQUEST_GET_LOGS = "gossip_request_get_logs"
|
||||
CLUSTER_GOSSIP_EVENT_RESPONSE_GET_LOGS = "gossip_response_get_logs"
|
||||
CLUSTER_GOSSIP_EVENT_REQUEST_GET_CLUSTER_STATS = "gossip_request_cluster_stats"
|
||||
CLUSTER_GOSSIP_EVENT_RESPONSE_GET_CLUSTER_STATS = "gossip_response_cluster_stats"
|
||||
CLUSTER_GOSSIP_EVENT_REQUEST_GET_PLUGIN_STATUSES = "gossip_request_plugin_statuses"
|
||||
CLUSTER_GOSSIP_EVENT_RESPONSE_GET_PLUGIN_STATUSES = "gossip_response_plugin_statuses"
|
||||
CLUSTER_GOSSIP_EVENT_REQUEST_SAVE_CONFIG = "gossip_request_save_config"
|
||||
CLUSTER_GOSSIP_EVENT_RESPONSE_SAVE_CONFIG = "gossip_response_save_config"
|
||||
|
||||
// SendTypes for ClusterMessage.
|
||||
CLUSTER_SEND_BEST_EFFORT = "best_effort"
|
||||
CLUSTER_SEND_RELIABLE = "reliable"
|
||||
|
49
vendor/github.com/mattermost/mattermost-server/v5/model/command.go
generated
vendored
49
vendor/github.com/mattermost/mattermost-server/v5/model/command.go
generated
vendored
@ -18,23 +18,26 @@ const (
|
||||
)
|
||||
|
||||
type Command struct {
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
Trigger string `json:"trigger"`
|
||||
Method string `json:"method"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
AutoComplete bool `json:"auto_complete"`
|
||||
AutoCompleteDesc string `json:"auto_complete_desc"`
|
||||
AutoCompleteHint string `json:"auto_complete_hint"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
Trigger string `json:"trigger"`
|
||||
Method string `json:"method"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
AutoComplete bool `json:"auto_complete"`
|
||||
AutoCompleteDesc string `json:"auto_complete_desc"`
|
||||
AutoCompleteHint string `json:"auto_complete_hint"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
// PluginId records the id of the plugin that created this Command. If it is blank, the Command
|
||||
// was not created by a plugin.
|
||||
PluginId string `json:"plugin_id"`
|
||||
AutocompleteData *AutocompleteData `db:"-" json:"autocomplete_data,omitempty"`
|
||||
// AutocompleteIconData is a base64 encoded svg
|
||||
AutocompleteIconData string `db:"-" json:"autocomplete_icon_data,omitempty"`
|
||||
@ -80,10 +83,20 @@ func (o *Command) IsValid() *AppError {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.update_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidId(o.CreatorId) {
|
||||
// If the CreatorId is blank, this should be a command created by a plugin.
|
||||
if o.CreatorId == "" && !IsValidPluginId(o.PluginId) {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.plugin_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
// If the PluginId is blank, this should be a command associated with a userId.
|
||||
if o.PluginId == "" && !IsValidId(o.CreatorId) {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreatorId != "" && o.PluginId != "" {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.plugin_id.app_error", nil, "command cannot have both a CreatorId and a PluginId", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidId(o.TeamId) {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.team_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
4
vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go
generated
vendored
4
vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go
generated
vendored
@ -20,9 +20,11 @@ type CommandArgs struct {
|
||||
Command string `json:"command"`
|
||||
SiteURL string `json:"-"`
|
||||
T goi18n.TranslateFunc `json:"-"`
|
||||
Session Session `json:"-"`
|
||||
UserMentions UserMentionMap `json:"-"`
|
||||
ChannelMentions ChannelMentionMap `json:"-"`
|
||||
|
||||
// DO NOT USE Session field is deprecated. MM-26398
|
||||
Session Session `json:"-"`
|
||||
}
|
||||
|
||||
func (o *CommandArgs) ToJson() string {
|
||||
|
1033
vendor/github.com/mattermost/mattermost-server/v5/model/config.go
generated
vendored
1033
vendor/github.com/mattermost/mattermost-server/v5/model/config.go
generated
vendored
File diff suppressed because it is too large
Load Diff
12
vendor/github.com/mattermost/mattermost-server/v5/model/file_info.go
generated
vendored
12
vendor/github.com/mattermost/mattermost-server/v5/model/file_info.go
generated
vendored
@ -4,7 +4,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"image"
|
||||
"image/gif"
|
||||
@ -151,10 +150,10 @@ func NewInfo(name string) *FileInfo {
|
||||
return info
|
||||
}
|
||||
|
||||
func GetInfoForBytes(name string, data []byte) (*FileInfo, *AppError) {
|
||||
func GetInfoForBytes(name string, data io.ReadSeeker, size int) (*FileInfo, *AppError) {
|
||||
info := &FileInfo{
|
||||
Name: name,
|
||||
Size: int64(len(data)),
|
||||
Size: int64(size),
|
||||
}
|
||||
var err *AppError
|
||||
|
||||
@ -170,16 +169,17 @@ func GetInfoForBytes(name string, data []byte) (*FileInfo, *AppError) {
|
||||
|
||||
if info.IsImage() {
|
||||
// Only set the width and height if it's actually an image that we can understand
|
||||
if config, _, err := image.DecodeConfig(bytes.NewReader(data)); err == nil {
|
||||
if config, _, err := image.DecodeConfig(data); err == nil {
|
||||
info.Width = config.Width
|
||||
info.Height = config.Height
|
||||
|
||||
if info.MimeType == "image/gif" {
|
||||
// Just show the gif itself instead of a preview image for animated gifs
|
||||
if gifConfig, err := gif.DecodeAll(bytes.NewReader(data)); err != nil {
|
||||
data.Seek(0, io.SeekStart)
|
||||
if gifConfig, err := gif.DecodeAll(data); err != nil {
|
||||
// Still return the rest of the info even though it doesn't appear to be an actual gif
|
||||
info.HasPreviewImage = true
|
||||
return info, NewAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, "name="+name, http.StatusBadRequest)
|
||||
return info, NewAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||
} else {
|
||||
info.HasPreviewImage = len(gifConfig.Image) == 1
|
||||
}
|
||||
|
11
vendor/github.com/mattermost/mattermost-server/v5/model/group.go
generated
vendored
11
vendor/github.com/mattermost/mattermost-server/v5/model/group.go
generated
vendored
@ -94,6 +94,11 @@ type PageOpts struct {
|
||||
PerPage int
|
||||
}
|
||||
|
||||
type GroupStats struct {
|
||||
GroupID string `json:"group_id"`
|
||||
TotalMemberCount int64 `json:"total_member_count"`
|
||||
}
|
||||
|
||||
func (group *Group) Patch(patch *GroupPatch) {
|
||||
if patch.Name != nil {
|
||||
group.Name = patch.Name
|
||||
@ -208,3 +213,9 @@ func GroupPatchFromJson(data io.Reader) *GroupPatch {
|
||||
json.NewDecoder(data).Decode(&groupPatch)
|
||||
return groupPatch
|
||||
}
|
||||
|
||||
func GroupStatsFromJson(data io.Reader) *GroupStats {
|
||||
var groupStats *GroupStats
|
||||
json.NewDecoder(data).Decode(&groupStats)
|
||||
return groupStats
|
||||
}
|
||||
|
58
vendor/github.com/mattermost/mattermost-server/v5/model/integrity.go
generated
vendored
Normal file
58
vendor/github.com/mattermost/mattermost-server/v5/model/integrity.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type OrphanedRecord struct {
|
||||
ParentId *string `json:"parent_id"`
|
||||
ChildId *string `json:"child_id"`
|
||||
}
|
||||
|
||||
type RelationalIntegrityCheckData struct {
|
||||
ParentName string `json:"parent_name"`
|
||||
ChildName string `json:"child_name"`
|
||||
ParentIdAttr string `json:"parent_id_attr"`
|
||||
ChildIdAttr string `json:"child_id_attr"`
|
||||
Records []OrphanedRecord `json:"records"`
|
||||
}
|
||||
|
||||
type IntegrityCheckResult struct {
|
||||
Data interface{} `json:"data"`
|
||||
Err error `json:"err"`
|
||||
}
|
||||
|
||||
func (r *IntegrityCheckResult) UnmarshalJSON(b []byte) error {
|
||||
var data map[string]interface{}
|
||||
if err := json.Unmarshal(b, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
if d, ok := data["data"]; ok && d != nil {
|
||||
var rdata RelationalIntegrityCheckData
|
||||
m := d.(map[string]interface{})
|
||||
rdata.ParentName = m["parent_name"].(string)
|
||||
rdata.ChildName = m["child_name"].(string)
|
||||
rdata.ParentIdAttr = m["parent_id_attr"].(string)
|
||||
rdata.ChildIdAttr = m["child_id_attr"].(string)
|
||||
for _, recData := range m["records"].([]interface{}) {
|
||||
var record OrphanedRecord
|
||||
m := recData.(map[string]interface{})
|
||||
if val := m["parent_id"]; val != nil {
|
||||
record.ParentId = NewString(val.(string))
|
||||
}
|
||||
if val := m["child_id"]; val != nil {
|
||||
record.ChildId = NewString(val.(string))
|
||||
}
|
||||
rdata.Records = append(rdata.Records, record)
|
||||
}
|
||||
r.Data = rdata
|
||||
}
|
||||
if err, ok := data["err"]; ok && err != nil {
|
||||
r.Err = errors.New(data["err"].(string))
|
||||
}
|
||||
return nil
|
||||
}
|
6
vendor/github.com/mattermost/mattermost-server/v5/model/job.go
generated
vendored
6
vendor/github.com/mattermost/mattermost-server/v5/model/job.go
generated
vendored
@ -19,6 +19,9 @@ const (
|
||||
JOB_TYPE_LDAP_SYNC = "ldap_sync"
|
||||
JOB_TYPE_MIGRATIONS = "migrations"
|
||||
JOB_TYPE_PLUGINS = "plugins"
|
||||
JOB_TYPE_EXPIRY_NOTIFY = "expiry_notify"
|
||||
JOB_TYPE_PRODUCT_NOTICES = "product_notices"
|
||||
JOB_TYPE_ACTIVE_USERS = "active_users"
|
||||
|
||||
JOB_STATUS_PENDING = "pending"
|
||||
JOB_STATUS_IN_PROGRESS = "in_progress"
|
||||
@ -59,6 +62,9 @@ func (j *Job) IsValid() *AppError {
|
||||
case JOB_TYPE_MESSAGE_EXPORT:
|
||||
case JOB_TYPE_MIGRATIONS:
|
||||
case JOB_TYPE_PLUGINS:
|
||||
case JOB_TYPE_PRODUCT_NOTICES:
|
||||
case JOB_TYPE_EXPIRY_NOTIFY:
|
||||
case JOB_TYPE_ACTIVE_USERS:
|
||||
default:
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.type.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
4
vendor/github.com/mattermost/mattermost-server/v5/model/ldap.go
generated
vendored
4
vendor/github.com/mattermost/mattermost-server/v5/model/ldap.go
generated
vendored
@ -4,5 +4,7 @@
|
||||
package model
|
||||
|
||||
const (
|
||||
USER_AUTH_SERVICE_LDAP = "ldap"
|
||||
USER_AUTH_SERVICE_LDAP = "ldap"
|
||||
LDAP_PUBIC_CERTIFICATE_NAME = "ldap-public.crt"
|
||||
LDAP_PRIVATE_KEY_NAME = "ldap-private.key"
|
||||
)
|
||||
|
14
vendor/github.com/mattermost/mattermost-server/v5/model/license.go
generated
vendored
14
vendor/github.com/mattermost/mattermost-server/v5/model/license.go
generated
vendored
@ -13,7 +13,7 @@ const (
|
||||
EXPIRED_LICENSE_ERROR = "api.license.add_license.expired.app_error"
|
||||
INVALID_LICENSE_ERROR = "api.license.add_license.invalid.app_error"
|
||||
LICENSE_GRACE_PERIOD = 1000 * 60 * 60 * 24 * 10 //10 days
|
||||
LICENSE_RENEWAL_LINK = "https://licensing.mattermost.com/renew"
|
||||
LICENSE_RENEWAL_LINK = "https://mattermost.com/renew/"
|
||||
)
|
||||
|
||||
type LicenseRecord struct {
|
||||
@ -81,6 +81,8 @@ type Features struct {
|
||||
IDLoadedPushNotifications *bool `json:"id_loaded"`
|
||||
LockTeammateNameDisplay *bool `json:"lock_teammate_name_display"`
|
||||
EnterprisePlugins *bool `json:"enterprise_plugins"`
|
||||
AdvancedLogging *bool `json:"advanced_logging"`
|
||||
Cloud *bool `json:"cloud"`
|
||||
|
||||
// after we enabled more features we'll need to control them with this
|
||||
FutureFeatures *bool `json:"future_features"`
|
||||
@ -108,6 +110,8 @@ func (f *Features) ToMap() map[string]interface{} {
|
||||
"id_loaded": *f.IDLoadedPushNotifications,
|
||||
"lock_teammate_name_display": *f.LockTeammateNameDisplay,
|
||||
"enterprise_plugins": *f.EnterprisePlugins,
|
||||
"advanced_logging": *f.AdvancedLogging,
|
||||
"cloud": *f.Cloud,
|
||||
"future": *f.FutureFeatures,
|
||||
}
|
||||
}
|
||||
@ -212,6 +216,14 @@ func (f *Features) SetDefaults() {
|
||||
if f.EnterprisePlugins == nil {
|
||||
f.EnterprisePlugins = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.AdvancedLogging == nil {
|
||||
f.AdvancedLogging = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.Cloud == nil {
|
||||
f.Cloud = NewBool(false)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *License) IsExpired() bool {
|
||||
|
4
vendor/github.com/mattermost/mattermost-server/v5/model/link_metadata.go
generated
vendored
4
vendor/github.com/mattermost/mattermost-server/v5/model/link_metadata.go
generated
vendored
@ -171,9 +171,9 @@ func (o *LinkMetadata) DeserializeDataToConcreteType() error {
|
||||
|
||||
// FloorToNearestHour takes a timestamp (in milliseconds) and returns it rounded to the previous hour in UTC.
|
||||
func FloorToNearestHour(ms int64) int64 {
|
||||
t := time.Unix(0, ms*int64(1000*1000))
|
||||
t := time.Unix(0, ms*int64(1000*1000)).UTC()
|
||||
|
||||
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), 0, 0, 0, t.Location()).UnixNano() / int64(time.Millisecond)
|
||||
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), 0, 0, 0, time.UTC).UnixNano() / int64(time.Millisecond)
|
||||
}
|
||||
|
||||
// isRoundedToNearestHour returns true if the given timestamp (in milliseconds) has been rounded to the nearest hour in UTC.
|
||||
|
4
vendor/github.com/mattermost/mattermost-server/v5/model/migration.go
generated
vendored
4
vendor/github.com/mattermost/mattermost-server/v5/model/migration.go
generated
vendored
@ -4,6 +4,7 @@
|
||||
package model
|
||||
|
||||
const (
|
||||
ADVANCED_PERMISSIONS_MIGRATION_KEY = "AdvancedPermissionsMigrationComplete"
|
||||
MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2 = "migration_advanced_permissions_phase_2"
|
||||
|
||||
MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split"
|
||||
@ -17,4 +18,7 @@ const (
|
||||
MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS = "add_manage_guests_permissions"
|
||||
MIGRATION_KEY_CHANNEL_MODERATIONS_PERMISSIONS = "channel_moderations_permissions"
|
||||
MIGRATION_KEY_ADD_USE_GROUP_MENTIONS_PERMISSION = "add_use_group_mentions_permission"
|
||||
MIGRATION_KEY_ADD_SYSTEM_CONSOLE_PERMISSIONS = "add_system_console_permissions"
|
||||
MIGRATION_KEY_SIDEBAR_CATEGORIES_PHASE_2 = "migration_sidebar_categories_phase_2"
|
||||
MIGRATION_KEY_ADD_CONVERT_CHANNEL_PERMISSIONS = "add_convert_channel_permissions"
|
||||
)
|
||||
|
3
vendor/github.com/mattermost/mattermost-server/v5/model/outgoing_webhook.go
generated
vendored
3
vendor/github.com/mattermost/mattermost-server/v5/model/outgoing_webhook.go
generated
vendored
@ -112,6 +112,9 @@ func (o *OutgoingWebhookResponse) ToJson() string {
|
||||
func OutgoingWebhookResponseFromJson(data io.Reader) (*OutgoingWebhookResponse, error) {
|
||||
var o *OutgoingWebhookResponse
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err == io.EOF {
|
||||
return nil, nil
|
||||
}
|
||||
return o, err
|
||||
}
|
||||
|
||||
|
618
vendor/github.com/mattermost/mattermost-server/v5/model/permission.go
generated
vendored
618
vendor/github.com/mattermost/mattermost-server/v5/model/permission.go
generated
vendored
File diff suppressed because it is too large
Load Diff
16
vendor/github.com/mattermost/mattermost-server/v5/model/post.go
generated
vendored
16
vendor/github.com/mattermost/mattermost-server/v5/model/post.go
generated
vendored
@ -64,6 +64,7 @@ const (
|
||||
|
||||
POST_PROPS_MENTION_HIGHLIGHT_DISABLED = "mentionHighlightDisabled"
|
||||
POST_PROPS_GROUP_HIGHLIGHT_DISABLED = "disable_group_highlight"
|
||||
POST_SYSTEM_WARN_METRIC_STATUS = "warn_metric_status"
|
||||
)
|
||||
|
||||
var AT_MENTION_PATTEN = regexp.MustCompile(`\B@`)
|
||||
@ -312,7 +313,8 @@ func (o *Post) IsValid(maxPostSize int) *AppError {
|
||||
POST_CHANNEL_RESTORED,
|
||||
POST_CHANGE_CHANNEL_PRIVACY,
|
||||
POST_ME,
|
||||
POST_ADD_BOT_TEAMS_CHANNELS:
|
||||
POST_ADD_BOT_TEAMS_CHANNELS,
|
||||
POST_SYSTEM_WARN_METRIC_STATUS:
|
||||
default:
|
||||
if !strings.HasPrefix(o.Type, POST_CUSTOM_TYPE_PREFIX) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.type.app_error", nil, "id="+o.Type, http.StatusBadRequest)
|
||||
@ -495,15 +497,14 @@ func (o *SearchParameter) SearchParameterToJson() string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func SearchParameterFromJson(data io.Reader) *SearchParameter {
|
||||
func SearchParameterFromJson(data io.Reader) (*SearchParameter, error) {
|
||||
decoder := json.NewDecoder(data)
|
||||
var searchParam SearchParameter
|
||||
err := decoder.Decode(&searchParam)
|
||||
if err != nil {
|
||||
return nil
|
||||
if err := decoder.Decode(&searchParam); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &searchParam
|
||||
return &searchParam, nil
|
||||
}
|
||||
|
||||
func (o *Post) ChannelMentions() []string {
|
||||
@ -521,6 +522,9 @@ func (o *Post) DisableMentionHighlights() string {
|
||||
|
||||
// DisableMentionHighlights disables mention highlighting for a post patch if required.
|
||||
func (o *PostPatch) DisableMentionHighlights() {
|
||||
if o.Message == nil {
|
||||
return
|
||||
}
|
||||
if _, hasMentions := findAtChannelMention(*o.Message); hasMentions {
|
||||
if o.Props == nil {
|
||||
o.Props = &StringInterface{}
|
||||
|
1
vendor/github.com/mattermost/mattermost-server/v5/model/preference.go
generated
vendored
1
vendor/github.com/mattermost/mattermost-server/v5/model/preference.go
generated
vendored
@ -14,6 +14,7 @@ import (
|
||||
|
||||
const (
|
||||
PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW = "direct_channel_show"
|
||||
PREFERENCE_CATEGORY_GROUP_CHANNEL_SHOW = "group_channel_show"
|
||||
PREFERENCE_CATEGORY_TUTORIAL_STEPS = "tutorial_step"
|
||||
PREFERENCE_CATEGORY_ADVANCED_SETTINGS = "advanced_settings"
|
||||
PREFERENCE_CATEGORY_FLAGGED_POST = "flagged_post"
|
||||
|
213
vendor/github.com/mattermost/mattermost-server/v5/model/product_notices.go
generated
vendored
Normal file
213
vendor/github.com/mattermost/mattermost-server/v5/model/product_notices.go
generated
vendored
Normal file
@ -0,0 +1,213 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/pkg/errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ProductNotices []ProductNotice
|
||||
|
||||
func (r *ProductNotices) Marshal() ([]byte, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
func UnmarshalProductNotices(data []byte) (ProductNotices, error) {
|
||||
var r ProductNotices
|
||||
err := json.Unmarshal(data, &r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
// List of product notices. Order is important and is used to resolve priorities.
|
||||
// Each notice will only be show if conditions are met.
|
||||
type ProductNotice struct {
|
||||
Conditions Conditions `json:"conditions"`
|
||||
ID string `json:"id"` // Unique identifier for this notice. Can be a running number. Used for storing 'viewed'; state on the server.
|
||||
LocalizedMessages map[string]NoticeMessageInternal `json:"localizedMessages"` // Notice message data, organized by locale.; Example:; "localizedMessages": {; "en": { "title": "English", description: "English description"},; "frFR": { "title": "Frances", description: "French description"}; }
|
||||
Repeatable *bool `json:"repeatable,omitempty"` // Configurable flag if the notice should reappear after it’s seen and dismissed
|
||||
}
|
||||
|
||||
func (n *ProductNotice) SysAdminOnly() bool {
|
||||
return n.Conditions.Audience != nil && *n.Conditions.Audience == NoticeAudience_Sysadmin
|
||||
}
|
||||
|
||||
func (n *ProductNotice) TeamAdminOnly() bool {
|
||||
return n.Conditions.Audience != nil && *n.Conditions.Audience == NoticeAudience_TeamAdmin
|
||||
}
|
||||
|
||||
type Conditions struct {
|
||||
Audience *NoticeAudience `json:"audience,omitempty"`
|
||||
ClientType *NoticeClientType `json:"clientType,omitempty"` // Only show the notice on specific clients. Defaults to 'all'
|
||||
DesktopVersion []string `json:"desktopVersion,omitempty"` // What desktop client versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
|
||||
DisplayDate *string `json:"displayDate,omitempty"` // When to display the notice.; Examples:; "2020-03-01T00:00:00Z" - show on specified date; ">= 2020-03-01T00:00:00Z" - show after specified date; "< 2020-03-01T00:00:00Z" - show before the specified date; "> 2020-03-01T00:00:00Z <= 2020-04-01T00:00:00Z" - show only between the specified dates
|
||||
InstanceType *NoticeInstanceType `json:"instanceType,omitempty"`
|
||||
MobileVersion []string `json:"mobileVersion,omitempty"` // What mobile client versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
|
||||
NumberOfPosts *int64 `json:"numberOfPosts,omitempty"` // Only show the notice when server has more than specified number of posts
|
||||
NumberOfUsers *int64 `json:"numberOfUsers,omitempty"` // Only show the notice when server has more than specified number of users
|
||||
ServerConfig map[string]interface{} `json:"serverConfig,omitempty"` // Map of mattermost server config paths and their values. Notice will be displayed only if; the values match the target server config; Example: serverConfig: { "PluginSettings.Enable": true, "GuestAccountsSettings.Enable":; false }
|
||||
ServerVersion []string `json:"serverVersion,omitempty"` // What server versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
|
||||
Sku *NoticeSKU `json:"sku,omitempty"`
|
||||
UserConfig map[string]interface{} `json:"userConfig,omitempty"` // Map of user's settings and their values. Notice will be displayed only if the values; match the viewing users' config; Example: userConfig: { "new_sidebar.disabled": true }
|
||||
}
|
||||
|
||||
type NoticeMessageInternal struct {
|
||||
Action *NoticeAction `json:"action,omitempty"` // Optional action to perform on action button click. (defaults to closing the notice)
|
||||
ActionParam *string `json:"actionParam,omitempty"` // Optional action parameter.; Example: {"action": "url", actionParam: "/console/some-page"}
|
||||
ActionText *string `json:"actionText,omitempty"` // Optional override for the action button text (defaults to OK)
|
||||
Description string `json:"description"` // Notice content. Use {{Mattermost}} instead of plain text to support white-labeling. Text; supports Markdown.
|
||||
Image *string `json:"image,omitempty"`
|
||||
Title string `json:"title"` // Notice title. Use {{Mattermost}} instead of plain text to support white-labeling. Text; supports Markdown.
|
||||
}
|
||||
type NoticeMessages []NoticeMessage
|
||||
|
||||
type NoticeMessage struct {
|
||||
NoticeMessageInternal
|
||||
ID string `json:"id"`
|
||||
SysAdminOnly bool `json:"sysAdminOnly"`
|
||||
TeamAdminOnly bool `json:"teamAdminOnly"`
|
||||
}
|
||||
|
||||
func (r *NoticeMessages) Marshal() ([]byte, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
func UnmarshalProductNoticeMessages(data io.Reader) (NoticeMessages, error) {
|
||||
var r NoticeMessages
|
||||
err := json.NewDecoder(data).Decode(&r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
// User role, i.e. who will see the notice. Defaults to "all"
|
||||
type NoticeAudience string
|
||||
|
||||
func NewNoticeAudience(s NoticeAudience) *NoticeAudience {
|
||||
return &s
|
||||
}
|
||||
|
||||
func (a *NoticeAudience) Matches(sysAdmin bool, teamAdmin bool) bool {
|
||||
switch *a {
|
||||
case NoticeAudience_All:
|
||||
return true
|
||||
case NoticeAudience_Member:
|
||||
return !sysAdmin && !teamAdmin
|
||||
case NoticeAudience_Sysadmin:
|
||||
return sysAdmin
|
||||
case NoticeAudience_TeamAdmin:
|
||||
return teamAdmin
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const (
|
||||
NoticeAudience_All NoticeAudience = "all"
|
||||
NoticeAudience_Member NoticeAudience = "member"
|
||||
NoticeAudience_Sysadmin NoticeAudience = "sysadmin"
|
||||
NoticeAudience_TeamAdmin NoticeAudience = "teamadmin"
|
||||
)
|
||||
|
||||
// Only show the notice on specific clients. Defaults to 'all'
|
||||
//
|
||||
// Client type. Defaults to "all"
|
||||
type NoticeClientType string
|
||||
|
||||
func NewNoticeClientType(s NoticeClientType) *NoticeClientType { return &s }
|
||||
|
||||
func (c *NoticeClientType) Matches(other NoticeClientType) bool {
|
||||
switch *c {
|
||||
case NoticeClientType_All:
|
||||
return true
|
||||
case NoticeClientType_Mobile:
|
||||
return other == NoticeClientType_MobileIos || other == NoticeClientType_MobileAndroid
|
||||
default:
|
||||
return *c == other
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
NoticeClientType_All NoticeClientType = "all"
|
||||
NoticeClientType_Desktop NoticeClientType = "desktop"
|
||||
NoticeClientType_Mobile NoticeClientType = "mobile"
|
||||
NoticeClientType_MobileAndroid NoticeClientType = "mobile-android"
|
||||
NoticeClientType_MobileIos NoticeClientType = "mobile-ios"
|
||||
NoticeClientType_Web NoticeClientType = "web"
|
||||
)
|
||||
|
||||
func NoticeClientTypeFromString(s string) (NoticeClientType, error) {
|
||||
switch s {
|
||||
case "web":
|
||||
return NoticeClientType_Web, nil
|
||||
case "mobile-ios":
|
||||
return NoticeClientType_MobileIos, nil
|
||||
case "mobile-android":
|
||||
return NoticeClientType_MobileAndroid, nil
|
||||
case "desktop":
|
||||
return NoticeClientType_Desktop, nil
|
||||
}
|
||||
return NoticeClientType_All, errors.New("Invalid client type supplied")
|
||||
}
|
||||
|
||||
// Instance type. Defaults to "both"
|
||||
type NoticeInstanceType string
|
||||
|
||||
func NewNoticeInstanceType(n NoticeInstanceType) *NoticeInstanceType { return &n }
|
||||
func (t *NoticeInstanceType) Matches(isCloud bool) bool {
|
||||
if *t == NoticeInstanceType_Both {
|
||||
return true
|
||||
}
|
||||
if *t == NoticeInstanceType_Cloud && !isCloud {
|
||||
return false
|
||||
}
|
||||
if *t == NoticeInstanceType_OnPrem && isCloud {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
NoticeInstanceType_Both NoticeInstanceType = "both"
|
||||
NoticeInstanceType_Cloud NoticeInstanceType = "cloud"
|
||||
NoticeInstanceType_OnPrem NoticeInstanceType = "onprem"
|
||||
)
|
||||
|
||||
// SKU. Defaults to "all"
|
||||
type NoticeSKU string
|
||||
|
||||
func NewNoticeSKU(s NoticeSKU) *NoticeSKU { return &s }
|
||||
func (c *NoticeSKU) Matches(s string) bool {
|
||||
switch *c {
|
||||
case NoticeSKU_All:
|
||||
return true
|
||||
case NoticeSKU_E0, NoticeSKU_Team:
|
||||
return s == ""
|
||||
default:
|
||||
return s == string(*c)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
NoticeSKU_E0 NoticeSKU = "e0"
|
||||
NoticeSKU_E10 NoticeSKU = "e10"
|
||||
NoticeSKU_E20 NoticeSKU = "e20"
|
||||
NoticeSKU_All NoticeSKU = "all"
|
||||
NoticeSKU_Team NoticeSKU = "team"
|
||||
)
|
||||
|
||||
// Optional action to perform on action button click. (defaults to closing the notice)
|
||||
//
|
||||
// Possible actions to execute on button press
|
||||
type NoticeAction string
|
||||
|
||||
const (
|
||||
URL NoticeAction = "url"
|
||||
)
|
||||
|
||||
// Definition of the table keeping the 'viewed' state of each in-product notice per user
|
||||
type ProductNoticeViewState struct {
|
||||
UserId string
|
||||
NoticeId string
|
||||
Viewed int32
|
||||
Timestamp int64
|
||||
}
|
1
vendor/github.com/mattermost/mattermost-server/v5/model/push_notification.go
generated
vendored
1
vendor/github.com/mattermost/mattermost-server/v5/model/push_notification.go
generated
vendored
@ -19,6 +19,7 @@ const (
|
||||
PUSH_TYPE_MESSAGE = "message"
|
||||
PUSH_TYPE_CLEAR = "clear"
|
||||
PUSH_TYPE_UPDATE_BADGE = "update_badge"
|
||||
PUSH_TYPE_SESSION = "session"
|
||||
PUSH_MESSAGE_V2 = "v2"
|
||||
|
||||
PUSH_SOUND_NONE = "none"
|
||||
|
277
vendor/github.com/mattermost/mattermost-server/v5/model/role.go
generated
vendored
277
vendor/github.com/mattermost/mattermost-server/v5/model/role.go
generated
vendored
@ -9,10 +9,24 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SysconsoleAncillaryPermissions maps the non-sysconsole permissions required by each sysconsole view.
|
||||
var SysconsoleAncillaryPermissions map[string][]*Permission
|
||||
var SystemManagerDefaultPermissions []string
|
||||
var SystemUserManagerDefaultPermissions []string
|
||||
var SystemReadOnlyAdminDefaultPermissions []string
|
||||
|
||||
var BuiltInSchemeManagedRoleIDs []string
|
||||
|
||||
var NewSystemRoleIDs []string
|
||||
|
||||
func init() {
|
||||
BuiltInSchemeManagedRoleIDs = []string{
|
||||
NewSystemRoleIDs = []string{
|
||||
SYSTEM_USER_MANAGER_ROLE_ID,
|
||||
SYSTEM_READ_ONLY_ADMIN_ROLE_ID,
|
||||
SYSTEM_MANAGER_ROLE_ID,
|
||||
}
|
||||
|
||||
BuiltInSchemeManagedRoleIDs = append([]string{
|
||||
SYSTEM_GUEST_ROLE_ID,
|
||||
SYSTEM_USER_ROLE_ID,
|
||||
SYSTEM_ADMIN_ROLE_ID,
|
||||
@ -29,7 +43,125 @@ func init() {
|
||||
CHANNEL_GUEST_ROLE_ID,
|
||||
CHANNEL_USER_ROLE_ID,
|
||||
CHANNEL_ADMIN_ROLE_ID,
|
||||
}, NewSystemRoleIDs...)
|
||||
|
||||
// When updating the values here, the values in mattermost-redux must also be updated.
|
||||
SysconsoleAncillaryPermissions = map[string][]*Permission{
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id: {
|
||||
PERMISSION_READ_PUBLIC_CHANNEL,
|
||||
PERMISSION_READ_CHANNEL,
|
||||
PERMISSION_READ_PUBLIC_CHANNEL_GROUPS,
|
||||
PERMISSION_READ_PRIVATE_CHANNEL_GROUPS,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS.Id: {
|
||||
PERMISSION_READ_OTHER_USERS_TEAMS,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id: {
|
||||
PERMISSION_LIST_PRIVATE_TEAMS,
|
||||
PERMISSION_LIST_PUBLIC_TEAMS,
|
||||
PERMISSION_VIEW_TEAM,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id: {
|
||||
PERMISSION_READ_JOBS,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id: {
|
||||
PERMISSION_READ_JOBS,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_READ_REPORTING.Id: {
|
||||
PERMISSION_VIEW_TEAM,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS.Id: {
|
||||
PERMISSION_EDIT_OTHER_USERS,
|
||||
PERMISSION_DEMOTE_TO_GUEST,
|
||||
PERMISSION_PROMOTE_GUEST,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id: {
|
||||
PERMISSION_MANAGE_TEAM,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS,
|
||||
PERMISSION_DELETE_PRIVATE_CHANNEL,
|
||||
PERMISSION_DELETE_PUBLIC_CHANNEL,
|
||||
PERMISSION_MANAGE_CHANNEL_ROLES,
|
||||
PERMISSION_CONVERT_PUBLIC_CHANNEL_TO_PRIVATE,
|
||||
PERMISSION_CONVERT_PRIVATE_CHANNEL_TO_PUBLIC,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id: {
|
||||
PERMISSION_MANAGE_TEAM,
|
||||
PERMISSION_MANAGE_TEAM_ROLES,
|
||||
PERMISSION_REMOVE_USER_FROM_TEAM,
|
||||
PERMISSION_JOIN_PRIVATE_TEAMS,
|
||||
PERMISSION_JOIN_PUBLIC_TEAMS,
|
||||
PERMISSION_ADD_USER_TO_TEAM,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id: {
|
||||
PERMISSION_MANAGE_TEAM,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS,
|
||||
PERMISSION_CONVERT_PUBLIC_CHANNEL_TO_PRIVATE,
|
||||
PERMISSION_CONVERT_PRIVATE_CHANNEL_TO_PUBLIC,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id: {
|
||||
PERMISSION_MANAGE_JOBS,
|
||||
},
|
||||
PERMISSION_SYSCONSOLE_WRITE_SITE.Id: {
|
||||
PERMISSION_EDIT_BRAND,
|
||||
},
|
||||
}
|
||||
|
||||
SystemUserManagerDefaultPermissions = []string{
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id,
|
||||
}
|
||||
|
||||
SystemReadOnlyAdminDefaultPermissions = []string{
|
||||
PERMISSION_SYSCONSOLE_READ_ABOUT.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_REPORTING.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_SITE.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_PLUGINS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL.Id,
|
||||
}
|
||||
|
||||
SystemManagerDefaultPermissions = []string{
|
||||
PERMISSION_SYSCONSOLE_READ_ABOUT.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_REPORTING.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_SITE.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_SITE.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_PLUGINS.Id,
|
||||
PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id,
|
||||
PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id,
|
||||
}
|
||||
|
||||
// Add the ancillary permissions to each system role
|
||||
SystemUserManagerDefaultPermissions = addAncillaryPermissions(SystemUserManagerDefaultPermissions)
|
||||
SystemReadOnlyAdminDefaultPermissions = addAncillaryPermissions(SystemReadOnlyAdminDefaultPermissions)
|
||||
SystemManagerDefaultPermissions = addAncillaryPermissions(SystemManagerDefaultPermissions)
|
||||
}
|
||||
|
||||
type RoleType string
|
||||
@ -42,6 +174,9 @@ const (
|
||||
SYSTEM_POST_ALL_ROLE_ID = "system_post_all"
|
||||
SYSTEM_POST_ALL_PUBLIC_ROLE_ID = "system_post_all_public"
|
||||
SYSTEM_USER_ACCESS_TOKEN_ROLE_ID = "system_user_access_token"
|
||||
SYSTEM_USER_MANAGER_ROLE_ID = "system_user_manager"
|
||||
SYSTEM_READ_ONLY_ADMIN_ROLE_ID = "system_read_only_admin"
|
||||
SYSTEM_MANAGER_ROLE_ID = "system_manager"
|
||||
|
||||
TEAM_GUEST_ROLE_ID = "team_guest"
|
||||
TEAM_USER_ROLE_ID = "team_user"
|
||||
@ -135,8 +270,8 @@ func (r *Role) MergeChannelHigherScopedPermissions(higherScopedPermissions *Role
|
||||
higherScopedPermissionsMap := AsStringBoolMap(higherScopedPermissions.Permissions)
|
||||
rolePermissionsMap := AsStringBoolMap(r.Permissions)
|
||||
|
||||
for _, cp := range ALL_PERMISSIONS {
|
||||
if cp.Scope != PERMISSION_SCOPE_CHANNEL {
|
||||
for _, cp := range AllPermissions {
|
||||
if cp.Scope != PermissionScopeChannel {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -150,7 +285,7 @@ func (r *Role) MergeChannelHigherScopedPermissions(higherScopedPermissions *Role
|
||||
continue
|
||||
}
|
||||
|
||||
_, permissionIsModerated := CHANNEL_MODERATED_PERMISSIONS_MAP[cp.Id]
|
||||
_, permissionIsModerated := ChannelModeratedPermissionsMap[cp.Id]
|
||||
if permissionIsModerated {
|
||||
_, presentOnRole := rolePermissionsMap[cp.Id]
|
||||
if presentOnRole && presentOnHigherScope {
|
||||
@ -216,13 +351,13 @@ func ChannelModeratedPermissionsChangedByPatch(role *Role, patch *RolePatch) []s
|
||||
patchMap := make(map[string]bool)
|
||||
|
||||
for _, permission := range role.Permissions {
|
||||
if channelModeratedPermissionName, found := CHANNEL_MODERATED_PERMISSIONS_MAP[permission]; found {
|
||||
if channelModeratedPermissionName, found := ChannelModeratedPermissionsMap[permission]; found {
|
||||
roleMap[channelModeratedPermissionName] = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, permission := range *patch.Permissions {
|
||||
if channelModeratedPermissionName, found := CHANNEL_MODERATED_PERMISSIONS_MAP[permission]; found {
|
||||
if channelModeratedPermissionName, found := ChannelModeratedPermissionsMap[permission]; found {
|
||||
patchMap[channelModeratedPermissionName] = true
|
||||
}
|
||||
}
|
||||
@ -246,11 +381,11 @@ func ChannelModeratedPermissionsChangedByPatch(role *Role, patch *RolePatch) []s
|
||||
func (r *Role) GetChannelModeratedPermissions(channelType string) map[string]bool {
|
||||
moderatedPermissions := make(map[string]bool)
|
||||
for _, permission := range r.Permissions {
|
||||
if _, found := CHANNEL_MODERATED_PERMISSIONS_MAP[permission]; !found {
|
||||
if _, found := ChannelModeratedPermissionsMap[permission]; !found {
|
||||
continue
|
||||
}
|
||||
|
||||
for moderated, moderatedPermissionValue := range CHANNEL_MODERATED_PERMISSIONS_MAP {
|
||||
for moderated, moderatedPermissionValue := range ChannelModeratedPermissionsMap {
|
||||
// the moderated permission has already been found to be true so skip this iteration
|
||||
if moderatedPermissions[moderatedPermissionValue] {
|
||||
continue
|
||||
@ -279,14 +414,14 @@ func (r *Role) RolePatchFromChannelModerationsPatch(channelModerationsPatch []*C
|
||||
// Iterate through the list of existing permissions on the role and append permissions that we want to keep.
|
||||
for _, permission := range r.Permissions {
|
||||
// Permission is not moderated so dont add it to the patch and skip the channelModerationsPatch
|
||||
if _, isModerated := CHANNEL_MODERATED_PERMISSIONS_MAP[permission]; !isModerated {
|
||||
if _, isModerated := ChannelModeratedPermissionsMap[permission]; !isModerated {
|
||||
continue
|
||||
}
|
||||
|
||||
permissionEnabled := true
|
||||
// Check if permission has a matching moderated permission name inside the channel moderation patch
|
||||
for _, channelModerationPatch := range channelModerationsPatch {
|
||||
if *channelModerationPatch.Name == CHANNEL_MODERATED_PERMISSIONS_MAP[permission] {
|
||||
if *channelModerationPatch.Name == ChannelModeratedPermissionsMap[permission] {
|
||||
// Permission key exists in patch with a value of false so skip over it
|
||||
if roleName == "members" {
|
||||
if channelModerationPatch.Roles.Members != nil && !*channelModerationPatch.Roles.Members {
|
||||
@ -307,7 +442,7 @@ func (r *Role) RolePatchFromChannelModerationsPatch(channelModerationsPatch []*C
|
||||
|
||||
// Iterate through the patch and add any permissions that dont already exist on the role
|
||||
for _, channelModerationPatch := range channelModerationsPatch {
|
||||
for permission, moderatedPermissionName := range CHANNEL_MODERATED_PERMISSIONS_MAP {
|
||||
for permission, moderatedPermissionName := range ChannelModeratedPermissionsMap {
|
||||
if roleName == "members" && channelModerationPatch.Roles.Members != nil && *channelModerationPatch.Roles.Members && *channelModerationPatch.Name == moderatedPermissionName {
|
||||
permissionsToAddToPatch[permission] = true
|
||||
}
|
||||
@ -349,7 +484,7 @@ func (r *Role) IsValidWithoutId() bool {
|
||||
|
||||
for _, permission := range r.Permissions {
|
||||
permissionValidated := false
|
||||
for _, p := range ALL_PERMISSIONS {
|
||||
for _, p := range append(AllPermissions, DeprecatedPermissions...) {
|
||||
if permission == p.Id {
|
||||
permissionValidated = true
|
||||
break
|
||||
@ -364,6 +499,23 @@ func (r *Role) IsValidWithoutId() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func CleanRoleNames(roleNames []string) ([]string, bool) {
|
||||
var cleanedRoleNames []string
|
||||
for _, roleName := range roleNames {
|
||||
if strings.TrimSpace(roleName) == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if !IsValidRoleName(roleName) {
|
||||
return roleNames, false
|
||||
}
|
||||
|
||||
cleanedRoleNames = append(cleanedRoleNames, roleName)
|
||||
}
|
||||
|
||||
return cleanedRoleNames, true
|
||||
}
|
||||
|
||||
func IsValidRoleName(roleName string) bool {
|
||||
if len(roleName) <= 0 || len(roleName) > ROLE_NAME_MAX_LENGTH {
|
||||
return false
|
||||
@ -493,6 +645,8 @@ func MakeDefaultRoles() map[string]*Role {
|
||||
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
|
||||
PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id,
|
||||
PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id,
|
||||
PERMISSION_CONVERT_PUBLIC_CHANNEL_TO_PRIVATE.Id,
|
||||
PERMISSION_CONVERT_PRIVATE_CHANNEL_TO_PUBLIC.Id,
|
||||
},
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
@ -562,6 +716,38 @@ func MakeDefaultRoles() map[string]*Role {
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[SYSTEM_USER_MANAGER_ROLE_ID] = &Role{
|
||||
Name: "system_user_manager",
|
||||
DisplayName: "authentication.roles.system_user_manager.name",
|
||||
Description: "authentication.roles.system_user_manager.description",
|
||||
Permissions: SystemUserManagerDefaultPermissions,
|
||||
SchemeManaged: false,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[SYSTEM_READ_ONLY_ADMIN_ROLE_ID] = &Role{
|
||||
Name: "system_read_only_admin",
|
||||
DisplayName: "authentication.roles.system_read_only_admin.name",
|
||||
Description: "authentication.roles.system_read_only_admin.description",
|
||||
Permissions: SystemReadOnlyAdminDefaultPermissions,
|
||||
SchemeManaged: false,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
roles[SYSTEM_MANAGER_ROLE_ID] = &Role{
|
||||
Name: "system_manager",
|
||||
DisplayName: "authentication.roles.system_manager.name",
|
||||
Description: "authentication.roles.system_manager.description",
|
||||
Permissions: SystemManagerDefaultPermissions,
|
||||
SchemeManaged: false,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
allPermissionIDs := []string{}
|
||||
for _, permission := range AllPermissions {
|
||||
allPermissionIDs = append(allPermissionIDs, permission.Id)
|
||||
}
|
||||
|
||||
roles[SYSTEM_ADMIN_ROLE_ID] = &Role{
|
||||
Name: "system_admin",
|
||||
DisplayName: "authentication.roles.global_admin.name",
|
||||
@ -569,64 +755,21 @@ func MakeDefaultRoles() map[string]*Role {
|
||||
// System admins can do anything channel and team admins can do
|
||||
// plus everything members of teams and channels can do to all teams
|
||||
// and channels on the system
|
||||
Permissions: append(
|
||||
append(
|
||||
append(
|
||||
append(
|
||||
[]string{
|
||||
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
|
||||
PERMISSION_MANAGE_SYSTEM.Id,
|
||||
PERMISSION_MANAGE_ROLES.Id,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
|
||||
PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
|
||||
PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id,
|
||||
PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
|
||||
PERMISSION_CREATE_PRIVATE_CHANNEL.Id,
|
||||
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
|
||||
PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS.Id,
|
||||
PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS.Id,
|
||||
PERMISSION_EDIT_OTHER_USERS.Id,
|
||||
PERMISSION_EDIT_OTHERS_POSTS.Id,
|
||||
PERMISSION_MANAGE_OAUTH.Id,
|
||||
PERMISSION_INVITE_USER.Id,
|
||||
PERMISSION_INVITE_GUEST.Id,
|
||||
PERMISSION_PROMOTE_GUEST.Id,
|
||||
PERMISSION_DEMOTE_TO_GUEST.Id,
|
||||
PERMISSION_DELETE_POST.Id,
|
||||
PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
PERMISSION_CREATE_TEAM.Id,
|
||||
PERMISSION_ADD_USER_TO_TEAM.Id,
|
||||
PERMISSION_LIST_USERS_WITHOUT_TEAM.Id,
|
||||
PERMISSION_MANAGE_JOBS.Id,
|
||||
PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
PERMISSION_CREATE_POST_EPHEMERAL.Id,
|
||||
PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
|
||||
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
||||
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
||||
PERMISSION_CREATE_BOT.Id,
|
||||
PERMISSION_READ_BOTS.Id,
|
||||
PERMISSION_READ_OTHERS_BOTS.Id,
|
||||
PERMISSION_MANAGE_BOTS.Id,
|
||||
PERMISSION_MANAGE_OTHERS_BOTS.Id,
|
||||
PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
PERMISSION_LIST_PRIVATE_TEAMS.Id,
|
||||
PERMISSION_JOIN_PRIVATE_TEAMS.Id,
|
||||
PERMISSION_VIEW_MEMBERS.Id,
|
||||
},
|
||||
roles[TEAM_USER_ROLE_ID].Permissions...,
|
||||
),
|
||||
roles[CHANNEL_USER_ROLE_ID].Permissions...,
|
||||
),
|
||||
roles[TEAM_ADMIN_ROLE_ID].Permissions...,
|
||||
),
|
||||
roles[CHANNEL_ADMIN_ROLE_ID].Permissions...,
|
||||
),
|
||||
Permissions: allPermissionIDs,
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
}
|
||||
|
||||
return roles
|
||||
}
|
||||
|
||||
func addAncillaryPermissions(permissions []string) []string {
|
||||
for _, permission := range permissions {
|
||||
if ancillaryPermissions, ok := SysconsoleAncillaryPermissions[permission]; ok {
|
||||
for _, ancillaryPermission := range ancillaryPermissions {
|
||||
permissions = append(permissions, ancillaryPermission.Id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return permissions
|
||||
}
|
||||
|
1
vendor/github.com/mattermost/mattermost-server/v5/model/saml.go
generated
vendored
1
vendor/github.com/mattermost/mattermost-server/v5/model/saml.go
generated
vendored
@ -15,6 +15,7 @@ const (
|
||||
USER_AUTH_SERVICE_SAML_TEXT = "SAML"
|
||||
USER_AUTH_SERVICE_IS_SAML = "isSaml"
|
||||
USER_AUTH_SERVICE_IS_MOBILE = "isMobile"
|
||||
USER_AUTH_SERVICE_IS_OAUTH = "isOAuthUser"
|
||||
)
|
||||
|
||||
type SamlAuthRequest struct {
|
||||
|
11
vendor/github.com/mattermost/mattermost-server/v5/model/search_params.go
generated
vendored
11
vendor/github.com/mattermost/mattermost-server/v5/model/search_params.go
generated
vendored
@ -4,6 +4,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@ -367,3 +368,13 @@ func ParseSearchParams(text string, timeZoneOffset int) []*SearchParams {
|
||||
|
||||
return paramsList
|
||||
}
|
||||
|
||||
func IsSearchParamsListValid(paramsList []*SearchParams) *AppError {
|
||||
// All SearchParams should have same IncludeDeletedChannels value.
|
||||
for _, params := range paramsList {
|
||||
if params.IncludeDeletedChannels != paramsList[0].IncludeDeletedChannels {
|
||||
return NewAppError("IsSearchParamsListValid", "model.search_params_list.is_valid.include_deleted_channels.app_error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
1622
vendor/github.com/mattermost/mattermost-server/v5/model/serialized_gen.go
generated
vendored
Normal file
1622
vendor/github.com/mattermost/mattermost-server/v5/model/serialized_gen.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
24
vendor/github.com/mattermost/mattermost-server/v5/model/session.go
generated
vendored
24
vendor/github.com/mattermost/mattermost-server/v5/model/session.go
generated
vendored
@ -30,6 +30,11 @@ const (
|
||||
SESSION_USER_ACCESS_TOKEN_EXPIRY = 100 * 365 // 100 years
|
||||
)
|
||||
|
||||
//msgp:tuple Session
|
||||
|
||||
// Session contains the user session details.
|
||||
// This struct's serializer methods are auto-generated. If a new field is added/removed,
|
||||
// please run make gen-serialized.
|
||||
type Session struct {
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
@ -40,6 +45,7 @@ type Session struct {
|
||||
DeviceId string `json:"device_id"`
|
||||
Roles string `json:"roles"`
|
||||
IsOAuth bool `json:"is_oauth"`
|
||||
ExpiredNotify bool `json:"expired_notify"`
|
||||
Props StringMap `json:"props"`
|
||||
TeamMembers []*TeamMember `json:"team_members" db:"-"`
|
||||
Local bool `json:"local" db:"-"`
|
||||
@ -114,6 +120,9 @@ func (me *Session) IsExpired() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Deprecated: SetExpireInDays is deprecated and should not be used.
|
||||
// Use (*App).SetSessionExpireInDays instead which handles the
|
||||
// cases where the new ExpiresAt is not relative to CreateAt.
|
||||
func (me *Session) SetExpireInDays(days int) {
|
||||
if me.CreateAt == 0 {
|
||||
me.ExpiresAt = GetMillis() + (1000 * 60 * 60 * 24 * int64(days))
|
||||
@ -171,8 +180,21 @@ func (me *Session) IsSaml() bool {
|
||||
return isSaml
|
||||
}
|
||||
|
||||
func (me *Session) IsOAuthUser() bool {
|
||||
val, ok := me.Props[USER_AUTH_SERVICE_IS_OAUTH]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
isOAuthUser, err := strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
mlog.Error("Error parsing boolean property from Session", mlog.Err(err))
|
||||
return false
|
||||
}
|
||||
return isOAuthUser
|
||||
}
|
||||
|
||||
func (me *Session) IsSSOLogin() bool {
|
||||
return me.IsOAuth || me.IsSaml()
|
||||
return me.IsOAuthUser() || me.IsSaml()
|
||||
}
|
||||
|
||||
func (me *Session) GetUserRoles() []string {
|
||||
|
3
vendor/github.com/mattermost/mattermost-server/v5/model/status.go
generated
vendored
3
vendor/github.com/mattermost/mattermost-server/v5/model/status.go
generated
vendored
@ -35,7 +35,8 @@ func (o *Status) ToJson() string {
|
||||
}
|
||||
|
||||
func (o *Status) ToClusterJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
oCopy := *o
|
||||
b, _ := json.Marshal(oCopy)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
|
151
vendor/github.com/mattermost/mattermost-server/v5/model/system.go
generated
vendored
151
vendor/github.com/mattermost/mattermost-server/v5/model/system.go
generated
vendored
@ -10,15 +10,37 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SYSTEM_DIAGNOSTIC_ID = "DiagnosticId"
|
||||
SYSTEM_RAN_UNIT_TESTS = "RanUnitTests"
|
||||
SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime"
|
||||
SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId"
|
||||
SYSTEM_LAST_COMPLIANCE_TIME = "LastComplianceTime"
|
||||
SYSTEM_ASYMMETRIC_SIGNING_KEY = "AsymmetricSigningKey"
|
||||
SYSTEM_POST_ACTION_COOKIE_SECRET = "PostActionCookieSecret"
|
||||
SYSTEM_INSTALLATION_DATE_KEY = "InstallationDate"
|
||||
SYSTEM_FIRST_SERVER_RUN_TIMESTAMP_KEY = "FirstServerRunTimestamp"
|
||||
SYSTEM_TELEMETRY_ID = "DiagnosticId"
|
||||
SYSTEM_RAN_UNIT_TESTS = "RanUnitTests"
|
||||
SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime"
|
||||
SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId"
|
||||
SYSTEM_LAST_COMPLIANCE_TIME = "LastComplianceTime"
|
||||
SYSTEM_ASYMMETRIC_SIGNING_KEY = "AsymmetricSigningKey"
|
||||
SYSTEM_POST_ACTION_COOKIE_SECRET = "PostActionCookieSecret"
|
||||
SYSTEM_INSTALLATION_DATE_KEY = "InstallationDate"
|
||||
SYSTEM_FIRST_SERVER_RUN_TIMESTAMP_KEY = "FirstServerRunTimestamp"
|
||||
SYSTEM_CLUSTER_ENCRYPTION_KEY = "ClusterEncryptionKey"
|
||||
SYSTEM_UPGRADED_FROM_TE_ID = "UpgradedFromTE"
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_TEAMS_5 = "warn_metric_number_of_teams_5"
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_CHANNELS_50 = "warn_metric_number_of_channels_50"
|
||||
SYSTEM_WARN_METRIC_MFA = "warn_metric_mfa"
|
||||
SYSTEM_WARN_METRIC_EMAIL_DOMAIN = "warn_metric_email_domain"
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_100 = "warn_metric_number_of_active_users_100"
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_200 = "warn_metric_number_of_active_users_200"
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_300 = "warn_metric_number_of_active_users_300"
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500 = "warn_metric_number_of_active_users_500"
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_POSTS_2M = "warn_metric_number_of_posts_2M"
|
||||
SYSTEM_WARN_METRIC_LAST_RUN_TIMESTAMP_KEY = "LastWarnMetricRunTimestamp"
|
||||
)
|
||||
|
||||
const (
|
||||
WARN_METRIC_STATUS_LIMIT_REACHED = "true"
|
||||
WARN_METRIC_STATUS_RUNONCE = "runonce"
|
||||
WARN_METRIC_STATUS_ACK = "ack"
|
||||
WARN_METRIC_STATUS_STORE_PREFIX = "warn_metric_"
|
||||
WARN_METRIC_JOB_INTERVAL = 24 * 7
|
||||
WARN_METRIC_NUMBER_OF_ACTIVE_USERS_25 = 25
|
||||
WARN_METRIC_JOB_WAIT_TIME = 1000 * 3600 * 24 * 7 // 7 days
|
||||
)
|
||||
|
||||
type System struct {
|
||||
@ -69,3 +91,114 @@ func ServerBusyStateFromJson(r io.Reader) *ServerBusyState {
|
||||
json.NewDecoder(r).Decode(&sbs)
|
||||
return sbs
|
||||
}
|
||||
|
||||
var WarnMetricsTable = map[string]WarnMetric{
|
||||
SYSTEM_WARN_METRIC_MFA: {
|
||||
Id: SYSTEM_WARN_METRIC_MFA,
|
||||
Limit: -1,
|
||||
IsBotOnly: true,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SYSTEM_WARN_METRIC_EMAIL_DOMAIN: {
|
||||
Id: SYSTEM_WARN_METRIC_EMAIL_DOMAIN,
|
||||
Limit: -1,
|
||||
IsBotOnly: true,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_TEAMS_5: {
|
||||
Id: SYSTEM_WARN_METRIC_NUMBER_OF_TEAMS_5,
|
||||
Limit: 5,
|
||||
IsBotOnly: true,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_CHANNELS_50: {
|
||||
Id: SYSTEM_WARN_METRIC_NUMBER_OF_CHANNELS_50,
|
||||
Limit: 50,
|
||||
IsBotOnly: true,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_100: {
|
||||
Id: SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_100,
|
||||
Limit: 100,
|
||||
IsBotOnly: true,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_200: {
|
||||
Id: SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_200,
|
||||
Limit: 200,
|
||||
IsBotOnly: true,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_300: {
|
||||
Id: SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_300,
|
||||
Limit: 300,
|
||||
IsBotOnly: true,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500: {
|
||||
Id: SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500,
|
||||
Limit: 500,
|
||||
IsBotOnly: false,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SYSTEM_WARN_METRIC_NUMBER_OF_POSTS_2M: {
|
||||
Id: SYSTEM_WARN_METRIC_NUMBER_OF_POSTS_2M,
|
||||
Limit: 2000000,
|
||||
IsBotOnly: false,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
}
|
||||
|
||||
type WarnMetric struct {
|
||||
Id string
|
||||
Limit int64
|
||||
IsBotOnly bool
|
||||
IsRunOnce bool
|
||||
}
|
||||
|
||||
type WarnMetricDisplayTexts struct {
|
||||
BotTitle string
|
||||
BotMessageBody string
|
||||
BotSuccessMessage string
|
||||
EmailBody string
|
||||
}
|
||||
type WarnMetricStatus struct {
|
||||
Id string `json:"id"`
|
||||
Limit int64 `json:"limit"`
|
||||
Acked bool `json:"acked"`
|
||||
StoreStatus string `json:"store_status,omitempty"`
|
||||
}
|
||||
|
||||
func (wms *WarnMetricStatus) ToJson() string {
|
||||
b, _ := json.Marshal(wms)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func WarnMetricStatusFromJson(data io.Reader) *WarnMetricStatus {
|
||||
var o WarnMetricStatus
|
||||
if err := json.NewDecoder(data).Decode(&o); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
return &o
|
||||
}
|
||||
}
|
||||
|
||||
func MapWarnMetricStatusToJson(o map[string]*WarnMetricStatus) string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
type SendWarnMetricAck struct {
|
||||
ForceAck bool `json:"forceAck"`
|
||||
}
|
||||
|
||||
func (swma *SendWarnMetricAck) ToJson() string {
|
||||
b, _ := json.Marshal(swma)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func SendWarnMetricAckFromJson(r io.Reader) *SendWarnMetricAck {
|
||||
var swma *SendWarnMetricAck
|
||||
json.NewDecoder(r).Decode(&swma)
|
||||
return swma
|
||||
}
|
||||
|
9
vendor/github.com/mattermost/mattermost-server/v5/model/team_search.go
generated
vendored
9
vendor/github.com/mattermost/mattermost-server/v5/model/team_search.go
generated
vendored
@ -9,9 +9,12 @@ import (
|
||||
)
|
||||
|
||||
type TeamSearch struct {
|
||||
Term string `json:"term"`
|
||||
Page *int `json:"page,omitempty"`
|
||||
PerPage *int `json:"per_page,omitempty"`
|
||||
Term string `json:"term"`
|
||||
Page *int `json:"page,omitempty"`
|
||||
PerPage *int `json:"per_page,omitempty"`
|
||||
AllowOpenInvite *bool `json:"allow_open_invite,omitempty"`
|
||||
GroupConstrained *bool `json:"group_constrained,omitempty"`
|
||||
IncludeGroupConstrained *bool `json:"include_group_constrained,omitempty"`
|
||||
}
|
||||
|
||||
func (t *TeamSearch) IsPaginated() bool {
|
||||
|
25
vendor/github.com/mattermost/mattermost-server/v5/model/typing_request.go
generated
vendored
Normal file
25
vendor/github.com/mattermost/mattermost-server/v5/model/typing_request.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type TypingRequest struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
ParentId string `json:"parent_id"`
|
||||
}
|
||||
|
||||
func (o *TypingRequest) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func TypingRequestFromJson(data io.Reader) *TypingRequest {
|
||||
var o *TypingRequest
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
141
vendor/github.com/mattermost/mattermost-server/v5/model/upload_session.go
generated
vendored
Normal file
141
vendor/github.com/mattermost/mattermost-server/v5/model/upload_session.go
generated
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// UploadType defines the type of an upload.
|
||||
type UploadType string
|
||||
|
||||
const (
|
||||
UploadTypeAttachment UploadType = "attachment"
|
||||
UploadTypeImport UploadType = "import"
|
||||
)
|
||||
|
||||
// UploadSession contains information used to keep track of a file upload.
|
||||
type UploadSession struct {
|
||||
// The unique identifier for the session.
|
||||
Id string `json:"id"`
|
||||
// The type of the upload.
|
||||
Type UploadType `json:"type"`
|
||||
// The timestamp of creation.
|
||||
CreateAt int64 `json:"create_at"`
|
||||
// The id of the user performing the upload.
|
||||
UserId string `json:"user_id"`
|
||||
// The id of the channel to upload to.
|
||||
ChannelId string `json:"channel_id"`
|
||||
// The name of the file to upload.
|
||||
Filename string `json:"filename"`
|
||||
// The path where the file is stored.
|
||||
Path string `json:"-"`
|
||||
// The size of the file to upload.
|
||||
FileSize int64 `json:"file_size"`
|
||||
// The amount of received data in bytes. If equal to FileSize it means the
|
||||
// upload has finished.
|
||||
FileOffset int64 `json:"file_offset"`
|
||||
}
|
||||
|
||||
// ToJson serializes the UploadSession into JSON and returns it as string.
|
||||
func (us *UploadSession) ToJson() string {
|
||||
b, _ := json.Marshal(us)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// UploadSessionsToJson serializes a list of UploadSession into JSON and
|
||||
// returns it as string.
|
||||
func UploadSessionsToJson(uss []*UploadSession) string {
|
||||
b, _ := json.Marshal(uss)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// UploadSessionsFromJson deserializes a list of UploadSession from JSON data.
|
||||
func UploadSessionsFromJson(data io.Reader) []*UploadSession {
|
||||
decoder := json.NewDecoder(data)
|
||||
var uss []*UploadSession
|
||||
if err := decoder.Decode(&uss); err != nil {
|
||||
return nil
|
||||
}
|
||||
return uss
|
||||
}
|
||||
|
||||
// UploadSessionFromJson deserializes the UploadSession from JSON data.
|
||||
func UploadSessionFromJson(data io.Reader) *UploadSession {
|
||||
decoder := json.NewDecoder(data)
|
||||
var us UploadSession
|
||||
if err := decoder.Decode(&us); err != nil {
|
||||
return nil
|
||||
}
|
||||
return &us
|
||||
}
|
||||
|
||||
// PreSave is a utility function used to fill required information.
|
||||
func (us *UploadSession) PreSave() {
|
||||
if us.Id == "" {
|
||||
us.Id = NewId()
|
||||
}
|
||||
|
||||
if us.CreateAt == 0 {
|
||||
us.CreateAt = GetMillis()
|
||||
}
|
||||
}
|
||||
|
||||
// IsValid validates an UploadType. It returns an error in case of
|
||||
// failure.
|
||||
func (t UploadType) IsValid() error {
|
||||
switch t {
|
||||
case UploadTypeAttachment:
|
||||
return nil
|
||||
case UploadTypeImport:
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
return fmt.Errorf("invalid UploadType %s", t)
|
||||
}
|
||||
|
||||
// IsValid validates an UploadSession. It returns an error in case of
|
||||
// failure.
|
||||
func (us *UploadSession) IsValid() *AppError {
|
||||
if !IsValidId(us.Id) {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if err := us.Type.IsValid(); err != nil {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.type.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidId(us.UserId) {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.user_id.app_error", nil, "id="+us.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if us.Type == UploadTypeAttachment && !IsValidId(us.ChannelId) {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.channel_id.app_error", nil, "id="+us.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if us.CreateAt == 0 {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.create_at.app_error", nil, "id="+us.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if us.Filename == "" {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.filename.app_error", nil, "id="+us.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if us.FileSize <= 0 {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.file_size.app_error", nil, "id="+us.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if us.FileOffset < 0 || us.FileOffset > us.FileSize {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.file_offset.app_error", nil, "id="+us.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if us.Path == "" {
|
||||
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.path.app_error", nil, "id="+us.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
6
vendor/github.com/mattermost/mattermost-server/v5/model/user.go
generated
vendored
6
vendor/github.com/mattermost/mattermost-server/v5/model/user.go
generated
vendored
@ -59,6 +59,11 @@ const (
|
||||
USER_LOCALE_MAX_LENGTH = 5
|
||||
)
|
||||
|
||||
//msgp:tuple User
|
||||
|
||||
// User contains the details about the user.
|
||||
// This struct's serializer methods are auto-generated. If a new field is added/removed,
|
||||
// please run make gen-serialized.
|
||||
type User struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at,omitempty"`
|
||||
@ -124,6 +129,7 @@ type UserForIndexing struct {
|
||||
Nickname string `json:"nickname"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
Roles string `json:"roles"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
TeamsIds []string `json:"team_id"`
|
||||
|
8
vendor/github.com/mattermost/mattermost-server/v5/model/user_count.go
generated
vendored
8
vendor/github.com/mattermost/mattermost-server/v5/model/user_count.go
generated
vendored
@ -13,6 +13,14 @@ type UserCountOptions struct {
|
||||
ExcludeRegularUsers bool
|
||||
// Only include users on a specific team. "" for any team.
|
||||
TeamId string
|
||||
// Only include users on a specific channel. "" for any channel.
|
||||
ChannelId string
|
||||
// Restrict to search in a list of teams and channels
|
||||
ViewRestrictions *ViewUsersRestrictions
|
||||
// Only include users matching any of the given system wide roles.
|
||||
Roles []string
|
||||
// Only include users matching any of the given channel roles, must be used with ChannelId.
|
||||
ChannelRoles []string
|
||||
// Only include users matching any of the given team roles, must be used with TeamId.
|
||||
TeamRoles []string
|
||||
}
|
||||
|
8
vendor/github.com/mattermost/mattermost-server/v5/model/user_get.go
generated
vendored
8
vendor/github.com/mattermost/mattermost-server/v5/model/user_get.go
generated
vendored
@ -12,6 +12,8 @@ type UserGetOptions struct {
|
||||
InChannelId string
|
||||
// Filters the users not in the channel
|
||||
NotInChannelId string
|
||||
// Filters the users in the group
|
||||
InGroupId string
|
||||
// Filters the users group constrained
|
||||
GroupConstrained bool
|
||||
// Filters the users without a team
|
||||
@ -22,6 +24,12 @@ type UserGetOptions struct {
|
||||
Active bool
|
||||
// Filters for the given role
|
||||
Role string
|
||||
// Filters for users matching any of the given system wide roles
|
||||
Roles []string
|
||||
// Filters for users matching any of the given channel roles, must be used with InChannelId
|
||||
ChannelRoles []string
|
||||
// Filters for users matching any of the given team roles, must be used with InTeamId
|
||||
TeamRoles []string
|
||||
// Sorting option
|
||||
Sort string
|
||||
// Restrict to search in a list of teams and channels
|
||||
|
30
vendor/github.com/mattermost/mattermost-server/v5/model/user_search.go
generated
vendored
30
vendor/github.com/mattermost/mattermost-server/v5/model/user_search.go
generated
vendored
@ -13,16 +13,20 @@ const USER_SEARCH_DEFAULT_LIMIT = 100
|
||||
|
||||
// UserSearch captures the parameters provided by a client for initiating a user search.
|
||||
type UserSearch struct {
|
||||
Term string `json:"term"`
|
||||
TeamId string `json:"team_id"`
|
||||
NotInTeamId string `json:"not_in_team_id"`
|
||||
InChannelId string `json:"in_channel_id"`
|
||||
NotInChannelId string `json:"not_in_channel_id"`
|
||||
GroupConstrained bool `json:"group_constrained"`
|
||||
AllowInactive bool `json:"allow_inactive"`
|
||||
WithoutTeam bool `json:"without_team"`
|
||||
Limit int `json:"limit"`
|
||||
Role string `json:"role"`
|
||||
Term string `json:"term"`
|
||||
TeamId string `json:"team_id"`
|
||||
NotInTeamId string `json:"not_in_team_id"`
|
||||
InChannelId string `json:"in_channel_id"`
|
||||
NotInChannelId string `json:"not_in_channel_id"`
|
||||
InGroupId string `json:"in_group_id"`
|
||||
GroupConstrained bool `json:"group_constrained"`
|
||||
AllowInactive bool `json:"allow_inactive"`
|
||||
WithoutTeam bool `json:"without_team"`
|
||||
Limit int `json:"limit"`
|
||||
Role string `json:"role"`
|
||||
Roles []string `json:"roles"`
|
||||
ChannelRoles []string `json:"channel_roles"`
|
||||
TeamRoles []string `json:"team_roles"`
|
||||
}
|
||||
|
||||
// ToJson convert a User to a json string
|
||||
@ -60,6 +64,12 @@ type UserSearchOptions struct {
|
||||
Limit int
|
||||
// Filters for the given role
|
||||
Role string
|
||||
// Filters for users that have any of the given system roles
|
||||
Roles []string
|
||||
// Filters for users that have the given channel roles to be used when searching in a channel
|
||||
ChannelRoles []string
|
||||
// Filters for users that have the given team roles to be used when searching in a team
|
||||
TeamRoles []string
|
||||
// Restrict to search in a list of teams and channels
|
||||
ViewRestrictions *ViewUsersRestrictions
|
||||
// List of allowed channels
|
||||
|
8
vendor/github.com/mattermost/mattermost-server/v5/model/utils.go
generated
vendored
8
vendor/github.com/mattermost/mattermost-server/v5/model/utils.go
generated
vendored
@ -659,12 +659,12 @@ func AsStringBoolMap(list []string) map[string]bool {
|
||||
|
||||
// SanitizeUnicode will remove undesirable Unicode characters from a string.
|
||||
func SanitizeUnicode(s string) string {
|
||||
return strings.Map(filterBlacklist, s)
|
||||
return strings.Map(filterBlocklist, s)
|
||||
}
|
||||
|
||||
// filterBlacklist returns `r` if it is not in the blacklist, otherwise drop (-1).
|
||||
// Blacklist is taken from https://www.w3.org/TR/unicode-xml/#Charlist
|
||||
func filterBlacklist(r rune) rune {
|
||||
// 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
|
||||
|
3
vendor/github.com/mattermost/mattermost-server/v5/model/version.go
generated
vendored
3
vendor/github.com/mattermost/mattermost-server/v5/model/version.go
generated
vendored
@ -13,6 +13,9 @@ import (
|
||||
// It should be maintained in chronological order with most current
|
||||
// release at the front of the list.
|
||||
var versions = []string{
|
||||
"5.28.0",
|
||||
"5.27.0",
|
||||
"5.26.0",
|
||||
"5.25.0",
|
||||
"5.24.0",
|
||||
"5.23.0",
|
||||
|
6
vendor/github.com/mattermost/mattermost-server/v5/model/websocket_message.go
generated
vendored
6
vendor/github.com/mattermost/mattermost-server/v5/model/websocket_message.go
generated
vendored
@ -62,6 +62,12 @@ const (
|
||||
WEBSOCKET_EVENT_RECEIVED_GROUP_NOT_ASSOCIATED_TO_TEAM = "received_group_not_associated_to_team"
|
||||
WEBSOCKET_EVENT_RECEIVED_GROUP_ASSOCIATED_TO_CHANNEL = "received_group_associated_to_channel"
|
||||
WEBSOCKET_EVENT_RECEIVED_GROUP_NOT_ASSOCIATED_TO_CHANNEL = "received_group_not_associated_to_channel"
|
||||
WEBSOCKET_EVENT_SIDEBAR_CATEGORY_CREATED = "sidebar_category_created"
|
||||
WEBSOCKET_EVENT_SIDEBAR_CATEGORY_UPDATED = "sidebar_category_updated"
|
||||
WEBSOCKET_EVENT_SIDEBAR_CATEGORY_DELETED = "sidebar_category_deleted"
|
||||
WEBSOCKET_EVENT_SIDEBAR_CATEGORY_ORDER_UPDATED = "sidebar_category_order_updated"
|
||||
WEBSOCKET_WARN_METRIC_STATUS_RECEIVED = "warn_metric_status_received"
|
||||
WEBSOCKET_WARN_METRIC_STATUS_REMOVED = "warn_metric_status_removed"
|
||||
)
|
||||
|
||||
type WebSocketMessage interface {
|
||||
|
Reference in New Issue
Block a user