mirror of
https://github.com/mattermost/focalboard.git
synced 2024-11-19 20:32:00 +02:00
[Refactor]: updated dependency for focalboard server (#5009)
* refactor: updated dependency for focalboard server * chore: more dependency fixes * refactor: removed the unless code * refactor: added ctx for login and removed unnessary code * refactor: bump up go version * refactor: removed the commented code * chore: upgraded golinter version * fix: linter issue * refactor: removed feature flg fix golinter * refactor: removed feature flag from code * revert: statistic and it's function * refactor: removed ProductLimit related code * refactor: removed isWithinViewsLimit implementation * refactor: moved function GetUsedCardsCount to statistics.go from cloud.go * refactor: removed insight code board * refactor: removed limit dialog * refactor: updated dependencies for linux * chore: golinter fix * chore: updated helper test function to use newLogger * fix: go test * refactor: db ping attempts from config * revert: feature in action * revert: feature flag in action * revert: boardsEditor setting --------- Co-authored-by: Rajat Dabade <rajat@Rajats-MacBook-Pro.local>
This commit is contained in:
parent
7a31925d8a
commit
c8e729b6fe
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -33,7 +33,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: "Test server: ${{matrix['db']}}"
|
||||
run: cd focalboard; make server-test-${{matrix['db']}}
|
||||
@ -53,7 +53,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
@ -92,7 +92,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: "Test server (minimum): ${{matrix['db']}}"
|
||||
run: cd focalboard; make server-test-mini-${{matrix['db']}}
|
||||
@ -114,7 +114,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: "Test server (minimum): ${{matrix['db']}}"
|
||||
run: cd focalboard; make server-test-mini-${{matrix['db']}}
|
||||
|
8
.github/workflows/dev-release.yml
vendored
8
.github/workflows/dev-release.yml
vendored
@ -38,7 +38,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
@ -98,7 +98,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: List Xcode versions
|
||||
run: ls -n /Applications/ | grep Xcode*
|
||||
@ -144,7 +144,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@v1
|
||||
@ -197,7 +197,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
|
4
.github/workflows/lint-server.yml
vendored
4
.github/workflows/lint-server.yml
vendored
@ -30,12 +30,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
path: "focalboard"
|
||||
- name: set up golangci-lint
|
||||
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.50.1
|
||||
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.59.0
|
||||
- name: lint
|
||||
run: |
|
||||
cd focalboard
|
||||
|
8
.github/workflows/prod-release.yml
vendored
8
.github/workflows/prod-release.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
@ -96,7 +96,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: List Xcode versions
|
||||
run: ls -n /Applications/ | grep Xcode*
|
||||
@ -143,7 +143,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@v1
|
||||
@ -197,7 +197,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.5
|
||||
go-version: 1.21
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
|
@ -3,6 +3,7 @@
|
||||
"port": 8000,
|
||||
"dbtype": "sqlite3",
|
||||
"dbconfig": "./focalboard.db?_busy_timeout=5000",
|
||||
"dbpingattempts": 5,
|
||||
"dbtableprefix": "",
|
||||
"postgres_dbconfig": "dbname=focalboard sslmode=disable",
|
||||
"useSSL": false,
|
||||
|
156
linux/go.mod
156
linux/go.mod
@ -1,122 +1,118 @@
|
||||
module github.com/mattermost/focalboard/linux
|
||||
|
||||
go 1.19
|
||||
go 1.21
|
||||
|
||||
toolchain go1.21.8
|
||||
|
||||
replace github.com/mattermost/focalboard/server => ../server
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/mattermost/focalboard/server v0.0.0-20230104182634-f909c2552e37
|
||||
github.com/mattermost/mattermost-server/v6 v6.0.0-20230321114510-b61c096497ac
|
||||
github.com/mattermost/mattermost/server/public v0.1.3
|
||||
github.com/webview/webview v0.0.0-20220314230258-a2b7746141c3
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Masterminds/squirrel v1.5.3 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.15.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/graph-gophers/graphql-go v1.5.1-0.20230110080634-edea822f558a // indirect
|
||||
github.com/hashicorp/go-hclog v1.4.0 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.8 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.1 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.15.14 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/krolaw/zipstream v0.0.0-20180621105154-0a2661891f94 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/lib/pq v1.10.7 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.16 // indirect
|
||||
github.com/mattermost/mattermost-plugin-api v0.1.1 // indirect
|
||||
github.com/mattermost/morph v1.0.5-0.20221115094356-4c18a75b1f5e // indirect
|
||||
github.com/mattermost/squirrel v0.2.0 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956 // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.21 // indirect
|
||||
github.com/mattermost/mattermost/server/v8 v8.0.0-20240529104128-9d30a62c9471 // indirect
|
||||
github.com/mattermost/morph v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.45 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.70 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.12.1 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.33.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect
|
||||
github.com/rivo/uniseg v0.4.3 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.19.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/rudderlabs/analytics-go v3.3.3+incompatible // indirect
|
||||
github.com/segmentio/backo-go v1.0.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/segmentio/backo-go v1.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.10.1 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/tidwall/gjson v1.14.4 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/stretchr/testify v1.9.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tidwall/gjson v1.17.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/tinylib/msgp v1.1.9 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/wiggin77/merror v1.0.4 // indirect
|
||||
github.com/wiggin77/merror v1.0.5 // indirect
|
||||
github.com/wiggin77/srslog v1.0.1 // indirect
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
|
||||
github.com/yuin/goldmark v1.5.3 // indirect
|
||||
golang.org/x/crypto v0.5.0 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/tools v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230104163317-caabf589fcbf // indirect
|
||||
google.golang.org/grpc v1.51.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
github.com/yuin/goldmark v1.7.1 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240529005216-23cca8864a10 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
|
||||
google.golang.org/grpc v1.64.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.22.2 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.20.1 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect
|
||||
modernc.org/libc v1.50.9 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.29.10 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
)
|
||||
|
2072
linux/go.sum
2072
linux/go.sum
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/permissions/localpermissions"
|
||||
"github.com/webview/webview"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
var sessionToken string = "su-" + uuid.New().String()
|
||||
@ -71,13 +71,13 @@ func runServer(port int) (*server.Server, error) {
|
||||
permissionsService := localpermissions.New(db, logger)
|
||||
|
||||
params := server.Params{
|
||||
Cfg: config,
|
||||
SingleUserToken: sessionToken,
|
||||
DBStore: db,
|
||||
Logger: logger,
|
||||
ServerID: "",
|
||||
WSAdapter: nil,
|
||||
NotifyBackends: nil,
|
||||
Cfg: config,
|
||||
SingleUserToken: sessionToken,
|
||||
DBStore: db,
|
||||
Logger: logger,
|
||||
ServerID: "",
|
||||
WSAdapter: nil,
|
||||
NotifyBackends: nil,
|
||||
PermissionsService: permissionsService,
|
||||
}
|
||||
|
||||
|
@ -31,10 +31,7 @@ linters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
- deadcode
|
||||
- ineffassign
|
||||
- structcheck
|
||||
- varcheck
|
||||
- unparam
|
||||
- errcheck
|
||||
- govet
|
||||
@ -48,13 +45,12 @@ linters:
|
||||
- staticcheck
|
||||
- prealloc
|
||||
- asciicheck
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
- goconst
|
||||
- gocritic
|
||||
- godot
|
||||
- goerr113
|
||||
- err113
|
||||
- goheader
|
||||
- revive
|
||||
- nakedret
|
||||
@ -75,9 +71,7 @@ issues:
|
||||
exclude-rules:
|
||||
- path: server/manifest.go
|
||||
linters:
|
||||
- deadcode
|
||||
- unused
|
||||
- varcheck
|
||||
- path: server/configuration.go
|
||||
linters:
|
||||
- unused
|
||||
|
@ -1,15 +1,35 @@
|
||||
module github.com/mattermost/mattermost-plugin-starter-template/build
|
||||
|
||||
go 1.19
|
||||
go 1.21
|
||||
|
||||
toolchain go1.21.8
|
||||
|
||||
require (
|
||||
github.com/go-git/go-git/v5 v5.1.0
|
||||
github.com/mattermost/mattermost-server/v6 v6.0.0-20220802151854-f07c31c5d933
|
||||
github.com/mattermost/mattermost/server/public v0.1.3
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.7.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.2 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/grpc v1.62.0 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
@ -17,11 +37,11 @@ require (
|
||||
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a // indirect
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.0.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.1 // indirect
|
||||
github.com/graph-gophers/graphql-go v1.4.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
@ -30,8 +50,9 @@ require (
|
||||
github.com/klauspost/compress v1.15.6 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.13 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.15 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956 // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.21 // indirect
|
||||
github.com/mattermost/mattermost/server/public v0.1.3
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.28 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
@ -40,23 +61,23 @@ require (
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/philhofer/fwd v1.1.1 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/tinylib/msgp v1.1.6 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/tinylib/msgp v1.1.9 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/wiggin77/merror v1.0.3 // indirect
|
||||
github.com/wiggin77/merror v1.0.5 // indirect
|
||||
github.com/wiggin77/srslog v1.0.1 // indirect
|
||||
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
|
||||
golang.org/x/net v0.0.0-20220614195744-fb05da6f9022 // indirect
|
||||
golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/crypto v0.20.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
gopkg.in/ini.v1 v1.66.6 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
@ -18,6 +18,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
@ -32,6 +34,9 @@ github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a h1:
|
||||
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a/go.mod h1:emQhSYTXqB0xxjLITTw4EaWZ+8IIQYw+kx9GqNUKdLg=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
@ -43,6 +48,8 @@ github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
|
||||
github.com/go-asn1-ber/asn1-ber v1.3.2-0.20191121212151-29be175fc3a3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
@ -62,9 +69,13 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
@ -75,15 +86,29 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/graph-gophers/graphql-go v1.4.0 h1:JE9wveRTSXwJyjdRd6bOQ7Ob5bewTUQ58Jv4OiVdpdE=
|
||||
github.com/graph-gophers/graphql-go v1.4.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I=
|
||||
github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A=
|
||||
github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI=
|
||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
@ -116,10 +141,25 @@ github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 h1:Khvh6waxG
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404/go.mod h1:RyS7FDNQlzF1PsjbJWHRI35exqaKGSO9qD4iv8QjE34=
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d h1:/RJ/UV7M5c7L2TQ0KNm4yZxxFvC1nvRz/gY/Daa35aI=
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d/go.mod h1:HLbgMEI5K131jpxGazJ97AxfPDt31osq36YS1oxFQPQ=
|
||||
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956 h1:Y1Tu/swM31pVwwb2BTCsOdamENjjWCI6qmfHLbk6OZI=
|
||||
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956/go.mod h1:SRl30Lb7/QoYyohYeVBuqYvvmXSZJxZgiV3Zf6VbxjI=
|
||||
github.com/mattermost/logr/v2 v2.0.15 h1:+WNbGcsc3dBao65eXlceB6dTILNJRIrvubnsTl3zBew=
|
||||
github.com/mattermost/logr/v2 v2.0.15/go.mod h1:mpPp935r5dIkFDo2y9Q87cQWhFR/4xXpNh0k/y8Hmwg=
|
||||
github.com/mattermost/logr/v2 v2.0.21 h1:CMHsP+nrbRlEC4g7BwOk1GAnMtHkniFhlSQPXy52be4=
|
||||
github.com/mattermost/logr/v2 v2.0.21/go.mod h1:kZkB/zqKL9e+RY5gB3vGpsyenC+TpuiOenjMkvJJbzc=
|
||||
github.com/mattermost/mattermost-server/v6 v6.0.0-20220802151854-f07c31c5d933 h1:h7EibO8cwWeK8dLhC/A5tKGbkYSuJKZ0+2EXW7jDHoA=
|
||||
github.com/mattermost/mattermost-server/v6 v6.0.0-20220802151854-f07c31c5d933/go.mod h1:otnBnKY9Y0eNkUKeD161de+BUBlESwANTnrkPT/392Y=
|
||||
github.com/mattermost/mattermost/server/public v0.1.3 h1:A3hQ3rNCwHfKAVxe7Hk3Zd9p2pyUKRmxtRPnkWP5SFM=
|
||||
github.com/mattermost/mattermost/server/public v0.1.3/go.mod h1:PDPb/iqzJJ5ZvK/m70oDF55AXN/cOvVFj96Yu4e6j+Q=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
@ -130,6 +170,8 @@ github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo
|
||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -140,6 +182,8 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
|
||||
@ -149,6 +193,8 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ=
|
||||
github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
|
||||
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -188,6 +234,7 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED
|
||||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@ -195,21 +242,29 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw=
|
||||
github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw=
|
||||
github.com/tinylib/msgp v1.1.9 h1:SHf3yoO2sGA0veCJeCBYLHuttAVFHGm2RHgNodW7wQU=
|
||||
github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
github.com/wiggin77/merror v1.0.2/go.mod h1:uQTcIU0Z6jRK4OwqganPYerzQxSFJ4GSHM3aurxxQpg=
|
||||
github.com/wiggin77/merror v1.0.3 h1:8+ZHV+aSnJoYghE3EUThl15C6rvF2TYRSvOSBjdmNR8=
|
||||
github.com/wiggin77/merror v1.0.3/go.mod h1:H2ETSu7/bPE0Ymf4bEwdUoo73OOEkdClnoRisfw0Nm0=
|
||||
github.com/wiggin77/merror v1.0.5 h1:P+lzicsn4vPMycAf2mFf7Zk6G9eco5N+jB1qJ2XW3ME=
|
||||
github.com/wiggin77/merror v1.0.5/go.mod h1:H2ETSu7/bPE0Ymf4bEwdUoo73OOEkdClnoRisfw0Nm0=
|
||||
github.com/wiggin77/srslog v1.0.1 h1:gA2XjSMy3DrRdX9UqLuDtuVAAshb8bE1NhX1YK0Qe+8=
|
||||
github.com/wiggin77/srslog v1.0.1/go.mod h1:fehkyYDq1QfuYn60TDPu9YdY2bB85VUW2mvN1WynEls=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
@ -230,6 +285,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@ -250,6 +307,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220614195744-fb05da6f9022 h1:0qjDla5xICC2suMtyRH/QqX3B1btXTfNsIt/i4LFgO0=
|
||||
golang.org/x/net v0.0.0-20220614195744-fb05da6f9022/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -269,12 +328,22 @@ golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 h1:PgOr27OhUx2IRqGJ2RxAWI4dJQ7bi9cSrB82uzFzfUA=
|
||||
golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -283,6 +352,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -308,10 +379,18 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
@ -321,6 +400,8 @@ gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI=
|
||||
gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -5,9 +5,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
const pluginIDGoFileTemplate = `// This file is automatically generated. Do not modify it manually.
|
||||
@ -18,7 +17,7 @@ import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
var manifest *model.Manifest
|
||||
|
@ -2,13 +2,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
const helpText = `
|
||||
@ -91,7 +92,8 @@ func getClient() (*model.Client4, error) {
|
||||
if adminUsername != "" && adminPassword != "" {
|
||||
client := model.NewAPIv4Client(siteURL)
|
||||
log.Printf("Authenticating as %s against %s.", adminUsername, siteURL)
|
||||
_, _, err := client.Login(adminUsername, adminPassword)
|
||||
ctx := context.Background()
|
||||
_, _, err := client.Login(ctx, adminUsername, adminPassword)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to login as %s: %w", adminUsername, err)
|
||||
}
|
||||
@ -119,14 +121,16 @@ func deploy(client *model.Client4, pluginID, bundlePath string) error {
|
||||
}
|
||||
defer pluginBundle.Close()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
log.Print("Uploading plugin via API.")
|
||||
_, _, err = client.UploadPluginForced(pluginBundle)
|
||||
_, _, err = client.UploadPluginForced(ctx, pluginBundle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to upload plugin bundle: %s", err)
|
||||
}
|
||||
|
||||
log.Print("Enabling plugin.")
|
||||
_, err = client.EnablePlugin(pluginID)
|
||||
_, err = client.EnablePlugin(ctx, pluginID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to enable plugin: %s", err)
|
||||
}
|
||||
@ -136,8 +140,10 @@ func deploy(client *model.Client4, pluginID, bundlePath string) error {
|
||||
|
||||
// disablePlugin attempts to disable the plugin via the Client4 API.
|
||||
func disablePlugin(client *model.Client4, pluginID string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
log.Print("Disabling plugin.")
|
||||
_, err := client.DisablePlugin(pluginID)
|
||||
_, err := client.DisablePlugin(ctx, pluginID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to disable plugin: %w", err)
|
||||
}
|
||||
@ -147,8 +153,10 @@ func disablePlugin(client *model.Client4, pluginID string) error {
|
||||
|
||||
// enablePlugin attempts to enable the plugin via the Client4 API.
|
||||
func enablePlugin(client *model.Client4, pluginID string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
log.Print("Enabling plugin.")
|
||||
_, err := client.EnablePlugin(pluginID)
|
||||
_, err := client.EnablePlugin(ctx, pluginID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to enable plugin: %w", err)
|
||||
}
|
||||
|
@ -1,123 +1,121 @@
|
||||
module github.com/mattermost/focalboard/mattermost-plugin
|
||||
|
||||
go 1.19
|
||||
go 1.21
|
||||
|
||||
toolchain go1.21.8
|
||||
|
||||
require (
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/mattermost/focalboard/server v0.0.0-20230104182634-f909c2552e37
|
||||
github.com/mattermost/mattermost-plugin-api v0.1.1
|
||||
github.com/mattermost/mattermost-server/v6 v6.0.0-20230321114510-b61c096497ac
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/mattermost/mattermost/server/public v0.1.3
|
||||
github.com/stretchr/testify v1.9.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.2.0 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.3 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/mattermost/mattermost/server/v8 v8.0.0-20240529104128-9d30a62c9471 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240529005216-23cca8864a10 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.15.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/graph-gophers/graphql-go v1.5.1-0.20230110080634-edea822f558a // indirect
|
||||
github.com/hashicorp/go-hclog v1.4.0 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.8 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.1 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.15.14 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/krolaw/zipstream v0.0.0-20180621105154-0a2661891f94 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/lib/pq v1.10.7 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.16 // indirect
|
||||
github.com/mattermost/morph v1.0.5-0.20221115094356-4c18a75b1f5e // indirect
|
||||
github.com/mattermost/squirrel v0.2.0 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956 // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.21 // indirect
|
||||
github.com/mattermost/morph v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.45 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.70 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.12.1 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.33.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect
|
||||
github.com/rivo/uniseg v0.4.3 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.19.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/rudderlabs/analytics-go v3.3.3+incompatible // indirect
|
||||
github.com/segmentio/backo-go v1.0.1 // indirect
|
||||
github.com/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/segmentio/backo-go v1.1.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.10.1 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/tidwall/gjson v1.14.4 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tidwall/gjson v1.17.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/tinylib/msgp v1.1.9 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/wiggin77/merror v1.0.4 // indirect
|
||||
github.com/wiggin77/merror v1.0.5 // indirect
|
||||
github.com/wiggin77/srslog v1.0.1 // indirect
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
|
||||
github.com/yuin/goldmark v1.5.3 // indirect
|
||||
golang.org/x/crypto v0.5.0 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/tools v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230104163317-caabf589fcbf // indirect
|
||||
google.golang.org/grpc v1.51.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
github.com/yuin/goldmark v1.7.1 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
google.golang.org/grpc v1.64.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.22.2 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.20.1 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/libc v1.50.9 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.29.10 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,10 +9,10 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
type storeService interface {
|
||||
@ -180,14 +180,6 @@ func (a *pluginAPIAdapter) PublishPluginClusterEvent(ev mm_model.PluginClusterEv
|
||||
return a.api.PublishPluginClusterEvent(ev, opts)
|
||||
}
|
||||
|
||||
//
|
||||
// Cloud service.
|
||||
//
|
||||
|
||||
func (a *pluginAPIAdapter) GetCloudLimits() (*mm_model.ProductLimits, error) {
|
||||
return a.api.GetCloudLimits()
|
||||
}
|
||||
|
||||
//
|
||||
// Config service.
|
||||
//
|
||||
|
@ -1,84 +0,0 @@
|
||||
package boards
|
||||
|
||||
import (
|
||||
"github.com/mattermost/focalboard/server/app"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/product"
|
||||
)
|
||||
|
||||
// boardsServiceAPI provides a service API for other products such as Channels.
|
||||
type boardsServiceAPI struct {
|
||||
app *app.App
|
||||
}
|
||||
|
||||
func NewBoardsServiceAPI(app *BoardsApp) *boardsServiceAPI {
|
||||
return &boardsServiceAPI{
|
||||
app: app.server.App(),
|
||||
}
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) GetTemplates(teamID string, userID string) ([]*model.Board, error) {
|
||||
return bs.app.GetTemplateBoards(teamID, userID)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) GetBoard(boardID string) (*model.Board, error) {
|
||||
return bs.app.GetBoard(boardID)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) CreateBoard(board *model.Board, userID string, addmember bool) (*model.Board, error) {
|
||||
return bs.app.CreateBoard(board, userID, addmember)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) PatchBoard(boardPatch *model.BoardPatch, boardID string, userID string) (*model.Board, error) {
|
||||
return bs.app.PatchBoard(boardPatch, boardID, userID)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) DeleteBoard(boardID string, userID string) error {
|
||||
return bs.app.DeleteBoard(boardID, userID)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) SearchBoards(searchTerm string, searchField model.BoardSearchField,
|
||||
userID string, includePublicBoards bool) ([]*model.Board, error) {
|
||||
return bs.app.SearchBoardsForUser(searchTerm, searchField, userID, includePublicBoards)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) LinkBoardToChannel(boardID string, channelID string, userID string) (*model.Board, error) {
|
||||
patch := &model.BoardPatch{
|
||||
ChannelID: &channelID,
|
||||
}
|
||||
return bs.app.PatchBoard(patch, boardID, userID)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) GetCards(boardID string) ([]*model.Card, error) {
|
||||
return bs.app.GetCardsForBoard(boardID, 0, 0)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) GetCard(cardID string) (*model.Card, error) {
|
||||
return bs.app.GetCardByID(cardID)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) CreateCard(card *model.Card, boardID string, userID string) (*model.Card, error) {
|
||||
return bs.app.CreateCard(card, boardID, userID, false)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) PatchCard(cardPatch *model.CardPatch, cardID string, userID string) (*model.Card, error) {
|
||||
return bs.app.PatchCard(cardPatch, cardID, userID, false)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) DeleteCard(cardID string, userID string) error {
|
||||
return bs.app.DeleteBlock(cardID, userID)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) HasPermissionToBoard(userID, boardID string, permission *mm_model.Permission) bool {
|
||||
return bs.app.HasPermissionToBoard(userID, boardID, permission)
|
||||
}
|
||||
|
||||
func (bs *boardsServiceAPI) DuplicateBoard(boardID string, userID string,
|
||||
toTeam string, asTemplate bool) (*model.BoardsAndBlocks, []*model.BoardMember, error) {
|
||||
return bs.app.DuplicateBoard(boardID, userID, toTeam, asTemplate)
|
||||
}
|
||||
|
||||
// Ensure boardsServiceAPI implements product.BoardsService interface.
|
||||
var _ product.BoardsService = (*boardsServiceAPI)(nil)
|
@ -17,12 +17,11 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/store/mattermostauthlayer"
|
||||
"github.com/mattermost/focalboard/server/services/store/sqlstore"
|
||||
"github.com/mattermost/focalboard/server/ws"
|
||||
"github.com/mattermost/mattermost/server/public/pluginapi/cluster"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-api/cluster"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -214,12 +213,6 @@ func (b *BoardsApp) OnPluginClusterEvent(_ *plugin.Context, ev mm_model.PluginCl
|
||||
b.wsPluginAdapter.HandleClusterEvent(ev)
|
||||
}
|
||||
|
||||
func (b *BoardsApp) OnCloudLimitsUpdated(limits *mm_model.ProductLimits) {
|
||||
if err := b.server.App().SetCloudLimits(limits); err != nil {
|
||||
b.logger.Error("Error setting the cloud limits for Boards", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
|
||||
// ServeHTTP demonstrates a plugin that handles HTTP requests by greeting the world.
|
||||
func (b *BoardsApp) ServeHTTP(_ *plugin.Context, w http.ResponseWriter, r *http.Request) {
|
||||
router := b.server.GetRootRouter()
|
||||
|
@ -11,8 +11,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func TestSetConfiguration(t *testing.T) {
|
||||
@ -62,6 +62,20 @@ func TestSetConfiguration(t *testing.T) {
|
||||
PrivacySettings: *basePrivacySettings,
|
||||
}
|
||||
|
||||
t.Run("test boards feature flags", func(t *testing.T) {
|
||||
featureFlags := &model.FeatureFlags{
|
||||
TestFeature: "test",
|
||||
TestBoolFeature: boolTrue,
|
||||
}
|
||||
|
||||
mmConfig := baseConfig
|
||||
mmConfig.FeatureFlags = featureFlags
|
||||
|
||||
config := createBoardsConfig(*mmConfig, "", "")
|
||||
assert.Equal(t, "true", config.FeatureFlags["TestBoolFeature"])
|
||||
assert.Equal(t, "test", config.FeatureFlags["TestFeature"])
|
||||
})
|
||||
|
||||
t.Run("test enable telemetry", func(t *testing.T) {
|
||||
logSettings := &model.LogSettings{
|
||||
EnableDiagnostics: &boolTrue,
|
||||
@ -82,24 +96,6 @@ func TestSetConfiguration(t *testing.T) {
|
||||
config := createBoardsConfig(*mmConfig, "", "")
|
||||
assert.Equal(t, true, config.EnablePublicSharedBoards)
|
||||
})
|
||||
|
||||
t.Run("test boards feature flags", func(t *testing.T) {
|
||||
featureFlags := &model.FeatureFlags{
|
||||
TestFeature: "test",
|
||||
TestBoolFeature: boolTrue,
|
||||
BoardsFeatureFlags: "hello_world-myTest",
|
||||
}
|
||||
|
||||
mmConfig := baseConfig
|
||||
mmConfig.FeatureFlags = featureFlags
|
||||
|
||||
config := createBoardsConfig(*mmConfig, "", "")
|
||||
assert.Equal(t, "true", config.FeatureFlags["TestBoolFeature"])
|
||||
assert.Equal(t, "test", config.FeatureFlags["TestFeature"])
|
||||
|
||||
assert.Equal(t, "true", config.FeatureFlags["hello_world"])
|
||||
assert.Equal(t, "true", config.FeatureFlags["myTest"])
|
||||
})
|
||||
}
|
||||
|
||||
func TestServeHTTP(t *testing.T) {
|
||||
@ -108,7 +104,7 @@ func TestServeHTTP(t *testing.T) {
|
||||
|
||||
b := &BoardsApp{
|
||||
server: th.Server,
|
||||
logger: mlog.CreateConsoleTestLogger(true, mlog.LvlError),
|
||||
logger: mlog.CreateConsoleTestLogger(t),
|
||||
}
|
||||
|
||||
assert := assert.New(t)
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/mattermost/focalboard/server/services/config"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
const defaultS3Timeout = 60 * 1000 // 60 seconds
|
||||
@ -81,9 +81,7 @@ func createBoardsConfig(mmconfig mm_model.Config, baseURL string, serverID strin
|
||||
}
|
||||
|
||||
serverRoot := baseURL + "/plugins/focalboard"
|
||||
if mmconfig.FeatureFlags.BoardsProduct {
|
||||
serverRoot = baseURL + "/boards"
|
||||
}
|
||||
|
||||
return &config.Configuration{
|
||||
ServerRoot: serverRoot,
|
||||
Port: -1,
|
||||
@ -118,6 +116,21 @@ func createBoardsConfig(mmconfig mm_model.Config, baseURL string, serverID strin
|
||||
}
|
||||
}
|
||||
|
||||
func parseFeatureFlags(configFeatureFlags map[string]string) map[string]string {
|
||||
featureFlags := make(map[string]string)
|
||||
for key, value := range configFeatureFlags {
|
||||
// Break out FeatureFlags and pass remaining
|
||||
if key == boardsFeatureFlagName {
|
||||
for _, flag := range strings.Split(value, "-") {
|
||||
featureFlags[flag] = "true"
|
||||
}
|
||||
} else {
|
||||
featureFlags[key] = value
|
||||
}
|
||||
}
|
||||
return featureFlags
|
||||
}
|
||||
|
||||
func getPluginSetting(mmConfig mm_model.Config, key string) (interface{}, bool) {
|
||||
plugin, ok := mmConfig.PluginSettings.Plugins[PluginName]
|
||||
if !ok {
|
||||
@ -142,18 +155,3 @@ func getPluginSettingInt(mmConfig mm_model.Config, key string, def int) int {
|
||||
}
|
||||
return int(math.Round(valFloat))
|
||||
}
|
||||
|
||||
func parseFeatureFlags(configFeatureFlags map[string]string) map[string]string {
|
||||
featureFlags := make(map[string]string)
|
||||
for key, value := range configFeatureFlags {
|
||||
// Break out FeatureFlags and pass remaining
|
||||
if key == boardsFeatureFlagName {
|
||||
for _, flag := range strings.Split(value, "-") {
|
||||
featureFlags[flag] = "true"
|
||||
}
|
||||
} else {
|
||||
featureFlags[key] = value
|
||||
}
|
||||
}
|
||||
return featureFlags
|
||||
}
|
||||
|
@ -75,23 +75,17 @@ func (b *BoardsApp) OnConfigurationChange() error {
|
||||
}
|
||||
mmconfig := b.servicesAPI.GetConfig()
|
||||
|
||||
// handle plugin configuration settings
|
||||
enableShareBoards := false
|
||||
if mmconfig.PluginSettings.Plugins[PluginName][SharedBoardsName] == true {
|
||||
enableShareBoards = true
|
||||
}
|
||||
if mmconfig.ProductSettings.EnablePublicSharedBoards != nil {
|
||||
enableShareBoards = *mmconfig.ProductSettings.EnablePublicSharedBoards
|
||||
}
|
||||
|
||||
configuration := &configuration{
|
||||
EnablePublicSharedBoards: enableShareBoards,
|
||||
}
|
||||
b.setConfiguration(configuration)
|
||||
b.server.Config().EnablePublicSharedBoards = enableShareBoards
|
||||
|
||||
// handle feature flags
|
||||
b.server.Config().FeatureFlags = parseFeatureFlags(mmconfig.FeatureFlags.ToMap())
|
||||
|
||||
// handle Data Retention settings
|
||||
enableBoardsDeletion := false
|
||||
if mmconfig.DataRetentionSettings.EnableBoardsDeletion != nil {
|
||||
|
@ -14,8 +14,8 @@ import (
|
||||
|
||||
mockservicesapi "github.com/mattermost/focalboard/server/model/mocks"
|
||||
|
||||
serverModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
serverModel "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -54,9 +54,6 @@ func TestOnConfigurationChange(t *testing.T) {
|
||||
basePlugins[PluginName] = make(map[string]interface{})
|
||||
basePlugins[PluginName][SharedBoardsName] = true
|
||||
|
||||
baseFeatureFlags := &serverModel.FeatureFlags{
|
||||
BoardsFeatureFlags: "Feature1-Feature2",
|
||||
}
|
||||
basePluginSettings := &serverModel.PluginSettings{
|
||||
Directory: &stringRef,
|
||||
Plugins: basePlugins,
|
||||
@ -77,7 +74,6 @@ func TestOnConfigurationChange(t *testing.T) {
|
||||
}
|
||||
|
||||
baseConfig := &serverModel.Config{
|
||||
FeatureFlags: baseFeatureFlags,
|
||||
PluginSettings: *basePluginSettings,
|
||||
DataRetentionSettings: *baseDataRetentionSettings,
|
||||
TeamSettings: *baseTeamSettings,
|
||||
@ -96,7 +92,7 @@ func TestOnConfigurationChange(t *testing.T) {
|
||||
server: th.Server,
|
||||
wsPluginAdapter: &FakePluginAdapter{},
|
||||
servicesAPI: api,
|
||||
logger: mlog.CreateConsoleTestLogger(true, mlog.LvlError),
|
||||
logger: mlog.CreateConsoleTestLogger(&testing.T{}),
|
||||
}
|
||||
|
||||
err := b.OnConfigurationChange()
|
||||
@ -106,10 +102,6 @@ func TestOnConfigurationChange(t *testing.T) {
|
||||
// make sure both App and Server got updated
|
||||
assert.True(t, b.server.Config().EnablePublicSharedBoards)
|
||||
assert.True(t, b.server.App().GetClientConfig().EnablePublicSharedBoards)
|
||||
|
||||
assert.Equal(t, "true", b.server.Config().FeatureFlags["Feature1"])
|
||||
assert.Equal(t, "true", b.server.Config().FeatureFlags["Feature2"])
|
||||
assert.Equal(t, "", b.server.Config().FeatureFlags["Feature3"])
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/store/mockstore"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
type TestHelperMockStore struct {
|
||||
@ -53,7 +53,7 @@ func newTestServerMock(mockStore *mockstore.MockStore) *server.Server {
|
||||
WebPath: "/",
|
||||
}
|
||||
|
||||
logger := mlog.CreateConsoleTestLogger(true, mlog.LvlDebug)
|
||||
logger, _ := mlog.NewLogger()
|
||||
|
||||
mockStore.EXPECT().GetTeam(gomock.Any()).Return(nil, nil).AnyTimes()
|
||||
mockStore.EXPECT().UpsertTeamSignupToken(gomock.Any()).AnyTimes()
|
||||
@ -79,9 +79,10 @@ func TestRunDataRetention(t *testing.T) {
|
||||
th, tearDown := SetupTestHelperMockStore(t)
|
||||
defer tearDown()
|
||||
|
||||
logger, _ := mlog.NewLogger()
|
||||
b := &BoardsApp{
|
||||
server: th.Server,
|
||||
logger: mlog.CreateConsoleTestLogger(true, mlog.LvlError),
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
now := time.Now().UnixNano()
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/permissions"
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
type notifyBackendParams struct {
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/markdown"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/markdown"
|
||||
)
|
||||
|
||||
func postWithBoardsEmbed(post *mm_model.Post) *mm_model.Post {
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
pluginapi "github.com/mattermost/mattermost-plugin-api"
|
||||
pluginapi "github.com/mattermost/mattermost/server/public/pluginapi"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -1,7 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
2
mattermost-plugin/server/manifest.go
generated
2
mattermost-plugin/server/manifest.go
generated
@ -6,7 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
var manifest *model.Manifest
|
||||
|
@ -11,11 +11,11 @@ import (
|
||||
"github.com/mattermost/focalboard/mattermost-plugin/server/boards"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
|
||||
pluginapi "github.com/mattermost/mattermost-plugin-api"
|
||||
pluginapi "github.com/mattermost/mattermost/server/public/pluginapi"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
var ErrPluginNotAllowed = errors.New("boards plugin not allowed while Boards product enabled")
|
||||
@ -23,16 +23,10 @@ var ErrPluginNotAllowed = errors.New("boards plugin not allowed while Boards pro
|
||||
// Plugin implements the interface expected by the Mattermost server to communicate between the server and plugin processes.
|
||||
type Plugin struct {
|
||||
plugin.MattermostPlugin
|
||||
|
||||
boardsApp *boards.BoardsApp
|
||||
}
|
||||
|
||||
func (p *Plugin) OnActivate() error {
|
||||
if p.API.GetConfig().FeatureFlags.BoardsProduct {
|
||||
p.API.LogError(ErrPluginNotAllowed.Error())
|
||||
return ErrPluginNotAllowed
|
||||
}
|
||||
|
||||
client := pluginapi.NewClient(p.API, p.Driver)
|
||||
|
||||
logger, _ := mlog.NewLogger()
|
||||
@ -97,10 +91,6 @@ func (p *Plugin) MessageWillBeUpdated(ctx *plugin.Context, newPost, oldPost *mm_
|
||||
return p.boardsApp.MessageWillBeUpdated(ctx, newPost, oldPost)
|
||||
}
|
||||
|
||||
func (p *Plugin) OnCloudLimitsUpdated(limits *mm_model.ProductLimits) {
|
||||
p.boardsApp.OnCloudLimitsUpdated(limits)
|
||||
}
|
||||
|
||||
func (p *Plugin) RunDataRetention(nowTime, batchSize int64) (int64, error) {
|
||||
return p.boardsApp.RunDataRetention(nowTime, batchSize)
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ import '../../../webapp/src/styles/focalboard-variables.scss'
|
||||
import '../../../webapp/src/styles/main.scss'
|
||||
import '../../../webapp/src/styles/labels.scss'
|
||||
import octoClient from '../../../webapp/src/octoClient'
|
||||
import {Constants} from '../../../webapp/src/constants'
|
||||
import {Board} from '../../../webapp/src/blocks/board'
|
||||
|
||||
import appBarIcon from '../../../webapp/static/app-bar-icon.png'
|
||||
@ -368,21 +367,6 @@ export default class Plugin {
|
||||
false
|
||||
)
|
||||
|
||||
// Insights handler
|
||||
if (this.registry?.registerInsightsHandler) {
|
||||
this.registry?.registerInsightsHandler(async (timeRange: string, page: number, perPage: number, teamId: string, insightType: string) => {
|
||||
if (insightType === Constants.myInsights) {
|
||||
const data = await octoClient.getMyTopBoards(timeRange, page, perPage, teamId)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
const data = await octoClient.getTeamTopBoards(timeRange, page, perPage, teamId)
|
||||
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
// Site statistics handler
|
||||
if (registry.registerSiteStatisticsHandler) {
|
||||
registry.registerSiteStatisticsHandler(async () => {
|
||||
|
@ -41,13 +41,12 @@ linters:
|
||||
- staticcheck
|
||||
- prealloc
|
||||
- asciicheck
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
- goconst
|
||||
- gocritic
|
||||
- godot
|
||||
- goerr113
|
||||
- err113
|
||||
- goheader
|
||||
- revive
|
||||
- nakedret
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
type AdminSetPasswordData struct {
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
"github.com/mattermost/focalboard/server/services/permissions"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -85,8 +85,6 @@ func (a *API) RegisterRoutes(r *mux.Router) {
|
||||
a.registerAchivesRoutes(apiv2)
|
||||
a.registerSubscriptionsRoutes(apiv2)
|
||||
a.registerFilesRoutes(apiv2)
|
||||
a.registerLimitsRoutes(apiv2)
|
||||
a.registerInsightsRoutes(apiv2)
|
||||
a.registerOnboardingRoutes(apiv2)
|
||||
a.registerSearchRoutes(apiv2)
|
||||
a.registerConfigRoutes(apiv2)
|
||||
|
@ -9,14 +9,14 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
pluginapi "github.com/mattermost/mattermost-plugin-api"
|
||||
pluginapi "github.com/mattermost/mattermost/server/public/pluginapi"
|
||||
)
|
||||
|
||||
func TestErrorResponse(t *testing.T) {
|
||||
testAPI := API{logger: mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)}
|
||||
testAPI := API{logger: mlog.CreateConsoleTestLogger(t)}
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/auth"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerAuthRoutes(r *mux.Router) {
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerBlocksRoutes(r *mux.Router) {
|
||||
@ -159,13 +159,6 @@ func (a *API) handleGetBlocks(w http.ResponseWriter, r *http.Request) {
|
||||
mlog.Int("block_count", len(blocks)),
|
||||
)
|
||||
|
||||
var bErr error
|
||||
blocks, bErr = a.app.ApplyCloudLimits(blocks)
|
||||
if bErr != nil {
|
||||
a.errorResponse(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
json, err := json.Marshal(blocks)
|
||||
if err != nil {
|
||||
a.errorResponse(w, r, err)
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerBoardsRoutes(r *mux.Router) {
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerBoardsAndBlocksRoutes(r *mux.Router) {
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerChannelsRoutes(r *mux.Router) {
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -20,9 +20,9 @@ import (
|
||||
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
var UnsafeContentTypes = [...]string{
|
||||
|
@ -1,258 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
func (a *API) registerInsightsRoutes(r *mux.Router) {
|
||||
// Insights APIs
|
||||
r.HandleFunc("/teams/{teamID}/boards/insights", a.sessionRequired(a.handleTeamBoardsInsights)).Methods("GET")
|
||||
r.HandleFunc("/users/me/boards/insights", a.sessionRequired(a.handleUserBoardsInsights)).Methods("GET")
|
||||
}
|
||||
|
||||
func (a *API) handleTeamBoardsInsights(w http.ResponseWriter, r *http.Request) {
|
||||
// swagger:operation GET /teams/{teamID}/boards/insights handleTeamBoardsInsights
|
||||
//
|
||||
// Returns team boards insights
|
||||
//
|
||||
// ---
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: teamID
|
||||
// in: path
|
||||
// description: Team ID
|
||||
// required: true
|
||||
// type: string
|
||||
// - name: time_range
|
||||
// in: query
|
||||
// description: duration of data to calculate insights for
|
||||
// required: true
|
||||
// type: string
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page offset for top boards
|
||||
// required: true
|
||||
// type: string
|
||||
// - name: per_page
|
||||
// in: query
|
||||
// description: limit for boards in a page.
|
||||
// required: true
|
||||
// type: string
|
||||
// security:
|
||||
// - BearerAuth: []
|
||||
// responses:
|
||||
// '200':
|
||||
// description: success
|
||||
// schema:
|
||||
// type: array
|
||||
// items:
|
||||
// "$ref": "#/definitions/BoardInsight"
|
||||
// default:
|
||||
// description: internal error
|
||||
// schema:
|
||||
// "$ref": "#/definitions/ErrorResponse"
|
||||
|
||||
if !a.MattermostAuth {
|
||||
a.errorResponse(w, r, model.NewErrNotImplemented("not permitted in standalone mode"))
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
teamID := vars["teamID"]
|
||||
userID := getUserID(r)
|
||||
query := r.URL.Query()
|
||||
timeRange := query.Get("time_range")
|
||||
|
||||
if !a.permissions.HasPermissionToTeam(userID, teamID, model.PermissionViewTeam) {
|
||||
a.errorResponse(w, r, model.NewErrPermission("access denied to team"))
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := a.makeAuditRecord(r, "getTeamBoardsInsights", audit.Fail)
|
||||
defer a.audit.LogRecord(audit.LevelRead, auditRec)
|
||||
|
||||
page, err := strconv.Atoi(query.Get("page"))
|
||||
if err != nil {
|
||||
message := fmt.Sprintf("error converting page parameter to integer: %s", err)
|
||||
a.errorResponse(w, r, model.NewErrBadRequest(message))
|
||||
return
|
||||
}
|
||||
if page < 0 {
|
||||
a.errorResponse(w, r, model.NewErrBadRequest("Invalid page parameter"))
|
||||
}
|
||||
|
||||
perPage, err := strconv.Atoi(query.Get("per_page"))
|
||||
if err != nil {
|
||||
message := fmt.Sprintf("error converting per_page parameter to integer: %s", err)
|
||||
a.errorResponse(w, r, model.NewErrBadRequest(message))
|
||||
return
|
||||
}
|
||||
if perPage < 0 {
|
||||
a.errorResponse(w, r, model.NewErrBadRequest("Invalid page parameter"))
|
||||
}
|
||||
|
||||
userTimezone, aErr := a.app.GetUserTimezone(userID)
|
||||
if aErr != nil {
|
||||
message := fmt.Sprintf("Error getting time zone of user: %s", aErr)
|
||||
a.errorResponse(w, r, model.NewErrBadRequest(message))
|
||||
return
|
||||
}
|
||||
userLocation, _ := time.LoadLocation(userTimezone)
|
||||
if userLocation == nil {
|
||||
userLocation = time.Now().UTC().Location()
|
||||
}
|
||||
// get unix time for duration
|
||||
startTime, appErr := mmModel.GetStartOfDayForTimeRange(timeRange, userLocation)
|
||||
if appErr != nil {
|
||||
a.errorResponse(w, r, model.NewErrBadRequest(appErr.Message))
|
||||
return
|
||||
}
|
||||
|
||||
boardsInsights, err := a.app.GetTeamBoardsInsights(userID, teamID, &mmModel.InsightsOpts{
|
||||
StartUnixMilli: mmModel.GetMillisForTime(*startTime),
|
||||
Page: page,
|
||||
PerPage: perPage,
|
||||
})
|
||||
if err != nil {
|
||||
a.errorResponse(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := json.Marshal(boardsInsights)
|
||||
if err != nil {
|
||||
a.errorResponse(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonBytesResponse(w, http.StatusOK, data)
|
||||
|
||||
auditRec.AddMeta("teamBoardsInsightCount", len(boardsInsights.Items))
|
||||
auditRec.Success()
|
||||
}
|
||||
|
||||
func (a *API) handleUserBoardsInsights(w http.ResponseWriter, r *http.Request) {
|
||||
// swagger:operation GET /users/me/boards/insights getUserBoardsInsights
|
||||
//
|
||||
// Returns user boards insights
|
||||
//
|
||||
// ---
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: teamID
|
||||
// in: path
|
||||
// description: Team ID
|
||||
// required: true
|
||||
// type: string
|
||||
// - name: time_range
|
||||
// in: query
|
||||
// description: duration of data to calculate insights for
|
||||
// required: true
|
||||
// type: string
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page offset for top boards
|
||||
// required: true
|
||||
// type: string
|
||||
// - name: per_page
|
||||
// in: query
|
||||
// description: limit for boards in a page.
|
||||
// required: true
|
||||
// type: string
|
||||
// security:
|
||||
// - BearerAuth: []
|
||||
// responses:
|
||||
// '200':
|
||||
// description: success
|
||||
// schema:
|
||||
// type: array
|
||||
// items:
|
||||
// "$ref": "#/definitions/BoardInsight"
|
||||
// default:
|
||||
// description: internal error
|
||||
// schema:
|
||||
// "$ref": "#/definitions/ErrorResponse"
|
||||
|
||||
if !a.MattermostAuth {
|
||||
a.errorResponse(w, r, model.NewErrNotImplemented("not permitted in standalone mode"))
|
||||
return
|
||||
}
|
||||
|
||||
userID := getUserID(r)
|
||||
query := r.URL.Query()
|
||||
teamID := query.Get("team_id")
|
||||
timeRange := query.Get("time_range")
|
||||
|
||||
if !a.permissions.HasPermissionToTeam(userID, teamID, model.PermissionViewTeam) {
|
||||
a.errorResponse(w, r, model.NewErrPermission("access denied to team"))
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := a.makeAuditRecord(r, "getUserBoardsInsights", audit.Fail)
|
||||
defer a.audit.LogRecord(audit.LevelRead, auditRec)
|
||||
page, err := strconv.Atoi(query.Get("page"))
|
||||
if err != nil {
|
||||
a.errorResponse(w, r, model.NewErrBadRequest("error converting page parameter to integer"))
|
||||
return
|
||||
}
|
||||
|
||||
if page < 0 {
|
||||
a.errorResponse(w, r, model.NewErrBadRequest("Invalid page parameter"))
|
||||
}
|
||||
perPage, err := strconv.Atoi(query.Get("per_page"))
|
||||
if err != nil {
|
||||
message := fmt.Sprintf("error converting per_page parameter to integer: %s", err)
|
||||
a.errorResponse(w, r, model.NewErrBadRequest(message))
|
||||
return
|
||||
}
|
||||
|
||||
if perPage < 0 {
|
||||
a.errorResponse(w, r, model.NewErrBadRequest("Invalid page parameter"))
|
||||
}
|
||||
userTimezone, aErr := a.app.GetUserTimezone(userID)
|
||||
if aErr != nil {
|
||||
message := fmt.Sprintf("Error getting time zone of user: %s", aErr)
|
||||
a.errorResponse(w, r, model.NewErrBadRequest(message))
|
||||
return
|
||||
}
|
||||
userLocation, _ := time.LoadLocation(userTimezone)
|
||||
if userLocation == nil {
|
||||
userLocation = time.Now().UTC().Location()
|
||||
}
|
||||
// get unix time for duration
|
||||
startTime, appErr := mmModel.GetStartOfDayForTimeRange(timeRange, userLocation)
|
||||
if appErr != nil {
|
||||
a.errorResponse(w, r, model.NewErrBadRequest(appErr.Message))
|
||||
return
|
||||
}
|
||||
|
||||
boardsInsights, err := a.app.GetUserBoardsInsights(userID, teamID, &mmModel.InsightsOpts{
|
||||
StartUnixMilli: mmModel.GetMillisForTime(*startTime),
|
||||
Page: page,
|
||||
PerPage: perPage,
|
||||
})
|
||||
if err != nil {
|
||||
a.errorResponse(w, r, err)
|
||||
return
|
||||
}
|
||||
data, err := json.Marshal(boardsInsights)
|
||||
if err != nil {
|
||||
a.errorResponse(w, r, err)
|
||||
return
|
||||
}
|
||||
jsonBytesResponse(w, http.StatusOK, data)
|
||||
|
||||
auditRec.AddMeta("userBoardInsightCount", len(boardsInsights.Items))
|
||||
auditRec.Success()
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
)
|
||||
|
||||
func (a *API) registerLimitsRoutes(r *mux.Router) {
|
||||
// limits
|
||||
r.HandleFunc("/limits", a.sessionRequired(a.handleCloudLimits)).Methods("GET")
|
||||
r.HandleFunc("/teams/{teamID}/notifyadminupgrade", a.sessionRequired(a.handleNotifyAdminUpgrade)).Methods(http.MethodPost)
|
||||
}
|
||||
|
||||
func (a *API) handleCloudLimits(w http.ResponseWriter, r *http.Request) {
|
||||
// swagger:operation GET /limits cloudLimits
|
||||
//
|
||||
// Fetches the cloud limits of the server.
|
||||
//
|
||||
// ---
|
||||
// produces:
|
||||
// - application/json
|
||||
// security:
|
||||
// - BearerAuth: []
|
||||
// responses:
|
||||
// '200':
|
||||
// description: success
|
||||
// schema:
|
||||
// "$ref": "#/definitions/BoardsCloudLimits"
|
||||
// default:
|
||||
// description: internal error
|
||||
// schema:
|
||||
// "$ref": "#/definitions/ErrorResponse"
|
||||
|
||||
boardsCloudLimits, err := a.app.GetBoardsCloudLimits()
|
||||
if err != nil {
|
||||
a.errorResponse(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := json.Marshal(boardsCloudLimits)
|
||||
if err != nil {
|
||||
a.errorResponse(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonBytesResponse(w, http.StatusOK, data)
|
||||
}
|
||||
|
||||
func (a *API) handleNotifyAdminUpgrade(w http.ResponseWriter, r *http.Request) {
|
||||
// swagger:operation GET /api/v2/teams/{teamID}/notifyadminupgrade handleNotifyAdminUpgrade
|
||||
//
|
||||
// Notifies admins for upgrade request.
|
||||
//
|
||||
// ---
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: teamID
|
||||
// in: path
|
||||
// description: Team ID
|
||||
// required: true
|
||||
// type: string
|
||||
// security:
|
||||
// - BearerAuth: []
|
||||
// responses:
|
||||
// '200':
|
||||
// description: success
|
||||
// default:
|
||||
// description: internal error
|
||||
// schema:
|
||||
// "$ref": "#/definitions/ErrorResponse"
|
||||
|
||||
if !a.MattermostAuth {
|
||||
a.errorResponse(w, r, model.NewErrNotImplemented("not permitted in standalone mode"))
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
teamID := vars["teamID"]
|
||||
|
||||
if err := a.app.NotifyPortalAdminsUpgradeRequest(teamID); err != nil {
|
||||
jsonStringResponse(w, http.StatusOK, "{}")
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerMembersRoutes(r *mux.Router) {
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerSearchRoutes(r *mux.Router) {
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
var ErrTurningOnSharing = errors.New("turning on sharing for board failed, see log for details")
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
func (a *API) registerStatisticsRoutes(r *mux.Router) {
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerSubscriptionsRoutes(r *mux.Router) {
|
||||
|
@ -9,11 +9,11 @@ import (
|
||||
|
||||
"github.com/mattermost/focalboard/server/app"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func TestHello(t *testing.T) {
|
||||
testAPI := API{logger: mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)}
|
||||
testAPI := API{logger: mlog.CreateConsoleTestLogger(t)}
|
||||
|
||||
t.Run("Returns 'Hello' on success", func(t *testing.T) {
|
||||
request, _ := http.NewRequest(http.MethodGet, "/hello", nil)
|
||||
@ -35,7 +35,7 @@ func TestHello(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPing(t *testing.T) {
|
||||
testAPI := API{logger: mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)}
|
||||
testAPI := API{logger: mlog.CreateConsoleTestLogger(t)}
|
||||
|
||||
t.Run("Returns metadata on success", func(t *testing.T) {
|
||||
request, _ := http.NewRequest(http.MethodGet, "/ping", nil)
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/audit"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *API) registerTemplatesRoutes(r *mux.Router) {
|
||||
|
@ -15,9 +15,9 @@ import (
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
"github.com/mattermost/focalboard/server/ws"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/filestore"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/v8/platform/shared/filestore"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/auth"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/notify"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
var ErrBlocksFromMultipleBoards = errors.New("the block set contain blocks from multiple boards")
|
||||
@ -54,15 +54,6 @@ func (a *App) DuplicateBlock(boardID string, blockID string, userID string, asTe
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
if uErr := a.UpdateCardLimitTimestamp(); uErr != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed duplicating a block",
|
||||
mlog.Err(uErr),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
return blocks, err
|
||||
}
|
||||
|
||||
@ -76,16 +67,6 @@ func (a *App) PatchBlockAndNotify(blockID string, blockPatch *model.BlockPatch,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if a.IsCloudLimited() {
|
||||
containsLimitedBlocks, lErr := a.ContainsLimitedBlocks([]*model.Block{oldBlock})
|
||||
if lErr != nil {
|
||||
return nil, lErr
|
||||
}
|
||||
if containsLimitedBlocks {
|
||||
return nil, model.ErrPatchUpdatesLimitedCards
|
||||
}
|
||||
}
|
||||
|
||||
board, err := a.store.GetBoard(oldBlock.BoardID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -127,16 +108,6 @@ func (a *App) PatchBlocksAndNotify(teamID string, blockPatches *model.BlockPatch
|
||||
return err
|
||||
}
|
||||
|
||||
if a.IsCloudLimited() {
|
||||
containsLimitedBlocks, err := a.ContainsLimitedBlocks(oldBlocks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if containsLimitedBlocks {
|
||||
return model.ErrPatchUpdatesLimitedCards
|
||||
}
|
||||
}
|
||||
|
||||
if err := a.store.PatchBlocks(blockPatches, modifiedByID); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -182,47 +153,9 @@ func (a *App) InsertBlockAndNotify(block *model.Block, modifiedByID string, disa
|
||||
})
|
||||
}
|
||||
|
||||
go func() {
|
||||
if uErr := a.UpdateCardLimitTimestamp(); uErr != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after inserting a block",
|
||||
mlog.Err(uErr),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *App) isWithinViewsLimit(boardID string, block *model.Block) (bool, error) {
|
||||
// ToDo: Cloud Limits have been disabled by design. We should
|
||||
// revisit the decision and update the related code accordingly
|
||||
|
||||
/*
|
||||
limits, err := a.GetBoardsCloudLimits()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if limits.Views == model.LimitUnlimited {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
views, err := a.store.GetBlocksWithParentAndType(boardID, block.ParentID, model.TypeView)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// < rather than <= because we'll be creating new view if this
|
||||
// check passes. When that view is created, the limit will be reached.
|
||||
// That's why we need to check for if existing + the being-created
|
||||
// view doesn't exceed the limit.
|
||||
return len(views) < limits.Views, nil
|
||||
*/
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (a *App) InsertBlocks(blocks []*model.Block, modifiedByID string) ([]*model.Block, error) {
|
||||
return a.InsertBlocksAndNotify(blocks, modifiedByID, false)
|
||||
}
|
||||
@ -247,20 +180,6 @@ func (a *App) InsertBlocksAndNotify(blocks []*model.Block, modifiedByID string,
|
||||
|
||||
needsNotify := make([]*model.Block, 0, len(blocks))
|
||||
for i := range blocks {
|
||||
// this check is needed to whitelist inbuilt template
|
||||
// initialization. They do contain more than 5 views per board.
|
||||
if boardID != "0" && blocks[i].Type == model.TypeView {
|
||||
withinLimit, err := a.isWithinViewsLimit(board.ID, blocks[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !withinLimit {
|
||||
a.logger.Info("views limit reached on board", mlog.String("board_id", blocks[i].ParentID), mlog.String("team_id", board.TeamID))
|
||||
return nil, model.ErrViewsLimitReached
|
||||
}
|
||||
}
|
||||
|
||||
err := a.store.InsertBlock(blocks[i], modifiedByID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -282,15 +201,6 @@ func (a *App) InsertBlocksAndNotify(blocks []*model.Block, modifiedByID string,
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
if err := a.UpdateCardLimitTimestamp(); err != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after inserting blocks",
|
||||
mlog.Err(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
return blocks, nil
|
||||
}
|
||||
|
||||
@ -332,15 +242,6 @@ func (a *App) DeleteBlockAndNotify(blockID string, modifiedBy string, disableNot
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
if err := a.UpdateCardLimitTimestamp(); err != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after deleting a block",
|
||||
mlog.Err(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -394,15 +295,6 @@ func (a *App) UndeleteBlock(blockID string, modifiedBy string) (*model.Block, er
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
if err := a.UpdateCardLimitTimestamp(); err != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after undeleting a block",
|
||||
mlog.Err(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
return block, nil
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,10 @@ import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
)
|
||||
@ -186,100 +184,6 @@ func TestUndeleteBlock(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsWithinViewsLimit(t *testing.T) {
|
||||
t.Skipf("The Cloud Limits feature has been disabled")
|
||||
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
fakeLicense := &mmModel.License{
|
||||
Features: &mmModel.Features{Cloud: mmModel.NewBool(true)},
|
||||
}
|
||||
|
||||
t.Run("within views limit", func(t *testing.T) {
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
|
||||
cloudLimit := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{
|
||||
Views: mmModel.NewInt(2),
|
||||
},
|
||||
}
|
||||
th.Store.EXPECT().GetCloudLimits().Return(cloudLimit, nil)
|
||||
th.Store.EXPECT().GetUsedCardsCount().Return(1, nil)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(1), nil)
|
||||
th.Store.EXPECT().GetBlocksWithParentAndType("board_id", "parent_id", "view").Return([]*model.Block{{}}, nil)
|
||||
|
||||
withinLimits, err := th.App.isWithinViewsLimit("board_id", &model.Block{ParentID: "parent_id"})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, withinLimits)
|
||||
})
|
||||
|
||||
t.Run("view limit exactly reached", func(t *testing.T) {
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
|
||||
cloudLimit := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{
|
||||
Views: mmModel.NewInt(1),
|
||||
},
|
||||
}
|
||||
th.Store.EXPECT().GetCloudLimits().Return(cloudLimit, nil)
|
||||
th.Store.EXPECT().GetUsedCardsCount().Return(1, nil)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(1), nil)
|
||||
th.Store.EXPECT().GetBlocksWithParentAndType("board_id", "parent_id", "view").Return([]*model.Block{{}}, nil)
|
||||
|
||||
withinLimits, err := th.App.isWithinViewsLimit("board_id", &model.Block{ParentID: "parent_id"})
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, withinLimits)
|
||||
})
|
||||
|
||||
t.Run("view limit already exceeded", func(t *testing.T) {
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
|
||||
cloudLimit := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{
|
||||
Views: mmModel.NewInt(2),
|
||||
},
|
||||
}
|
||||
th.Store.EXPECT().GetCloudLimits().Return(cloudLimit, nil)
|
||||
th.Store.EXPECT().GetUsedCardsCount().Return(1, nil)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(1), nil)
|
||||
th.Store.EXPECT().GetBlocksWithParentAndType("board_id", "parent_id", "view").Return([]*model.Block{{}, {}, {}}, nil)
|
||||
|
||||
withinLimits, err := th.App.isWithinViewsLimit("board_id", &model.Block{ParentID: "parent_id"})
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, withinLimits)
|
||||
})
|
||||
|
||||
t.Run("creating first view", func(t *testing.T) {
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
|
||||
cloudLimit := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{
|
||||
Views: mmModel.NewInt(2),
|
||||
},
|
||||
}
|
||||
th.Store.EXPECT().GetCloudLimits().Return(cloudLimit, nil)
|
||||
th.Store.EXPECT().GetUsedCardsCount().Return(1, nil)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(1), nil)
|
||||
th.Store.EXPECT().GetBlocksWithParentAndType("board_id", "parent_id", "view").Return([]*model.Block{}, nil)
|
||||
|
||||
withinLimits, err := th.App.isWithinViewsLimit("board_id", &model.Block{ParentID: "parent_id"})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, withinLimits)
|
||||
})
|
||||
|
||||
t.Run("is not a cloud SKU so limits don't apply", func(t *testing.T) {
|
||||
nonCloudLicense := &mmModel.License{
|
||||
Features: &mmModel.Features{Cloud: mmModel.NewBool(false)},
|
||||
}
|
||||
th.Store.EXPECT().GetLicense().Return(nonCloudLicense)
|
||||
|
||||
withinLimits, err := th.App.isWithinViewsLimit("board_id", &model.Block{ParentID: "parent_id"})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, withinLimits)
|
||||
})
|
||||
}
|
||||
|
||||
func TestInsertBlocks(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
@ -325,12 +229,6 @@ func TestInsertBlocks(t *testing.T) {
|
||||
}
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
|
||||
cloudLimit := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{
|
||||
Views: mmModel.NewInt(2),
|
||||
},
|
||||
}
|
||||
th.Store.EXPECT().GetCloudLimits().Return(cloudLimit, nil)
|
||||
th.Store.EXPECT().GetUsedCardsCount().Return(1, nil)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(1), nil)
|
||||
th.Store.EXPECT().GetBlocksWithParentAndType("test-board-id", "parent_id", "view").Return([]*model.Block{{}}, nil)
|
||||
@ -357,12 +255,6 @@ func TestInsertBlocks(t *testing.T) {
|
||||
}
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
|
||||
cloudLimit := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{
|
||||
Views: mmModel.NewInt(2),
|
||||
},
|
||||
}
|
||||
th.Store.EXPECT().GetCloudLimits().Return(cloudLimit, nil)
|
||||
th.Store.EXPECT().GetUsedCardsCount().Return(1, nil)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(1), nil)
|
||||
th.Store.EXPECT().GetBlocksWithParentAndType("test-board-id", "parent_id", "view").Return([]*model.Block{{}, {}}, nil)
|
||||
@ -398,12 +290,6 @@ func TestInsertBlocks(t *testing.T) {
|
||||
}
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense).Times(2)
|
||||
|
||||
cloudLimit := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{
|
||||
Views: mmModel.NewInt(2),
|
||||
},
|
||||
}
|
||||
th.Store.EXPECT().GetCloudLimits().Return(cloudLimit, nil).Times(2)
|
||||
th.Store.EXPECT().GetUsedCardsCount().Return(1, nil).Times(2)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(1), nil).Times(2)
|
||||
th.Store.EXPECT().GetBlocksWithParentAndType("test-board-id", "parent_id", "view").Return([]*model.Block{{}}, nil).Times(2)
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/notify"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -219,17 +219,6 @@ func (a *App) DuplicateBoard(boardID, userID, toTeam string, asTemplate bool) (*
|
||||
return nil
|
||||
})
|
||||
|
||||
if len(bab.Blocks) != 0 {
|
||||
go func() {
|
||||
if uErr := a.UpdateCardLimitTimestamp(); uErr != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after duplicating a board",
|
||||
mlog.Err(uErr),
|
||||
)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return bab, members, err
|
||||
}
|
||||
|
||||
@ -469,15 +458,6 @@ func (a *App) DeleteBoard(boardID, userID string) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
if err := a.UpdateCardLimitTimestamp(); err != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after deleting a board",
|
||||
mlog.Err(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -715,14 +695,5 @@ func (a *App) UndeleteBoard(boardID string, modifiedBy string) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
if err := a.UpdateCardLimitTimestamp(); err != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after undeleting a board",
|
||||
mlog.Err(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/notify"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *App) CreateBoardsAndBlocks(bab *model.BoardsAndBlocks, userID string, addMember bool) (*model.BoardsAndBlocks, error) {
|
||||
@ -44,17 +44,6 @@ func (a *App) CreateBoardsAndBlocks(bab *model.BoardsAndBlocks, userID string, a
|
||||
}
|
||||
}
|
||||
|
||||
if len(newBab.Blocks) != 0 {
|
||||
go func() {
|
||||
if uErr := a.UpdateCardLimitTimestamp(); uErr != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after creating boards and blocks",
|
||||
mlog.Err(uErr),
|
||||
)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for _, board := range newBab.Boards {
|
||||
if !board.IsTemplate {
|
||||
if err := a.addBoardsToDefaultCategory(userID, board.TeamID, []*model.Board{board}); err != nil {
|
||||
@ -72,16 +61,6 @@ func (a *App) PatchBoardsAndBlocks(pbab *model.PatchBoardsAndBlocks, userID stri
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if a.IsCloudLimited() {
|
||||
containsLimitedBlocks, cErr := a.ContainsLimitedBlocks(oldBlocks)
|
||||
if cErr != nil {
|
||||
return nil, cErr
|
||||
}
|
||||
if containsLimitedBlocks {
|
||||
return nil, model.ErrPatchUpdatesLimitedCards
|
||||
}
|
||||
}
|
||||
|
||||
oldBlocksMap := map[string]*model.Block{}
|
||||
for _, block := range oldBlocks {
|
||||
oldBlocksMap[block.ID] = block
|
||||
@ -152,16 +131,5 @@ func (a *App) DeleteBoardsAndBlocks(dbab *model.DeleteBoardsAndBlocks, userID st
|
||||
return nil
|
||||
})
|
||||
|
||||
if len(dbab.Blocks) != 0 {
|
||||
go func() {
|
||||
if uErr := a.UpdateCardLimitTimestamp(); uErr != nil {
|
||||
a.logger.Error(
|
||||
"UpdateCardLimitTimestamp failed after deleting boards and blocks",
|
||||
mlog.Err(uErr),
|
||||
)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -16,9 +16,6 @@ func TestGetClientConfig(t *testing.T) {
|
||||
newConfiguration.Telemetry = true
|
||||
newConfiguration.TelemetryID = "abcde"
|
||||
newConfiguration.EnablePublicSharedBoards = true
|
||||
newConfiguration.FeatureFlags = make(map[string]string)
|
||||
newConfiguration.FeatureFlags["BoardsFeature1"] = "true"
|
||||
newConfiguration.FeatureFlags["BoardsFeature2"] = "true"
|
||||
newConfiguration.TeammateNameDisplay = "username"
|
||||
th.App.SetConfig(&newConfiguration)
|
||||
|
||||
@ -26,7 +23,6 @@ func TestGetClientConfig(t *testing.T) {
|
||||
require.True(t, clientConfig.EnablePublicSharedBoards)
|
||||
require.True(t, clientConfig.Telemetry)
|
||||
require.Equal(t, "abcde", clientConfig.TelemetryID)
|
||||
require.Equal(t, 2, len(clientConfig.FeatureFlags))
|
||||
require.Equal(t, "username", clientConfig.TeammateNameDisplay)
|
||||
})
|
||||
}
|
||||
|
@ -1,334 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
)
|
||||
|
||||
var ErrNilPluginAPI = errors.New("server not running in plugin mode")
|
||||
|
||||
// GetBoardsCloudLimits returns the limits of the server, and an empty
|
||||
// limits struct if there are no limits set.
|
||||
func (a *App) GetBoardsCloudLimits() (*model.BoardsCloudLimits, error) {
|
||||
// ToDo: Cloud Limits have been disabled by design. We should
|
||||
// revisit the decision and update the related code accordingly
|
||||
/*
|
||||
if !a.IsCloud() {
|
||||
return &model.BoardsCloudLimits{}, nil
|
||||
}
|
||||
|
||||
productLimits, err := a.store.GetCloudLimits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
usedCards, err := a.store.GetUsedCardsCount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cardLimitTimestamp, err := a.store.GetCardLimitTimestamp()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
boardsCloudLimits := &model.BoardsCloudLimits{
|
||||
UsedCards: usedCards,
|
||||
CardLimitTimestamp: cardLimitTimestamp,
|
||||
}
|
||||
if productLimits != nil && productLimits.Boards != nil {
|
||||
if productLimits.Boards.Cards != nil {
|
||||
boardsCloudLimits.Cards = *productLimits.Boards.Cards
|
||||
}
|
||||
if productLimits.Boards.Views != nil {
|
||||
boardsCloudLimits.Views = *productLimits.Boards.Views
|
||||
}
|
||||
}
|
||||
|
||||
return boardsCloudLimits, nil
|
||||
*/
|
||||
|
||||
return &model.BoardsCloudLimits{}, nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsedCardsCount() (int, error) {
|
||||
return a.store.GetUsedCardsCount()
|
||||
}
|
||||
|
||||
// IsCloud returns true if the server is running as a plugin in a
|
||||
// cloud licensed server.
|
||||
func (a *App) IsCloud() bool {
|
||||
return utils.IsCloudLicense(a.store.GetLicense())
|
||||
}
|
||||
|
||||
// IsCloudLimited returns true if the server is running in cloud mode
|
||||
// and the card limit has been set.
|
||||
func (a *App) IsCloudLimited() bool {
|
||||
// ToDo: Cloud Limits have been disabled by design. We should
|
||||
// revisit the decision and update the related code accordingly
|
||||
|
||||
// return a.CardLimit() != 0 && a.IsCloud()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// SetCloudLimits sets the limits of the server.
|
||||
func (a *App) SetCloudLimits(limits *mmModel.ProductLimits) error {
|
||||
oldCardLimit := a.CardLimit()
|
||||
|
||||
// if the limit object doesn't come complete, we assume limits are
|
||||
// being disabled
|
||||
cardLimit := 0
|
||||
if limits != nil && limits.Boards != nil && limits.Boards.Cards != nil {
|
||||
cardLimit = *limits.Boards.Cards
|
||||
}
|
||||
|
||||
if oldCardLimit != cardLimit {
|
||||
a.logger.Info(
|
||||
"setting new cloud limits",
|
||||
mlog.Int("oldCardLimit", oldCardLimit),
|
||||
mlog.Int("cardLimit", cardLimit),
|
||||
)
|
||||
a.SetCardLimit(cardLimit)
|
||||
return a.doUpdateCardLimitTimestamp()
|
||||
}
|
||||
|
||||
a.logger.Info(
|
||||
"setting new cloud limits, equivalent to the existing ones",
|
||||
mlog.Int("cardLimit", cardLimit),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// doUpdateCardLimitTimestamp performs the update without running any
|
||||
// checks.
|
||||
func (a *App) doUpdateCardLimitTimestamp() error {
|
||||
cardLimitTimestamp, err := a.store.UpdateCardLimitTimestamp(a.CardLimit())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.wsAdapter.BroadcastCardLimitTimestampChange(cardLimitTimestamp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCardLimitTimestamp checks if the server is a cloud instance
|
||||
// with limits applied, and if that's true, recalculates the card
|
||||
// limit timestamp and propagates the new one to the connected
|
||||
// clients.
|
||||
func (a *App) UpdateCardLimitTimestamp() error {
|
||||
if !a.IsCloudLimited() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return a.doUpdateCardLimitTimestamp()
|
||||
}
|
||||
|
||||
// getTemplateMapForBlocks gets all board ids for the blocks, and
|
||||
// builds a map with the board IDs as the key and their isTemplate
|
||||
// field as the value.
|
||||
func (a *App) getTemplateMapForBlocks(blocks []*model.Block) (map[string]bool, error) {
|
||||
boardMap := map[string]*model.Board{}
|
||||
for _, block := range blocks {
|
||||
if _, ok := boardMap[block.BoardID]; !ok {
|
||||
board, err := a.store.GetBoard(block.BoardID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
boardMap[block.BoardID] = board
|
||||
}
|
||||
}
|
||||
|
||||
templateMap := map[string]bool{}
|
||||
for boardID, board := range boardMap {
|
||||
templateMap[boardID] = board.IsTemplate
|
||||
}
|
||||
|
||||
return templateMap, nil
|
||||
}
|
||||
|
||||
// ApplyCloudLimits takes a set of blocks and, if the server is cloud
|
||||
// limited, limits those that are outside of the card limit and don't
|
||||
// belong to a template.
|
||||
func (a *App) ApplyCloudLimits(blocks []*model.Block) ([]*model.Block, error) {
|
||||
// if there is no limit currently being applied, return
|
||||
if !a.IsCloudLimited() {
|
||||
return blocks, nil
|
||||
}
|
||||
|
||||
cardLimitTimestamp, err := a.store.GetCardLimitTimestamp()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
templateMap, err := a.getTemplateMapForBlocks(blocks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
limitedBlocks := make([]*model.Block, len(blocks))
|
||||
for i, block := range blocks {
|
||||
// if the block belongs to a template, it will never be
|
||||
// limited
|
||||
if isTemplate, ok := templateMap[block.BoardID]; ok && isTemplate {
|
||||
limitedBlocks[i] = block
|
||||
continue
|
||||
}
|
||||
|
||||
if block.ShouldBeLimited(cardLimitTimestamp) {
|
||||
limitedBlocks[i] = block.GetLimited()
|
||||
} else {
|
||||
limitedBlocks[i] = block
|
||||
}
|
||||
}
|
||||
|
||||
return limitedBlocks, nil
|
||||
}
|
||||
|
||||
// ContainsLimitedBlocks checks if a list of blocks contain any block
|
||||
// that references a limited card.
|
||||
func (a *App) ContainsLimitedBlocks(blocks []*model.Block) (bool, error) {
|
||||
cardLimitTimestamp, err := a.store.GetCardLimitTimestamp()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if cardLimitTimestamp == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
cards := []*model.Block{}
|
||||
cardIDMap := map[string]bool{}
|
||||
for _, block := range blocks {
|
||||
switch block.Type {
|
||||
case model.TypeCard:
|
||||
cards = append(cards, block)
|
||||
default:
|
||||
cardIDMap[block.ParentID] = true
|
||||
}
|
||||
}
|
||||
|
||||
cardIDs := []string{}
|
||||
// if the card is already present on the set, we don't need to
|
||||
// fetch it from the database
|
||||
for cardID := range cardIDMap {
|
||||
alreadyPresent := false
|
||||
for _, card := range cards {
|
||||
if card.ID == cardID {
|
||||
alreadyPresent = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !alreadyPresent {
|
||||
cardIDs = append(cardIDs, cardID)
|
||||
}
|
||||
}
|
||||
|
||||
if len(cardIDs) > 0 {
|
||||
fetchedCards, fErr := a.store.GetBlocksByIDs(cardIDs)
|
||||
if fErr != nil {
|
||||
return false, fErr
|
||||
}
|
||||
cards = append(cards, fetchedCards...)
|
||||
}
|
||||
|
||||
templateMap, err := a.getTemplateMapForBlocks(cards)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, card := range cards {
|
||||
isTemplate, ok := templateMap[card.BoardID]
|
||||
if !ok {
|
||||
return false, newErrBoardNotFoundInTemplateMap(card.BoardID)
|
||||
}
|
||||
|
||||
// if the block belongs to a template, it will never be
|
||||
// limited
|
||||
if isTemplate {
|
||||
continue
|
||||
}
|
||||
|
||||
if card.ShouldBeLimited(cardLimitTimestamp) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
type errBoardNotFoundInTemplateMap struct {
|
||||
id string
|
||||
}
|
||||
|
||||
func newErrBoardNotFoundInTemplateMap(id string) *errBoardNotFoundInTemplateMap {
|
||||
return &errBoardNotFoundInTemplateMap{id}
|
||||
}
|
||||
|
||||
func (eb *errBoardNotFoundInTemplateMap) Error() string {
|
||||
return fmt.Sprintf("board %q not found in template map", eb.id)
|
||||
}
|
||||
|
||||
func (a *App) NotifyPortalAdminsUpgradeRequest(teamID string) error {
|
||||
if a.servicesAPI == nil {
|
||||
return ErrNilPluginAPI
|
||||
}
|
||||
|
||||
team, err := a.store.GetTeam(teamID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ofWhat string
|
||||
if team == nil {
|
||||
ofWhat = "your organization"
|
||||
} else {
|
||||
ofWhat = team.Title
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("A member of %s has notified you to upgrade this workspace before the trial ends.", ofWhat)
|
||||
|
||||
page := 0
|
||||
getUsersOptions := &mmModel.UserGetOptions{
|
||||
Active: true,
|
||||
Role: mmModel.SystemAdminRoleId,
|
||||
PerPage: 50,
|
||||
Page: page,
|
||||
}
|
||||
|
||||
for ; true; page++ {
|
||||
getUsersOptions.Page = page
|
||||
systemAdmins, appErr := a.servicesAPI.GetUsersFromProfiles(getUsersOptions)
|
||||
if appErr != nil {
|
||||
a.logger.Error("failed to fetch system admins", mlog.Int("page_size", getUsersOptions.PerPage), mlog.Int("page", page), mlog.Err(appErr))
|
||||
return appErr
|
||||
}
|
||||
|
||||
if len(systemAdmins) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
receiptUserIDs := []string{}
|
||||
for _, systemAdmin := range systemAdmins {
|
||||
receiptUserIDs = append(receiptUserIDs, systemAdmin.Id)
|
||||
}
|
||||
|
||||
if err := a.store.SendMessage(message, "custom_cloud_upgrade_nudge", receiptUserIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,780 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
mockservicesapi "github.com/mattermost/focalboard/server/model/mocks"
|
||||
)
|
||||
|
||||
func TestIsCloud(t *testing.T) {
|
||||
t.Run("if it's not running on plugin mode", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
th.Store.EXPECT().GetLicense().Return(nil)
|
||||
require.False(t, th.App.IsCloud())
|
||||
})
|
||||
|
||||
t.Run("if it's running on plugin mode but the license is incomplete", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
fakeLicense := &mmModel.License{}
|
||||
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
require.False(t, th.App.IsCloud())
|
||||
|
||||
fakeLicense = &mmModel.License{Features: &mmModel.Features{}}
|
||||
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
require.False(t, th.App.IsCloud())
|
||||
})
|
||||
|
||||
t.Run("if it's running on plugin mode, with a non-cloud license", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
fakeLicense := &mmModel.License{
|
||||
Features: &mmModel.Features{Cloud: mmModel.NewBool(false)},
|
||||
}
|
||||
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
require.False(t, th.App.IsCloud())
|
||||
})
|
||||
|
||||
t.Run("if it's running on plugin mode with a cloud license", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
fakeLicense := &mmModel.License{
|
||||
Features: &mmModel.Features{Cloud: mmModel.NewBool(true)},
|
||||
}
|
||||
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
require.True(t, th.App.IsCloud())
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsCloudLimited(t *testing.T) {
|
||||
t.Skipf("The Cloud Limits feature has been disabled")
|
||||
|
||||
t.Run("if no limit has been set, it should be false", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
require.False(t, th.App.IsCloudLimited())
|
||||
})
|
||||
|
||||
t.Run("if the limit is set, it should be true", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
fakeLicense := &mmModel.License{
|
||||
Features: &mmModel.Features{Cloud: mmModel.NewBool(true)},
|
||||
}
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
|
||||
th.App.SetCardLimit(5)
|
||||
require.True(t, th.App.IsCloudLimited())
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetCloudLimits(t *testing.T) {
|
||||
t.Skipf("The Cloud Limits feature has been disabled")
|
||||
|
||||
t.Run("if the limits are empty, it should do nothing", func(t *testing.T) {
|
||||
t.Run("limits empty", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
|
||||
require.NoError(t, th.App.SetCloudLimits(nil))
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
})
|
||||
|
||||
t.Run("limits not empty but board limits empty", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
|
||||
limits := &mmModel.ProductLimits{}
|
||||
|
||||
require.NoError(t, th.App.SetCloudLimits(limits))
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
})
|
||||
|
||||
t.Run("limits not empty but board limits values empty", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
|
||||
limits := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{},
|
||||
}
|
||||
|
||||
require.NoError(t, th.App.SetCloudLimits(limits))
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("if the limits are not empty, it should update them and calculate the new timestamp", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
|
||||
newCardLimitTimestamp := int64(27)
|
||||
th.Store.EXPECT().UpdateCardLimitTimestamp(5).Return(newCardLimitTimestamp, nil)
|
||||
|
||||
limits := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{Cards: mmModel.NewInt(5)},
|
||||
}
|
||||
|
||||
require.NoError(t, th.App.SetCloudLimits(limits))
|
||||
require.Equal(t, 5, th.App.CardLimit())
|
||||
})
|
||||
|
||||
t.Run("if the limits are already set and we unset them, the timestamp will be unset too", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
th.App.SetCardLimit(20)
|
||||
|
||||
th.Store.EXPECT().UpdateCardLimitTimestamp(0)
|
||||
|
||||
require.NoError(t, th.App.SetCloudLimits(nil))
|
||||
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
})
|
||||
|
||||
t.Run("if the limits are already set and we try to set the same ones again", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
th.App.SetCardLimit(20)
|
||||
|
||||
// the call to update card limit timestamp should not happen
|
||||
// as the limits didn't change
|
||||
th.Store.EXPECT().UpdateCardLimitTimestamp(gomock.Any()).Times(0)
|
||||
|
||||
limits := &mmModel.ProductLimits{
|
||||
Boards: &mmModel.BoardsLimits{Cards: mmModel.NewInt(20)},
|
||||
}
|
||||
|
||||
require.NoError(t, th.App.SetCloudLimits(limits))
|
||||
require.Equal(t, 20, th.App.CardLimit())
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateCardLimitTimestamp(t *testing.T) {
|
||||
t.Skipf("The Cloud Limits feature has been disabled")
|
||||
|
||||
fakeLicense := &mmModel.License{
|
||||
Features: &mmModel.Features{Cloud: mmModel.NewBool(true)},
|
||||
}
|
||||
|
||||
t.Run("if the server is a cloud instance but not limited, it should do nothing", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
|
||||
// the license check will not be done as the limit not being
|
||||
// set is enough for the method to return
|
||||
th.Store.EXPECT().GetLicense().Times(0)
|
||||
// no call to UpdateCardLimitTimestamp should happen as the
|
||||
// method should shortcircuit if not cloud limited
|
||||
th.Store.EXPECT().UpdateCardLimitTimestamp(gomock.Any()).Times(0)
|
||||
|
||||
require.NoError(t, th.App.UpdateCardLimitTimestamp())
|
||||
})
|
||||
|
||||
t.Run("if the server is a cloud instance and the timestamp is set, it should run the update", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
th.App.SetCardLimit(5)
|
||||
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
// no call to UpdateCardLimitTimestamp should happen as the
|
||||
// method should shortcircuit if not cloud limited
|
||||
th.Store.EXPECT().UpdateCardLimitTimestamp(5)
|
||||
|
||||
require.NoError(t, th.App.UpdateCardLimitTimestamp())
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetTemplateMapForBlocks(t *testing.T) {
|
||||
t.Skipf("The Cloud Limits feature has been disabled")
|
||||
|
||||
t.Run("should fetch the necessary boards from the database", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
board1 := &model.Board{
|
||||
ID: "board1",
|
||||
Type: model.BoardTypeOpen,
|
||||
IsTemplate: true,
|
||||
}
|
||||
|
||||
board2 := &model.Board{
|
||||
ID: "board2",
|
||||
Type: model.BoardTypeOpen,
|
||||
IsTemplate: false,
|
||||
}
|
||||
|
||||
blocks := []*model.Block{
|
||||
{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
},
|
||||
{
|
||||
ID: "card2",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board2",
|
||||
BoardID: "board2",
|
||||
},
|
||||
{
|
||||
ID: "text2",
|
||||
Type: model.TypeText,
|
||||
ParentID: "card2",
|
||||
BoardID: "board2",
|
||||
},
|
||||
}
|
||||
|
||||
th.Store.EXPECT().
|
||||
GetBoard("board1").
|
||||
Return(board1, nil).
|
||||
Times(1)
|
||||
th.Store.EXPECT().
|
||||
GetBoard("board2").
|
||||
Return(board2, nil).
|
||||
Times(1)
|
||||
|
||||
templateMap, err := th.App.getTemplateMapForBlocks(blocks)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, templateMap, 2)
|
||||
require.Contains(t, templateMap, "board1")
|
||||
require.True(t, templateMap["board1"])
|
||||
require.Contains(t, templateMap, "board2")
|
||||
require.False(t, templateMap["board2"])
|
||||
})
|
||||
|
||||
t.Run("should fail if the board is not in the database", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
blocks := []*model.Block{
|
||||
{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
},
|
||||
{
|
||||
ID: "card2",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board2",
|
||||
BoardID: "board2",
|
||||
},
|
||||
}
|
||||
|
||||
th.Store.EXPECT().
|
||||
GetBoard("board1").
|
||||
Return(nil, sql.ErrNoRows).
|
||||
Times(1)
|
||||
|
||||
templateMap, err := th.App.getTemplateMapForBlocks(blocks)
|
||||
require.ErrorIs(t, err, sql.ErrNoRows)
|
||||
require.Empty(t, templateMap)
|
||||
})
|
||||
}
|
||||
|
||||
func TestApplyCloudLimits(t *testing.T) {
|
||||
t.Skipf("The Cloud Limits feature has been disabled")
|
||||
|
||||
fakeLicense := &mmModel.License{
|
||||
Features: &mmModel.Features{Cloud: mmModel.NewBool(true)},
|
||||
}
|
||||
|
||||
board1 := &model.Board{
|
||||
ID: "board1",
|
||||
Type: model.BoardTypeOpen,
|
||||
IsTemplate: false,
|
||||
}
|
||||
|
||||
template := &model.Board{
|
||||
ID: "template",
|
||||
Type: model.BoardTypeOpen,
|
||||
IsTemplate: true,
|
||||
}
|
||||
|
||||
blocks := []*model.Block{
|
||||
{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 100,
|
||||
},
|
||||
{
|
||||
ID: "text1",
|
||||
Type: model.TypeText,
|
||||
ParentID: "card1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 100,
|
||||
},
|
||||
{
|
||||
ID: "card2",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 200,
|
||||
},
|
||||
{
|
||||
ID: "card-from-template",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "template",
|
||||
BoardID: "template",
|
||||
UpdateAt: 1,
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("if the server is not limited, it should return the blocks untouched", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
require.Zero(t, th.App.CardLimit())
|
||||
|
||||
newBlocks, err := th.App.ApplyCloudLimits(blocks)
|
||||
require.NoError(t, err)
|
||||
require.ElementsMatch(t, blocks, newBlocks)
|
||||
})
|
||||
|
||||
t.Run("if the server is limited, it should limit the blocks that are beyond the card limit timestamp", func(t *testing.T) {
|
||||
findBlock := func(blocks []*model.Block, id string) *model.Block {
|
||||
for _, block := range blocks {
|
||||
if block.ID == id {
|
||||
return block
|
||||
}
|
||||
}
|
||||
require.FailNow(t, "block %s not found", id)
|
||||
return &model.Block{} // this should never be reached
|
||||
}
|
||||
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
th.App.SetCardLimit(5)
|
||||
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(150), nil)
|
||||
th.Store.EXPECT().GetBoard("board1").Return(board1, nil).Times(1)
|
||||
th.Store.EXPECT().GetBoard("template").Return(template, nil).Times(1)
|
||||
|
||||
newBlocks, err := th.App.ApplyCloudLimits(blocks)
|
||||
require.NoError(t, err)
|
||||
|
||||
// should be limited as it's beyond the threshold
|
||||
require.True(t, findBlock(newBlocks, "card1").Limited)
|
||||
// only cards are limited
|
||||
require.False(t, findBlock(newBlocks, "text1").Limited)
|
||||
// should not be limited as it's not beyond the threshold
|
||||
require.False(t, findBlock(newBlocks, "card2").Limited)
|
||||
// cards belonging to templates are never limited
|
||||
require.False(t, findBlock(newBlocks, "card-from-template").Limited)
|
||||
})
|
||||
}
|
||||
|
||||
func TestContainsLimitedBlocks(t *testing.T) {
|
||||
t.Skipf("The Cloud Limits feature has been disabled")
|
||||
|
||||
// for all the following tests, the timestamp will be set to 150,
|
||||
// which means that blocks with an UpdateAt set to 100 will be
|
||||
// outside the active window and possibly limited, and blocks with
|
||||
// UpdateAt set to 200 will not
|
||||
|
||||
t.Run("should return false if the card limit timestamp is zero", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
blocks := []*model.Block{
|
||||
{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 100,
|
||||
},
|
||||
}
|
||||
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(int64(0), nil)
|
||||
|
||||
containsLimitedBlocks, err := th.App.ContainsLimitedBlocks(blocks)
|
||||
require.NoError(t, err)
|
||||
require.False(t, containsLimitedBlocks)
|
||||
})
|
||||
|
||||
t.Run("should return true if the block set contains a card that is limited", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
blocks := []*model.Block{
|
||||
{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 100,
|
||||
},
|
||||
}
|
||||
|
||||
board1 := &model.Board{
|
||||
ID: "board1",
|
||||
Type: model.BoardTypePrivate,
|
||||
}
|
||||
|
||||
th.App.SetCardLimit(500)
|
||||
cardLimitTimestamp := int64(150)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(cardLimitTimestamp, nil)
|
||||
th.Store.EXPECT().GetBoard("board1").Return(board1, nil)
|
||||
|
||||
containsLimitedBlocks, err := th.App.ContainsLimitedBlocks(blocks)
|
||||
require.NoError(t, err)
|
||||
require.True(t, containsLimitedBlocks)
|
||||
})
|
||||
|
||||
t.Run("should return false if that same block belongs to a template", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
blocks := []*model.Block{
|
||||
{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 100,
|
||||
},
|
||||
}
|
||||
|
||||
board1 := &model.Board{
|
||||
ID: "board1",
|
||||
Type: model.BoardTypeOpen,
|
||||
IsTemplate: true,
|
||||
}
|
||||
|
||||
th.App.SetCardLimit(500)
|
||||
cardLimitTimestamp := int64(150)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(cardLimitTimestamp, nil)
|
||||
th.Store.EXPECT().GetBoard("board1").Return(board1, nil)
|
||||
|
||||
containsLimitedBlocks, err := th.App.ContainsLimitedBlocks(blocks)
|
||||
require.NoError(t, err)
|
||||
require.False(t, containsLimitedBlocks)
|
||||
})
|
||||
|
||||
t.Run("should return true if the block contains a content block that belongs to a card that should be limited", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
blocks := []*model.Block{
|
||||
{
|
||||
ID: "text1",
|
||||
Type: model.TypeText,
|
||||
ParentID: "card1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 200,
|
||||
},
|
||||
}
|
||||
|
||||
card1 := &model.Block{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 100,
|
||||
}
|
||||
|
||||
board1 := &model.Board{
|
||||
ID: "board1",
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
|
||||
th.App.SetCardLimit(500)
|
||||
cardLimitTimestamp := int64(150)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(cardLimitTimestamp, nil)
|
||||
th.Store.EXPECT().GetBlocksByIDs([]string{"card1"}).Return([]*model.Block{card1}, nil)
|
||||
th.Store.EXPECT().GetBoard("board1").Return(board1, nil)
|
||||
|
||||
containsLimitedBlocks, err := th.App.ContainsLimitedBlocks(blocks)
|
||||
require.NoError(t, err)
|
||||
require.True(t, containsLimitedBlocks)
|
||||
})
|
||||
|
||||
t.Run("should return false if that same block belongs to a card that is inside the active window", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
blocks := []*model.Block{
|
||||
{
|
||||
ID: "text1",
|
||||
Type: model.TypeText,
|
||||
ParentID: "card1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 200,
|
||||
},
|
||||
}
|
||||
|
||||
card1 := &model.Block{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 200,
|
||||
}
|
||||
|
||||
board1 := &model.Board{
|
||||
ID: "board1",
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
|
||||
th.App.SetCardLimit(500)
|
||||
cardLimitTimestamp := int64(150)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(cardLimitTimestamp, nil)
|
||||
th.Store.EXPECT().GetBlocksByIDs([]string{"card1"}).Return([]*model.Block{card1}, nil)
|
||||
th.Store.EXPECT().GetBoard("board1").Return(board1, nil)
|
||||
|
||||
containsLimitedBlocks, err := th.App.ContainsLimitedBlocks(blocks)
|
||||
require.NoError(t, err)
|
||||
require.False(t, containsLimitedBlocks)
|
||||
})
|
||||
|
||||
t.Run("should reach to the database to fetch the necessary information only in an efficient way", func(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
blocks := []*model.Block{
|
||||
// a content block that references a card that needs
|
||||
// fetching
|
||||
{
|
||||
ID: "text1",
|
||||
Type: model.TypeText,
|
||||
ParentID: "card1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 100,
|
||||
},
|
||||
// a board that needs fetching referenced by a card and a content block
|
||||
{
|
||||
ID: "card2",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board2",
|
||||
BoardID: "board2",
|
||||
// per timestamp should be limited but the board is a
|
||||
// template
|
||||
UpdateAt: 100,
|
||||
},
|
||||
{
|
||||
ID: "text2",
|
||||
Type: model.TypeText,
|
||||
ParentID: "card2",
|
||||
BoardID: "board2",
|
||||
UpdateAt: 200,
|
||||
},
|
||||
// a content block that references a card and a board,
|
||||
// both absent
|
||||
{
|
||||
ID: "image3",
|
||||
Type: model.TypeImage,
|
||||
ParentID: "card3",
|
||||
BoardID: "board3",
|
||||
UpdateAt: 100,
|
||||
},
|
||||
}
|
||||
|
||||
card1 := &model.Block{
|
||||
ID: "card1",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board1",
|
||||
BoardID: "board1",
|
||||
UpdateAt: 200,
|
||||
}
|
||||
|
||||
card3 := &model.Block{
|
||||
ID: "card3",
|
||||
Type: model.TypeCard,
|
||||
ParentID: "board3",
|
||||
BoardID: "board3",
|
||||
UpdateAt: 200,
|
||||
}
|
||||
|
||||
board1 := &model.Board{
|
||||
ID: "board1",
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
|
||||
board2 := &model.Board{
|
||||
ID: "board2",
|
||||
Type: model.BoardTypeOpen,
|
||||
IsTemplate: true,
|
||||
}
|
||||
|
||||
board3 := &model.Board{
|
||||
ID: "board3",
|
||||
Type: model.BoardTypePrivate,
|
||||
}
|
||||
|
||||
th.App.SetCardLimit(500)
|
||||
cardLimitTimestamp := int64(150)
|
||||
th.Store.EXPECT().GetCardLimitTimestamp().Return(cardLimitTimestamp, nil)
|
||||
th.Store.EXPECT().GetBlocksByIDs(gomock.InAnyOrder([]string{"card1", "card3"})).Return([]*model.Block{card1, card3}, nil)
|
||||
th.Store.EXPECT().GetBoard("board1").Return(board1, nil)
|
||||
th.Store.EXPECT().GetBoard("board2").Return(board2, nil)
|
||||
th.Store.EXPECT().GetBoard("board3").Return(board3, nil)
|
||||
|
||||
containsLimitedBlocks, err := th.App.ContainsLimitedBlocks(blocks)
|
||||
require.NoError(t, err)
|
||||
require.False(t, containsLimitedBlocks)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNotifyPortalAdminsUpgradeRequest(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
t.Run("should send message", func(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
servicesAPI := mockservicesapi.NewMockServicesAPI(ctrl)
|
||||
|
||||
sysAdmin1 := &mmModel.User{
|
||||
Id: "michael-scott",
|
||||
Username: "Michael Scott",
|
||||
}
|
||||
|
||||
sysAdmin2 := &mmModel.User{
|
||||
Id: "dwight-schrute",
|
||||
Username: "Dwight Schrute",
|
||||
}
|
||||
|
||||
getUsersOptionsPage0 := &mmModel.UserGetOptions{
|
||||
Active: true,
|
||||
Role: mmModel.SystemAdminRoleId,
|
||||
PerPage: 50,
|
||||
Page: 0,
|
||||
}
|
||||
servicesAPI.EXPECT().GetUsersFromProfiles(getUsersOptionsPage0).Return([]*mmModel.User{sysAdmin1, sysAdmin2}, nil)
|
||||
|
||||
getUsersOptionsPage1 := &mmModel.UserGetOptions{
|
||||
Active: true,
|
||||
Role: mmModel.SystemAdminRoleId,
|
||||
PerPage: 50,
|
||||
Page: 1,
|
||||
}
|
||||
servicesAPI.EXPECT().GetUsersFromProfiles(getUsersOptionsPage1).Return([]*mmModel.User{}, nil)
|
||||
|
||||
th.App.servicesAPI = servicesAPI
|
||||
|
||||
team := &model.Team{
|
||||
Title: "Dunder Mifflin",
|
||||
}
|
||||
|
||||
th.Store.EXPECT().GetTeam("team-id-1").Return(team, nil)
|
||||
th.Store.EXPECT().SendMessage(gomock.Any(), "custom_cloud_upgrade_nudge", gomock.Any()).Return(nil).Times(1)
|
||||
|
||||
err := th.App.NotifyPortalAdminsUpgradeRequest("team-id-1")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("no sys admins found", func(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
servicesAPI := mockservicesapi.NewMockServicesAPI(ctrl)
|
||||
|
||||
getUsersOptionsPage0 := &mmModel.UserGetOptions{
|
||||
Active: true,
|
||||
Role: mmModel.SystemAdminRoleId,
|
||||
PerPage: 50,
|
||||
Page: 0,
|
||||
}
|
||||
servicesAPI.EXPECT().GetUsersFromProfiles(getUsersOptionsPage0).Return([]*mmModel.User{}, nil)
|
||||
|
||||
th.App.servicesAPI = servicesAPI
|
||||
|
||||
team := &model.Team{
|
||||
Title: "Dunder Mifflin",
|
||||
}
|
||||
|
||||
th.Store.EXPECT().GetTeam("team-id-1").Return(team, nil)
|
||||
|
||||
err := th.App.NotifyPortalAdminsUpgradeRequest("team-id-1")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("iterate multiple pages", func(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
servicesAPI := mockservicesapi.NewMockServicesAPI(ctrl)
|
||||
|
||||
sysAdmin1 := &mmModel.User{
|
||||
Id: "michael-scott",
|
||||
Username: "Michael Scott",
|
||||
}
|
||||
|
||||
sysAdmin2 := &mmModel.User{
|
||||
Id: "dwight-schrute",
|
||||
Username: "Dwight Schrute",
|
||||
}
|
||||
|
||||
getUsersOptionsPage0 := &mmModel.UserGetOptions{
|
||||
Active: true,
|
||||
Role: mmModel.SystemAdminRoleId,
|
||||
PerPage: 50,
|
||||
Page: 0,
|
||||
}
|
||||
servicesAPI.EXPECT().GetUsersFromProfiles(getUsersOptionsPage0).Return([]*mmModel.User{sysAdmin1}, nil)
|
||||
|
||||
getUsersOptionsPage1 := &mmModel.UserGetOptions{
|
||||
Active: true,
|
||||
Role: mmModel.SystemAdminRoleId,
|
||||
PerPage: 50,
|
||||
Page: 1,
|
||||
}
|
||||
servicesAPI.EXPECT().GetUsersFromProfiles(getUsersOptionsPage1).Return([]*mmModel.User{sysAdmin2}, nil)
|
||||
|
||||
getUsersOptionsPage2 := &mmModel.UserGetOptions{
|
||||
Active: true,
|
||||
Role: mmModel.SystemAdminRoleId,
|
||||
PerPage: 50,
|
||||
Page: 2,
|
||||
}
|
||||
servicesAPI.EXPECT().GetUsersFromProfiles(getUsersOptionsPage2).Return([]*mmModel.User{}, nil)
|
||||
|
||||
th.App.servicesAPI = servicesAPI
|
||||
|
||||
team := &model.Team{
|
||||
Title: "Dunder Mifflin",
|
||||
}
|
||||
|
||||
th.Store.EXPECT().GetTeam("team-id-1").Return(team, nil)
|
||||
th.Store.EXPECT().SendMessage(gomock.Any(), "custom_cloud_upgrade_nudge", gomock.Any()).Return(nil).Times(2)
|
||||
|
||||
err := th.App.NotifyPortalAdminsUpgradeRequest("team-id-1")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
@ -160,6 +160,7 @@ func TestMoveContentBlock(t *testing.T) {
|
||||
|
||||
for _, tc := range ttCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tc := tc
|
||||
if tc.parentBlock != nil {
|
||||
if tc.parentBlock.ID == "invalid-card" {
|
||||
th.Store.EXPECT().GetBlock(tc.srcBlock.ParentID).Return(nil, model.NewErrNotFound("test"))
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/wiggin77/merror"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -8,11 +8,11 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/filestore"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/v8/platform/shared/filestore"
|
||||
)
|
||||
|
||||
const emptyString = "empty"
|
||||
|
@ -13,10 +13,10 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin/plugintest/mock"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/filestore"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/filestore/mocks"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/plugin/plugintest/mock"
|
||||
"github.com/mattermost/mattermost/server/v8/platform/shared/filestore"
|
||||
"github.com/mattermost/mattermost/server/v8/platform/shared/filestore/mocks"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -17,8 +17,8 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/webhook"
|
||||
"github.com/mattermost/focalboard/server/ws"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/filestore/mocks"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/v8/platform/shared/filestore/mocks"
|
||||
)
|
||||
|
||||
type TestHelper struct {
|
||||
@ -35,7 +35,7 @@ func SetupTestHelper(t *testing.T) (*TestHelper, func()) {
|
||||
store := mockstore.NewMockStore(ctrl)
|
||||
filesBackend := &mocks.FileBackend{}
|
||||
auth := auth.New(&cfg, store, nil)
|
||||
logger := mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)
|
||||
logger, _ := mlog.NewLogger()
|
||||
sessionToken := "TESTTOKEN"
|
||||
wsserver := ws.NewServer(auth, sessionToken, false, logger, store)
|
||||
webhook := webhook.NewClient(&cfg, logger)
|
||||
@ -43,7 +43,7 @@ func SetupTestHelper(t *testing.T) (*TestHelper, func()) {
|
||||
|
||||
mockStore := permissionsMocks.NewMockStore(ctrl)
|
||||
mockAPI := mmpermissionsMocks.NewMockAPI(ctrl)
|
||||
permissions := mmpermissions.New(mockStore, mockAPI, mlog.CreateConsoleTestLogger(true, mlog.LvlError))
|
||||
permissions := mmpermissions.New(mockStore, mockAPI, mlog.CreateConsoleTestLogger(t))
|
||||
|
||||
appServices := Services{
|
||||
Auth: auth,
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -3,7 +3,7 @@ package app
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
// initialize is called when the App is first created.
|
||||
|
@ -1,83 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (a *App) GetTeamBoardsInsights(userID string, teamID string, opts *mmModel.InsightsOpts) (*model.BoardInsightsList, error) {
|
||||
// check if server is properly licensed, and user is not a guest
|
||||
userPermitted, err := insightPermissionGate(a, userID, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !userPermitted {
|
||||
return nil, errors.New("User isn't authorized to access insights.")
|
||||
}
|
||||
boardIDs, err := getUserBoards(userID, teamID, a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.store.GetTeamBoardsInsights(teamID, opts.StartUnixMilli, opts.Page*opts.PerPage, opts.PerPage, boardIDs)
|
||||
}
|
||||
|
||||
func (a *App) GetUserBoardsInsights(userID string, teamID string, opts *mmModel.InsightsOpts) (*model.BoardInsightsList, error) {
|
||||
// check if server is properly licensed, and user is not a guest
|
||||
userPermitted, err := insightPermissionGate(a, userID, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !userPermitted {
|
||||
return nil, errors.New("User isn't authorized to access insights.")
|
||||
}
|
||||
boardIDs, err := getUserBoards(userID, teamID, a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.store.GetUserBoardsInsights(teamID, userID, opts.StartUnixMilli, opts.Page*opts.PerPage, opts.PerPage, boardIDs)
|
||||
}
|
||||
|
||||
func insightPermissionGate(a *App, userID string, isMyInsights bool) (bool, error) {
|
||||
licenseError := errors.New("invalid license/authorization to use insights API")
|
||||
guestError := errors.New("guests aren't authorized to use insights API")
|
||||
lic := a.store.GetLicense()
|
||||
|
||||
user, err := a.store.GetUserByID(userID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if user.IsGuest {
|
||||
return false, guestError
|
||||
}
|
||||
|
||||
if lic == nil && !isMyInsights {
|
||||
a.logger.Debug("Deployment doesn't have a license")
|
||||
return false, licenseError
|
||||
}
|
||||
|
||||
if !isMyInsights && (lic.SkuShortName != mmModel.LicenseShortSkuProfessional && lic.SkuShortName != mmModel.LicenseShortSkuEnterprise) {
|
||||
return false, licenseError
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (a *App) GetUserTimezone(userID string) (string, error) {
|
||||
return a.store.GetUserTimezone(userID)
|
||||
}
|
||||
|
||||
func getUserBoards(userID string, teamID string, a *App) ([]string, error) {
|
||||
// get boards accessible by user and filter boardIDs
|
||||
boards, err := a.store.GetBoardsForUserAndTeam(userID, teamID, true)
|
||||
if err != nil {
|
||||
return nil, errors.New("error getting boards for user")
|
||||
}
|
||||
boardIDs := make([]string, 0, len(boards))
|
||||
|
||||
for _, board := range boards {
|
||||
boardIDs = append(boardIDs, board.ID)
|
||||
}
|
||||
return boardIDs, nil
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var mockInsightsBoards = []*model.Board{
|
||||
{
|
||||
ID: "mock-user-workspace-id",
|
||||
Title: "MockUserWorkspace",
|
||||
},
|
||||
}
|
||||
|
||||
var mockTeamInsights = []*model.BoardInsight{
|
||||
{
|
||||
BoardID: "board-id-1",
|
||||
},
|
||||
{
|
||||
BoardID: "board-id-2",
|
||||
},
|
||||
}
|
||||
|
||||
var mockTeamInsightsList = &model.BoardInsightsList{
|
||||
InsightsListData: mmModel.InsightsListData{HasNext: false},
|
||||
Items: mockTeamInsights,
|
||||
}
|
||||
|
||||
type insightError struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
func (ie insightError) Error() string {
|
||||
return ie.msg
|
||||
}
|
||||
|
||||
func TestGetTeamAndUserBoardsInsights(t *testing.T) {
|
||||
th, tearDown := SetupTestHelper(t)
|
||||
defer tearDown()
|
||||
|
||||
t.Run("success query", func(t *testing.T) {
|
||||
fakeLicense := &mmModel.License{Features: &mmModel.Features{}, SkuShortName: mmModel.LicenseShortSkuEnterprise}
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense).AnyTimes()
|
||||
fakeUser := &model.User{
|
||||
ID: "user-id",
|
||||
IsGuest: false,
|
||||
}
|
||||
th.Store.EXPECT().GetUserByID("user-id").Return(fakeUser, nil).AnyTimes()
|
||||
th.Store.EXPECT().GetBoardsForUserAndTeam("user-id", "team-id", true).Return(mockInsightsBoards, nil).AnyTimes()
|
||||
th.Store.EXPECT().
|
||||
GetTeamBoardsInsights("team-id", int64(0), 0, 10, []string{"mock-user-workspace-id"}).
|
||||
Return(mockTeamInsightsList, nil)
|
||||
results, err := th.App.GetTeamBoardsInsights("user-id", "team-id", &mmModel.InsightsOpts{StartUnixMilli: 0, Page: 0, PerPage: 10})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, results.Items, 2)
|
||||
th.Store.EXPECT().
|
||||
GetUserBoardsInsights("team-id", "user-id", int64(0), 0, 10, []string{"mock-user-workspace-id"}).
|
||||
Return(mockTeamInsightsList, nil)
|
||||
results, err = th.App.GetUserBoardsInsights("user-id", "team-id", &mmModel.InsightsOpts{StartUnixMilli: 0, Page: 0, PerPage: 10})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, results.Items, 2)
|
||||
})
|
||||
|
||||
t.Run("fail query", func(t *testing.T) {
|
||||
fakeLicense := &mmModel.License{Features: &mmModel.Features{}, SkuShortName: mmModel.LicenseShortSkuEnterprise}
|
||||
th.Store.EXPECT().GetLicense().Return(fakeLicense).AnyTimes()
|
||||
fakeUser := &model.User{
|
||||
ID: "user-id",
|
||||
IsGuest: false,
|
||||
}
|
||||
th.Store.EXPECT().GetUserByID("user-id").Return(fakeUser, nil).AnyTimes()
|
||||
th.Store.EXPECT().GetBoardsForUserAndTeam("user-id", "team-id", true).Return(mockInsightsBoards, nil).AnyTimes()
|
||||
th.Store.EXPECT().
|
||||
GetTeamBoardsInsights("team-id", int64(0), 0, 10, []string{"mock-user-workspace-id"}).
|
||||
Return(nil, insightError{"board-insight-error"})
|
||||
_, err := th.App.GetTeamBoardsInsights("user-id", "team-id", &mmModel.InsightsOpts{StartUnixMilli: 0, Page: 0, PerPage: 10})
|
||||
require.Error(t, err)
|
||||
require.ErrorIs(t, err, insightError{"board-insight-error"})
|
||||
th.Store.EXPECT().
|
||||
GetUserBoardsInsights("team-id", "user-id", int64(0), 0, 10, []string{"mock-user-workspace-id"}).
|
||||
Return(nil, insightError{"board-insight-error"})
|
||||
_, err = th.App.GetUserBoardsInsights("user-id", "team-id", &mmModel.InsightsOpts{StartUnixMilli: 0, Page: 0, PerPage: 10})
|
||||
require.Error(t, err)
|
||||
require.ErrorIs(t, err, insightError{"board-insight-error"})
|
||||
})
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
func (a *App) HasPermissionToBoard(userID, boardID string, permission *mm_model.Permission) bool {
|
||||
|
8
server/app/statistics.go
Normal file
8
server/app/statistics.go
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
func (a *App) GetUsedCardsCount() (int, error) {
|
||||
return a.store.GetUsedCardsCount()
|
||||
}
|
@ -4,7 +4,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *App) CreateSubscription(sub *model.Subscription) (*model.Subscription, error) {
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *App) GetRootTeam() (*model.Team, error) {
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/assets"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/plugin/plugintest/mock"
|
||||
"github.com/mattermost/mattermost/server/public/plugin/plugintest/mock"
|
||||
)
|
||||
|
||||
func TestApp_initializeTemplates(t *testing.T) {
|
||||
|
@ -2,7 +2,7 @@ package app
|
||||
|
||||
import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
func (a *App) GetTeamUsers(teamID string, asGuestID string) ([]*model.User, error) {
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
type TestHelper struct {
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/api"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -215,36 +215,6 @@ func (c *Client) GetTeam(teamID string) (*model.Team, *Response) {
|
||||
return model.TeamFromJSON(r.Body), BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client) GetTeamBoardsInsights(teamID string, userID string, timeRange string, page int, perPage int) (*model.BoardInsightsList, *Response) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
r, err := c.DoAPIGet(c.GetTeamRoute(teamID)+"/boards/insights"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
var boardInsightsList *model.BoardInsightsList
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&boardInsightsList); jsonErr != nil {
|
||||
return nil, BuildErrorResponse(r, jsonErr)
|
||||
}
|
||||
return boardInsightsList, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client) GetUserBoardsInsights(teamID string, userID string, timeRange string, page int, perPage int) (*model.BoardInsightsList, *Response) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v&team_id=%v", timeRange, page, perPage, teamID)
|
||||
r, err := c.DoAPIGet(c.GetMeRoute()+"/boards/insights"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
var boardInsightsList *model.BoardInsightsList
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&boardInsightsList); jsonErr != nil {
|
||||
return nil, BuildErrorResponse(r, jsonErr)
|
||||
}
|
||||
return boardInsightsList, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client) GetBlocksForBoard(boardID string) ([]*model.Block, *Response) {
|
||||
r, err := c.DoAPIGet(c.GetBlocksRoute(boardID), "")
|
||||
if err != nil {
|
||||
@ -973,22 +943,6 @@ func (c *Client) ImportArchive(teamID string, data io.Reader) *Response {
|
||||
return BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client) GetLimits() (*model.BoardsCloudLimits, *Response) {
|
||||
r, err := c.DoAPIGet("/limits", "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
var limits *model.BoardsCloudLimits
|
||||
err = json.NewDecoder(r.Body).Decode(&limits)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
|
||||
return limits, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client) MoveContentBlock(srcBlockID string, dstBlockID string, where string, userID string) (bool, *Response) {
|
||||
r, err := c.DoAPIPost("/content-blocks/"+srcBlockID+"/moveto/"+where+"/"+dstBlockID, "")
|
||||
if err != nil {
|
||||
@ -999,22 +953,6 @@ func (c *Client) MoveContentBlock(srcBlockID string, dstBlockID string, where st
|
||||
return true, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client) GetStatistics() (*model.BoardsStatistics, *Response) {
|
||||
r, err := c.DoAPIGet("/statistics", "")
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
var stats *model.BoardsStatistics
|
||||
err = json.NewDecoder(r.Body).Decode(&stats)
|
||||
if err != nil {
|
||||
return nil, BuildErrorResponse(r, err)
|
||||
}
|
||||
|
||||
return stats, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client) GetBoardsForCompliance(teamID string, page, perPage int) (*model.BoardsComplianceResponse, *Response) {
|
||||
query := fmt.Sprintf("?team_id=%s&page=%d&per_page=%d", teamID, page, perPage)
|
||||
r, err := c.DoAPIGet("/admin/boards"+query, "")
|
||||
|
161
server/go.mod
161
server/go.mod
@ -1,121 +1,118 @@
|
||||
module github.com/mattermost/focalboard/server
|
||||
|
||||
go 1.19
|
||||
go 1.21
|
||||
|
||||
toolchain go1.21.8
|
||||
|
||||
require (
|
||||
github.com/Masterminds/squirrel v1.5.3
|
||||
github.com/Masterminds/squirrel v1.5.4
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/krolaw/zipstream v0.0.0-20180621105154-0a2661891f94
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/mattermost/mattermost-plugin-api v0.1.1
|
||||
github.com/mattermost/mattermost-server/v6 v6.0.0-20230321114510-b61c096497ac
|
||||
github.com/mattermost/morph v1.0.5-0.20221115094356-4c18a75b1f5e
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mattermost/logr/v2 v2.0.21
|
||||
github.com/mattermost/mattermost/server/public v0.1.3
|
||||
github.com/mattermost/mattermost/server/v8 v8.0.0-20240529104128-9d30a62c9471
|
||||
github.com/mattermost/morph v1.1.0
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||
github.com/mgdelacroix/foundation v0.0.0-20220812143423-0bfc18f73538
|
||||
github.com/mgdelacroix/foundation v0.0.0-20230510073833-0660207768ef
|
||||
github.com/oklog/run v1.1.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.12.1
|
||||
github.com/rivo/uniseg v0.4.3
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/rivo/uniseg v0.4.7
|
||||
github.com/rudderlabs/analytics-go v3.3.3+incompatible
|
||||
github.com/sergi/go-diff v1.2.0
|
||||
github.com/spf13/viper v1.10.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/wiggin77/merror v1.0.4
|
||||
golang.org/x/crypto v0.5.0
|
||||
github.com/sergi/go-diff v1.3.1
|
||||
github.com/spf13/viper v1.18.2
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/wiggin77/merror v1.0.5
|
||||
golang.org/x/crypto v0.23.0
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.15.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/graph-gophers/graphql-go v1.5.1-0.20230110080634-edea822f558a // indirect
|
||||
github.com/hashicorp/go-hclog v1.4.0 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.8 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.1 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.15.14 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
|
||||
github.com/jmoiron/sqlx v1.4.0 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.16 // indirect
|
||||
github.com/mattermost/squirrel v0.2.0 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.45 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.70 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.33.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/segmentio/backo-go v1.0.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/segmentio/backo-go v1.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/tidwall/gjson v1.14.4 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tidwall/gjson v1.17.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/tinylib/msgp v1.1.9 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/wiggin77/srslog v1.0.1 // indirect
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
|
||||
github.com/yuin/goldmark v1.5.3 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/tools v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230104163317-caabf589fcbf // indirect
|
||||
google.golang.org/grpc v1.51.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
github.com/yuin/goldmark v1.7.1 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240529005216-23cca8864a10 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
|
||||
google.golang.org/grpc v1.64.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.22.2 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.20.1 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect
|
||||
modernc.org/libc v1.50.9 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.29.10 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
)
|
||||
|
2062
server/go.sum
2062
server/go.sum
File diff suppressed because it is too large
Load Diff
@ -19,8 +19,8 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/store/sqlstore"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
var errTestStore = errors.New("plugin test store error")
|
||||
|
@ -1,55 +0,0 @@
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/focalboard/server/client"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStatisticsLocalMode(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("an unauthenticated client should not be able to get statistics", func(t *testing.T) {
|
||||
th.Logout(th.Client)
|
||||
|
||||
stats, resp := th.Client.GetStatistics()
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, stats)
|
||||
})
|
||||
|
||||
t.Run("Check authenticated user, not admin", func(t *testing.T) {
|
||||
th.Login1()
|
||||
|
||||
stats, resp := th.Client.GetStatistics()
|
||||
th.CheckNotImplemented(resp)
|
||||
require.Nil(t, stats)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStatisticsPluginMode(t *testing.T) {
|
||||
th := SetupTestHelperPluginMode(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Permissions are tested in permissions_test.go
|
||||
// This tests the functionality.
|
||||
t.Run("Check authenticated user, admin", func(t *testing.T) {
|
||||
th.Client = client.NewClient(th.Server.Config().ServerRoot, "")
|
||||
th.Client.HTTPHeader["Mattermost-User-Id"] = userAdmin
|
||||
|
||||
stats, resp := th.Client.GetStatistics()
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, stats)
|
||||
|
||||
numberCards := 2
|
||||
th.CreateBoardAndCards("testTeam", model.BoardTypeOpen, numberCards)
|
||||
|
||||
stats, resp = th.Client.GetStatistics()
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, stats)
|
||||
require.Equal(t, 1, stats.Boards)
|
||||
require.Equal(t, numberCards, stats.Cards)
|
||||
})
|
||||
}
|
@ -3,7 +3,7 @@ package integrationtests
|
||||
import (
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
type TestStore struct {
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
"github.com/mattermost/focalboard/server/services/permissions/localpermissions"
|
||||
)
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
// Active server used with shared code (dll)
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
// GenerateBlockIDs generates new IDs for all the blocks of the list,
|
||||
|
@ -1,62 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
// BoardInsightsList is a response type with pagination support.
|
||||
type BoardInsightsList struct {
|
||||
mmModel.InsightsListData
|
||||
Items []*BoardInsight `json:"items"`
|
||||
}
|
||||
|
||||
// BoardInsight gives insight into activities in a Board
|
||||
// swagger:model
|
||||
type BoardInsight struct {
|
||||
// ID of the board
|
||||
// required: true
|
||||
BoardID string `json:"boardID"`
|
||||
|
||||
// icon of the board
|
||||
// required: false
|
||||
Icon string `json:"icon"`
|
||||
|
||||
// Title of the board
|
||||
// required: false
|
||||
Title string `json:"title"`
|
||||
|
||||
// Metric of how active the board is
|
||||
// required: true
|
||||
ActivityCount string `json:"activityCount"`
|
||||
|
||||
// IDs of users active on the board
|
||||
// required: true
|
||||
ActiveUsers mmModel.StringArray `json:"activeUsers"`
|
||||
|
||||
// ID of user who created the board
|
||||
// required: true
|
||||
CreatedBy string `json:"createdBy"`
|
||||
}
|
||||
|
||||
func BoardInsightsFromJSON(data io.Reader) []BoardInsight {
|
||||
var boardInsights []BoardInsight
|
||||
_ = json.NewDecoder(data).Decode(&boardInsights)
|
||||
return boardInsights
|
||||
}
|
||||
|
||||
// GetTopBoardInsightsListWithPagination adds a rank to each item in the given list of BoardInsight and checks if there is
|
||||
// another page that can be fetched based on the given limit and offset. The given list of BoardInsight is assumed to be
|
||||
// sorted by ActivityCount(score). Returns a BoardInsightsList.
|
||||
func GetTopBoardInsightsListWithPagination(boards []*BoardInsight, limit int) *BoardInsightsList {
|
||||
// Add pagination support
|
||||
var hasNext bool
|
||||
if limit != 0 && len(boards) == limit+1 {
|
||||
hasNext = true
|
||||
boards = boards[:len(boards)-1]
|
||||
}
|
||||
|
||||
return &BoardInsightsList{InsightsListData: mmModel.InsightsListData{HasNext: hasNext}, Items: boards}
|
||||
}
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
var ErrNoBoardsInBoardsAndBlocks = errors.New("at least one board is required")
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func TestIsValidBoardsAndBlocks(t *testing.T) {
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
|
||||
pluginapi "github.com/mattermost/mattermost-plugin-api"
|
||||
pluginapi "github.com/mattermost/mattermost/server/public/pluginapi"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
func NewFileInfo(name string) *mm_model.FileInfo {
|
||||
|
8
server/model/log_level.go
Normal file
8
server/model/log_level.go
Normal file
@ -0,0 +1,8 @@
|
||||
package model
|
||||
|
||||
import "github.com/mattermost/logr/v2"
|
||||
|
||||
var LvlFBTelemetry = logr.Level{
|
||||
ID: 9000,
|
||||
Name: "telemetry",
|
||||
}
|
@ -10,8 +10,8 @@ import (
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
mux "github.com/gorilla/mux"
|
||||
model "github.com/mattermost/mattermost-server/v6/model"
|
||||
mlog "github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
model "github.com/mattermost/mattermost/server/public/model"
|
||||
mlog "github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
// MockServicesAPI is a mock of ServicesAPI interface.
|
||||
@ -141,21 +141,6 @@ func (mr *MockServicesAPIMockRecorder) GetChannelsForTeamForUser(arg0, arg1, arg
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChannelsForTeamForUser", reflect.TypeOf((*MockServicesAPI)(nil).GetChannelsForTeamForUser), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// GetCloudLimits mocks base method.
|
||||
func (m *MockServicesAPI) GetCloudLimits() (*model.ProductLimits, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetCloudLimits")
|
||||
ret0, _ := ret[0].(*model.ProductLimits)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetCloudLimits indicates an expected call of GetCloudLimits.
|
||||
func (mr *MockServicesAPIMockRecorder) GetCloudLimits() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCloudLimits", reflect.TypeOf((*MockServicesAPI)(nil).GetCloudLimits))
|
||||
}
|
||||
|
||||
// GetConfig mocks base method.
|
||||
func (m *MockServicesAPI) GetConfig() *model.Config {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -3,7 +3,7 @@ package model
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/utils"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/utils"
|
||||
)
|
||||
|
||||
// NotificationHint provides a hint that a block has been modified and has subscribers that
|
||||
|
@ -1,7 +1,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
mmModel "github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
mm_model "github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -67,9 +67,6 @@ type ServicesAPI interface {
|
||||
PublishWebSocketEvent(event string, payload map[string]interface{}, broadcast *mm_model.WebsocketBroadcast)
|
||||
PublishPluginClusterEvent(ev mm_model.PluginClusterEvent, opts mm_model.PluginClusterEventSendOptions) error
|
||||
|
||||
// Cloud service
|
||||
GetCloudLimits() (*mm_model.ProductLimits, error)
|
||||
|
||||
// Config service
|
||||
GetConfig() *mm_model.Config
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user