Go modules (#22)
* Move to go modules * Move go.mod in root directory * Update Readme * Remove golang.org/x/tools from go.mod * Remove go list from targets * Set go version to 1.12 * Update Makefile Co-Authored-By: hanzei <16541325+hanzei@users.noreply.github.com> * Update dependencies * Fix build
This commit is contained in:
parent
05dd2de750
commit
fe3553d999
327 changed files with 208 additions and 58246 deletions
|
@ -1,25 +1,22 @@
|
|||
version: 2.1
|
||||
jobs:
|
||||
lint:
|
||||
executors:
|
||||
default:
|
||||
docker:
|
||||
- image: circleci/golang:1.12-node
|
||||
|
||||
working_directory: /go/src/github.com/mattermost/mattermost-plugin-sample
|
||||
jobs:
|
||||
lint:
|
||||
executor:
|
||||
name: default
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
- run: curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
- run: make check-style
|
||||
|
||||
test:
|
||||
docker:
|
||||
- image: circleci/golang:1.12-node
|
||||
|
||||
working_directory: /go/src/github.com/mattermost/mattermost-plugin-sample
|
||||
executor:
|
||||
name: default
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
- run: curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
- run: make test
|
||||
|
||||
workflows:
|
||||
|
|
29
Makefile
29
Makefile
|
@ -1,8 +1,8 @@
|
|||
GO ?= $(shell command -v go 2> /dev/null)
|
||||
DEP ?= $(shell command -v dep 2> /dev/null)
|
||||
NPM ?= $(shell command -v npm 2> /dev/null)
|
||||
CURL ?= $(shell command -v curl 2> /dev/null)
|
||||
MANIFEST_FILE ?= plugin.json
|
||||
export GO111MODULE=on
|
||||
|
||||
# You can include assets this directory into the bundle. This can be e.g. used to include profile pictures.
|
||||
ASSETS_DIR ?= assets
|
||||
|
@ -22,7 +22,7 @@ apply:
|
|||
|
||||
## Runs govet and gofmt against all packages.
|
||||
.PHONY: check-style
|
||||
check-style: server/.depensure webapp/.npminstall gofmt govet
|
||||
check-style: webapp/.npminstall gofmt govet
|
||||
@echo Checking for style guide compliance
|
||||
|
||||
ifneq ($(HAS_WEBAPP),)
|
||||
|
@ -54,22 +54,16 @@ endif
|
|||
govet:
|
||||
ifneq ($(HAS_SERVER),)
|
||||
@echo Running govet
|
||||
$(GO) get golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
|
||||
$(GO) vet $$(go list ./server/...)
|
||||
$(GO) vet -vettool=$(GOPATH)/bin/shadow $$(go list ./server/...)
|
||||
@# Workaroung because you can't install binaries without adding them to go.mod
|
||||
env GO111MODULE=off $(GO) get golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
|
||||
$(GO) vet ./server/...
|
||||
$(GO) vet -vettool=$(GOPATH)/bin/shadow ./server/...
|
||||
@echo Govet success
|
||||
endif
|
||||
|
||||
## Ensures the server dependencies are installed.
|
||||
server/.depensure:
|
||||
ifneq ($(HAS_SERVER),)
|
||||
cd server && $(DEP) ensure
|
||||
touch $@
|
||||
endif
|
||||
|
||||
## Builds the server, if it exists, including support for multiple architectures.
|
||||
.PHONY: server
|
||||
server: server/.depensure
|
||||
server:
|
||||
ifneq ($(HAS_SERVER),)
|
||||
mkdir -p server/dist;
|
||||
cd server && env GOOS=linux GOARCH=amd64 $(GO) build -o dist/plugin-linux-amd64;
|
||||
|
@ -140,9 +134,9 @@ endif
|
|||
|
||||
## Runs any lints and unit tests defined for the server and webapp, if they exist.
|
||||
.PHONY: test
|
||||
test: server/.depensure webapp/.npminstall
|
||||
test: webapp/.npminstall
|
||||
ifneq ($(HAS_SERVER),)
|
||||
cd server && $(GO) test -race -v ./...
|
||||
$(GO) test -race -v ./server/...
|
||||
endif
|
||||
ifneq ($(HAS_WEBAPP),)
|
||||
cd webapp && $(NPM) run fix;
|
||||
|
@ -152,8 +146,8 @@ endif
|
|||
.PHONY: coverage
|
||||
coverage: server/.depensure webapp/.npminstall
|
||||
ifneq ($(HAS_SERVER),)
|
||||
cd server && $(GO) test -race -coverprofile=coverage.txt ./...
|
||||
@cd server && $(GO) tool cover -html=coverage.txt
|
||||
$(GO) test -race -coverprofile=server/coverage.txt ./server/...
|
||||
$(GO) tool cover -html=server/coverage.txt
|
||||
endif
|
||||
|
||||
## Clean removes all build artifacts.
|
||||
|
@ -162,7 +156,6 @@ clean:
|
|||
rm -fr dist/
|
||||
ifneq ($(HAS_SERVER),)
|
||||
rm -fr server/dist
|
||||
rm -fr server/.depensure
|
||||
endif
|
||||
ifneq ($(HAS_WEBAPP),)
|
||||
rm -fr webapp/.npminstall
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
This plugin serves as a starting point for writing a Mattermost plugin. Feel free to base your own plugin off this repository.
|
||||
|
||||
## Getting Started
|
||||
Shallow clone the repository to a directory matching your plugin name:
|
||||
Shallow clone the repository to a directory outside of `$GOPATH` matching your plugin name:
|
||||
```
|
||||
git clone --depth 1 https://github.com/mattermost/mattermost-plugin-sample com.example.my-plugin
|
||||
```
|
||||
|
|
136
build/manifest/Gopkg.lock
generated
136
build/manifest/Gopkg.lock
generated
|
@ -1,136 +0,0 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:705c40022f5c03bf96ffeb6477858d88565064485a513abcd0f11a0911546cb6"
|
||||
name = "github.com/blang/semver"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "2ee87856327ba09384cabd113bc6b5d174e9ec0f"
|
||||
version = "v3.5.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:bc36a17a513f15717b5fa3dcfd666f5ddb6fd3db06f5f2834ac2f5979d4f5070"
|
||||
name = "github.com/gorilla/websocket"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5ed622c449da6d44c3c8329331ff47a9e5844f71"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1cebd7208d10c6f20d5fd71c9c7062fea74524842db93fec2993fb5ea4975c73"
|
||||
name = "github.com/mattermost/mattermost-server"
|
||||
packages = [
|
||||
"mlog",
|
||||
"model",
|
||||
"utils/jsonutils",
|
||||
"utils/markdown",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "0c1207215852a8726c3f09dea157d597fec368df"
|
||||
version = "v5.6.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:07140002dbf37da92090f731b46fa47be4820b82fe5c14a035203b0e813d0ec2"
|
||||
name = "github.com/nicksnyder/go-i18n"
|
||||
packages = [
|
||||
"i18n",
|
||||
"i18n/bundle",
|
||||
"i18n/language",
|
||||
"i18n/translation",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "0dc1626d56435e9d605a29875701721c54bc9bbd"
|
||||
version = "v1.10.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:361de06aa7ae272616cbe71c3994a654cc6316324e30998e650f7765b20c5b33"
|
||||
name = "github.com/pborman/uuid"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "e790cca94e6cc75c7064b1332e63811d4aae1a53"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e"
|
||||
name = "github.com/pelletier/go-toml"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3c1a69cdae3501bf75e76d0d86dc6f2b0a7421bc205c0cb7b96b19eed464a34d"
|
||||
name = "go.uber.org/atomic"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "1ea20fb1cbb1cc08cbd0d913a96dead89aa18289"
|
||||
version = "v1.3.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:60bf2a5e347af463c42ed31a493d817f8a72f102543060ed992754e689805d1a"
|
||||
name = "go.uber.org/multierr"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d9a420eae5f76973feeb733fbf58f6a89173255b63b27a7ae4b2124a73dc6c5b"
|
||||
name = "go.uber.org/zap"
|
||||
packages = [
|
||||
".",
|
||||
"buffer",
|
||||
"internal/bufferpool",
|
||||
"internal/color",
|
||||
"internal/exit",
|
||||
"zapcore",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "4d45f9617f7d90f7a663ff21c7a4321dbe78098b"
|
||||
version = "v1.9.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:1ecf2a49df33be51e757d0033d5d51d5f784f35f68e5a38f797b2d3f03357d71"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"bcrypt",
|
||||
"blowfish",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "c126467f60eb25f8f27e5a981f32a87e3965053f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c805e517269b0ba4c21ded5836019ed7d16953d4026cb7d00041d039c7906be9"
|
||||
name = "gopkg.in/natefinch/lumberjack.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "a96e63847dc3c67d17befa69c303767e2f84e54f"
|
||||
version = "v2.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/mattermost/mattermost-server/model",
|
||||
"github.com/pkg/errors",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
|
@ -1,11 +0,0 @@
|
|||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/mattermost/mattermost-server"
|
||||
version = "~5.6.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/pkg/errors"
|
||||
version = "0.8.0"
|
21
build/manifest/vendor/github.com/blang/semver/.travis.yml
generated
vendored
21
build/manifest/vendor/github.com/blang/semver/.travis.yml
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
language: go
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.4.3
|
||||
- go: 1.5.4
|
||||
- go: 1.6.3
|
||||
- go: 1.7
|
||||
- go: tip
|
||||
allow_failures:
|
||||
- go: tip
|
||||
install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
script:
|
||||
- echo "Test and track coverage" ; $HOME/gopath/bin/goveralls -package "." -service=travis-ci
|
||||
-repotoken $COVERALLS_TOKEN
|
||||
- echo "Build examples" ; cd examples && go build
|
||||
- echo "Check if gofmt'd" ; diff -u <(echo -n) <(gofmt -d -s .)
|
||||
env:
|
||||
global:
|
||||
secure: HroGEAUQpVq9zX1b1VIkraLiywhGbzvNnTZq2TMxgK7JHP8xqNplAeF1izrR2i4QLL9nsY+9WtYss4QuPvEtZcVHUobw6XnL6radF7jS1LgfYZ9Y7oF+zogZ2I5QUMRLGA7rcxQ05s7mKq3XZQfeqaNts4bms/eZRefWuaFZbkw=
|
22
build/manifest/vendor/github.com/blang/semver/LICENSE
generated
vendored
22
build/manifest/vendor/github.com/blang/semver/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
194
build/manifest/vendor/github.com/blang/semver/README.md
generated
vendored
194
build/manifest/vendor/github.com/blang/semver/README.md
generated
vendored
|
@ -1,194 +0,0 @@
|
|||
semver for golang [](https://travis-ci.org/blang/semver) [](https://godoc.org/github.com/blang/semver) [](https://coveralls.io/r/blang/semver?branch=master)
|
||||
======
|
||||
|
||||
semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
|
||||
|
||||
Usage
|
||||
-----
|
||||
```bash
|
||||
$ go get github.com/blang/semver
|
||||
```
|
||||
Note: Always vendor your dependencies or fix on a specific version tag.
|
||||
|
||||
```go
|
||||
import github.com/blang/semver
|
||||
v1, err := semver.Make("1.0.0-beta")
|
||||
v2, err := semver.Make("2.0.0-beta")
|
||||
v1.Compare(v2)
|
||||
```
|
||||
|
||||
Also check the [GoDocs](http://godoc.org/github.com/blang/semver).
|
||||
|
||||
Why should I use this lib?
|
||||
-----
|
||||
|
||||
- Fully spec compatible
|
||||
- No reflection
|
||||
- No regex
|
||||
- Fully tested (Coverage >99%)
|
||||
- Readable parsing/validation errors
|
||||
- Fast (See [Benchmarks](#benchmarks))
|
||||
- Only Stdlib
|
||||
- Uses values instead of pointers
|
||||
- Many features, see below
|
||||
|
||||
|
||||
Features
|
||||
-----
|
||||
|
||||
- Parsing and validation at all levels
|
||||
- Comparator-like comparisons
|
||||
- Compare Helper Methods
|
||||
- InPlace manipulation
|
||||
- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1`
|
||||
- Wildcards `>=1.x`, `<=2.5.x`
|
||||
- Sortable (implements sort.Interface)
|
||||
- database/sql compatible (sql.Scanner/Valuer)
|
||||
- encoding/json compatible (json.Marshaler/Unmarshaler)
|
||||
|
||||
Ranges
|
||||
------
|
||||
|
||||
A `Range` is a set of conditions which specify which versions satisfy the range.
|
||||
|
||||
A condition is composed of an operator and a version. The supported operators are:
|
||||
|
||||
- `<1.0.0` Less than `1.0.0`
|
||||
- `<=1.0.0` Less than or equal to `1.0.0`
|
||||
- `>1.0.0` Greater than `1.0.0`
|
||||
- `>=1.0.0` Greater than or equal to `1.0.0`
|
||||
- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0`
|
||||
- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`.
|
||||
|
||||
Note that spaces between the operator and the version will be gracefully tolerated.
|
||||
|
||||
A `Range` can link multiple `Ranges` separated by space:
|
||||
|
||||
Ranges can be linked by logical AND:
|
||||
|
||||
- `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0`
|
||||
- `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2`
|
||||
|
||||
Ranges can also be linked by logical OR:
|
||||
|
||||
- `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x`
|
||||
|
||||
AND has a higher precedence than OR. It's not possible to use brackets.
|
||||
|
||||
Ranges can be combined by both AND and OR
|
||||
|
||||
- `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
|
||||
|
||||
Range usage:
|
||||
|
||||
```
|
||||
v, err := semver.Parse("1.2.3")
|
||||
range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0")
|
||||
if range(v) {
|
||||
//valid
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Example
|
||||
-----
|
||||
|
||||
Have a look at full examples in [examples/main.go](examples/main.go)
|
||||
|
||||
```go
|
||||
import github.com/blang/semver
|
||||
|
||||
v, err := semver.Make("0.0.1-alpha.preview+123.github")
|
||||
fmt.Printf("Major: %d\n", v.Major)
|
||||
fmt.Printf("Minor: %d\n", v.Minor)
|
||||
fmt.Printf("Patch: %d\n", v.Patch)
|
||||
fmt.Printf("Pre: %s\n", v.Pre)
|
||||
fmt.Printf("Build: %s\n", v.Build)
|
||||
|
||||
// Prerelease versions array
|
||||
if len(v.Pre) > 0 {
|
||||
fmt.Println("Prerelease versions:")
|
||||
for i, pre := range v.Pre {
|
||||
fmt.Printf("%d: %q\n", i, pre)
|
||||
}
|
||||
}
|
||||
|
||||
// Build meta data array
|
||||
if len(v.Build) > 0 {
|
||||
fmt.Println("Build meta data:")
|
||||
for i, build := range v.Build {
|
||||
fmt.Printf("%d: %q\n", i, build)
|
||||
}
|
||||
}
|
||||
|
||||
v001, err := semver.Make("0.0.1")
|
||||
// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE
|
||||
v001.GT(v) == true
|
||||
v.LT(v001) == true
|
||||
v.GTE(v) == true
|
||||
v.LTE(v) == true
|
||||
|
||||
// Or use v.Compare(v2) for comparisons (-1, 0, 1):
|
||||
v001.Compare(v) == 1
|
||||
v.Compare(v001) == -1
|
||||
v.Compare(v) == 0
|
||||
|
||||
// Manipulate Version in place:
|
||||
v.Pre[0], err = semver.NewPRVersion("beta")
|
||||
if err != nil {
|
||||
fmt.Printf("Error parsing pre release version: %q", err)
|
||||
}
|
||||
|
||||
fmt.Println("\nValidate versions:")
|
||||
v.Build[0] = "?"
|
||||
|
||||
err = v.Validate()
|
||||
if err != nil {
|
||||
fmt.Printf("Validation failed: %s\n", err)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Benchmarks
|
||||
-----
|
||||
|
||||
BenchmarkParseSimple-4 5000000 390 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkParseComplex-4 1000000 1813 ns/op 256 B/op 7 allocs/op
|
||||
BenchmarkParseAverage-4 1000000 1171 ns/op 163 B/op 4 allocs/op
|
||||
BenchmarkStringSimple-4 20000000 119 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkStringLarger-4 10000000 206 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStringComplex-4 5000000 324 ns/op 80 B/op 3 allocs/op
|
||||
BenchmarkStringAverage-4 5000000 273 ns/op 53 B/op 2 allocs/op
|
||||
BenchmarkValidateSimple-4 200000000 9.33 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkValidateComplex-4 3000000 469 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkValidateAverage-4 5000000 256 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkCompareSimple-4 100000000 11.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkCompareComplex-4 50000000 30.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkCompareAverage-4 30000000 41.5 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkSort-4 3000000 419 ns/op 256 B/op 2 allocs/op
|
||||
BenchmarkRangeParseSimple-4 2000000 850 ns/op 192 B/op 5 allocs/op
|
||||
BenchmarkRangeParseAverage-4 1000000 1677 ns/op 400 B/op 10 allocs/op
|
||||
BenchmarkRangeParseComplex-4 300000 5214 ns/op 1440 B/op 30 allocs/op
|
||||
BenchmarkRangeMatchSimple-4 50000000 25.6 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkRangeMatchAverage-4 30000000 56.4 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkRangeMatchComplex-4 10000000 153 ns/op 0 B/op 0 allocs/op
|
||||
|
||||
See benchmark cases at [semver_test.go](semver_test.go)
|
||||
|
||||
|
||||
Motivation
|
||||
-----
|
||||
|
||||
I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like.
|
||||
|
||||
|
||||
Contribution
|
||||
-----
|
||||
|
||||
Feel free to make a pull request. For bigger changes create a issue first to discuss about it.
|
||||
|
||||
|
||||
License
|
||||
-----
|
||||
|
||||
See [LICENSE](LICENSE) file.
|
23
build/manifest/vendor/github.com/blang/semver/json.go
generated
vendored
23
build/manifest/vendor/github.com/blang/semver/json.go
generated
vendored
|
@ -1,23 +0,0 @@
|
|||
package semver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// MarshalJSON implements the encoding/json.Marshaler interface.
|
||||
func (v Version) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
|
||||
func (v *Version) UnmarshalJSON(data []byte) (err error) {
|
||||
var versionString string
|
||||
|
||||
if err = json.Unmarshal(data, &versionString); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
*v, err = Parse(versionString)
|
||||
|
||||
return
|
||||
}
|
17
build/manifest/vendor/github.com/blang/semver/package.json
generated
vendored
17
build/manifest/vendor/github.com/blang/semver/package.json
generated
vendored
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"author": "blang",
|
||||
"bugs": {
|
||||
"URL": "https://github.com/blang/semver/issues",
|
||||
"url": "https://github.com/blang/semver/issues"
|
||||
},
|
||||
"gx": {
|
||||
"dvcsimport": "github.com/blang/semver"
|
||||
},
|
||||
"gxVersion": "0.10.0",
|
||||
"language": "go",
|
||||
"license": "MIT",
|
||||
"name": "semver",
|
||||
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
|
||||
"version": "3.5.1"
|
||||
}
|
||||
|
416
build/manifest/vendor/github.com/blang/semver/range.go
generated
vendored
416
build/manifest/vendor/github.com/blang/semver/range.go
generated
vendored
|
@ -1,416 +0,0 @@
|
|||
package semver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type wildcardType int
|
||||
|
||||
const (
|
||||
noneWildcard wildcardType = iota
|
||||
majorWildcard wildcardType = 1
|
||||
minorWildcard wildcardType = 2
|
||||
patchWildcard wildcardType = 3
|
||||
)
|
||||
|
||||
func wildcardTypefromInt(i int) wildcardType {
|
||||
switch i {
|
||||
case 1:
|
||||
return majorWildcard
|
||||
case 2:
|
||||
return minorWildcard
|
||||
case 3:
|
||||
return patchWildcard
|
||||
default:
|
||||
return noneWildcard
|
||||
}
|
||||
}
|
||||
|
||||
type comparator func(Version, Version) bool
|
||||
|
||||
var (
|
||||
compEQ comparator = func(v1 Version, v2 Version) bool {
|
||||
return v1.Compare(v2) == 0
|
||||
}
|
||||
compNE = func(v1 Version, v2 Version) bool {
|
||||
return v1.Compare(v2) != 0
|
||||
}
|
||||
compGT = func(v1 Version, v2 Version) bool {
|
||||
return v1.Compare(v2) == 1
|
||||
}
|
||||
compGE = func(v1 Version, v2 Version) bool {
|
||||
return v1.Compare(v2) >= 0
|
||||
}
|
||||
compLT = func(v1 Version, v2 Version) bool {
|
||||
return v1.Compare(v2) == -1
|
||||
}
|
||||
compLE = func(v1 Version, v2 Version) bool {
|
||||
return v1.Compare(v2) <= 0
|
||||
}
|
||||
)
|
||||
|
||||
type versionRange struct {
|
||||
v Version
|
||||
c comparator
|
||||
}
|
||||
|
||||
// rangeFunc creates a Range from the given versionRange.
|
||||
func (vr *versionRange) rangeFunc() Range {
|
||||
return Range(func(v Version) bool {
|
||||
return vr.c(v, vr.v)
|
||||
})
|
||||
}
|
||||
|
||||
// Range represents a range of versions.
|
||||
// A Range can be used to check if a Version satisfies it:
|
||||
//
|
||||
// range, err := semver.ParseRange(">1.0.0 <2.0.0")
|
||||
// range(semver.MustParse("1.1.1") // returns true
|
||||
type Range func(Version) bool
|
||||
|
||||
// OR combines the existing Range with another Range using logical OR.
|
||||
func (rf Range) OR(f Range) Range {
|
||||
return Range(func(v Version) bool {
|
||||
return rf(v) || f(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AND combines the existing Range with another Range using logical AND.
|
||||
func (rf Range) AND(f Range) Range {
|
||||
return Range(func(v Version) bool {
|
||||
return rf(v) && f(v)
|
||||
})
|
||||
}
|
||||
|
||||
// ParseRange parses a range and returns a Range.
|
||||
// If the range could not be parsed an error is returned.
|
||||
//
|
||||
// Valid ranges are:
|
||||
// - "<1.0.0"
|
||||
// - "<=1.0.0"
|
||||
// - ">1.0.0"
|
||||
// - ">=1.0.0"
|
||||
// - "1.0.0", "=1.0.0", "==1.0.0"
|
||||
// - "!1.0.0", "!=1.0.0"
|
||||
//
|
||||
// A Range can consist of multiple ranges separated by space:
|
||||
// Ranges can be linked by logical AND:
|
||||
// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0"
|
||||
// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2
|
||||
//
|
||||
// Ranges can also be linked by logical OR:
|
||||
// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x"
|
||||
//
|
||||
// AND has a higher precedence than OR. It's not possible to use brackets.
|
||||
//
|
||||
// Ranges can be combined by both AND and OR
|
||||
//
|
||||
// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
|
||||
func ParseRange(s string) (Range, error) {
|
||||
parts := splitAndTrim(s)
|
||||
orParts, err := splitORParts(parts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
expandedParts, err := expandWildcardVersion(orParts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var orFn Range
|
||||
for _, p := range expandedParts {
|
||||
var andFn Range
|
||||
for _, ap := range p {
|
||||
opStr, vStr, err := splitComparatorVersion(ap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vr, err := buildVersionRange(opStr, vStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err)
|
||||
}
|
||||
rf := vr.rangeFunc()
|
||||
|
||||
// Set function
|
||||
if andFn == nil {
|
||||
andFn = rf
|
||||
} else { // Combine with existing function
|
||||
andFn = andFn.AND(rf)
|
||||
}
|
||||
}
|
||||
if orFn == nil {
|
||||
orFn = andFn
|
||||
} else {
|
||||
orFn = orFn.OR(andFn)
|
||||
}
|
||||
|
||||
}
|
||||
return orFn, nil
|
||||
}
|
||||
|
||||
// splitORParts splits the already cleaned parts by '||'.
|
||||
// Checks for invalid positions of the operator and returns an
|
||||
// error if found.
|
||||
func splitORParts(parts []string) ([][]string, error) {
|
||||
var ORparts [][]string
|
||||
last := 0
|
||||
for i, p := range parts {
|
||||
if p == "||" {
|
||||
if i == 0 {
|
||||
return nil, fmt.Errorf("First element in range is '||'")
|
||||
}
|
||||
ORparts = append(ORparts, parts[last:i])
|
||||
last = i + 1
|
||||
}
|
||||
}
|
||||
if last == len(parts) {
|
||||
return nil, fmt.Errorf("Last element in range is '||'")
|
||||
}
|
||||
ORparts = append(ORparts, parts[last:])
|
||||
return ORparts, nil
|
||||
}
|
||||
|
||||
// buildVersionRange takes a slice of 2: operator and version
|
||||
// and builds a versionRange, otherwise an error.
|
||||
func buildVersionRange(opStr, vStr string) (*versionRange, error) {
|
||||
c := parseComparator(opStr)
|
||||
if c == nil {
|
||||
return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, ""))
|
||||
}
|
||||
v, err := Parse(vStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err)
|
||||
}
|
||||
|
||||
return &versionRange{
|
||||
v: v,
|
||||
c: c,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
// inArray checks if a byte is contained in an array of bytes
|
||||
func inArray(s byte, list []byte) bool {
|
||||
for _, el := range list {
|
||||
if el == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// splitAndTrim splits a range string by spaces and cleans whitespaces
|
||||
func splitAndTrim(s string) (result []string) {
|
||||
last := 0
|
||||
var lastChar byte
|
||||
excludeFromSplit := []byte{'>', '<', '='}
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) {
|
||||
if last < i-1 {
|
||||
result = append(result, s[last:i])
|
||||
}
|
||||
last = i + 1
|
||||
} else if s[i] != ' ' {
|
||||
lastChar = s[i]
|
||||
}
|
||||
}
|
||||
if last < len(s)-1 {
|
||||
result = append(result, s[last:])
|
||||
}
|
||||
|
||||
for i, v := range result {
|
||||
result[i] = strings.Replace(v, " ", "", -1)
|
||||
}
|
||||
|
||||
// parts := strings.Split(s, " ")
|
||||
// for _, x := range parts {
|
||||
// if s := strings.TrimSpace(x); len(s) != 0 {
|
||||
// result = append(result, s)
|
||||
// }
|
||||
// }
|
||||
return
|
||||
}
|
||||
|
||||
// splitComparatorVersion splits the comparator from the version.
|
||||
// Input must be free of leading or trailing spaces.
|
||||
func splitComparatorVersion(s string) (string, string, error) {
|
||||
i := strings.IndexFunc(s, unicode.IsDigit)
|
||||
if i == -1 {
|
||||
return "", "", fmt.Errorf("Could not get version from string: %q", s)
|
||||
}
|
||||
return strings.TrimSpace(s[0:i]), s[i:], nil
|
||||
}
|
||||
|
||||
// getWildcardType will return the type of wildcard that the
|
||||
// passed version contains
|
||||
func getWildcardType(vStr string) wildcardType {
|
||||
parts := strings.Split(vStr, ".")
|
||||
nparts := len(parts)
|
||||
wildcard := parts[nparts-1]
|
||||
|
||||
possibleWildcardType := wildcardTypefromInt(nparts)
|
||||
if wildcard == "x" {
|
||||
return possibleWildcardType
|
||||
}
|
||||
|
||||
return noneWildcard
|
||||
}
|
||||
|
||||
// createVersionFromWildcard will convert a wildcard version
|
||||
// into a regular version, replacing 'x's with '0's, handling
|
||||
// special cases like '1.x.x' and '1.x'
|
||||
func createVersionFromWildcard(vStr string) string {
|
||||
// handle 1.x.x
|
||||
vStr2 := strings.Replace(vStr, ".x.x", ".x", 1)
|
||||
vStr2 = strings.Replace(vStr2, ".x", ".0", 1)
|
||||
parts := strings.Split(vStr2, ".")
|
||||
|
||||
// handle 1.x
|
||||
if len(parts) == 2 {
|
||||
return vStr2 + ".0"
|
||||
}
|
||||
|
||||
return vStr2
|
||||
}
|
||||
|
||||
// incrementMajorVersion will increment the major version
|
||||
// of the passed version
|
||||
func incrementMajorVersion(vStr string) (string, error) {
|
||||
parts := strings.Split(vStr, ".")
|
||||
i, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
parts[0] = strconv.Itoa(i + 1)
|
||||
|
||||
return strings.Join(parts, "."), nil
|
||||
}
|
||||
|
||||
// incrementMajorVersion will increment the minor version
|
||||
// of the passed version
|
||||
func incrementMinorVersion(vStr string) (string, error) {
|
||||
parts := strings.Split(vStr, ".")
|
||||
i, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
parts[1] = strconv.Itoa(i + 1)
|
||||
|
||||
return strings.Join(parts, "."), nil
|
||||
}
|
||||
|
||||
// expandWildcardVersion will expand wildcards inside versions
|
||||
// following these rules:
|
||||
//
|
||||
// * when dealing with patch wildcards:
|
||||
// >= 1.2.x will become >= 1.2.0
|
||||
// <= 1.2.x will become < 1.3.0
|
||||
// > 1.2.x will become >= 1.3.0
|
||||
// < 1.2.x will become < 1.2.0
|
||||
// != 1.2.x will become < 1.2.0 >= 1.3.0
|
||||
//
|
||||
// * when dealing with minor wildcards:
|
||||
// >= 1.x will become >= 1.0.0
|
||||
// <= 1.x will become < 2.0.0
|
||||
// > 1.x will become >= 2.0.0
|
||||
// < 1.0 will become < 1.0.0
|
||||
// != 1.x will become < 1.0.0 >= 2.0.0
|
||||
//
|
||||
// * when dealing with wildcards without
|
||||
// version operator:
|
||||
// 1.2.x will become >= 1.2.0 < 1.3.0
|
||||
// 1.x will become >= 1.0.0 < 2.0.0
|
||||
func expandWildcardVersion(parts [][]string) ([][]string, error) {
|
||||
var expandedParts [][]string
|
||||
for _, p := range parts {
|
||||
var newParts []string
|
||||
for _, ap := range p {
|
||||
if strings.Index(ap, "x") != -1 {
|
||||
opStr, vStr, err := splitComparatorVersion(ap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
versionWildcardType := getWildcardType(vStr)
|
||||
flatVersion := createVersionFromWildcard(vStr)
|
||||
|
||||
var resultOperator string
|
||||
var shouldIncrementVersion bool
|
||||
switch opStr {
|
||||
case ">":
|
||||
resultOperator = ">="
|
||||
shouldIncrementVersion = true
|
||||
case ">=":
|
||||
resultOperator = ">="
|
||||
case "<":
|
||||
resultOperator = "<"
|
||||
case "<=":
|
||||
resultOperator = "<"
|
||||
shouldIncrementVersion = true
|
||||
case "", "=", "==":
|
||||
newParts = append(newParts, ">="+flatVersion)
|
||||
resultOperator = "<"
|
||||
shouldIncrementVersion = true
|
||||
case "!=", "!":
|
||||
newParts = append(newParts, "<"+flatVersion)
|
||||
resultOperator = ">="
|
||||
shouldIncrementVersion = true
|
||||
}
|
||||
|
||||
var resultVersion string
|
||||
if shouldIncrementVersion {
|
||||
switch versionWildcardType {
|
||||
case patchWildcard:
|
||||
resultVersion, _ = incrementMinorVersion(flatVersion)
|
||||
case minorWildcard:
|
||||
resultVersion, _ = incrementMajorVersion(flatVersion)
|
||||
}
|
||||
} else {
|
||||
resultVersion = flatVersion
|
||||
}
|
||||
|
||||
ap = resultOperator + resultVersion
|
||||
}
|
||||
newParts = append(newParts, ap)
|
||||
}
|
||||
expandedParts = append(expandedParts, newParts)
|
||||
}
|
||||
|
||||
return expandedParts, nil
|
||||
}
|
||||
|
||||
func parseComparator(s string) comparator {
|
||||
switch s {
|
||||
case "==":
|
||||
fallthrough
|
||||
case "":
|
||||
fallthrough
|
||||
case "=":
|
||||
return compEQ
|
||||
case ">":
|
||||
return compGT
|
||||
case ">=":
|
||||
return compGE
|
||||
case "<":
|
||||
return compLT
|
||||
case "<=":
|
||||
return compLE
|
||||
case "!":
|
||||
fallthrough
|
||||
case "!=":
|
||||
return compNE
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustParseRange is like ParseRange but panics if the range cannot be parsed.
|
||||
func MustParseRange(s string) Range {
|
||||
r, err := ParseRange(s)
|
||||
if err != nil {
|
||||
panic(`semver: ParseRange(` + s + `): ` + err.Error())
|
||||
}
|
||||
return r
|
||||
}
|
418
build/manifest/vendor/github.com/blang/semver/semver.go
generated
vendored
418
build/manifest/vendor/github.com/blang/semver/semver.go
generated
vendored
|
@ -1,418 +0,0 @@
|
|||
package semver
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
numbers string = "0123456789"
|
||||
alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
|
||||
alphanum = alphas + numbers
|
||||
)
|
||||
|
||||
// SpecVersion is the latest fully supported spec version of semver
|
||||
var SpecVersion = Version{
|
||||
Major: 2,
|
||||
Minor: 0,
|
||||
Patch: 0,
|
||||
}
|
||||
|
||||
// Version represents a semver compatible version
|
||||
type Version struct {
|
||||
Major uint64
|
||||
Minor uint64
|
||||
Patch uint64
|
||||
Pre []PRVersion
|
||||
Build []string //No Precendence
|
||||
}
|
||||
|
||||
// Version to string
|
||||
func (v Version) String() string {
|
||||
b := make([]byte, 0, 5)
|
||||
b = strconv.AppendUint(b, v.Major, 10)
|
||||
b = append(b, '.')
|
||||
b = strconv.AppendUint(b, v.Minor, 10)
|
||||
b = append(b, '.')
|
||||
b = strconv.AppendUint(b, v.Patch, 10)
|
||||
|
||||
if len(v.Pre) > 0 {
|
||||
b = append(b, '-')
|
||||
b = append(b, v.Pre[0].String()...)
|
||||
|
||||
for _, pre := range v.Pre[1:] {
|
||||
b = append(b, '.')
|
||||
b = append(b, pre.String()...)
|
||||
}
|
||||
}
|
||||
|
||||
if len(v.Build) > 0 {
|
||||
b = append(b, '+')
|
||||
b = append(b, v.Build[0]...)
|
||||
|
||||
for _, build := range v.Build[1:] {
|
||||
b = append(b, '.')
|
||||
b = append(b, build...)
|
||||
}
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// Equals checks if v is equal to o.
|
||||
func (v Version) Equals(o Version) bool {
|
||||
return (v.Compare(o) == 0)
|
||||
}
|
||||
|
||||
// EQ checks if v is equal to o.
|
||||
func (v Version) EQ(o Version) bool {
|
||||
return (v.Compare(o) == 0)
|
||||
}
|
||||
|
||||
// NE checks if v is not equal to o.
|
||||
func (v Version) NE(o Version) bool {
|
||||
return (v.Compare(o) != 0)
|
||||
}
|
||||
|
||||
// GT checks if v is greater than o.
|
||||
func (v Version) GT(o Version) bool {
|
||||
return (v.Compare(o) == 1)
|
||||
}
|
||||
|
||||
// GTE checks if v is greater than or equal to o.
|
||||
func (v Version) GTE(o Version) bool {
|
||||
return (v.Compare(o) >= 0)
|
||||
}
|
||||
|
||||
// GE checks if v is greater than or equal to o.
|
||||
func (v Version) GE(o Version) bool {
|
||||
return (v.Compare(o) >= 0)
|
||||
}
|
||||
|
||||
// LT checks if v is less than o.
|
||||
func (v Version) LT(o Version) bool {
|
||||
return (v.Compare(o) == -1)
|
||||
}
|
||||
|
||||
// LTE checks if v is less than or equal to o.
|
||||
func (v Version) LTE(o Version) bool {
|
||||
return (v.Compare(o) <= 0)
|
||||
}
|
||||
|
||||
// LE checks if v is less than or equal to o.
|
||||
func (v Version) LE(o Version) bool {
|
||||
return (v.Compare(o) <= 0)
|
||||
}
|
||||
|
||||
// Compare compares Versions v to o:
|
||||
// -1 == v is less than o
|
||||
// 0 == v is equal to o
|
||||
// 1 == v is greater than o
|
||||
func (v Version) Compare(o Version) int {
|
||||
if v.Major != o.Major {
|
||||
if v.Major > o.Major {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
if v.Minor != o.Minor {
|
||||
if v.Minor > o.Minor {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
if v.Patch != o.Patch {
|
||||
if v.Patch > o.Patch {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// Quick comparison if a version has no prerelease versions
|
||||
if len(v.Pre) == 0 && len(o.Pre) == 0 {
|
||||
return 0
|
||||
} else if len(v.Pre) == 0 && len(o.Pre) > 0 {
|
||||
return 1
|
||||
} else if len(v.Pre) > 0 && len(o.Pre) == 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
i := 0
|
||||
for ; i < len(v.Pre) && i < len(o.Pre); i++ {
|
||||
if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
|
||||
continue
|
||||
} else if comp == 1 {
|
||||
return 1
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// If all pr versions are the equal but one has further prversion, this one greater
|
||||
if i == len(v.Pre) && i == len(o.Pre) {
|
||||
return 0
|
||||
} else if i == len(v.Pre) && i < len(o.Pre) {
|
||||
return -1
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Validate validates v and returns error in case
|
||||
func (v Version) Validate() error {
|
||||
// Major, Minor, Patch already validated using uint64
|
||||
|
||||
for _, pre := range v.Pre {
|
||||
if !pre.IsNum { //Numeric prerelease versions already uint64
|
||||
if len(pre.VersionStr) == 0 {
|
||||
return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
|
||||
}
|
||||
if !containsOnly(pre.VersionStr, alphanum) {
|
||||
return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, build := range v.Build {
|
||||
if len(build) == 0 {
|
||||
return fmt.Errorf("Build meta data can not be empty %q", build)
|
||||
}
|
||||
if !containsOnly(build, alphanum) {
|
||||
return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
|
||||
func New(s string) (vp *Version, err error) {
|
||||
v, err := Parse(s)
|
||||
vp = &v
|
||||
return
|
||||
}
|
||||
|
||||
// Make is an alias for Parse, parses version string and returns a validated Version or error
|
||||
func Make(s string) (Version, error) {
|
||||
return Parse(s)
|
||||
}
|
||||
|
||||
// ParseTolerant allows for certain version specifications that do not strictly adhere to semver
|
||||
// specs to be parsed by this library. It does so by normalizing versions before passing them to
|
||||
// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions
|
||||
// with only major and minor components specified
|
||||
func ParseTolerant(s string) (Version, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.TrimPrefix(s, "v")
|
||||
|
||||
// Split into major.minor.(patch+pr+meta)
|
||||
parts := strings.SplitN(s, ".", 3)
|
||||
if len(parts) < 3 {
|
||||
if strings.ContainsAny(parts[len(parts)-1], "+-") {
|
||||
return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data")
|
||||
}
|
||||
for len(parts) < 3 {
|
||||
parts = append(parts, "0")
|
||||
}
|
||||
s = strings.Join(parts, ".")
|
||||
}
|
||||
|
||||
return Parse(s)
|
||||
}
|
||||
|
||||
// Parse parses version string and returns a validated Version or error
|
||||
func Parse(s string) (Version, error) {
|
||||
if len(s) == 0 {
|
||||
return Version{}, errors.New("Version string empty")
|
||||
}
|
||||
|
||||
// Split into major.minor.(patch+pr+meta)
|
||||
parts := strings.SplitN(s, ".", 3)
|
||||
if len(parts) != 3 {
|
||||
return Version{}, errors.New("No Major.Minor.Patch elements found")
|
||||
}
|
||||
|
||||
// Major
|
||||
if !containsOnly(parts[0], numbers) {
|
||||
return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
|
||||
}
|
||||
if hasLeadingZeroes(parts[0]) {
|
||||
return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
|
||||
}
|
||||
major, err := strconv.ParseUint(parts[0], 10, 64)
|
||||
if err != nil {
|
||||
return Version{}, err
|
||||
}
|
||||
|
||||
// Minor
|
||||
if !containsOnly(parts[1], numbers) {
|
||||
return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
|
||||
}
|
||||
if hasLeadingZeroes(parts[1]) {
|
||||
return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
|
||||
}
|
||||
minor, err := strconv.ParseUint(parts[1], 10, 64)
|
||||
if err != nil {
|
||||
return Version{}, err
|
||||
}
|
||||
|
||||
v := Version{}
|
||||
v.Major = major
|
||||
v.Minor = minor
|
||||
|
||||
var build, prerelease []string
|
||||
patchStr := parts[2]
|
||||
|
||||
if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
|
||||
build = strings.Split(patchStr[buildIndex+1:], ".")
|
||||
patchStr = patchStr[:buildIndex]
|
||||
}
|
||||
|
||||
if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
|
||||
prerelease = strings.Split(patchStr[preIndex+1:], ".")
|
||||
patchStr = patchStr[:preIndex]
|
||||
}
|
||||
|
||||
if !containsOnly(patchStr, numbers) {
|
||||
return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
|
||||
}
|
||||
if hasLeadingZeroes(patchStr) {
|
||||
return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
|
||||
}
|
||||
patch, err := strconv.ParseUint(patchStr, 10, 64)
|
||||
if err != nil {
|
||||
return Version{}, err
|
||||
}
|
||||
|
||||
v.Patch = patch
|
||||
|
||||
// Prerelease
|
||||
for _, prstr := range prerelease {
|
||||
parsedPR, err := NewPRVersion(prstr)
|
||||
if err != nil {
|
||||
return Version{}, err
|
||||
}
|
||||
v.Pre = append(v.Pre, parsedPR)
|
||||
}
|
||||
|
||||
// Build meta data
|
||||
for _, str := range build {
|
||||
if len(str) == 0 {
|
||||
return Version{}, errors.New("Build meta data is empty")
|
||||
}
|
||||
if !containsOnly(str, alphanum) {
|
||||
return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
|
||||
}
|
||||
v.Build = append(v.Build, str)
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// MustParse is like Parse but panics if the version cannot be parsed.
|
||||
func MustParse(s string) Version {
|
||||
v, err := Parse(s)
|
||||
if err != nil {
|
||||
panic(`semver: Parse(` + s + `): ` + err.Error())
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// PRVersion represents a PreRelease Version
|
||||
type PRVersion struct {
|
||||
VersionStr string
|
||||
VersionNum uint64
|
||||
IsNum bool
|
||||
}
|
||||
|
||||
// NewPRVersion creates a new valid prerelease version
|
||||
func NewPRVersion(s string) (PRVersion, error) {
|
||||
if len(s) == 0 {
|
||||
return PRVersion{}, errors.New("Prerelease is empty")
|
||||
}
|
||||
v := PRVersion{}
|
||||
if containsOnly(s, numbers) {
|
||||
if hasLeadingZeroes(s) {
|
||||
return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
|
||||
}
|
||||
num, err := strconv.ParseUint(s, 10, 64)
|
||||
|
||||
// Might never be hit, but just in case
|
||||
if err != nil {
|
||||
return PRVersion{}, err
|
||||
}
|
||||
v.VersionNum = num
|
||||
v.IsNum = true
|
||||
} else if containsOnly(s, alphanum) {
|
||||
v.VersionStr = s
|
||||
v.IsNum = false
|
||||
} else {
|
||||
return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// IsNumeric checks if prerelease-version is numeric
|
||||
func (v PRVersion) IsNumeric() bool {
|
||||
return v.IsNum
|
||||
}
|
||||
|
||||
// Compare compares two PreRelease Versions v and o:
|
||||
// -1 == v is less than o
|
||||
// 0 == v is equal to o
|
||||
// 1 == v is greater than o
|
||||
func (v PRVersion) Compare(o PRVersion) int {
|
||||
if v.IsNum && !o.IsNum {
|
||||
return -1
|
||||
} else if !v.IsNum && o.IsNum {
|
||||
return 1
|
||||
} else if v.IsNum && o.IsNum {
|
||||
if v.VersionNum == o.VersionNum {
|
||||
return 0
|
||||
} else if v.VersionNum > o.VersionNum {
|
||||
return 1
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
} else { // both are Alphas
|
||||
if v.VersionStr == o.VersionStr {
|
||||
return 0
|
||||
} else if v.VersionStr > o.VersionStr {
|
||||
return 1
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PreRelease version to string
|
||||
func (v PRVersion) String() string {
|
||||
if v.IsNum {
|
||||
return strconv.FormatUint(v.VersionNum, 10)
|
||||
}
|
||||
return v.VersionStr
|
||||
}
|
||||
|
||||
func containsOnly(s string, set string) bool {
|
||||
return strings.IndexFunc(s, func(r rune) bool {
|
||||
return !strings.ContainsRune(set, r)
|
||||
}) == -1
|
||||
}
|
||||
|
||||
func hasLeadingZeroes(s string) bool {
|
||||
return len(s) > 1 && s[0] == '0'
|
||||
}
|
||||
|
||||
// NewBuildVersion creates a new valid build version
|
||||
func NewBuildVersion(s string) (string, error) {
|
||||
if len(s) == 0 {
|
||||
return "", errors.New("Buildversion is empty")
|
||||
}
|
||||
if !containsOnly(s, alphanum) {
|
||||
return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
|
||||
}
|
||||
return s, nil
|
||||
}
|
28
build/manifest/vendor/github.com/blang/semver/sort.go
generated
vendored
28
build/manifest/vendor/github.com/blang/semver/sort.go
generated
vendored
|
@ -1,28 +0,0 @@
|
|||
package semver
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Versions represents multiple versions.
|
||||
type Versions []Version
|
||||
|
||||
// Len returns length of version collection
|
||||
func (s Versions) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
// Swap swaps two versions inside the collection by its indices
|
||||
func (s Versions) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
// Less checks if version at index i is less than version at index j
|
||||
func (s Versions) Less(i, j int) bool {
|
||||
return s[i].LT(s[j])
|
||||
}
|
||||
|
||||
// Sort sorts a slice of versions
|
||||
func Sort(versions []Version) {
|
||||
sort.Sort(Versions(versions))
|
||||
}
|
30
build/manifest/vendor/github.com/blang/semver/sql.go
generated
vendored
30
build/manifest/vendor/github.com/blang/semver/sql.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package semver
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Scan implements the database/sql.Scanner interface.
|
||||
func (v *Version) Scan(src interface{}) (err error) {
|
||||
var str string
|
||||
switch src := src.(type) {
|
||||
case string:
|
||||
str = src
|
||||
case []byte:
|
||||
str = string(src)
|
||||
default:
|
||||
return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
|
||||
}
|
||||
|
||||
if t, err := Parse(str); err == nil {
|
||||
*v = t
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Value implements the database/sql/driver.Valuer interface.
|
||||
func (v Version) Value() (driver.Value, error) {
|
||||
return v.String(), nil
|
||||
}
|
25
build/manifest/vendor/github.com/gorilla/websocket/.gitignore
generated
vendored
25
build/manifest/vendor/github.com/gorilla/websocket/.gitignore
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
|
||||
.idea/
|
||||
*.iml
|
21
build/manifest/vendor/github.com/gorilla/websocket/.travis.yml
generated
vendored
21
build/manifest/vendor/github.com/gorilla/websocket/.travis.yml
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
language: go
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.4
|
||||
- go: 1.5.x
|
||||
- go: 1.6.x
|
||||
- go: 1.7.x
|
||||
- go: 1.8.x
|
||||
- go: 1.9.x
|
||||
- go: 1.10.x
|
||||
- go: tip
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
script:
|
||||
- go get -t -v ./...
|
||||
- diff -u <(echo -n) <(gofmt -d .)
|
||||
- go vet $(go list ./... | grep -v /vendor/)
|
||||
- go test -v -race ./...
|
9
build/manifest/vendor/github.com/gorilla/websocket/AUTHORS
generated
vendored
9
build/manifest/vendor/github.com/gorilla/websocket/AUTHORS
generated
vendored
|
@ -1,9 +0,0 @@
|
|||
# This is the official list of Gorilla WebSocket authors for copyright
|
||||
# purposes.
|
||||
#
|
||||
# Please keep the list sorted.
|
||||
|
||||
Gary Burd <gary@beagledreams.com>
|
||||
Google LLC (https://opensource.google.com/)
|
||||
Joachim Bauch <mail@joachim-bauch.de>
|
||||
|
22
build/manifest/vendor/github.com/gorilla/websocket/LICENSE
generated
vendored
22
build/manifest/vendor/github.com/gorilla/websocket/LICENSE
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
64
build/manifest/vendor/github.com/gorilla/websocket/README.md
generated
vendored
64
build/manifest/vendor/github.com/gorilla/websocket/README.md
generated
vendored
|
@ -1,64 +0,0 @@
|
|||
# Gorilla WebSocket
|
||||
|
||||
Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
|
||||
[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
|
||||
|
||||
[](https://travis-ci.org/gorilla/websocket)
|
||||
[](https://godoc.org/github.com/gorilla/websocket)
|
||||
|
||||
### Documentation
|
||||
|
||||
* [API Reference](http://godoc.org/github.com/gorilla/websocket)
|
||||
* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
|
||||
* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
|
||||
* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
|
||||
* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
|
||||
|
||||
### Status
|
||||
|
||||
The Gorilla WebSocket package provides a complete and tested implementation of
|
||||
the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
|
||||
package API is stable.
|
||||
|
||||
### Installation
|
||||
|
||||
go get github.com/gorilla/websocket
|
||||
|
||||
### Protocol Compliance
|
||||
|
||||
The Gorilla WebSocket package passes the server tests in the [Autobahn Test
|
||||
Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn
|
||||
subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
|
||||
|
||||
### Gorilla WebSocket compared with other packages
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th>
|
||||
<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
|
||||
<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
|
||||
<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
|
||||
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
|
||||
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>
|
||||
<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>
|
||||
<tr><td colspan="3">Other Features</tr></td>
|
||||
<tr><td><a href="https://tools.ietf.org/html/rfc7692">Compression Extensions</a></td><td>Experimental</td><td>No</td></tr>
|
||||
<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr>
|
||||
<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
|
||||
</table>
|
||||
|
||||
Notes:
|
||||
|
||||
1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
|
||||
2. The application can get the type of a received data message by implementing
|
||||
a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)
|
||||
function.
|
||||
3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.
|
||||
Read returns when the input buffer is full or a frame boundary is
|
||||
encountered. Each call to Write sends a single frame message. The Gorilla
|
||||
io.Reader and io.WriteCloser operate on a single WebSocket message.
|
||||
|
330
build/manifest/vendor/github.com/gorilla/websocket/client.go
generated
vendored
330
build/manifest/vendor/github.com/gorilla/websocket/client.go
generated
vendored
|
@ -1,330 +0,0 @@
|
|||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ErrBadHandshake is returned when the server response to opening handshake is
|
||||
// invalid.
|
||||
var ErrBadHandshake = errors.New("websocket: bad handshake")
|
||||
|
||||
var errInvalidCompression = errors.New("websocket: invalid compression negotiation")
|
||||
|
||||
// NewClient creates a new client connection using the given net connection.
|
||||
// The URL u specifies the host and request URI. Use requestHeader to specify
|
||||
// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
|
||||
// (Cookie). Use the response.Header to get the selected subprotocol
|
||||
// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
|
||||
//
|
||||
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
|
||||
// non-nil *http.Response so that callers can handle redirects, authentication,
|
||||
// etc.
|
||||
//
|
||||
// Deprecated: Use Dialer instead.
|
||||
func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {
|
||||
d := Dialer{
|
||||
ReadBufferSize: readBufSize,
|
||||
WriteBufferSize: writeBufSize,
|
||||
NetDial: func(net, addr string) (net.Conn, error) {
|
||||
return netConn, nil
|
||||
},
|
||||
}
|
||||
return d.Dial(u.String(), requestHeader)
|
||||
}
|
||||
|
||||
// A Dialer contains options for connecting to WebSocket server.
|
||||
type Dialer struct {
|
||||
// NetDial specifies the dial function for creating TCP connections. If
|
||||
// NetDial is nil, net.Dial is used.
|
||||
NetDial func(network, addr string) (net.Conn, error)
|
||||
|
||||
// Proxy specifies a function to return a proxy for a given
|
||||
// Request. If the function returns a non-nil error, the
|
||||
// request is aborted with the provided error.
|
||||
// If Proxy is nil or returns a nil *URL, no proxy is used.
|
||||
Proxy func(*http.Request) (*url.URL, error)
|
||||
|
||||
// TLSClientConfig specifies the TLS configuration to use with tls.Client.
|
||||
// If nil, the default configuration is used.
|
||||
TLSClientConfig *tls.Config
|
||||
|
||||
// HandshakeTimeout specifies the duration for the handshake to complete.
|
||||
HandshakeTimeout time.Duration
|
||||
|
||||
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
|
||||
// size is zero, then a useful default size is used. The I/O buffer sizes
|
||||
// do not limit the size of the messages that can be sent or received.
|
||||
ReadBufferSize, WriteBufferSize int
|
||||
|
||||
// Subprotocols specifies the client's requested subprotocols.
|
||||
Subprotocols []string
|
||||
|
||||
// EnableCompression specifies if the client should attempt to negotiate
|
||||
// per message compression (RFC 7692). Setting this value to true does not
|
||||
// guarantee that compression will be supported. Currently only "no context
|
||||
// takeover" modes are supported.
|
||||
EnableCompression bool
|
||||
|
||||
// Jar specifies the cookie jar.
|
||||
// If Jar is nil, cookies are not sent in requests and ignored
|
||||
// in responses.
|
||||
Jar http.CookieJar
|
||||
}
|
||||
|
||||
var errMalformedURL = errors.New("malformed ws or wss URL")
|
||||
|
||||
func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
|
||||
hostPort = u.Host
|
||||
hostNoPort = u.Host
|
||||
if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") {
|
||||
hostNoPort = hostNoPort[:i]
|
||||
} else {
|
||||
switch u.Scheme {
|
||||
case "wss":
|
||||
hostPort += ":443"
|
||||
case "https":
|
||||
hostPort += ":443"
|
||||
default:
|
||||
hostPort += ":80"
|
||||
}
|
||||
}
|
||||
return hostPort, hostNoPort
|
||||
}
|
||||
|
||||
// DefaultDialer is a dialer with all fields set to the default values.
|
||||
var DefaultDialer = &Dialer{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
HandshakeTimeout: 45 * time.Second,
|
||||
}
|
||||
|
||||
// nilDialer is dialer to use when receiver is nil.
|
||||
var nilDialer Dialer = *DefaultDialer
|
||||
|
||||
// Dial creates a new client connection. Use requestHeader to specify the
|
||||
// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
|
||||
// Use the response.Header to get the selected subprotocol
|
||||
// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
|
||||
//
|
||||
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
|
||||
// non-nil *http.Response so that callers can handle redirects, authentication,
|
||||
// etcetera. The response body may not contain the entire response and does not
|
||||
// need to be closed by the application.
|
||||
func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
|
||||
|
||||
if d == nil {
|
||||
d = &nilDialer
|
||||
}
|
||||
|
||||
challengeKey, err := generateChallengeKey()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
u, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "ws":
|
||||
u.Scheme = "http"
|
||||
case "wss":
|
||||
u.Scheme = "https"
|
||||
default:
|
||||
return nil, nil, errMalformedURL
|
||||
}
|
||||
|
||||
if u.User != nil {
|
||||
// User name and password are not allowed in websocket URIs.
|
||||
return nil, nil, errMalformedURL
|
||||
}
|
||||
|
||||
req := &http.Request{
|
||||
Method: "GET",
|
||||
URL: u,
|
||||
Proto: "HTTP/1.1",
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 1,
|
||||
Header: make(http.Header),
|
||||
Host: u.Host,
|
||||
}
|
||||
|
||||
// Set the cookies present in the cookie jar of the dialer
|
||||
if d.Jar != nil {
|
||||
for _, cookie := range d.Jar.Cookies(u) {
|
||||
req.AddCookie(cookie)
|
||||
}
|
||||
}
|
||||
|
||||
// Set the request headers using the capitalization for names and values in
|
||||
// RFC examples. Although the capitalization shouldn't matter, there are
|
||||
// servers that depend on it. The Header.Set method is not used because the
|
||||
// method canonicalizes the header names.
|
||||
req.Header["Upgrade"] = []string{"websocket"}
|
||||
req.Header["Connection"] = []string{"Upgrade"}
|
||||
req.Header["Sec-WebSocket-Key"] = []string{challengeKey}
|
||||
req.Header["Sec-WebSocket-Version"] = []string{"13"}
|
||||
if len(d.Subprotocols) > 0 {
|
||||
req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")}
|
||||
}
|
||||
for k, vs := range requestHeader {
|
||||
switch {
|
||||
case k == "Host":
|
||||
if len(vs) > 0 {
|
||||
req.Host = vs[0]
|
||||
}
|
||||
case k == "Upgrade" ||
|
||||
k == "Connection" ||
|
||||
k == "Sec-Websocket-Key" ||
|
||||
k == "Sec-Websocket-Version" ||
|
||||
k == "Sec-Websocket-Extensions" ||
|
||||
(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
|
||||
return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
|
||||
case k == "Sec-Websocket-Protocol":
|
||||
req.Header["Sec-WebSocket-Protocol"] = vs
|
||||
default:
|
||||
req.Header[k] = vs
|
||||
}
|
||||
}
|
||||
|
||||
if d.EnableCompression {
|
||||
req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"}
|
||||
}
|
||||
|
||||
var deadline time.Time
|
||||
if d.HandshakeTimeout != 0 {
|
||||
deadline = time.Now().Add(d.HandshakeTimeout)
|
||||
}
|
||||
|
||||
// Get network dial function.
|
||||
netDial := d.NetDial
|
||||
if netDial == nil {
|
||||
netDialer := &net.Dialer{Deadline: deadline}
|
||||
netDial = netDialer.Dial
|
||||
}
|
||||
|
||||
// If needed, wrap the dial function to set the connection deadline.
|
||||
if !deadline.Equal(time.Time{}) {
|
||||
forwardDial := netDial
|
||||
netDial = func(network, addr string) (net.Conn, error) {
|
||||
c, err := forwardDial(network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = c.SetDeadline(deadline)
|
||||
if err != nil {
|
||||
c.Close()
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
// If needed, wrap the dial function to connect through a proxy.
|
||||
if d.Proxy != nil {
|
||||
proxyURL, err := d.Proxy(req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if proxyURL != nil {
|
||||
dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
netDial = dialer.Dial
|
||||
}
|
||||
}
|
||||
|
||||
hostPort, hostNoPort := hostPortNoPort(u)
|
||||
netConn, err := netDial("tcp", hostPort)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if netConn != nil {
|
||||
netConn.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if u.Scheme == "https" {
|
||||
cfg := cloneTLSConfig(d.TLSClientConfig)
|
||||
if cfg.ServerName == "" {
|
||||
cfg.ServerName = hostNoPort
|
||||
}
|
||||
tlsConn := tls.Client(netConn, cfg)
|
||||
netConn = tlsConn
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if !cfg.InsecureSkipVerify {
|
||||
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize)
|
||||
|
||||
if err := req.Write(netConn); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
resp, err := http.ReadResponse(conn.br, req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if d.Jar != nil {
|
||||
if rc := resp.Cookies(); len(rc) > 0 {
|
||||
d.Jar.SetCookies(u, rc)
|
||||
}
|
||||
}
|
||||
|
||||
if resp.StatusCode != 101 ||
|
||||
!strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
|
||||
!strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
|
||||
resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) {
|
||||
// Before closing the network connection on return from this
|
||||
// function, slurp up some of the response to aid application
|
||||
// debugging.
|
||||
buf := make([]byte, 1024)
|
||||
n, _ := io.ReadFull(resp.Body, buf)
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
|
||||
return nil, resp, ErrBadHandshake
|
||||
}
|
||||
|
||||
for _, ext := range parseExtensions(resp.Header) {
|
||||
if ext[""] != "permessage-deflate" {
|
||||
continue
|
||||
}
|
||||
_, snct := ext["server_no_context_takeover"]
|
||||
_, cnct := ext["client_no_context_takeover"]
|
||||
if !snct || !cnct {
|
||||
return nil, resp, errInvalidCompression
|
||||
}
|
||||
conn.newCompressionWriter = compressNoContextTakeover
|
||||
conn.newDecompressionReader = decompressNoContextTakeover
|
||||
break
|
||||
}
|
||||
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
|
||||
|
||||
netConn.SetDeadline(time.Time{})
|
||||
netConn = nil // to avoid close in defer.
|
||||
return conn, resp, nil
|
||||
}
|
16
build/manifest/vendor/github.com/gorilla/websocket/client_clone.go
generated
vendored
16
build/manifest/vendor/github.com/gorilla/websocket/client_clone.go
generated
vendored
|
@ -1,16 +0,0 @@
|
|||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{}
|
||||
}
|
||||
return cfg.Clone()
|
||||
}
|
38
build/manifest/vendor/github.com/gorilla/websocket/client_clone_legacy.go
generated
vendored
38
build/manifest/vendor/github.com/gorilla/websocket/client_clone_legacy.go
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
// cloneTLSConfig clones all public fields except the fields
|
||||
// SessionTicketsDisabled and SessionTicketKey. This avoids copying the
|
||||
// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a
|
||||
// config in active use.
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{}
|
||||
}
|
||||
return &tls.Config{
|
||||
Rand: cfg.Rand,
|
||||
Time: cfg.Time,
|
||||
Certificates: cfg.Certificates,
|
||||
NameToCertificate: cfg.NameToCertificate,
|
||||
GetCertificate: cfg.GetCertificate,
|
||||
RootCAs: cfg.RootCAs,
|
||||
NextProtos: cfg.NextProtos,
|
||||
ServerName: cfg.ServerName,
|
||||
ClientAuth: cfg.ClientAuth,
|
||||
ClientCAs: cfg.ClientCAs,
|
||||
InsecureSkipVerify: cfg.InsecureSkipVerify,
|
||||
CipherSuites: cfg.CipherSuites,
|
||||
PreferServerCipherSuites: cfg.PreferServerCipherSuites,
|
||||
ClientSessionCache: cfg.ClientSessionCache,
|
||||
MinVersion: cfg.MinVersion,
|
||||
MaxVersion: cfg.MaxVersion,
|
||||
CurvePreferences: cfg.CurvePreferences,
|
||||
}
|
||||
}
|
148
build/manifest/vendor/github.com/gorilla/websocket/compression.go
generated
vendored
148
build/manifest/vendor/github.com/gorilla/websocket/compression.go
generated
vendored
|
@ -1,148 +0,0 @@
|
|||
// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"compress/flate"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6
|
||||
maxCompressionLevel = flate.BestCompression
|
||||
defaultCompressionLevel = 1
|
||||
)
|
||||
|
||||
var (
|
||||
flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool
|
||||
flateReaderPool = sync.Pool{New: func() interface{} {
|
||||
return flate.NewReader(nil)
|
||||
}}
|
||||
)
|
||||
|
||||
func decompressNoContextTakeover(r io.Reader) io.ReadCloser {
|
||||
const tail =
|
||||
// Add four bytes as specified in RFC
|
||||
"\x00\x00\xff\xff" +
|
||||
// Add final block to squelch unexpected EOF error from flate reader.
|
||||
"\x01\x00\x00\xff\xff"
|
||||
|
||||
fr, _ := flateReaderPool.Get().(io.ReadCloser)
|
||||
fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)
|
||||
return &flateReadWrapper{fr}
|
||||
}
|
||||
|
||||
func isValidCompressionLevel(level int) bool {
|
||||
return minCompressionLevel <= level && level <= maxCompressionLevel
|
||||
}
|
||||
|
||||
func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser {
|
||||
p := &flateWriterPools[level-minCompressionLevel]
|
||||
tw := &truncWriter{w: w}
|
||||
fw, _ := p.Get().(*flate.Writer)
|
||||
if fw == nil {
|
||||
fw, _ = flate.NewWriter(tw, level)
|
||||
} else {
|
||||
fw.Reset(tw)
|
||||
}
|
||||
return &flateWriteWrapper{fw: fw, tw: tw, p: p}
|
||||
}
|
||||
|
||||
// truncWriter is an io.Writer that writes all but the last four bytes of the
|
||||
// stream to another io.Writer.
|
||||
type truncWriter struct {
|
||||
w io.WriteCloser
|
||||
n int
|
||||
p [4]byte
|
||||
}
|
||||
|
||||
func (w *truncWriter) Write(p []byte) (int, error) {
|
||||
n := 0
|
||||
|
||||
// fill buffer first for simplicity.
|
||||
if w.n < len(w.p) {
|
||||
n = copy(w.p[w.n:], p)
|
||||
p = p[n:]
|
||||
w.n += n
|
||||
if len(p) == 0 {
|
||||
return n, nil
|
||||
}
|
||||
}
|
||||
|
||||
m := len(p)
|
||||
if m > len(w.p) {
|
||||
m = len(w.p)
|
||||
}
|
||||
|
||||
if nn, err := w.w.Write(w.p[:m]); err != nil {
|
||||
return n + nn, err
|
||||
}
|
||||
|
||||
copy(w.p[:], w.p[m:])
|
||||
copy(w.p[len(w.p)-m:], p[len(p)-m:])
|
||||
nn, err := w.w.Write(p[:len(p)-m])
|
||||
return n + nn, err
|
||||
}
|
||||
|
||||
type flateWriteWrapper struct {
|
||||
fw *flate.Writer
|
||||
tw *truncWriter
|
||||
p *sync.Pool
|
||||
}
|
||||
|
||||
func (w *flateWriteWrapper) Write(p []byte) (int, error) {
|
||||
if w.fw == nil {
|
||||
return 0, errWriteClosed
|
||||
}
|
||||
return w.fw.Write(p)
|
||||
}
|
||||
|
||||
func (w *flateWriteWrapper) Close() error {
|
||||
if w.fw == nil {
|
||||
return errWriteClosed
|
||||
}
|
||||
err1 := w.fw.Flush()
|
||||
w.p.Put(w.fw)
|
||||
w.fw = nil
|
||||
if w.tw.p != [4]byte{0, 0, 0xff, 0xff} {
|
||||
return errors.New("websocket: internal error, unexpected bytes at end of flate stream")
|
||||
}
|
||||
err2 := w.tw.w.Close()
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
return err2
|
||||
}
|
||||
|
||||
type flateReadWrapper struct {
|
||||
fr io.ReadCloser
|
||||
}
|
||||
|
||||
func (r *flateReadWrapper) Read(p []byte) (int, error) {
|
||||
if r.fr == nil {
|
||||
return 0, io.ErrClosedPipe
|
||||
}
|
||||
n, err := r.fr.Read(p)
|
||||
if err == io.EOF {
|
||||
// Preemptively place the reader back in the pool. This helps with
|
||||
// scenarios where the application does not call NextReader() soon after
|
||||
// this final read.
|
||||
r.Close()
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *flateReadWrapper) Close() error {
|
||||
if r.fr == nil {
|
||||
return io.ErrClosedPipe
|
||||
}
|
||||
err := r.fr.Close()
|
||||
flateReaderPool.Put(r.fr)
|
||||
r.fr = nil
|
||||
return err
|
||||
}
|
1157
build/manifest/vendor/github.com/gorilla/websocket/conn.go
generated
vendored
1157
build/manifest/vendor/github.com/gorilla/websocket/conn.go
generated
vendored
File diff suppressed because it is too large
Load diff
18
build/manifest/vendor/github.com/gorilla/websocket/conn_read.go
generated
vendored
18
build/manifest/vendor/github.com/gorilla/websocket/conn_read.go
generated
vendored
|
@ -1,18 +0,0 @@
|
|||
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.5
|
||||
|
||||
package websocket
|
||||
|
||||
import "io"
|
||||
|
||||
func (c *Conn) read(n int) ([]byte, error) {
|
||||
p, err := c.br.Peek(n)
|
||||
if err == io.EOF {
|
||||
err = errUnexpectedEOF
|
||||
}
|
||||
c.br.Discard(len(p))
|
||||
return p, err
|
||||
}
|
21
build/manifest/vendor/github.com/gorilla/websocket/conn_read_legacy.go
generated
vendored
21
build/manifest/vendor/github.com/gorilla/websocket/conn_read_legacy.go
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.5
|
||||
|
||||
package websocket
|
||||
|
||||
import "io"
|
||||
|
||||
func (c *Conn) read(n int) ([]byte, error) {
|
||||
p, err := c.br.Peek(n)
|
||||
if err == io.EOF {
|
||||
err = errUnexpectedEOF
|
||||
}
|
||||
if len(p) > 0 {
|
||||
// advance over the bytes just read
|
||||
io.ReadFull(c.br, p)
|
||||
}
|
||||
return p, err
|
||||
}
|
15
build/manifest/vendor/github.com/gorilla/websocket/conn_write.go
generated
vendored
15
build/manifest/vendor/github.com/gorilla/websocket/conn_write.go
generated
vendored
|
@ -1,15 +0,0 @@
|
|||
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
import "net"
|
||||
|
||||
func (c *Conn) writeBufs(bufs ...[]byte) error {
|
||||
b := net.Buffers(bufs)
|
||||
_, err := b.WriteTo(c.conn)
|
||||
return err
|
||||
}
|
18
build/manifest/vendor/github.com/gorilla/websocket/conn_write_legacy.go
generated
vendored
18
build/manifest/vendor/github.com/gorilla/websocket/conn_write_legacy.go
generated
vendored
|
@ -1,18 +0,0 @@
|
|||
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
func (c *Conn) writeBufs(bufs ...[]byte) error {
|
||||
for _, buf := range bufs {
|
||||
if len(buf) > 0 {
|
||||
if _, err := c.conn.Write(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
180
build/manifest/vendor/github.com/gorilla/websocket/doc.go
generated
vendored
180
build/manifest/vendor/github.com/gorilla/websocket/doc.go
generated
vendored
|
@ -1,180 +0,0 @@
|
|||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package websocket implements the WebSocket protocol defined in RFC 6455.
|
||||
//
|
||||
// Overview
|
||||
//
|
||||
// The Conn type represents a WebSocket connection. A server application calls
|
||||
// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn:
|
||||
//
|
||||
// var upgrader = websocket.Upgrader{
|
||||
// ReadBufferSize: 1024,
|
||||
// WriteBufferSize: 1024,
|
||||
// }
|
||||
//
|
||||
// func handler(w http.ResponseWriter, r *http.Request) {
|
||||
// conn, err := upgrader.Upgrade(w, r, nil)
|
||||
// if err != nil {
|
||||
// log.Println(err)
|
||||
// return
|
||||
// }
|
||||
// ... Use conn to send and receive messages.
|
||||
// }
|
||||
//
|
||||
// Call the connection's WriteMessage and ReadMessage methods to send and
|
||||
// receive messages as a slice of bytes. This snippet of code shows how to echo
|
||||
// messages using these methods:
|
||||
//
|
||||
// for {
|
||||
// messageType, p, err := conn.ReadMessage()
|
||||
// if err != nil {
|
||||
// log.Println(err)
|
||||
// return
|
||||
// }
|
||||
// if err := conn.WriteMessage(messageType, p); err != nil {
|
||||
// log.Println(err)
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// In above snippet of code, p is a []byte and messageType is an int with value
|
||||
// websocket.BinaryMessage or websocket.TextMessage.
|
||||
//
|
||||
// An application can also send and receive messages using the io.WriteCloser
|
||||
// and io.Reader interfaces. To send a message, call the connection NextWriter
|
||||
// method to get an io.WriteCloser, write the message to the writer and close
|
||||
// the writer when done. To receive a message, call the connection NextReader
|
||||
// method to get an io.Reader and read until io.EOF is returned. This snippet
|
||||
// shows how to echo messages using the NextWriter and NextReader methods:
|
||||
//
|
||||
// for {
|
||||
// messageType, r, err := conn.NextReader()
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// w, err := conn.NextWriter(messageType)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if _, err := io.Copy(w, r); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if err := w.Close(); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Data Messages
|
||||
//
|
||||
// The WebSocket protocol distinguishes between text and binary data messages.
|
||||
// Text messages are interpreted as UTF-8 encoded text. The interpretation of
|
||||
// binary messages is left to the application.
|
||||
//
|
||||
// This package uses the TextMessage and BinaryMessage integer constants to
|
||||
// identify the two data message types. The ReadMessage and NextReader methods
|
||||
// return the type of the received message. The messageType argument to the
|
||||
// WriteMessage and NextWriter methods specifies the type of a sent message.
|
||||
//
|
||||
// It is the application's responsibility to ensure that text messages are
|
||||
// valid UTF-8 encoded text.
|
||||
//
|
||||
// Control Messages
|
||||
//
|
||||
// The WebSocket protocol defines three types of control messages: close, ping
|
||||
// and pong. Call the connection WriteControl, WriteMessage or NextWriter
|
||||
// methods to send a control message to the peer.
|
||||
//
|
||||
// Connections handle received close messages by calling the handler function
|
||||
// set with the SetCloseHandler method and by returning a *CloseError from the
|
||||
// NextReader, ReadMessage or the message Read method. The default close
|
||||
// handler sends a close message to the peer.
|
||||
//
|
||||
// Connections handle received ping messages by calling the handler function
|
||||
// set with the SetPingHandler method. The default ping handler sends a pong
|
||||
// message to the peer.
|
||||
//
|
||||
// Connections handle received pong messages by calling the handler function
|
||||
// set with the SetPongHandler method. The default pong handler does nothing.
|
||||
// If an application sends ping messages, then the application should set a
|
||||
// pong handler to receive the corresponding pong.
|
||||
//
|
||||
// The control message handler functions are called from the NextReader,
|
||||
// ReadMessage and message reader Read methods. The default close and ping
|
||||
// handlers can block these methods for a short time when the handler writes to
|
||||
// the connection.
|
||||
//
|
||||
// The application must read the connection to process close, ping and pong
|
||||
// messages sent from the peer. If the application is not otherwise interested
|
||||
// in messages from the peer, then the application should start a goroutine to
|
||||
// read and discard messages from the peer. A simple example is:
|
||||
//
|
||||
// func readLoop(c *websocket.Conn) {
|
||||
// for {
|
||||
// if _, _, err := c.NextReader(); err != nil {
|
||||
// c.Close()
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Concurrency
|
||||
//
|
||||
// Connections support one concurrent reader and one concurrent writer.
|
||||
//
|
||||
// Applications are responsible for ensuring that no more than one goroutine
|
||||
// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
|
||||
// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and
|
||||
// that no more than one goroutine calls the read methods (NextReader,
|
||||
// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)
|
||||
// concurrently.
|
||||
//
|
||||
// The Close and WriteControl methods can be called concurrently with all other
|
||||
// methods.
|
||||
//
|
||||
// Origin Considerations
|
||||
//
|
||||
// Web browsers allow Javascript applications to open a WebSocket connection to
|
||||
// any host. It's up to the server to enforce an origin policy using the Origin
|
||||
// request header sent by the browser.
|
||||
//
|
||||
// The Upgrader calls the function specified in the CheckOrigin field to check
|
||||
// the origin. If the CheckOrigin function returns false, then the Upgrade
|
||||
// method fails the WebSocket handshake with HTTP status 403.
|
||||
//
|
||||
// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail
|
||||
// the handshake if the Origin request header is present and the Origin host is
|
||||
// not equal to the Host request header.
|
||||
//
|
||||
// The deprecated package-level Upgrade function does not perform origin
|
||||
// checking. The application is responsible for checking the Origin header
|
||||
// before calling the Upgrade function.
|
||||
//
|
||||
// Compression EXPERIMENTAL
|
||||
//
|
||||
// Per message compression extensions (RFC 7692) are experimentally supported
|
||||
// by this package in a limited capacity. Setting the EnableCompression option
|
||||
// to true in Dialer or Upgrader will attempt to negotiate per message deflate
|
||||
// support.
|
||||
//
|
||||
// var upgrader = websocket.Upgrader{
|
||||
// EnableCompression: true,
|
||||
// }
|
||||
//
|
||||
// If compression was successfully negotiated with the connection's peer, any
|
||||
// message received in compressed form will be automatically decompressed.
|
||||
// All Read methods will return uncompressed bytes.
|
||||
//
|
||||
// Per message compression of messages written to a connection can be enabled
|
||||
// or disabled by calling the corresponding Conn method:
|
||||
//
|
||||
// conn.EnableWriteCompression(false)
|
||||
//
|
||||
// Currently this package does not support compression with "context takeover".
|
||||
// This means that messages must be compressed and decompressed in isolation,
|
||||
// without retaining sliding window or dictionary state across messages. For
|
||||
// more details refer to RFC 7692.
|
||||
//
|
||||
// Use of compression is experimental and may result in decreased performance.
|
||||
package websocket
|
60
build/manifest/vendor/github.com/gorilla/websocket/json.go
generated
vendored
60
build/manifest/vendor/github.com/gorilla/websocket/json.go
generated
vendored
|
@ -1,60 +0,0 @@
|
|||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// WriteJSON writes the JSON encoding of v as a message.
|
||||
//
|
||||
// Deprecated: Use c.WriteJSON instead.
|
||||
func WriteJSON(c *Conn, v interface{}) error {
|
||||
return c.WriteJSON(v)
|
||||
}
|
||||
|
||||
// WriteJSON writes the JSON encoding of v as a message.
|
||||
//
|
||||
// See the documentation for encoding/json Marshal for details about the
|
||||
// conversion of Go values to JSON.
|
||||
func (c *Conn) WriteJSON(v interface{}) error {
|
||||
w, err := c.NextWriter(TextMessage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err1 := json.NewEncoder(w).Encode(v)
|
||||
err2 := w.Close()
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
return err2
|
||||
}
|
||||
|
||||
// ReadJSON reads the next JSON-encoded message from the connection and stores
|
||||
// it in the value pointed to by v.
|
||||
//
|
||||
// Deprecated: Use c.ReadJSON instead.
|
||||
func ReadJSON(c *Conn, v interface{}) error {
|
||||
return c.ReadJSON(v)
|
||||
}
|
||||
|
||||
// ReadJSON reads the next JSON-encoded message from the connection and stores
|
||||
// it in the value pointed to by v.
|
||||
//
|
||||
// See the documentation for the encoding/json Unmarshal function for details
|
||||
// about the conversion of JSON to a Go value.
|
||||
func (c *Conn) ReadJSON(v interface{}) error {
|
||||
_, r, err := c.NextReader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.NewDecoder(r).Decode(v)
|
||||
if err == io.EOF {
|
||||
// One value is expected in the message.
|
||||
err = io.ErrUnexpectedEOF
|
||||
}
|
||||
return err
|
||||
}
|
54
build/manifest/vendor/github.com/gorilla/websocket/mask.go
generated
vendored
54
build/manifest/vendor/github.com/gorilla/websocket/mask.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
|
||||
// this source code is governed by a BSD-style license that can be found in the
|
||||
// LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package websocket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const wordSize = int(unsafe.Sizeof(uintptr(0)))
|
||||
|
||||
func maskBytes(key [4]byte, pos int, b []byte) int {
|
||||
// Mask one byte at a time for small buffers.
|
||||
if len(b) < 2*wordSize {
|
||||
for i := range b {
|
||||
b[i] ^= key[pos&3]
|
||||
pos++
|
||||
}
|
||||
return pos & 3
|
||||
}
|
||||
|
||||
// Mask one byte at a time to word boundary.
|
||||
if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {
|
||||
n = wordSize - n
|
||||
for i := range b[:n] {
|
||||
b[i] ^= key[pos&3]
|
||||
pos++
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
|
||||
// Create aligned word size key.
|
||||
var k [wordSize]byte
|
||||
for i := range k {
|
||||
k[i] = key[(pos+i)&3]
|
||||
}
|
||||
kw := *(*uintptr)(unsafe.Pointer(&k))
|
||||
|
||||
// Mask one word at a time.
|
||||
n := (len(b) / wordSize) * wordSize
|
||||
for i := 0; i < n; i += wordSize {
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw
|
||||
}
|
||||
|
||||
// Mask one byte at a time for remaining bytes.
|
||||
b = b[n:]
|
||||
for i := range b {
|
||||
b[i] ^= key[pos&3]
|
||||
pos++
|
||||
}
|
||||
|
||||
return pos & 3
|
||||
}
|
15
build/manifest/vendor/github.com/gorilla/websocket/mask_safe.go
generated
vendored
15
build/manifest/vendor/github.com/gorilla/websocket/mask_safe.go
generated
vendored
|
@ -1,15 +0,0 @@
|
|||
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
|
||||
// this source code is governed by a BSD-style license that can be found in the
|
||||
// LICENSE file.
|
||||
|
||||
// +build appengine
|
||||
|
||||
package websocket
|
||||
|
||||
func maskBytes(key [4]byte, pos int, b []byte) int {
|
||||
for i := range b {
|
||||
b[i] ^= key[pos&3]
|
||||
pos++
|
||||
}
|
||||
return pos & 3
|
||||
}
|
103
build/manifest/vendor/github.com/gorilla/websocket/prepared.go
generated
vendored
103
build/manifest/vendor/github.com/gorilla/websocket/prepared.go
generated
vendored
|
@ -1,103 +0,0 @@
|
|||
// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PreparedMessage caches on the wire representations of a message payload.
|
||||
// Use PreparedMessage to efficiently send a message payload to multiple
|
||||
// connections. PreparedMessage is especially useful when compression is used
|
||||
// because the CPU and memory expensive compression operation can be executed
|
||||
// once for a given set of compression options.
|
||||
type PreparedMessage struct {
|
||||
messageType int
|
||||
data []byte
|
||||
err error
|
||||
mu sync.Mutex
|
||||
frames map[prepareKey]*preparedFrame
|
||||
}
|
||||
|
||||
// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage.
|
||||
type prepareKey struct {
|
||||
isServer bool
|
||||
compress bool
|
||||
compressionLevel int
|
||||
}
|
||||
|
||||
// preparedFrame contains data in wire representation.
|
||||
type preparedFrame struct {
|
||||
once sync.Once
|
||||
data []byte
|
||||
}
|
||||
|
||||
// NewPreparedMessage returns an initialized PreparedMessage. You can then send
|
||||
// it to connection using WritePreparedMessage method. Valid wire
|
||||
// representation will be calculated lazily only once for a set of current
|
||||
// connection options.
|
||||
func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) {
|
||||
pm := &PreparedMessage{
|
||||
messageType: messageType,
|
||||
frames: make(map[prepareKey]*preparedFrame),
|
||||
data: data,
|
||||
}
|
||||
|
||||
// Prepare a plain server frame.
|
||||
_, frameData, err := pm.frame(prepareKey{isServer: true, compress: false})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// To protect against caller modifying the data argument, remember the data
|
||||
// copied to the plain server frame.
|
||||
pm.data = frameData[len(frameData)-len(data):]
|
||||
return pm, nil
|
||||
}
|
||||
|
||||
func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {
|
||||
pm.mu.Lock()
|
||||
frame, ok := pm.frames[key]
|
||||
if !ok {
|
||||
frame = &preparedFrame{}
|
||||
pm.frames[key] = frame
|
||||
}
|
||||
pm.mu.Unlock()
|
||||
|
||||
var err error
|
||||
frame.once.Do(func() {
|
||||
// Prepare a frame using a 'fake' connection.
|
||||
// TODO: Refactor code in conn.go to allow more direct construction of
|
||||
// the frame.
|
||||
mu := make(chan bool, 1)
|
||||
mu <- true
|
||||
var nc prepareConn
|
||||
c := &Conn{
|
||||
conn: &nc,
|
||||
mu: mu,
|
||||
isServer: key.isServer,
|
||||
compressionLevel: key.compressionLevel,
|
||||
enableWriteCompression: true,
|
||||
writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize),
|
||||
}
|
||||
if key.compress {
|
||||
c.newCompressionWriter = compressNoContextTakeover
|
||||
}
|
||||
err = c.WriteMessage(pm.messageType, pm.data)
|
||||
frame.data = nc.buf.Bytes()
|
||||
})
|
||||
return pm.messageType, frame.data, err
|
||||
}
|
||||
|
||||
type prepareConn struct {
|
||||
buf bytes.Buffer
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) }
|
||||
func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }
|
77
build/manifest/vendor/github.com/gorilla/websocket/proxy.go
generated
vendored
77
build/manifest/vendor/github.com/gorilla/websocket/proxy.go
generated
vendored
|
@ -1,77 +0,0 @@
|
|||
// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type netDialerFunc func(network, addr string) (net.Conn, error)
|
||||
|
||||
func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
|
||||
return fn(network, addr)
|
||||
}
|
||||
|
||||
func init() {
|
||||
proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
|
||||
return &httpProxyDialer{proxyURL: proxyURL, fowardDial: forwardDialer.Dial}, nil
|
||||
})
|
||||
}
|
||||
|
||||
type httpProxyDialer struct {
|
||||
proxyURL *url.URL
|
||||
fowardDial func(network, addr string) (net.Conn, error)
|
||||
}
|
||||
|
||||
func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
|
||||
hostPort, _ := hostPortNoPort(hpd.proxyURL)
|
||||
conn, err := hpd.fowardDial(network, hostPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
connectHeader := make(http.Header)
|
||||
if user := hpd.proxyURL.User; user != nil {
|
||||
proxyUser := user.Username()
|
||||
if proxyPassword, passwordSet := user.Password(); passwordSet {
|
||||
credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword))
|
||||
connectHeader.Set("Proxy-Authorization", "Basic "+credential)
|
||||
}
|
||||
}
|
||||
|
||||
connectReq := &http.Request{
|
||||
Method: "CONNECT",
|
||||
URL: &url.URL{Opaque: addr},
|
||||
Host: addr,
|
||||
Header: connectHeader,
|
||||
}
|
||||
|
||||
if err := connectReq.Write(conn); err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read response. It's OK to use and discard buffered reader here becaue
|
||||
// the remote server does not speak until spoken to.
|
||||
br := bufio.NewReader(conn)
|
||||
resp, err := http.ReadResponse(br, connectReq)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
conn.Close()
|
||||
f := strings.SplitN(resp.Status, " ", 2)
|
||||
return nil, errors.New(f[1])
|
||||
}
|
||||
return conn, nil
|
||||
}
|
298
build/manifest/vendor/github.com/gorilla/websocket/server.go
generated
vendored
298
build/manifest/vendor/github.com/gorilla/websocket/server.go
generated
vendored
|
@ -1,298 +0,0 @@
|
|||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// HandshakeError describes an error with the handshake from the peer.
|
||||
type HandshakeError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (e HandshakeError) Error() string { return e.message }
|
||||
|
||||
// Upgrader specifies parameters for upgrading an HTTP connection to a
|
||||
// WebSocket connection.
|
||||
type Upgrader struct {
|
||||
// HandshakeTimeout specifies the duration for the handshake to complete.
|
||||
HandshakeTimeout time.Duration
|
||||
|
||||
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
|
||||
// size is zero, then buffers allocated by the HTTP server are used. The
|
||||
// I/O buffer sizes do not limit the size of the messages that can be sent
|
||||
// or received.
|
||||
ReadBufferSize, WriteBufferSize int
|
||||
|
||||
// Subprotocols specifies the server's supported protocols in order of
|
||||
// preference. If this field is set, then the Upgrade method negotiates a
|
||||
// subprotocol by selecting the first match in this list with a protocol
|
||||
// requested by the client.
|
||||
Subprotocols []string
|
||||
|
||||
// Error specifies the function for generating HTTP error responses. If Error
|
||||
// is nil, then http.Error is used to generate the HTTP response.
|
||||
Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
|
||||
|
||||
// CheckOrigin returns true if the request Origin header is acceptable. If
|
||||
// CheckOrigin is nil, then a safe default is used: return false if the
|
||||
// Origin request header is present and the origin host is not equal to
|
||||
// request Host header.
|
||||
//
|
||||
// A CheckOrigin function should carefully validate the request origin to
|
||||
// prevent cross-site request forgery.
|
||||
CheckOrigin func(r *http.Request) bool
|
||||
|
||||
// EnableCompression specify if the server should attempt to negotiate per
|
||||
// message compression (RFC 7692). Setting this value to true does not
|
||||
// guarantee that compression will be supported. Currently only "no context
|
||||
// takeover" modes are supported.
|
||||
EnableCompression bool
|
||||
}
|
||||
|
||||
func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {
|
||||
err := HandshakeError{reason}
|
||||
if u.Error != nil {
|
||||
u.Error(w, r, status, err)
|
||||
} else {
|
||||
w.Header().Set("Sec-Websocket-Version", "13")
|
||||
http.Error(w, http.StatusText(status), status)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// checkSameOrigin returns true if the origin is not set or is equal to the request host.
|
||||
func checkSameOrigin(r *http.Request) bool {
|
||||
origin := r.Header["Origin"]
|
||||
if len(origin) == 0 {
|
||||
return true
|
||||
}
|
||||
u, err := url.Parse(origin[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return equalASCIIFold(u.Host, r.Host)
|
||||
}
|
||||
|
||||
func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {
|
||||
if u.Subprotocols != nil {
|
||||
clientProtocols := Subprotocols(r)
|
||||
for _, serverProtocol := range u.Subprotocols {
|
||||
for _, clientProtocol := range clientProtocols {
|
||||
if clientProtocol == serverProtocol {
|
||||
return clientProtocol
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if responseHeader != nil {
|
||||
return responseHeader.Get("Sec-Websocket-Protocol")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
|
||||
//
|
||||
// The responseHeader is included in the response to the client's upgrade
|
||||
// request. Use the responseHeader to specify cookies (Set-Cookie) and the
|
||||
// application negotiated subprotocol (Sec-WebSocket-Protocol).
|
||||
//
|
||||
// If the upgrade fails, then Upgrade replies to the client with an HTTP error
|
||||
// response.
|
||||
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
|
||||
const badHandshake = "websocket: the client is not using the websocket protocol: "
|
||||
|
||||
if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
|
||||
return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header")
|
||||
}
|
||||
|
||||
if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
|
||||
return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header")
|
||||
}
|
||||
|
||||
if r.Method != "GET" {
|
||||
return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET")
|
||||
}
|
||||
|
||||
if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") {
|
||||
return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header")
|
||||
}
|
||||
|
||||
if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok {
|
||||
return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported")
|
||||
}
|
||||
|
||||
checkOrigin := u.CheckOrigin
|
||||
if checkOrigin == nil {
|
||||
checkOrigin = checkSameOrigin
|
||||
}
|
||||
if !checkOrigin(r) {
|
||||
return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin")
|
||||
}
|
||||
|
||||
challengeKey := r.Header.Get("Sec-Websocket-Key")
|
||||
if challengeKey == "" {
|
||||
return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-WebSocket-Key' header is missing or blank")
|
||||
}
|
||||
|
||||
subprotocol := u.selectSubprotocol(r, responseHeader)
|
||||
|
||||
// Negotiate PMCE
|
||||
var compress bool
|
||||
if u.EnableCompression {
|
||||
for _, ext := range parseExtensions(r.Header) {
|
||||
if ext[""] != "permessage-deflate" {
|
||||
continue
|
||||
}
|
||||
compress = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
netConn net.Conn
|
||||
err error
|
||||
)
|
||||
|
||||
h, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
|
||||
}
|
||||
var brw *bufio.ReadWriter
|
||||
netConn, brw, err = h.Hijack()
|
||||
if err != nil {
|
||||
return u.returnError(w, r, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
if brw.Reader.Buffered() > 0 {
|
||||
netConn.Close()
|
||||
return nil, errors.New("websocket: client sent data before handshake is complete")
|
||||
}
|
||||
|
||||
c := newConnBRW(netConn, true, u.ReadBufferSize, u.WriteBufferSize, brw)
|
||||
c.subprotocol = subprotocol
|
||||
|
||||
if compress {
|
||||
c.newCompressionWriter = compressNoContextTakeover
|
||||
c.newDecompressionReader = decompressNoContextTakeover
|
||||
}
|
||||
|
||||
p := c.writeBuf[:0]
|
||||
p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
|
||||
p = append(p, computeAcceptKey(challengeKey)...)
|
||||
p = append(p, "\r\n"...)
|
||||
if c.subprotocol != "" {
|
||||
p = append(p, "Sec-WebSocket-Protocol: "...)
|
||||
p = append(p, c.subprotocol...)
|
||||
p = append(p, "\r\n"...)
|
||||
}
|
||||
if compress {
|
||||
p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...)
|
||||
}
|
||||
for k, vs := range responseHeader {
|
||||
if k == "Sec-Websocket-Protocol" {
|
||||
continue
|
||||
}
|
||||
for _, v := range vs {
|
||||
p = append(p, k...)
|
||||
p = append(p, ": "...)
|
||||
for i := 0; i < len(v); i++ {
|
||||
b := v[i]
|
||||
if b <= 31 {
|
||||
// prevent response splitting.
|
||||
b = ' '
|
||||
}
|
||||
p = append(p, b)
|
||||
}
|
||||
p = append(p, "\r\n"...)
|
||||
}
|
||||
}
|
||||
p = append(p, "\r\n"...)
|
||||
|
||||
// Clear deadlines set by HTTP server.
|
||||
netConn.SetDeadline(time.Time{})
|
||||
|
||||
if u.HandshakeTimeout > 0 {
|
||||
netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))
|
||||
}
|
||||
if _, err = netConn.Write(p); err != nil {
|
||||
netConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
if u.HandshakeTimeout > 0 {
|
||||
netConn.SetWriteDeadline(time.Time{})
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
|
||||
//
|
||||
// Deprecated: Use websocket.Upgrader instead.
|
||||
//
|
||||
// Upgrade does not perform origin checking. The application is responsible for
|
||||
// checking the Origin header before calling Upgrade. An example implementation
|
||||
// of the same origin policy check is:
|
||||
//
|
||||
// if req.Header.Get("Origin") != "http://"+req.Host {
|
||||
// http.Error(w, "Origin not allowed", http.StatusForbidden)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// If the endpoint supports subprotocols, then the application is responsible
|
||||
// for negotiating the protocol used on the connection. Use the Subprotocols()
|
||||
// function to get the subprotocols requested by the client. Use the
|
||||
// Sec-Websocket-Protocol response header to specify the subprotocol selected
|
||||
// by the application.
|
||||
//
|
||||
// The responseHeader is included in the response to the client's upgrade
|
||||
// request. Use the responseHeader to specify cookies (Set-Cookie) and the
|
||||
// negotiated subprotocol (Sec-Websocket-Protocol).
|
||||
//
|
||||
// The connection buffers IO to the underlying network connection. The
|
||||
// readBufSize and writeBufSize parameters specify the size of the buffers to
|
||||
// use. Messages can be larger than the buffers.
|
||||
//
|
||||
// If the request is not a valid WebSocket handshake, then Upgrade returns an
|
||||
// error of type HandshakeError. Applications should handle this error by
|
||||
// replying to the client with an HTTP error response.
|
||||
func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) {
|
||||
u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize}
|
||||
u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) {
|
||||
// don't return errors to maintain backwards compatibility
|
||||
}
|
||||
u.CheckOrigin = func(r *http.Request) bool {
|
||||
// allow all connections by default
|
||||
return true
|
||||
}
|
||||
return u.Upgrade(w, r, responseHeader)
|
||||
}
|
||||
|
||||
// Subprotocols returns the subprotocols requested by the client in the
|
||||
// Sec-Websocket-Protocol header.
|
||||
func Subprotocols(r *http.Request) []string {
|
||||
h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol"))
|
||||
if h == "" {
|
||||
return nil
|
||||
}
|
||||
protocols := strings.Split(h, ",")
|
||||
for i := range protocols {
|
||||
protocols[i] = strings.TrimSpace(protocols[i])
|
||||
}
|
||||
return protocols
|
||||
}
|
||||
|
||||
// IsWebSocketUpgrade returns true if the client requested upgrade to the
|
||||
// WebSocket protocol.
|
||||
func IsWebSocketUpgrade(r *http.Request) bool {
|
||||
return tokenListContainsValue(r.Header, "Connection", "upgrade") &&
|
||||
tokenListContainsValue(r.Header, "Upgrade", "websocket")
|
||||
}
|
237
build/manifest/vendor/github.com/gorilla/websocket/util.go
generated
vendored
237
build/manifest/vendor/github.com/gorilla/websocket/util.go
generated
vendored
|
@ -1,237 +0,0 @@
|
|||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
|
||||
|
||||
func computeAcceptKey(challengeKey string) string {
|
||||
h := sha1.New()
|
||||
h.Write([]byte(challengeKey))
|
||||
h.Write(keyGUID)
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func generateChallengeKey() (string, error) {
|
||||
p := make([]byte, 16)
|
||||
if _, err := io.ReadFull(rand.Reader, p); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(p), nil
|
||||
}
|
||||
|
||||
// Octet types from RFC 2616.
|
||||
var octetTypes [256]byte
|
||||
|
||||
const (
|
||||
isTokenOctet = 1 << iota
|
||||
isSpaceOctet
|
||||
)
|
||||
|
||||
func init() {
|
||||
// From RFC 2616
|
||||
//
|
||||
// OCTET = <any 8-bit sequence of data>
|
||||
// CHAR = <any US-ASCII character (octets 0 - 127)>
|
||||
// CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
||||
// CR = <US-ASCII CR, carriage return (13)>
|
||||
// LF = <US-ASCII LF, linefeed (10)>
|
||||
// SP = <US-ASCII SP, space (32)>
|
||||
// HT = <US-ASCII HT, horizontal-tab (9)>
|
||||
// <"> = <US-ASCII double-quote mark (34)>
|
||||
// CRLF = CR LF
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
// TEXT = <any OCTET except CTLs, but including LWS>
|
||||
// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
|
||||
// | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
|
||||
// token = 1*<any CHAR except CTLs or separators>
|
||||
// qdtext = <any TEXT except <">>
|
||||
|
||||
for c := 0; c < 256; c++ {
|
||||
var t byte
|
||||
isCtl := c <= 31 || c == 127
|
||||
isChar := 0 <= c && c <= 127
|
||||
isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0
|
||||
if strings.IndexRune(" \t\r\n", rune(c)) >= 0 {
|
||||
t |= isSpaceOctet
|
||||
}
|
||||
if isChar && !isCtl && !isSeparator {
|
||||
t |= isTokenOctet
|
||||
}
|
||||
octetTypes[c] = t
|
||||
}
|
||||
}
|
||||
|
||||
func skipSpace(s string) (rest string) {
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
if octetTypes[s[i]]&isSpaceOctet == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return s[i:]
|
||||
}
|
||||
|
||||
func nextToken(s string) (token, rest string) {
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
if octetTypes[s[i]]&isTokenOctet == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return s[:i], s[i:]
|
||||
}
|
||||
|
||||
func nextTokenOrQuoted(s string) (value string, rest string) {
|
||||
if !strings.HasPrefix(s, "\"") {
|
||||
return nextToken(s)
|
||||
}
|
||||
s = s[1:]
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch s[i] {
|
||||
case '"':
|
||||
return s[:i], s[i+1:]
|
||||
case '\\':
|
||||
p := make([]byte, len(s)-1)
|
||||
j := copy(p, s[:i])
|
||||
escape := true
|
||||
for i = i + 1; i < len(s); i++ {
|
||||
b := s[i]
|
||||
switch {
|
||||
case escape:
|
||||
escape = false
|
||||
p[j] = b
|
||||
j++
|
||||
case b == '\\':
|
||||
escape = true
|
||||
case b == '"':
|
||||
return string(p[:j]), s[i+1:]
|
||||
default:
|
||||
p[j] = b
|
||||
j++
|
||||
}
|
||||
}
|
||||
return "", ""
|
||||
}
|
||||
}
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// equalASCIIFold returns true if s is equal to t with ASCII case folding.
|
||||
func equalASCIIFold(s, t string) bool {
|
||||
for s != "" && t != "" {
|
||||
sr, size := utf8.DecodeRuneInString(s)
|
||||
s = s[size:]
|
||||
tr, size := utf8.DecodeRuneInString(t)
|
||||
t = t[size:]
|
||||
if sr == tr {
|
||||
continue
|
||||
}
|
||||
if 'A' <= sr && sr <= 'Z' {
|
||||
sr = sr + 'a' - 'A'
|
||||
}
|
||||
if 'A' <= tr && tr <= 'Z' {
|
||||
tr = tr + 'a' - 'A'
|
||||
}
|
||||
if sr != tr {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return s == t
|
||||
}
|
||||
|
||||
// tokenListContainsValue returns true if the 1#token header with the given
|
||||
// name contains a token equal to value with ASCII case folding.
|
||||
func tokenListContainsValue(header http.Header, name string, value string) bool {
|
||||
headers:
|
||||
for _, s := range header[name] {
|
||||
for {
|
||||
var t string
|
||||
t, s = nextToken(skipSpace(s))
|
||||
if t == "" {
|
||||
continue headers
|
||||
}
|
||||
s = skipSpace(s)
|
||||
if s != "" && s[0] != ',' {
|
||||
continue headers
|
||||
}
|
||||
if equalASCIIFold(t, value) {
|
||||
return true
|
||||
}
|
||||
if s == "" {
|
||||
continue headers
|
||||
}
|
||||
s = s[1:]
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// parseExtensiosn parses WebSocket extensions from a header.
|
||||
func parseExtensions(header http.Header) []map[string]string {
|
||||
// From RFC 6455:
|
||||
//
|
||||
// Sec-WebSocket-Extensions = extension-list
|
||||
// extension-list = 1#extension
|
||||
// extension = extension-token *( ";" extension-param )
|
||||
// extension-token = registered-token
|
||||
// registered-token = token
|
||||
// extension-param = token [ "=" (token | quoted-string) ]
|
||||
// ;When using the quoted-string syntax variant, the value
|
||||
// ;after quoted-string unescaping MUST conform to the
|
||||
// ;'token' ABNF.
|
||||
|
||||
var result []map[string]string
|
||||
headers:
|
||||
for _, s := range header["Sec-Websocket-Extensions"] {
|
||||
for {
|
||||
var t string
|
||||
t, s = nextToken(skipSpace(s))
|
||||
if t == "" {
|
||||
continue headers
|
||||
}
|
||||
ext := map[string]string{"": t}
|
||||
for {
|
||||
s = skipSpace(s)
|
||||
if !strings.HasPrefix(s, ";") {
|
||||
break
|
||||
}
|
||||
var k string
|
||||
k, s = nextToken(skipSpace(s[1:]))
|
||||
if k == "" {
|
||||
continue headers
|
||||
}
|
||||
s = skipSpace(s)
|
||||
var v string
|
||||
if strings.HasPrefix(s, "=") {
|
||||
v, s = nextTokenOrQuoted(skipSpace(s[1:]))
|
||||
s = skipSpace(s)
|
||||
}
|
||||
if s != "" && s[0] != ',' && s[0] != ';' {
|
||||
continue headers
|
||||
}
|
||||
ext[k] = v
|
||||
}
|
||||
if s != "" && s[0] != ',' {
|
||||
continue headers
|
||||
}
|
||||
result = append(result, ext)
|
||||
if s == "" {
|
||||
continue headers
|
||||
}
|
||||
s = s[1:]
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
473
build/manifest/vendor/github.com/gorilla/websocket/x_net_proxy.go
generated
vendored
473
build/manifest/vendor/github.com/gorilla/websocket/x_net_proxy.go
generated
vendored
|
@ -1,473 +0,0 @@
|
|||
// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
|
||||
//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy
|
||||
|
||||
// Package proxy provides support for a variety of protocols to proxy network
|
||||
// data.
|
||||
//
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type proxy_direct struct{}
|
||||
|
||||
// Direct is a direct proxy: one that makes network connections directly.
|
||||
var proxy_Direct = proxy_direct{}
|
||||
|
||||
func (proxy_direct) Dial(network, addr string) (net.Conn, error) {
|
||||
return net.Dial(network, addr)
|
||||
}
|
||||
|
||||
// A PerHost directs connections to a default Dialer unless the host name
|
||||
// requested matches one of a number of exceptions.
|
||||
type proxy_PerHost struct {
|
||||
def, bypass proxy_Dialer
|
||||
|
||||
bypassNetworks []*net.IPNet
|
||||
bypassIPs []net.IP
|
||||
bypassZones []string
|
||||
bypassHosts []string
|
||||
}
|
||||
|
||||
// NewPerHost returns a PerHost Dialer that directs connections to either
|
||||
// defaultDialer or bypass, depending on whether the connection matches one of
|
||||
// the configured rules.
|
||||
func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost {
|
||||
return &proxy_PerHost{
|
||||
def: defaultDialer,
|
||||
bypass: bypass,
|
||||
}
|
||||
}
|
||||
|
||||
// Dial connects to the address addr on the given network through either
|
||||
// defaultDialer or bypass.
|
||||
func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) {
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p.dialerForRequest(host).Dial(network, addr)
|
||||
}
|
||||
|
||||
func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer {
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
for _, net := range p.bypassNetworks {
|
||||
if net.Contains(ip) {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
for _, bypassIP := range p.bypassIPs {
|
||||
if bypassIP.Equal(ip) {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
return p.def
|
||||
}
|
||||
|
||||
for _, zone := range p.bypassZones {
|
||||
if strings.HasSuffix(host, zone) {
|
||||
return p.bypass
|
||||
}
|
||||
if host == zone[1:] {
|
||||
// For a zone ".example.com", we match "example.com"
|
||||
// too.
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
for _, bypassHost := range p.bypassHosts {
|
||||
if bypassHost == host {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
return p.def
|
||||
}
|
||||
|
||||
// AddFromString parses a string that contains comma-separated values
|
||||
// specifying hosts that should use the bypass proxy. Each value is either an
|
||||
// IP address, a CIDR range, a zone (*.example.com) or a host name
|
||||
// (localhost). A best effort is made to parse the string and errors are
|
||||
// ignored.
|
||||
func (p *proxy_PerHost) AddFromString(s string) {
|
||||
hosts := strings.Split(s, ",")
|
||||
for _, host := range hosts {
|
||||
host = strings.TrimSpace(host)
|
||||
if len(host) == 0 {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(host, "/") {
|
||||
// We assume that it's a CIDR address like 127.0.0.0/8
|
||||
if _, net, err := net.ParseCIDR(host); err == nil {
|
||||
p.AddNetwork(net)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
p.AddIP(ip)
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(host, "*.") {
|
||||
p.AddZone(host[1:])
|
||||
continue
|
||||
}
|
||||
p.AddHost(host)
|
||||
}
|
||||
}
|
||||
|
||||
// AddIP specifies an IP address that will use the bypass proxy. Note that
|
||||
// this will only take effect if a literal IP address is dialed. A connection
|
||||
// to a named host will never match an IP.
|
||||
func (p *proxy_PerHost) AddIP(ip net.IP) {
|
||||
p.bypassIPs = append(p.bypassIPs, ip)
|
||||
}
|
||||
|
||||
// AddNetwork specifies an IP range that will use the bypass proxy. Note that
|
||||
// this will only take effect if a literal IP address is dialed. A connection
|
||||
// to a named host will never match.
|
||||
func (p *proxy_PerHost) AddNetwork(net *net.IPNet) {
|
||||
p.bypassNetworks = append(p.bypassNetworks, net)
|
||||
}
|
||||
|
||||
// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
|
||||
// "example.com" matches "example.com" and all of its subdomains.
|
||||
func (p *proxy_PerHost) AddZone(zone string) {
|
||||
if strings.HasSuffix(zone, ".") {
|
||||
zone = zone[:len(zone)-1]
|
||||
}
|
||||
if !strings.HasPrefix(zone, ".") {
|
||||
zone = "." + zone
|
||||
}
|
||||
p.bypassZones = append(p.bypassZones, zone)
|
||||
}
|
||||
|
||||
// AddHost specifies a host name that will use the bypass proxy.
|
||||
func (p *proxy_PerHost) AddHost(host string) {
|
||||
if strings.HasSuffix(host, ".") {
|
||||
host = host[:len(host)-1]
|
||||
}
|
||||
p.bypassHosts = append(p.bypassHosts, host)
|
||||
}
|
||||
|
||||
// A Dialer is a means to establish a connection.
|
||||
type proxy_Dialer interface {
|
||||
// Dial connects to the given address via the proxy.
|
||||
Dial(network, addr string) (c net.Conn, err error)
|
||||
}
|
||||
|
||||
// Auth contains authentication parameters that specific Dialers may require.
|
||||
type proxy_Auth struct {
|
||||
User, Password string
|
||||
}
|
||||
|
||||
// FromEnvironment returns the dialer specified by the proxy related variables in
|
||||
// the environment.
|
||||
func proxy_FromEnvironment() proxy_Dialer {
|
||||
allProxy := proxy_allProxyEnv.Get()
|
||||
if len(allProxy) == 0 {
|
||||
return proxy_Direct
|
||||
}
|
||||
|
||||
proxyURL, err := url.Parse(allProxy)
|
||||
if err != nil {
|
||||
return proxy_Direct
|
||||
}
|
||||
proxy, err := proxy_FromURL(proxyURL, proxy_Direct)
|
||||
if err != nil {
|
||||
return proxy_Direct
|
||||
}
|
||||
|
||||
noProxy := proxy_noProxyEnv.Get()
|
||||
if len(noProxy) == 0 {
|
||||
return proxy
|
||||
}
|
||||
|
||||
perHost := proxy_NewPerHost(proxy, proxy_Direct)
|
||||
perHost.AddFromString(noProxy)
|
||||
return perHost
|
||||
}
|
||||
|
||||
// proxySchemes is a map from URL schemes to a function that creates a Dialer
|
||||
// from a URL with such a scheme.
|
||||
var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)
|
||||
|
||||
// RegisterDialerType takes a URL scheme and a function to generate Dialers from
|
||||
// a URL with that scheme and a forwarding Dialer. Registered schemes are used
|
||||
// by FromURL.
|
||||
func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) {
|
||||
if proxy_proxySchemes == nil {
|
||||
proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error))
|
||||
}
|
||||
proxy_proxySchemes[scheme] = f
|
||||
}
|
||||
|
||||
// FromURL returns a Dialer given a URL specification and an underlying
|
||||
// Dialer for it to make network requests.
|
||||
func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) {
|
||||
var auth *proxy_Auth
|
||||
if u.User != nil {
|
||||
auth = new(proxy_Auth)
|
||||
auth.User = u.User.Username()
|
||||
if p, ok := u.User.Password(); ok {
|
||||
auth.Password = p
|
||||
}
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "socks5":
|
||||
return proxy_SOCKS5("tcp", u.Host, auth, forward)
|
||||
}
|
||||
|
||||
// If the scheme doesn't match any of the built-in schemes, see if it
|
||||
// was registered by another package.
|
||||
if proxy_proxySchemes != nil {
|
||||
if f, ok := proxy_proxySchemes[u.Scheme]; ok {
|
||||
return f(u, forward)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
|
||||
}
|
||||
|
||||
var (
|
||||
proxy_allProxyEnv = &proxy_envOnce{
|
||||
names: []string{"ALL_PROXY", "all_proxy"},
|
||||
}
|
||||
proxy_noProxyEnv = &proxy_envOnce{
|
||||
names: []string{"NO_PROXY", "no_proxy"},
|
||||
}
|
||||
)
|
||||
|
||||
// envOnce looks up an environment variable (optionally by multiple
|
||||
// names) once. It mitigates expensive lookups on some platforms
|
||||
// (e.g. Windows).
|
||||
// (Borrowed from net/http/transport.go)
|
||||
type proxy_envOnce struct {
|
||||
names []string
|
||||
once sync.Once
|
||||
val string
|
||||
}
|
||||
|
||||
func (e *proxy_envOnce) Get() string {
|
||||
e.once.Do(e.init)
|
||||
return e.val
|
||||
}
|
||||
|
||||
func (e *proxy_envOnce) init() {
|
||||
for _, n := range e.names {
|
||||
e.val = os.Getenv(n)
|
||||
if e.val != "" {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address
|
||||
// with an optional username and password. See RFC 1928 and RFC 1929.
|
||||
func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) {
|
||||
s := &proxy_socks5{
|
||||
network: network,
|
||||
addr: addr,
|
||||
forward: forward,
|
||||
}
|
||||
if auth != nil {
|
||||
s.user = auth.User
|
||||
s.password = auth.Password
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
type proxy_socks5 struct {
|
||||
user, password string
|
||||
network, addr string
|
||||
forward proxy_Dialer
|
||||
}
|
||||
|
||||
const proxy_socks5Version = 5
|
||||
|
||||
const (
|
||||
proxy_socks5AuthNone = 0
|
||||
proxy_socks5AuthPassword = 2
|
||||
)
|
||||
|
||||
const proxy_socks5Connect = 1
|
||||
|
||||
const (
|
||||
proxy_socks5IP4 = 1
|
||||
proxy_socks5Domain = 3
|
||||
proxy_socks5IP6 = 4
|
||||
)
|
||||
|
||||
var proxy_socks5Errors = []string{
|
||||
"",
|
||||
"general failure",
|
||||
"connection forbidden",
|
||||
"network unreachable",
|
||||
"host unreachable",
|
||||
"connection refused",
|
||||
"TTL expired",
|
||||
"command not supported",
|
||||
"address type not supported",
|
||||
}
|
||||
|
||||
// Dial connects to the address addr on the given network via the SOCKS5 proxy.
|
||||
func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) {
|
||||
switch network {
|
||||
case "tcp", "tcp6", "tcp4":
|
||||
default:
|
||||
return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network)
|
||||
}
|
||||
|
||||
conn, err := s.forward.Dial(s.network, s.addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.connect(conn, addr); err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// connect takes an existing connection to a socks5 proxy server,
|
||||
// and commands the server to extend that connection to target,
|
||||
// which must be a canonical address with a host and port.
|
||||
func (s *proxy_socks5) connect(conn net.Conn, target string) error {
|
||||
host, portStr, err := net.SplitHostPort(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return errors.New("proxy: failed to parse port number: " + portStr)
|
||||
}
|
||||
if port < 1 || port > 0xffff {
|
||||
return errors.New("proxy: port number out of range: " + portStr)
|
||||
}
|
||||
|
||||
// the size here is just an estimate
|
||||
buf := make([]byte, 0, 6+len(host))
|
||||
|
||||
buf = append(buf, proxy_socks5Version)
|
||||
if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {
|
||||
buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword)
|
||||
} else {
|
||||
buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone)
|
||||
}
|
||||
|
||||
if _, err := conn.Write(buf); err != nil {
|
||||
return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
|
||||
return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
if buf[0] != 5 {
|
||||
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0])))
|
||||
}
|
||||
if buf[1] == 0xff {
|
||||
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication")
|
||||
}
|
||||
|
||||
// See RFC 1929
|
||||
if buf[1] == proxy_socks5AuthPassword {
|
||||
buf = buf[:0]
|
||||
buf = append(buf, 1 /* password protocol version */)
|
||||
buf = append(buf, uint8(len(s.user)))
|
||||
buf = append(buf, s.user...)
|
||||
buf = append(buf, uint8(len(s.password)))
|
||||
buf = append(buf, s.password...)
|
||||
|
||||
if _, err := conn.Write(buf); err != nil {
|
||||
return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
|
||||
return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
if buf[1] != 0 {
|
||||
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password")
|
||||
}
|
||||
}
|
||||
|
||||
buf = buf[:0]
|
||||
buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */)
|
||||
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
buf = append(buf, proxy_socks5IP4)
|
||||
ip = ip4
|
||||
} else {
|
||||
buf = append(buf, proxy_socks5IP6)
|
||||
}
|
||||
buf = append(buf, ip...)
|
||||
} else {
|
||||
if len(host) > 255 {
|
||||
return errors.New("proxy: destination host name too long: " + host)
|
||||
}
|
||||
buf = append(buf, proxy_socks5Domain)
|
||||
buf = append(buf, byte(len(host)))
|
||||
buf = append(buf, host...)
|
||||
}
|
||||
buf = append(buf, byte(port>>8), byte(port))
|
||||
|
||||
if _, err := conn.Write(buf); err != nil {
|
||||
return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(conn, buf[:4]); err != nil {
|
||||
return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
failure := "unknown error"
|
||||
if int(buf[1]) < len(proxy_socks5Errors) {
|
||||
failure = proxy_socks5Errors[buf[1]]
|
||||
}
|
||||
|
||||
if len(failure) > 0 {
|
||||
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure)
|
||||
}
|
||||
|
||||
bytesToDiscard := 0
|
||||
switch buf[3] {
|
||||
case proxy_socks5IP4:
|
||||
bytesToDiscard = net.IPv4len
|
||||
case proxy_socks5IP6:
|
||||
bytesToDiscard = net.IPv6len
|
||||
case proxy_socks5Domain:
|
||||
_, err := io.ReadFull(conn, buf[:1])
|
||||
if err != nil {
|
||||
return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
bytesToDiscard = int(buf[0])
|
||||
default:
|
||||
return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr)
|
||||
}
|
||||
|
||||
if cap(buf) < bytesToDiscard {
|
||||
buf = make([]byte, bytesToDiscard)
|
||||
} else {
|
||||
buf = buf[:bytesToDiscard]
|
||||
}
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
// Also need to discard the port number
|
||||
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
|
||||
return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
897
build/manifest/vendor/github.com/mattermost/mattermost-server/LICENSE.txt
generated
vendored
897
build/manifest/vendor/github.com/mattermost/mattermost-server/LICENSE.txt
generated
vendored
|
@ -1,897 +0,0 @@
|
|||
Mattermost Licensing
|
||||
|
||||
SOFTWARE LICENSING
|
||||
|
||||
You are licensed to use compiled versions of the Mattermost platform produced by Mattermost, Inc. under an MIT LICENSE
|
||||
|
||||
- See MIT-COMPILED-LICENSE.md included in compiled versions for details
|
||||
|
||||
You may be licensed to use source code to create compiled versions not produced by Mattermost, Inc. in one of two ways:
|
||||
|
||||
1. Under the Free Software Foundation’s GNU AGPL v.3.0, subject to the exceptions outlined in this policy; or
|
||||
2. Under a commercial license available from Mattermost, Inc. by contacting commercial@mattermost.com
|
||||
|
||||
You are licensed to use the source code in Admin Tools and Configuration Files (templates/, config/, model/,
|
||||
plugin/ and all subdirectories thereof) under the Apache License v2.0.
|
||||
|
||||
We promise that we will not enforce the copyleft provisions in AGPL v3.0 against you if your application (a) does not
|
||||
link to the Mattermost Platform directly, but exclusively uses the Mattermost Admin Tools and Configuration Files, and
|
||||
(b) you have not modified, added to or adapted the source code of Mattermost in a way that results in the creation of
|
||||
a “modified version” or “work based on” Mattermost as these terms are defined in the AGPL v3.0 license.
|
||||
|
||||
MATTERMOST TRADEMARK GUIDELINES
|
||||
|
||||
Your use of the mark Mattermost is subject to Mattermost, Inc's prior written approval and our organization’s Trademark
|
||||
Standards of Use at http://www.mattermost.org/trademark-standards-of-use/. For trademark approval or any questions
|
||||
you have about using these trademarks, please email trademark@mattermost.com
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The software is released under the terms of the GNU Affero General Public
|
||||
License, version 3.
|
||||
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
3791
build/manifest/vendor/github.com/mattermost/mattermost-server/NOTICE.txt
generated
vendored
3791
build/manifest/vendor/github.com/mattermost/mattermost-server/NOTICE.txt
generated
vendored
File diff suppressed because it is too large
Load diff
50
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/default.go
generated
vendored
50
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/default.go
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// defaultLog manually encodes the log to STDOUT, providing a basic, default logging implementation
|
||||
// before mlog is fully configured.
|
||||
func defaultLog(level, msg string, fields ...Field) {
|
||||
log := struct {
|
||||
Level string `json:"level"`
|
||||
Message string `json:"msg"`
|
||||
Fields []Field `json:"fields,omitempty"`
|
||||
}{
|
||||
level,
|
||||
msg,
|
||||
fields,
|
||||
}
|
||||
|
||||
if b, err := json.Marshal(log); err != nil {
|
||||
fmt.Printf(`{"level":"error","msg":"failed to encode log message"}%s`, "\n")
|
||||
} else {
|
||||
fmt.Printf("%s\n", b)
|
||||
}
|
||||
}
|
||||
|
||||
func defaultDebugLog(msg string, fields ...Field) {
|
||||
defaultLog("debug", msg, fields...)
|
||||
}
|
||||
|
||||
func defaultInfoLog(msg string, fields ...Field) {
|
||||
defaultLog("info", msg, fields...)
|
||||
}
|
||||
|
||||
func defaultWarnLog(msg string, fields ...Field) {
|
||||
defaultLog("warn", msg, fields...)
|
||||
}
|
||||
|
||||
func defaultErrorLog(msg string, fields ...Field) {
|
||||
defaultLog("error", msg, fields...)
|
||||
}
|
||||
|
||||
func defaultCriticalLog(msg string, fields ...Field) {
|
||||
// We map critical to error in zap, so be consistent.
|
||||
defaultLog("error", msg, fields...)
|
||||
}
|
44
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/global.go
generated
vendored
44
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/global.go
generated
vendored
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
var globalLogger *Logger
|
||||
|
||||
func InitGlobalLogger(logger *Logger) {
|
||||
glob := *logger
|
||||
glob.zap = glob.zap.WithOptions(zap.AddCallerSkip(1))
|
||||
globalLogger = &glob
|
||||
Debug = globalLogger.Debug
|
||||
Info = globalLogger.Info
|
||||
Warn = globalLogger.Warn
|
||||
Error = globalLogger.Error
|
||||
Critical = globalLogger.Critical
|
||||
}
|
||||
|
||||
func RedirectStdLog(logger *Logger) {
|
||||
zap.RedirectStdLogAt(logger.zap.With(zap.String("source", "stdlog")).WithOptions(zap.AddCallerSkip(-2)), zapcore.ErrorLevel)
|
||||
}
|
||||
|
||||
type LogFunc func(string, ...Field)
|
||||
|
||||
// DON'T USE THIS Modify the level on the app logger
|
||||
func GloballyDisableDebugLogForTest() {
|
||||
globalLogger.consoleLevel.SetLevel(zapcore.ErrorLevel)
|
||||
}
|
||||
|
||||
// DON'T USE THIS Modify the level on the app logger
|
||||
func GloballyEnableDebugLogForTest() {
|
||||
globalLogger.consoleLevel.SetLevel(zapcore.DebugLevel)
|
||||
}
|
||||
|
||||
var Debug LogFunc = defaultDebugLog
|
||||
var Info LogFunc = defaultInfoLog
|
||||
var Warn LogFunc = defaultWarnLog
|
||||
var Error LogFunc = defaultErrorLog
|
||||
var Critical LogFunc = defaultCriticalLog
|
173
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/log.go
generated
vendored
173
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/log.go
generated
vendored
|
@ -1,173 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
// Very verbose messages for debugging specific issues
|
||||
LevelDebug = "debug"
|
||||
// Default log level, informational
|
||||
LevelInfo = "info"
|
||||
// Warnings are messages about possible issues
|
||||
LevelWarn = "warn"
|
||||
// Errors are messages about things we know are problems
|
||||
LevelError = "error"
|
||||
)
|
||||
|
||||
// Type and function aliases from zap to limit the libraries scope into MM code
|
||||
type Field = zapcore.Field
|
||||
|
||||
var Int64 = zap.Int64
|
||||
var Int = zap.Int
|
||||
var Uint32 = zap.Uint32
|
||||
var String = zap.String
|
||||
var Any = zap.Any
|
||||
var Err = zap.Error
|
||||
var Bool = zap.Bool
|
||||
|
||||
type LoggerConfiguration struct {
|
||||
EnableConsole bool
|
||||
ConsoleJson bool
|
||||
ConsoleLevel string
|
||||
EnableFile bool
|
||||
FileJson bool
|
||||
FileLevel string
|
||||
FileLocation string
|
||||
}
|
||||
|
||||
type Logger struct {
|
||||
zap *zap.Logger
|
||||
consoleLevel zap.AtomicLevel
|
||||
fileLevel zap.AtomicLevel
|
||||
}
|
||||
|
||||
func getZapLevel(level string) zapcore.Level {
|
||||
switch level {
|
||||
case LevelInfo:
|
||||
return zapcore.InfoLevel
|
||||
case LevelWarn:
|
||||
return zapcore.WarnLevel
|
||||
case LevelDebug:
|
||||
return zapcore.DebugLevel
|
||||
case LevelError:
|
||||
return zapcore.ErrorLevel
|
||||
default:
|
||||
return zapcore.InfoLevel
|
||||
}
|
||||
}
|
||||
|
||||
func makeEncoder(json bool) zapcore.Encoder {
|
||||
encoderConfig := zap.NewProductionEncoderConfig()
|
||||
if json {
|
||||
return zapcore.NewJSONEncoder(encoderConfig)
|
||||
}
|
||||
|
||||
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
return zapcore.NewConsoleEncoder(encoderConfig)
|
||||
}
|
||||
|
||||
func NewLogger(config *LoggerConfiguration) *Logger {
|
||||
cores := []zapcore.Core{}
|
||||
logger := &Logger{
|
||||
consoleLevel: zap.NewAtomicLevelAt(getZapLevel(config.ConsoleLevel)),
|
||||
fileLevel: zap.NewAtomicLevelAt(getZapLevel(config.FileLevel)),
|
||||
}
|
||||
|
||||
if config.EnableConsole {
|
||||
writer := zapcore.Lock(os.Stdout)
|
||||
core := zapcore.NewCore(makeEncoder(config.ConsoleJson), writer, logger.consoleLevel)
|
||||
cores = append(cores, core)
|
||||
}
|
||||
|
||||
if config.EnableFile {
|
||||
writer := zapcore.AddSync(&lumberjack.Logger{
|
||||
Filename: config.FileLocation,
|
||||
MaxSize: 100,
|
||||
Compress: true,
|
||||
})
|
||||
core := zapcore.NewCore(makeEncoder(config.FileJson), writer, logger.fileLevel)
|
||||
cores = append(cores, core)
|
||||
}
|
||||
|
||||
combinedCore := zapcore.NewTee(cores...)
|
||||
|
||||
logger.zap = zap.New(combinedCore,
|
||||
zap.AddCallerSkip(1),
|
||||
zap.AddCaller(),
|
||||
)
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
func (l *Logger) ChangeLevels(config *LoggerConfiguration) {
|
||||
l.consoleLevel.SetLevel(getZapLevel(config.ConsoleLevel))
|
||||
l.fileLevel.SetLevel(getZapLevel(config.FileLevel))
|
||||
}
|
||||
|
||||
func (l *Logger) SetConsoleLevel(level string) {
|
||||
l.consoleLevel.SetLevel(getZapLevel(level))
|
||||
}
|
||||
|
||||
func (l *Logger) With(fields ...Field) *Logger {
|
||||
newlogger := *l
|
||||
newlogger.zap = newlogger.zap.With(fields...)
|
||||
return &newlogger
|
||||
}
|
||||
|
||||
func (l *Logger) StdLog(fields ...Field) *log.Logger {
|
||||
return zap.NewStdLog(l.With(fields...).zap.WithOptions(getStdLogOption()))
|
||||
}
|
||||
|
||||
// StdLogWriter returns a writer that can be hooked up to the output of a golang standard logger
|
||||
// anything written will be interpreted as log entries accordingly
|
||||
func (l *Logger) StdLogWriter() io.Writer {
|
||||
newLogger := *l
|
||||
newLogger.zap = newLogger.zap.WithOptions(zap.AddCallerSkip(4), getStdLogOption())
|
||||
f := newLogger.Info
|
||||
return &loggerWriter{f}
|
||||
}
|
||||
|
||||
func (l *Logger) WithCallerSkip(skip int) *Logger {
|
||||
newlogger := *l
|
||||
newlogger.zap = newlogger.zap.WithOptions(zap.AddCallerSkip(skip))
|
||||
return &newlogger
|
||||
}
|
||||
|
||||
// Made for the plugin interface, wraps mlog in a simpler interface
|
||||
// at the cost of performance
|
||||
func (l *Logger) Sugar() *SugarLogger {
|
||||
return &SugarLogger{
|
||||
wrappedLogger: l,
|
||||
zapSugar: l.zap.Sugar(),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Debug(message string, fields ...Field) {
|
||||
l.zap.Debug(message, fields...)
|
||||
}
|
||||
|
||||
func (l *Logger) Info(message string, fields ...Field) {
|
||||
l.zap.Info(message, fields...)
|
||||
}
|
||||
|
||||
func (l *Logger) Warn(message string, fields ...Field) {
|
||||
l.zap.Warn(message, fields...)
|
||||
}
|
||||
|
||||
func (l *Logger) Error(message string, fields ...Field) {
|
||||
l.zap.Error(message, fields...)
|
||||
}
|
||||
|
||||
func (l *Logger) Critical(message string, fields ...Field) {
|
||||
l.zap.Error(message, fields...)
|
||||
}
|
87
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/stdlog.go
generated
vendored
87
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/stdlog.go
generated
vendored
|
@ -1,87 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// Implementation of zapcore.Core to interpret log messages from a standard logger
|
||||
// and translate the levels to zapcore levels.
|
||||
type stdLogLevelInterpreterCore struct {
|
||||
wrappedCore zapcore.Core
|
||||
}
|
||||
|
||||
func stdLogInterpretZapEntry(entry zapcore.Entry) zapcore.Entry {
|
||||
message := entry.Message
|
||||
if strings.Index(message, "[DEBUG]") == 0 {
|
||||
entry.Level = zapcore.DebugLevel
|
||||
entry.Message = message[7:]
|
||||
} else if strings.Index(message, "[DEBG]") == 0 {
|
||||
entry.Level = zapcore.DebugLevel
|
||||
entry.Message = message[6:]
|
||||
} else if strings.Index(message, "[WARN]") == 0 {
|
||||
entry.Level = zapcore.WarnLevel
|
||||
entry.Message = message[6:]
|
||||
} else if strings.Index(message, "[ERROR]") == 0 {
|
||||
entry.Level = zapcore.ErrorLevel
|
||||
entry.Message = message[7:]
|
||||
} else if strings.Index(message, "[EROR]") == 0 {
|
||||
entry.Level = zapcore.ErrorLevel
|
||||
entry.Message = message[6:]
|
||||
} else if strings.Index(message, "[ERR]") == 0 {
|
||||
entry.Level = zapcore.ErrorLevel
|
||||
entry.Message = message[5:]
|
||||
} else if strings.Index(message, "[INFO]") == 0 {
|
||||
entry.Level = zapcore.InfoLevel
|
||||
entry.Message = message[6:]
|
||||
}
|
||||
return entry
|
||||
}
|
||||
|
||||
func (s *stdLogLevelInterpreterCore) Enabled(lvl zapcore.Level) bool {
|
||||
return s.wrappedCore.Enabled(lvl)
|
||||
}
|
||||
|
||||
func (s *stdLogLevelInterpreterCore) With(fields []zapcore.Field) zapcore.Core {
|
||||
return s.wrappedCore.With(fields)
|
||||
}
|
||||
|
||||
func (s *stdLogLevelInterpreterCore) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry) *zapcore.CheckedEntry {
|
||||
entry = stdLogInterpretZapEntry(entry)
|
||||
return s.wrappedCore.Check(entry, checkedEntry)
|
||||
}
|
||||
|
||||
func (s *stdLogLevelInterpreterCore) Write(entry zapcore.Entry, fields []zapcore.Field) error {
|
||||
entry = stdLogInterpretZapEntry(entry)
|
||||
return s.wrappedCore.Write(entry, fields)
|
||||
}
|
||||
|
||||
func (s *stdLogLevelInterpreterCore) Sync() error {
|
||||
return s.wrappedCore.Sync()
|
||||
}
|
||||
|
||||
func getStdLogOption() zap.Option {
|
||||
return zap.WrapCore(
|
||||
func(core zapcore.Core) zapcore.Core {
|
||||
return &stdLogLevelInterpreterCore{core}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type loggerWriter struct {
|
||||
logFunc func(msg string, fields ...Field)
|
||||
}
|
||||
|
||||
func (l *loggerWriter) Write(p []byte) (int, error) {
|
||||
trimmed := string(bytes.TrimSpace(p))
|
||||
for _, line := range strings.Split(trimmed, "\n") {
|
||||
l.logFunc(string(line))
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
28
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/sugar.go
generated
vendored
28
build/manifest/vendor/github.com/mattermost/mattermost-server/mlog/sugar.go
generated
vendored
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mlog
|
||||
|
||||
import "go.uber.org/zap"
|
||||
|
||||
// Made for the plugin interface, use the regular logger for other uses
|
||||
type SugarLogger struct {
|
||||
wrappedLogger *Logger
|
||||
zapSugar *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func (l *SugarLogger) Debug(msg string, keyValuePairs ...interface{}) {
|
||||
l.zapSugar.Debugw(msg, keyValuePairs...)
|
||||
}
|
||||
|
||||
func (l *SugarLogger) Info(msg string, keyValuePairs ...interface{}) {
|
||||
l.zapSugar.Infow(msg, keyValuePairs...)
|
||||
}
|
||||
|
||||
func (l *SugarLogger) Error(msg string, keyValuePairs ...interface{}) {
|
||||
l.zapSugar.Errorw(msg, keyValuePairs...)
|
||||
}
|
||||
|
||||
func (l *SugarLogger) Warn(msg string, keyValuePairs ...interface{}) {
|
||||
l.zapSugar.Warnw(msg, keyValuePairs...)
|
||||
}
|
96
build/manifest/vendor/github.com/mattermost/mattermost-server/model/access.go
generated
vendored
96
build/manifest/vendor/github.com/mattermost/mattermost-server/model/access.go
generated
vendored
|
@ -1,96 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
ACCESS_TOKEN_GRANT_TYPE = "authorization_code"
|
||||
ACCESS_TOKEN_TYPE = "bearer"
|
||||
REFRESH_TOKEN_GRANT_TYPE = "refresh_token"
|
||||
)
|
||||
|
||||
type AccessData struct {
|
||||
ClientId string `json:"client_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Token string `json:"token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
RedirectUri string `json:"redirect_uri"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
||||
type AccessResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
ExpiresIn int32 `json:"expires_in"`
|
||||
Scope string `json:"scope"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
// IsValid validates the AccessData and returns an error if it isn't configured
|
||||
// correctly.
|
||||
func (ad *AccessData) IsValid() *AppError {
|
||||
|
||||
if len(ad.ClientId) == 0 || len(ad.ClientId) > 26 {
|
||||
return NewAppError("AccessData.IsValid", "model.access.is_valid.client_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.UserId) == 0 || len(ad.UserId) > 26 {
|
||||
return NewAppError("AccessData.IsValid", "model.access.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.Token) != 26 {
|
||||
return NewAppError("AccessData.IsValid", "model.access.is_valid.access_token.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.RefreshToken) > 26 {
|
||||
return NewAppError("AccessData.IsValid", "model.access.is_valid.refresh_token.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.RedirectUri) == 0 || len(ad.RedirectUri) > 256 || !IsValidHttpUrl(ad.RedirectUri) {
|
||||
return NewAppError("AccessData.IsValid", "model.access.is_valid.redirect_uri.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (me *AccessData) IsExpired() bool {
|
||||
|
||||
if me.ExpiresAt <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if GetMillis() > me.ExpiresAt {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (ad *AccessData) ToJson() string {
|
||||
b, _ := json.Marshal(ad)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func AccessDataFromJson(data io.Reader) *AccessData {
|
||||
var ad *AccessData
|
||||
json.NewDecoder(data).Decode(&ad)
|
||||
return ad
|
||||
}
|
||||
|
||||
func (ar *AccessResponse) ToJson() string {
|
||||
b, _ := json.Marshal(ar)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func AccessResponseFromJson(data io.Reader) *AccessResponse {
|
||||
var ar *AccessResponse
|
||||
json.NewDecoder(data).Decode(&ar)
|
||||
return ar
|
||||
}
|
41
build/manifest/vendor/github.com/mattermost/mattermost-server/model/analytics_row.go
generated
vendored
41
build/manifest/vendor/github.com/mattermost/mattermost-server/model/analytics_row.go
generated
vendored
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type AnalyticsRow struct {
|
||||
Name string `json:"name"`
|
||||
Value float64 `json:"value"`
|
||||
}
|
||||
|
||||
type AnalyticsRows []*AnalyticsRow
|
||||
|
||||
func (me *AnalyticsRow) ToJson() string {
|
||||
b, _ := json.Marshal(me)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func AnalyticsRowFromJson(data io.Reader) *AnalyticsRow {
|
||||
var me *AnalyticsRow
|
||||
json.NewDecoder(data).Decode(&me)
|
||||
return me
|
||||
}
|
||||
|
||||
func (me AnalyticsRows) ToJson() string {
|
||||
if b, err := json.Marshal(me); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func AnalyticsRowsFromJson(data io.Reader) AnalyticsRows {
|
||||
var me AnalyticsRows
|
||||
json.NewDecoder(data).Decode(&me)
|
||||
return me
|
||||
}
|
30
build/manifest/vendor/github.com/mattermost/mattermost-server/model/audit.go
generated
vendored
30
build/manifest/vendor/github.com/mattermost/mattermost-server/model/audit.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type Audit struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UserId string `json:"user_id"`
|
||||
Action string `json:"action"`
|
||||
ExtraInfo string `json:"extra_info"`
|
||||
IpAddress string `json:"ip_address"`
|
||||
SessionId string `json:"session_id"`
|
||||
}
|
||||
|
||||
func (o *Audit) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func AuditFromJson(data io.Reader) *Audit {
|
||||
var o *Audit
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
34
build/manifest/vendor/github.com/mattermost/mattermost-server/model/audits.go
generated
vendored
34
build/manifest/vendor/github.com/mattermost/mattermost-server/model/audits.go
generated
vendored
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type Audits []Audit
|
||||
|
||||
func (o Audits) Etag() string {
|
||||
if len(o) > 0 {
|
||||
// the first in the list is always the most current
|
||||
return Etag(o[0].CreateAt)
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (o Audits) ToJson() string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func AuditsFromJson(data io.Reader) Audits {
|
||||
var o Audits
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
142
build/manifest/vendor/github.com/mattermost/mattermost-server/model/authorize.go
generated
vendored
142
build/manifest/vendor/github.com/mattermost/mattermost-server/model/authorize.go
generated
vendored
|
@ -1,142 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
AUTHCODE_EXPIRE_TIME = 60 * 10 // 10 minutes
|
||||
AUTHCODE_RESPONSE_TYPE = "code"
|
||||
IMPLICIT_RESPONSE_TYPE = "token"
|
||||
DEFAULT_SCOPE = "user"
|
||||
)
|
||||
|
||||
type AuthData struct {
|
||||
ClientId string `json:"client_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Code string `json:"code"`
|
||||
ExpiresIn int32 `json:"expires_in"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
RedirectUri string `json:"redirect_uri"`
|
||||
State string `json:"state"`
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
||||
type AuthorizeRequest struct {
|
||||
ResponseType string `json:"response_type"`
|
||||
ClientId string `json:"client_id"`
|
||||
RedirectUri string `json:"redirect_uri"`
|
||||
Scope string `json:"scope"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// IsValid validates the AuthData and returns an error if it isn't configured
|
||||
// correctly.
|
||||
func (ad *AuthData) IsValid() *AppError {
|
||||
|
||||
if len(ad.ClientId) != 26 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.client_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.UserId) != 26 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.Code) == 0 || len(ad.Code) > 128 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.auth_code.app_error", nil, "client_id="+ad.ClientId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if ad.ExpiresIn == 0 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.expires.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if ad.CreateAt <= 0 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.create_at.app_error", nil, "client_id="+ad.ClientId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.RedirectUri) > 256 || !IsValidHttpUrl(ad.RedirectUri) {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.redirect_uri.app_error", nil, "client_id="+ad.ClientId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.State) > 1024 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.state.app_error", nil, "client_id="+ad.ClientId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ad.Scope) > 128 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.scope.app_error", nil, "client_id="+ad.ClientId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsValid validates the AuthorizeRequest and returns an error if it isn't configured
|
||||
// correctly.
|
||||
func (ar *AuthorizeRequest) IsValid() *AppError {
|
||||
|
||||
if len(ar.ClientId) != 26 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.client_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ar.ResponseType) == 0 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.response_type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ar.RedirectUri) == 0 || len(ar.RedirectUri) > 256 || !IsValidHttpUrl(ar.RedirectUri) {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.redirect_uri.app_error", nil, "client_id="+ar.ClientId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ar.State) > 1024 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.state.app_error", nil, "client_id="+ar.ClientId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(ar.Scope) > 128 {
|
||||
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.scope.app_error", nil, "client_id="+ar.ClientId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ad *AuthData) PreSave() {
|
||||
if ad.ExpiresIn == 0 {
|
||||
ad.ExpiresIn = AUTHCODE_EXPIRE_TIME
|
||||
}
|
||||
|
||||
if ad.CreateAt == 0 {
|
||||
ad.CreateAt = GetMillis()
|
||||
}
|
||||
|
||||
if len(ad.Scope) == 0 {
|
||||
ad.Scope = DEFAULT_SCOPE
|
||||
}
|
||||
}
|
||||
|
||||
func (ad *AuthData) ToJson() string {
|
||||
b, _ := json.Marshal(ad)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func AuthDataFromJson(data io.Reader) *AuthData {
|
||||
var ad *AuthData
|
||||
json.NewDecoder(data).Decode(&ad)
|
||||
return ad
|
||||
}
|
||||
|
||||
func (ar *AuthorizeRequest) ToJson() string {
|
||||
b, _ := json.Marshal(ar)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func AuthorizeRequestFromJson(data io.Reader) *AuthorizeRequest {
|
||||
var ar *AuthorizeRequest
|
||||
json.NewDecoder(data).Decode(&ar)
|
||||
return ar
|
||||
}
|
||||
|
||||
func (ad *AuthData) IsExpired() bool {
|
||||
return GetMillis() > ad.CreateAt+int64(ad.ExpiresIn*1000)
|
||||
}
|
9
build/manifest/vendor/github.com/mattermost/mattermost-server/model/builtin.go
generated
vendored
9
build/manifest/vendor/github.com/mattermost/mattermost-server/model/builtin.go
generated
vendored
|
@ -1,9 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
func NewBool(b bool) *bool { return &b }
|
||||
func NewInt(n int) *int { return &n }
|
||||
func NewInt64(n int64) *int64 { return &n }
|
||||
func NewString(s string) *string { return &s }
|
32
build/manifest/vendor/github.com/mattermost/mattermost-server/model/bundle_info.go
generated
vendored
32
build/manifest/vendor/github.com/mattermost/mattermost-server/model/bundle_info.go
generated
vendored
|
@ -1,32 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import "github.com/mattermost/mattermost-server/mlog"
|
||||
|
||||
type BundleInfo struct {
|
||||
Path string
|
||||
|
||||
Manifest *Manifest
|
||||
ManifestPath string
|
||||
ManifestError error
|
||||
}
|
||||
|
||||
func (b *BundleInfo) WrapLogger(logger *mlog.Logger) *mlog.Logger {
|
||||
if b.Manifest != nil {
|
||||
return logger.With(mlog.String("plugin_id", b.Manifest.Id))
|
||||
}
|
||||
return logger.With(mlog.String("plugin_path", b.Path))
|
||||
}
|
||||
|
||||
// Returns bundle info for the given path. The return value is never nil.
|
||||
func BundleInfoForPath(path string) *BundleInfo {
|
||||
m, mpath, err := FindManifest(path)
|
||||
return &BundleInfo{
|
||||
Path: path,
|
||||
Manifest: m,
|
||||
ManifestPath: mpath,
|
||||
ManifestError: err,
|
||||
}
|
||||
}
|
225
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel.go
generated
vendored
225
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel.go
generated
vendored
|
@ -1,225 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
CHANNEL_OPEN = "O"
|
||||
CHANNEL_PRIVATE = "P"
|
||||
CHANNEL_DIRECT = "D"
|
||||
CHANNEL_GROUP = "G"
|
||||
CHANNEL_GROUP_MAX_USERS = 8
|
||||
CHANNEL_GROUP_MIN_USERS = 3
|
||||
DEFAULT_CHANNEL = "town-square"
|
||||
CHANNEL_DISPLAY_NAME_MAX_RUNES = 64
|
||||
CHANNEL_NAME_MIN_LENGTH = 2
|
||||
CHANNEL_NAME_MAX_LENGTH = 64
|
||||
CHANNEL_NAME_UI_MAX_LENGTH = 22
|
||||
CHANNEL_HEADER_MAX_RUNES = 1024
|
||||
CHANNEL_PURPOSE_MAX_RUNES = 250
|
||||
CHANNEL_CACHE_SIZE = 25000
|
||||
|
||||
CHANNEL_SORT_BY_USERNAME = "username"
|
||||
CHANNEL_SORT_BY_STATUS = "status"
|
||||
)
|
||||
|
||||
type Channel struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
TeamId string `json:"team_id"`
|
||||
Type string `json:"type"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
Header string `json:"header"`
|
||||
Purpose string `json:"purpose"`
|
||||
LastPostAt int64 `json:"last_post_at"`
|
||||
TotalMsgCount int64 `json:"total_msg_count"`
|
||||
ExtraUpdateAt int64 `json:"extra_update_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
SchemeId *string `json:"scheme_id"`
|
||||
Props map[string]interface{} `json:"props" db:"-"`
|
||||
}
|
||||
|
||||
type ChannelPatch struct {
|
||||
DisplayName *string `json:"display_name"`
|
||||
Name *string `json:"name"`
|
||||
Header *string `json:"header"`
|
||||
Purpose *string `json:"purpose"`
|
||||
}
|
||||
|
||||
type ChannelForExport struct {
|
||||
Channel
|
||||
TeamName string
|
||||
SchemeName *string
|
||||
}
|
||||
|
||||
func (o *Channel) DeepCopy() *Channel {
|
||||
copy := *o
|
||||
if copy.SchemeId != nil {
|
||||
copy.SchemeId = NewString(*o.SchemeId)
|
||||
}
|
||||
return ©
|
||||
}
|
||||
|
||||
func (o *Channel) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (o *ChannelPatch) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelFromJson(data io.Reader) *Channel {
|
||||
var o *Channel
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelPatchFromJson(data io.Reader) *ChannelPatch {
|
||||
var o *ChannelPatch
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Channel) Etag() string {
|
||||
return Etag(o.Id, o.UpdateAt)
|
||||
}
|
||||
|
||||
func (o *Channel) IsValid() *AppError {
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.DisplayName) > CHANNEL_DISPLAY_NAME_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.display_name.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidChannelIdentifier(o.Name) {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.2_or_more.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(o.Type == CHANNEL_OPEN || o.Type == CHANNEL_PRIVATE || o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP) {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.type.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.Header) > CHANNEL_HEADER_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.header.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.Purpose) > CHANNEL_PURPOSE_MAX_RUNES {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.purpose.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) > 26 {
|
||||
return NewAppError("Channel.IsValid", "model.channel.is_valid.creator_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Channel) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
o.CreateAt = GetMillis()
|
||||
o.UpdateAt = o.CreateAt
|
||||
o.ExtraUpdateAt = 0
|
||||
}
|
||||
|
||||
func (o *Channel) PreUpdate() {
|
||||
o.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (o *Channel) IsGroupOrDirect() bool {
|
||||
return o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP
|
||||
}
|
||||
|
||||
func (o *Channel) Patch(patch *ChannelPatch) {
|
||||
if patch.DisplayName != nil {
|
||||
o.DisplayName = *patch.DisplayName
|
||||
}
|
||||
|
||||
if patch.Name != nil {
|
||||
o.Name = *patch.Name
|
||||
}
|
||||
|
||||
if patch.Header != nil {
|
||||
o.Header = *patch.Header
|
||||
}
|
||||
|
||||
if patch.Purpose != nil {
|
||||
o.Purpose = *patch.Purpose
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Channel) MakeNonNil() {
|
||||
if o.Props == nil {
|
||||
o.Props = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Channel) AddProp(key string, value interface{}) {
|
||||
o.MakeNonNil()
|
||||
|
||||
o.Props[key] = value
|
||||
}
|
||||
|
||||
func GetDMNameFromIds(userId1, userId2 string) string {
|
||||
if userId1 > userId2 {
|
||||
return userId2 + "__" + userId1
|
||||
} else {
|
||||
return userId1 + "__" + userId2
|
||||
}
|
||||
}
|
||||
|
||||
func GetGroupDisplayNameFromUsers(users []*User, truncate bool) string {
|
||||
usernames := make([]string, len(users))
|
||||
for index, user := range users {
|
||||
usernames[index] = user.Username
|
||||
}
|
||||
|
||||
sort.Strings(usernames)
|
||||
|
||||
name := strings.Join(usernames, ", ")
|
||||
|
||||
if truncate && len(name) > CHANNEL_NAME_MAX_LENGTH {
|
||||
name = name[:CHANNEL_NAME_MAX_LENGTH]
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func GetGroupNameFromUserIds(userIds []string) string {
|
||||
sort.Strings(userIds)
|
||||
|
||||
h := sha1.New()
|
||||
for _, id := range userIds {
|
||||
io.WriteString(h, id)
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
54
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_count.go
generated
vendored
54
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_count.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type ChannelCounts struct {
|
||||
Counts map[string]int64 `json:"counts"`
|
||||
UpdateTimes map[string]int64 `json:"update_times"`
|
||||
}
|
||||
|
||||
func (o *ChannelCounts) Etag() string {
|
||||
|
||||
ids := []string{}
|
||||
for id := range o.Counts {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
sort.Strings(ids)
|
||||
|
||||
str := ""
|
||||
for _, id := range ids {
|
||||
str += id + strconv.FormatInt(o.Counts[id], 10)
|
||||
}
|
||||
|
||||
md5Counts := fmt.Sprintf("%x", md5.Sum([]byte(str)))
|
||||
|
||||
var update int64 = 0
|
||||
for _, u := range o.UpdateTimes {
|
||||
if u > update {
|
||||
update = u
|
||||
}
|
||||
}
|
||||
|
||||
return Etag(md5Counts, update)
|
||||
}
|
||||
|
||||
func (o *ChannelCounts) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelCountsFromJson(data io.Reader) *ChannelCounts {
|
||||
var o *ChannelCounts
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
34
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_data.go
generated
vendored
34
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_data.go
generated
vendored
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ChannelData struct {
|
||||
Channel *Channel `json:"channel"`
|
||||
Member *ChannelMember `json:"member"`
|
||||
}
|
||||
|
||||
func (o *ChannelData) Etag() string {
|
||||
var mt int64 = 0
|
||||
if o.Member != nil {
|
||||
mt = o.Member.LastUpdateAt
|
||||
}
|
||||
|
||||
return Etag(o.Channel.Id, o.Channel.UpdateAt, o.Channel.LastPostAt, mt)
|
||||
}
|
||||
|
||||
func (o *ChannelData) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelDataFromJson(data io.Reader) *ChannelData {
|
||||
var o *ChannelData
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
53
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_list.go
generated
vendored
53
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_list.go
generated
vendored
|
@ -1,53 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ChannelList []*Channel
|
||||
|
||||
func (o *ChannelList) ToJson() string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *ChannelList) Etag() string {
|
||||
|
||||
id := "0"
|
||||
var t int64 = 0
|
||||
var delta int64 = 0
|
||||
|
||||
for _, v := range *o {
|
||||
if v.LastPostAt > t {
|
||||
t = v.LastPostAt
|
||||
id = v.Id
|
||||
}
|
||||
|
||||
if v.UpdateAt > t {
|
||||
t = v.UpdateAt
|
||||
id = v.Id
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Etag(id, t, delta, len(*o))
|
||||
}
|
||||
|
||||
func ChannelListFromJson(data io.Reader) *ChannelList {
|
||||
var o *ChannelList
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelSliceFromJson(data io.Reader) []*Channel {
|
||||
var o []*Channel
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
171
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_member.go
generated
vendored
171
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_member.go
generated
vendored
|
@ -1,171 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
CHANNEL_NOTIFY_DEFAULT = "default"
|
||||
CHANNEL_NOTIFY_ALL = "all"
|
||||
CHANNEL_NOTIFY_MENTION = "mention"
|
||||
CHANNEL_NOTIFY_NONE = "none"
|
||||
CHANNEL_MARK_UNREAD_ALL = "all"
|
||||
CHANNEL_MARK_UNREAD_MENTION = "mention"
|
||||
IGNORE_CHANNEL_MENTIONS_DEFAULT = "default"
|
||||
IGNORE_CHANNEL_MENTIONS_OFF = "off"
|
||||
IGNORE_CHANNEL_MENTIONS_ON = "on"
|
||||
IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP = "ignore_channel_mentions"
|
||||
)
|
||||
|
||||
type ChannelUnread struct {
|
||||
TeamId string `json:"team_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
NotifyProps StringMap `json:"-"`
|
||||
}
|
||||
|
||||
type ChannelMember struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Roles string `json:"roles"`
|
||||
LastViewedAt int64 `json:"last_viewed_at"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
NotifyProps StringMap `json:"notify_props"`
|
||||
LastUpdateAt int64 `json:"last_update_at"`
|
||||
SchemeUser bool `json:"scheme_user"`
|
||||
SchemeAdmin bool `json:"scheme_admin"`
|
||||
ExplicitRoles string `json:"explicit_roles"`
|
||||
}
|
||||
|
||||
type ChannelMembers []ChannelMember
|
||||
|
||||
type ChannelMemberForExport struct {
|
||||
ChannelMember
|
||||
ChannelName string
|
||||
}
|
||||
|
||||
func (o *ChannelMembers) ToJson() string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *ChannelUnread) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelMembersFromJson(data io.Reader) *ChannelMembers {
|
||||
var o *ChannelMembers
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func ChannelUnreadFromJson(data io.Reader) *ChannelUnread {
|
||||
var o *ChannelUnread
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *ChannelMember) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelMemberFromJson(data io.Reader) *ChannelMember {
|
||||
var o *ChannelMember
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *ChannelMember) IsValid() *AppError {
|
||||
|
||||
if len(o.ChannelId) != 26 {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
notifyLevel := o.NotifyProps[DESKTOP_NOTIFY_PROP]
|
||||
if len(notifyLevel) > 20 || !IsChannelNotifyLevelValid(notifyLevel) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.notify_level.app_error", nil, "notify_level="+notifyLevel, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
markUnreadLevel := o.NotifyProps[MARK_UNREAD_NOTIFY_PROP]
|
||||
if len(markUnreadLevel) > 20 || !IsChannelMarkUnreadLevelValid(markUnreadLevel) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.unread_level.app_error", nil, "mark_unread_level="+markUnreadLevel, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if pushLevel, ok := o.NotifyProps[PUSH_NOTIFY_PROP]; ok {
|
||||
if len(pushLevel) > 20 || !IsChannelNotifyLevelValid(pushLevel) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.push_level.app_error", nil, "push_notification_level="+pushLevel, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
if sendEmail, ok := o.NotifyProps[EMAIL_NOTIFY_PROP]; ok {
|
||||
if len(sendEmail) > 20 || !IsSendEmailValid(sendEmail) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.email_value.app_error", nil, "push_notification_level="+sendEmail, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
if ignoreChannelMentions, ok := o.NotifyProps[IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP]; ok {
|
||||
if len(ignoreChannelMentions) > 40 || !IsIgnoreChannelMentionsValid(ignoreChannelMentions) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.ignore_channel_mentions_value.app_error", nil, "ignore_channel_mentions="+ignoreChannelMentions, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ChannelMember) PreSave() {
|
||||
o.LastUpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (o *ChannelMember) PreUpdate() {
|
||||
o.LastUpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (o *ChannelMember) GetRoles() []string {
|
||||
return strings.Fields(o.Roles)
|
||||
}
|
||||
|
||||
func IsChannelNotifyLevelValid(notifyLevel string) bool {
|
||||
return notifyLevel == CHANNEL_NOTIFY_DEFAULT ||
|
||||
notifyLevel == CHANNEL_NOTIFY_ALL ||
|
||||
notifyLevel == CHANNEL_NOTIFY_MENTION ||
|
||||
notifyLevel == CHANNEL_NOTIFY_NONE
|
||||
}
|
||||
|
||||
func IsChannelMarkUnreadLevelValid(markUnreadLevel string) bool {
|
||||
return markUnreadLevel == CHANNEL_MARK_UNREAD_ALL || markUnreadLevel == CHANNEL_MARK_UNREAD_MENTION
|
||||
}
|
||||
|
||||
func IsSendEmailValid(sendEmail string) bool {
|
||||
return sendEmail == CHANNEL_NOTIFY_DEFAULT || sendEmail == "true" || sendEmail == "false"
|
||||
}
|
||||
|
||||
func IsIgnoreChannelMentionsValid(ignoreChannelMentions string) bool {
|
||||
return ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_ON || ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_OFF || ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_DEFAULT
|
||||
}
|
||||
|
||||
func GetDefaultChannelNotifyProps() StringMap {
|
||||
return StringMap{
|
||||
DESKTOP_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
MARK_UNREAD_NOTIFY_PROP: CHANNEL_MARK_UNREAD_ALL,
|
||||
PUSH_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
EMAIL_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP: IGNORE_CHANNEL_MENTIONS_DEFAULT,
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
type ChannelMemberHistory struct {
|
||||
ChannelId string
|
||||
UserId string
|
||||
JoinTime int64
|
||||
LeaveTime *int64
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
type ChannelMemberHistoryResult struct {
|
||||
ChannelId string
|
||||
UserId string
|
||||
JoinTime int64
|
||||
LeaveTime *int64
|
||||
|
||||
// these two fields are never set in the database - when we SELECT, we join on Users to get them
|
||||
UserEmail string `db:"Email"`
|
||||
Username string
|
||||
}
|
28
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_mentions.go
generated
vendored
28
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_mentions.go
generated
vendored
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var channelMentionRegexp = regexp.MustCompile(`\B~[a-zA-Z0-9\-_]+`)
|
||||
|
||||
func ChannelMentions(message string) []string {
|
||||
var names []string
|
||||
|
||||
if strings.Contains(message, "~") {
|
||||
alreadyMentioned := make(map[string]bool)
|
||||
for _, match := range channelMentionRegexp.FindAllString(message, -1) {
|
||||
name := match[1:]
|
||||
if !alreadyMentioned[name] {
|
||||
names = append(names, name)
|
||||
alreadyMentioned[name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
26
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_search.go
generated
vendored
26
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_search.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ChannelSearch struct {
|
||||
Term string `json:"term"`
|
||||
}
|
||||
|
||||
// ToJson convert a Channel to a json string
|
||||
func (c *ChannelSearch) ToJson() string {
|
||||
b, _ := json.Marshal(c)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// ChannelSearchFromJson will decode the input and return a Channel
|
||||
func ChannelSearchFromJson(data io.Reader) *ChannelSearch {
|
||||
var cs *ChannelSearch
|
||||
json.NewDecoder(data).Decode(&cs)
|
||||
return cs
|
||||
}
|
25
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_stats.go
generated
vendored
25
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_stats.go
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ChannelStats struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
MemberCount int64 `json:"member_count"`
|
||||
}
|
||||
|
||||
func (o *ChannelStats) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelStatsFromJson(data io.Reader) *ChannelStats {
|
||||
var o *ChannelStats
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
41
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_view.go
generated
vendored
41
build/manifest/vendor/github.com/mattermost/mattermost-server/model/channel_view.go
generated
vendored
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ChannelView struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
PrevChannelId string `json:"prev_channel_id"`
|
||||
}
|
||||
|
||||
func (o *ChannelView) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelViewFromJson(data io.Reader) *ChannelView {
|
||||
var o *ChannelView
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
type ChannelViewResponse struct {
|
||||
Status string `json:"status"`
|
||||
LastViewedAtTimes map[string]int64 `json:"last_viewed_at_times"`
|
||||
}
|
||||
|
||||
func (o *ChannelViewResponse) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ChannelViewResponseFromJson(data io.Reader) *ChannelViewResponse {
|
||||
var o *ChannelViewResponse
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
3966
build/manifest/vendor/github.com/mattermost/mattermost-server/model/client4.go
generated
vendored
3966
build/manifest/vendor/github.com/mattermost/mattermost-server/model/client4.go
generated
vendored
File diff suppressed because it is too large
Load diff
133
build/manifest/vendor/github.com/mattermost/mattermost-server/model/cluster_discovery.go
generated
vendored
133
build/manifest/vendor/github.com/mattermost/mattermost-server/model/cluster_discovery.go
generated
vendored
|
@ -1,133 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
CDS_OFFLINE_AFTER_MILLIS = 1000 * 60 * 30 // 30 minutes
|
||||
CDS_TYPE_APP = "mattermost_app"
|
||||
)
|
||||
|
||||
type ClusterDiscovery struct {
|
||||
Id string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
ClusterName string `json:"cluster_name"`
|
||||
Hostname string `json:"hostname"`
|
||||
GossipPort int32 `json:"gossip_port"`
|
||||
Port int32 `json:"port"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
LastPingAt int64 `json:"last_ping_at"`
|
||||
}
|
||||
|
||||
func (o *ClusterDiscovery) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
o.CreateAt = GetMillis()
|
||||
o.LastPingAt = o.CreateAt
|
||||
}
|
||||
}
|
||||
|
||||
func (o *ClusterDiscovery) AutoFillHostname() {
|
||||
// attempt to set the hostname from the OS
|
||||
if len(o.Hostname) == 0 {
|
||||
if hn, err := os.Hostname(); err == nil {
|
||||
o.Hostname = hn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *ClusterDiscovery) AutoFillIpAddress() {
|
||||
// attempt to set the hostname to the first non-local IP address
|
||||
if len(o.Hostname) == 0 {
|
||||
o.Hostname = GetServerIpAddress()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *ClusterDiscovery) IsEqual(in *ClusterDiscovery) bool {
|
||||
if in == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if o.Type != in.Type {
|
||||
return false
|
||||
}
|
||||
|
||||
if o.ClusterName != in.ClusterName {
|
||||
return false
|
||||
}
|
||||
|
||||
if o.Hostname != in.Hostname {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func FilterClusterDiscovery(vs []*ClusterDiscovery, f func(*ClusterDiscovery) bool) []*ClusterDiscovery {
|
||||
copy := make([]*ClusterDiscovery, 0)
|
||||
for _, v := range vs {
|
||||
if f(v) {
|
||||
copy = append(copy, v)
|
||||
}
|
||||
}
|
||||
|
||||
return copy
|
||||
}
|
||||
|
||||
func (o *ClusterDiscovery) IsValid() *AppError {
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ClusterName) == 0 {
|
||||
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.name.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Type) == 0 {
|
||||
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Hostname) == 0 {
|
||||
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.hostname.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.LastPingAt == 0 {
|
||||
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.last_ping_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ClusterDiscovery) ToJson() string {
|
||||
b, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ClusterDiscoveryFromJson(data io.Reader) *ClusterDiscovery {
|
||||
decoder := json.NewDecoder(data)
|
||||
var me ClusterDiscovery
|
||||
err := decoder.Decode(&me)
|
||||
if err == nil {
|
||||
return &me
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
44
build/manifest/vendor/github.com/mattermost/mattermost-server/model/cluster_info.go
generated
vendored
44
build/manifest/vendor/github.com/mattermost/mattermost-server/model/cluster_info.go
generated
vendored
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ClusterInfo struct {
|
||||
Id string `json:"id"`
|
||||
Version string `json:"version"`
|
||||
ConfigHash string `json:"config_hash"`
|
||||
IpAddress string `json:"ipaddress"`
|
||||
Hostname string `json:"hostname"`
|
||||
}
|
||||
|
||||
func (me *ClusterInfo) ToJson() string {
|
||||
b, _ := json.Marshal(me)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ClusterInfoFromJson(data io.Reader) *ClusterInfo {
|
||||
var me *ClusterInfo
|
||||
json.NewDecoder(data).Decode(&me)
|
||||
return me
|
||||
}
|
||||
|
||||
func ClusterInfosToJson(objmap []*ClusterInfo) string {
|
||||
b, _ := json.Marshal(objmap)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ClusterInfosFromJson(data io.Reader) []*ClusterInfo {
|
||||
decoder := json.NewDecoder(data)
|
||||
|
||||
var objmap []*ClusterInfo
|
||||
if err := decoder.Decode(&objmap); err != nil {
|
||||
return make([]*ClusterInfo, 0)
|
||||
} else {
|
||||
return objmap
|
||||
}
|
||||
}
|
48
build/manifest/vendor/github.com/mattermost/mattermost-server/model/cluster_message.go
generated
vendored
48
build/manifest/vendor/github.com/mattermost/mattermost-server/model/cluster_message.go
generated
vendored
|
@ -1,48 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
CLUSTER_EVENT_PUBLISH = "publish"
|
||||
CLUSTER_EVENT_UPDATE_STATUS = "update_status"
|
||||
CLUSTER_EVENT_INVALIDATE_ALL_CACHES = "inv_all_caches"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS = "inv_reactions"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOK = "inv_webhook"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_POSTS = "inv_channel_posts"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS_NOTIFY_PROPS = "inv_channel_members_notify_props"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS = "inv_channel_members"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_BY_NAME = "inv_channel_name"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL = "inv_channel"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER = "inv_user"
|
||||
CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_USER = "clear_session_user"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES = "inv_roles"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES = "inv_schemes"
|
||||
|
||||
CLUSTER_SEND_BEST_EFFORT = "best_effort"
|
||||
CLUSTER_SEND_RELIABLE = "reliable"
|
||||
)
|
||||
|
||||
type ClusterMessage struct {
|
||||
Event string `json:"event"`
|
||||
SendType string `json:"-"`
|
||||
WaitForAllToSend bool `json:"-"`
|
||||
Data string `json:"data,omitempty"`
|
||||
Props map[string]string `json:"props,omitempty"`
|
||||
}
|
||||
|
||||
func (o *ClusterMessage) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ClusterMessageFromJson(data io.Reader) *ClusterMessage {
|
||||
var o *ClusterMessage
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
27
build/manifest/vendor/github.com/mattermost/mattermost-server/model/cluster_stats.go
generated
vendored
27
build/manifest/vendor/github.com/mattermost/mattermost-server/model/cluster_stats.go
generated
vendored
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ClusterStats struct {
|
||||
Id string `json:"id"`
|
||||
TotalWebsocketConnections int `json:"total_websocket_connections"`
|
||||
TotalReadDbConnections int `json:"total_read_db_connections"`
|
||||
TotalMasterDbConnections int `json:"total_master_db_connections"`
|
||||
}
|
||||
|
||||
func (me *ClusterStats) ToJson() string {
|
||||
b, _ := json.Marshal(me)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ClusterStatsFromJson(data io.Reader) *ClusterStats {
|
||||
var me *ClusterStats
|
||||
json.NewDecoder(data).Decode(&me)
|
||||
return me
|
||||
}
|
139
build/manifest/vendor/github.com/mattermost/mattermost-server/model/command.go
generated
vendored
139
build/manifest/vendor/github.com/mattermost/mattermost-server/model/command.go
generated
vendored
|
@ -1,139 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
COMMAND_METHOD_POST = "P"
|
||||
COMMAND_METHOD_GET = "G"
|
||||
MIN_TRIGGER_LENGTH = 1
|
||||
MAX_TRIGGER_LENGTH = 128
|
||||
)
|
||||
|
||||
type Command struct {
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
Trigger string `json:"trigger"`
|
||||
Method string `json:"method"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
AutoComplete bool `json:"auto_complete"`
|
||||
AutoCompleteDesc string `json:"auto_complete_desc"`
|
||||
AutoCompleteHint string `json:"auto_complete_hint"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (o *Command) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func CommandFromJson(data io.Reader) *Command {
|
||||
var o *Command
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func CommandListToJson(l []*Command) string {
|
||||
b, _ := json.Marshal(l)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func CommandListFromJson(data io.Reader) []*Command {
|
||||
var o []*Command
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Command) IsValid() *AppError {
|
||||
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Token) != 26 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.token.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.update_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) != 26 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.team_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Trigger) < MIN_TRIGGER_LENGTH || len(o.Trigger) > MAX_TRIGGER_LENGTH || strings.Index(o.Trigger, "/") == 0 || strings.Contains(o.Trigger, " ") {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.trigger.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.URL) == 0 || len(o.URL) > 1024 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.url.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidHttpUrl(o.URL) {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.url_http.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(o.Method == COMMAND_METHOD_GET || o.Method == COMMAND_METHOD_POST) {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.method.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.DisplayName) > 64 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.display_name.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Description) > 128 {
|
||||
return NewAppError("Command.IsValid", "model.command.is_valid.description.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Command) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
if o.Token == "" {
|
||||
o.Token = NewId()
|
||||
}
|
||||
|
||||
o.CreateAt = GetMillis()
|
||||
o.UpdateAt = o.CreateAt
|
||||
}
|
||||
|
||||
func (o *Command) PreUpdate() {
|
||||
o.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (o *Command) Sanitize() {
|
||||
o.Token = ""
|
||||
o.CreatorId = ""
|
||||
o.Method = ""
|
||||
o.URL = ""
|
||||
o.Username = ""
|
||||
o.IconURL = ""
|
||||
}
|
35
build/manifest/vendor/github.com/mattermost/mattermost-server/model/command_args.go
generated
vendored
35
build/manifest/vendor/github.com/mattermost/mattermost-server/model/command_args.go
generated
vendored
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
goi18n "github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
||||
type CommandArgs struct {
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
RootId string `json:"root_id"`
|
||||
ParentId string `json:"parent_id"`
|
||||
TriggerId string `json:"trigger_id,omitempty"`
|
||||
Command string `json:"command"`
|
||||
SiteURL string `json:"-"`
|
||||
T goi18n.TranslateFunc `json:"-"`
|
||||
Session Session `json:"-"`
|
||||
}
|
||||
|
||||
func (o *CommandArgs) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func CommandArgsFromJson(data io.Reader) *CommandArgs {
|
||||
var o *CommandArgs
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
75
build/manifest/vendor/github.com/mattermost/mattermost-server/model/command_response.go
generated
vendored
75
build/manifest/vendor/github.com/mattermost/mattermost-server/model/command_response.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/utils/jsonutils"
|
||||
)
|
||||
|
||||
const (
|
||||
COMMAND_RESPONSE_TYPE_IN_CHANNEL = "in_channel"
|
||||
COMMAND_RESPONSE_TYPE_EPHEMERAL = "ephemeral"
|
||||
)
|
||||
|
||||
type CommandResponse struct {
|
||||
ResponseType string `json:"response_type"`
|
||||
Text string `json:"text"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
Type string `json:"type"`
|
||||
Props StringInterface `json:"props"`
|
||||
GotoLocation string `json:"goto_location"`
|
||||
TriggerId string `json:"trigger_id"`
|
||||
Attachments []*SlackAttachment `json:"attachments"`
|
||||
ExtraResponses []*CommandResponse `json:"extra_responses"`
|
||||
}
|
||||
|
||||
func (o *CommandResponse) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func CommandResponseFromHTTPBody(contentType string, body io.Reader) (*CommandResponse, error) {
|
||||
if strings.TrimSpace(strings.Split(contentType, ";")[0]) == "application/json" {
|
||||
return CommandResponseFromJson(body)
|
||||
}
|
||||
if b, err := ioutil.ReadAll(body); err == nil {
|
||||
return CommandResponseFromPlainText(string(b)), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func CommandResponseFromPlainText(text string) *CommandResponse {
|
||||
return &CommandResponse{
|
||||
Text: text,
|
||||
}
|
||||
}
|
||||
|
||||
func CommandResponseFromJson(data io.Reader) (*CommandResponse, error) {
|
||||
b, err := ioutil.ReadAll(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var o CommandResponse
|
||||
err = json.Unmarshal(b, &o)
|
||||
if err != nil {
|
||||
return nil, jsonutils.HumanizeJsonError(err, b)
|
||||
}
|
||||
|
||||
o.Attachments = StringifySlackFieldValue(o.Attachments)
|
||||
|
||||
if o.ExtraResponses != nil {
|
||||
for _, resp := range o.ExtraResponses {
|
||||
resp.Attachments = StringifySlackFieldValue(resp.Attachments)
|
||||
}
|
||||
}
|
||||
|
||||
return &o, nil
|
||||
}
|
65
build/manifest/vendor/github.com/mattermost/mattermost-server/model/command_webhook.go
generated
vendored
65
build/manifest/vendor/github.com/mattermost/mattermost-server/model/command_webhook.go
generated
vendored
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type CommandWebhook struct {
|
||||
Id string
|
||||
CreateAt int64
|
||||
CommandId string
|
||||
UserId string
|
||||
ChannelId string
|
||||
RootId string
|
||||
ParentId string
|
||||
UseCount int
|
||||
}
|
||||
|
||||
const (
|
||||
COMMAND_WEBHOOK_LIFETIME = 1000 * 60 * 30
|
||||
)
|
||||
|
||||
func (o *CommandWebhook) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
o.CreateAt = GetMillis()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CommandWebhook) IsValid() *AppError {
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CommandId) != 26 {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.command_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ChannelId) != 26 {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.RootId) != 0 && len(o.RootId) != 26 {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.root_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ParentId) != 0 && len(o.ParentId) != 26 {
|
||||
return NewAppError("CommandWebhook.IsValid", "model.command_hook.parent_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
119
build/manifest/vendor/github.com/mattermost/mattermost-server/model/compliance.go
generated
vendored
119
build/manifest/vendor/github.com/mattermost/mattermost-server/model/compliance.go
generated
vendored
|
@ -1,119 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
COMPLIANCE_STATUS_CREATED = "created"
|
||||
COMPLIANCE_STATUS_RUNNING = "running"
|
||||
COMPLIANCE_STATUS_FINISHED = "finished"
|
||||
COMPLIANCE_STATUS_FAILED = "failed"
|
||||
COMPLIANCE_STATUS_REMOVED = "removed"
|
||||
|
||||
COMPLIANCE_TYPE_DAILY = "daily"
|
||||
COMPLIANCE_TYPE_ADHOC = "adhoc"
|
||||
)
|
||||
|
||||
type Compliance struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UserId string `json:"user_id"`
|
||||
Status string `json:"status"`
|
||||
Count int `json:"count"`
|
||||
Desc string `json:"desc"`
|
||||
Type string `json:"type"`
|
||||
StartAt int64 `json:"start_at"`
|
||||
EndAt int64 `json:"end_at"`
|
||||
Keywords string `json:"keywords"`
|
||||
Emails string `json:"emails"`
|
||||
}
|
||||
|
||||
type Compliances []Compliance
|
||||
|
||||
func (o *Compliance) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (me *Compliance) PreSave() {
|
||||
if me.Id == "" {
|
||||
me.Id = NewId()
|
||||
}
|
||||
|
||||
if me.Status == "" {
|
||||
me.Status = COMPLIANCE_STATUS_CREATED
|
||||
}
|
||||
|
||||
me.Count = 0
|
||||
me.Emails = NormalizeEmail(me.Emails)
|
||||
me.Keywords = strings.ToLower(me.Keywords)
|
||||
|
||||
me.CreateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (me *Compliance) JobName() string {
|
||||
jobName := me.Type
|
||||
if me.Type == COMPLIANCE_TYPE_DAILY {
|
||||
jobName += "-" + me.Desc
|
||||
}
|
||||
|
||||
jobName += "-" + me.Id
|
||||
|
||||
return jobName
|
||||
}
|
||||
|
||||
func (me *Compliance) IsValid() *AppError {
|
||||
|
||||
if len(me.Id) != 26 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if me.CreateAt == 0 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(me.Desc) > 512 || len(me.Desc) == 0 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.desc.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if me.StartAt == 0 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.start_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if me.EndAt == 0 {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.end_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if me.EndAt <= me.StartAt {
|
||||
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.start_end_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ComplianceFromJson(data io.Reader) *Compliance {
|
||||
var o *Compliance
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o Compliances) ToJson() string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func CompliancesFromJson(data io.Reader) Compliances {
|
||||
var o Compliances
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
117
build/manifest/vendor/github.com/mattermost/mattermost-server/model/compliance_post.go
generated
vendored
117
build/manifest/vendor/github.com/mattermost/mattermost-server/model/compliance_post.go
generated
vendored
|
@ -1,117 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CompliancePost struct {
|
||||
|
||||
// From Team
|
||||
TeamName string
|
||||
TeamDisplayName string
|
||||
|
||||
// From Channel
|
||||
ChannelName string
|
||||
ChannelDisplayName string
|
||||
ChannelType string
|
||||
|
||||
// From User
|
||||
UserUsername string
|
||||
UserEmail string
|
||||
UserNickname string
|
||||
|
||||
// From Post
|
||||
PostId string
|
||||
PostCreateAt int64
|
||||
PostUpdateAt int64
|
||||
PostDeleteAt int64
|
||||
PostRootId string
|
||||
PostParentId string
|
||||
PostOriginalId string
|
||||
PostMessage string
|
||||
PostType string
|
||||
PostProps string
|
||||
PostHashtags string
|
||||
PostFileIds string
|
||||
}
|
||||
|
||||
func CompliancePostHeader() []string {
|
||||
return []string{
|
||||
"TeamName",
|
||||
"TeamDisplayName",
|
||||
|
||||
"ChannelName",
|
||||
"ChannelDisplayName",
|
||||
"ChannelType",
|
||||
|
||||
"UserUsername",
|
||||
"UserEmail",
|
||||
"UserNickname",
|
||||
|
||||
"PostId",
|
||||
"PostCreateAt",
|
||||
"PostUpdateAt",
|
||||
"PostDeleteAt",
|
||||
"PostRootId",
|
||||
"PostParentId",
|
||||
"PostOriginalId",
|
||||
"PostMessage",
|
||||
"PostType",
|
||||
"PostProps",
|
||||
"PostHashtags",
|
||||
"PostFileIds",
|
||||
}
|
||||
}
|
||||
|
||||
func cleanComplianceStrings(in string) string {
|
||||
if matched, _ := regexp.MatchString("^\\s*(=|\\+|\\-)", in); matched {
|
||||
return "'" + in
|
||||
|
||||
} else {
|
||||
return in
|
||||
}
|
||||
}
|
||||
|
||||
func (me *CompliancePost) Row() []string {
|
||||
|
||||
postDeleteAt := ""
|
||||
if me.PostDeleteAt > 0 {
|
||||
postDeleteAt = time.Unix(0, me.PostDeleteAt*int64(1000*1000)).Format(time.RFC3339)
|
||||
}
|
||||
|
||||
postUpdateAt := ""
|
||||
if me.PostUpdateAt != me.PostCreateAt {
|
||||
postUpdateAt = time.Unix(0, me.PostUpdateAt*int64(1000*1000)).Format(time.RFC3339)
|
||||
}
|
||||
|
||||
return []string{
|
||||
cleanComplianceStrings(me.TeamName),
|
||||
cleanComplianceStrings(me.TeamDisplayName),
|
||||
|
||||
cleanComplianceStrings(me.ChannelName),
|
||||
cleanComplianceStrings(me.ChannelDisplayName),
|
||||
cleanComplianceStrings(me.ChannelType),
|
||||
|
||||
cleanComplianceStrings(me.UserUsername),
|
||||
cleanComplianceStrings(me.UserEmail),
|
||||
cleanComplianceStrings(me.UserNickname),
|
||||
|
||||
me.PostId,
|
||||
time.Unix(0, me.PostCreateAt*int64(1000*1000)).Format(time.RFC3339),
|
||||
postUpdateAt,
|
||||
postDeleteAt,
|
||||
|
||||
me.PostRootId,
|
||||
me.PostParentId,
|
||||
me.PostOriginalId,
|
||||
cleanComplianceStrings(me.PostMessage),
|
||||
me.PostType,
|
||||
me.PostProps,
|
||||
me.PostHashtags,
|
||||
me.PostFileIds,
|
||||
}
|
||||
}
|
2556
build/manifest/vendor/github.com/mattermost/mattermost-server/model/config.go
generated
vendored
2556
build/manifest/vendor/github.com/mattermost/mattermost-server/model/config.go
generated
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type DataRetentionPolicy struct {
|
||||
MessageDeletionEnabled bool `json:"message_deletion_enabled"`
|
||||
FileDeletionEnabled bool `json:"file_deletion_enabled"`
|
||||
MessageRetentionCutoff int64 `json:"message_retention_cutoff"`
|
||||
FileRetentionCutoff int64 `json:"file_retention_cutoff"`
|
||||
}
|
||||
|
||||
func (me *DataRetentionPolicy) ToJson() string {
|
||||
b, _ := json.Marshal(me)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func DataRetentionPolicyFromJson(data io.Reader) *DataRetentionPolicy {
|
||||
var me *DataRetentionPolicy
|
||||
json.NewDecoder(data).Decode(&me)
|
||||
return me
|
||||
}
|
91
build/manifest/vendor/github.com/mattermost/mattermost-server/model/emoji.go
generated
vendored
91
build/manifest/vendor/github.com/mattermost/mattermost-server/model/emoji.go
generated
vendored
|
@ -1,91 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const (
|
||||
EMOJI_NAME_MAX_LENGTH = 64
|
||||
EMOJI_SORT_BY_NAME = "name"
|
||||
)
|
||||
|
||||
var EMOJI_PATTERN = regexp.MustCompile(`:[a-zA-Z0-9_-]+:`)
|
||||
|
||||
type Emoji struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func inSystemEmoji(emojiName string) bool {
|
||||
_, ok := SystemEmojis[emojiName]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (emoji *Emoji) IsValid() *AppError {
|
||||
if len(emoji.Id) != 26 {
|
||||
return NewAppError("Emoji.IsValid", "model.emoji.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if emoji.CreateAt == 0 {
|
||||
return NewAppError("Emoji.IsValid", "model.emoji.create_at.app_error", nil, "id="+emoji.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if emoji.UpdateAt == 0 {
|
||||
return NewAppError("Emoji.IsValid", "model.emoji.update_at.app_error", nil, "id="+emoji.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(emoji.CreatorId) > 26 {
|
||||
return NewAppError("Emoji.IsValid", "model.emoji.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return IsValidEmojiName(emoji.Name)
|
||||
}
|
||||
|
||||
func IsValidEmojiName(name string) *AppError {
|
||||
if len(name) == 0 || len(name) > EMOJI_NAME_MAX_LENGTH || !IsValidAlphaNumHyphenUnderscore(name, false) || inSystemEmoji(name) {
|
||||
return NewAppError("Emoji.IsValid", "model.emoji.name.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (emoji *Emoji) PreSave() {
|
||||
if emoji.Id == "" {
|
||||
emoji.Id = NewId()
|
||||
}
|
||||
|
||||
emoji.CreateAt = GetMillis()
|
||||
emoji.UpdateAt = emoji.CreateAt
|
||||
}
|
||||
|
||||
func (emoji *Emoji) ToJson() string {
|
||||
b, _ := json.Marshal(emoji)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func EmojiFromJson(data io.Reader) *Emoji {
|
||||
var emoji *Emoji
|
||||
json.NewDecoder(data).Decode(&emoji)
|
||||
return emoji
|
||||
}
|
||||
|
||||
func EmojiListToJson(emojiList []*Emoji) string {
|
||||
b, _ := json.Marshal(emojiList)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func EmojiListFromJson(data io.Reader) []*Emoji {
|
||||
var emojiList []*Emoji
|
||||
json.NewDecoder(data).Decode(&emojiList)
|
||||
return emojiList
|
||||
}
|
6
build/manifest/vendor/github.com/mattermost/mattermost-server/model/emoji_data.go
generated
vendored
6
build/manifest/vendor/github.com/mattermost/mattermost-server/model/emoji_data.go
generated
vendored
File diff suppressed because one or more lines are too long
25
build/manifest/vendor/github.com/mattermost/mattermost-server/model/emoji_search.go
generated
vendored
25
build/manifest/vendor/github.com/mattermost/mattermost-server/model/emoji_search.go
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type EmojiSearch struct {
|
||||
Term string `json:"term"`
|
||||
PrefixOnly bool `json:"prefix_only"`
|
||||
}
|
||||
|
||||
func (es *EmojiSearch) ToJson() string {
|
||||
b, _ := json.Marshal(es)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func EmojiSearchFromJson(data io.Reader) *EmojiSearch {
|
||||
var es *EmojiSearch
|
||||
json.NewDecoder(data).Decode(&es)
|
||||
return es
|
||||
}
|
34
build/manifest/vendor/github.com/mattermost/mattermost-server/model/file.go
generated
vendored
34
build/manifest/vendor/github.com/mattermost/mattermost-server/model/file.go
generated
vendored
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
MaxImageSize = 6048 * 4032 // 24 megapixels, roughly 36MB as a raw image
|
||||
)
|
||||
|
||||
var (
|
||||
IMAGE_EXTENSIONS = [5]string{".jpg", ".jpeg", ".gif", ".bmp", ".png"}
|
||||
IMAGE_MIME_TYPES = map[string]string{".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".bmp": "image/bmp", ".png": "image/png", ".tiff": "image/tiff"}
|
||||
)
|
||||
|
||||
type FileUploadResponse struct {
|
||||
FileInfos []*FileInfo `json:"file_infos"`
|
||||
ClientIds []string `json:"client_ids"`
|
||||
}
|
||||
|
||||
func FileUploadResponseFromJson(data io.Reader) *FileUploadResponse {
|
||||
var o *FileUploadResponse
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *FileUploadResponse) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
170
build/manifest/vendor/github.com/mattermost/mattermost-server/model/file_info.go
generated
vendored
170
build/manifest/vendor/github.com/mattermost/mattermost-server/model/file_info.go
generated
vendored
|
@ -1,170 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"image"
|
||||
"image/gif"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FileInfo struct {
|
||||
Id string `json:"id"`
|
||||
CreatorId string `json:"user_id"`
|
||||
PostId string `json:"post_id,omitempty"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
Path string `json:"-"` // not sent back to the client
|
||||
ThumbnailPath string `json:"-"` // not sent back to the client
|
||||
PreviewPath string `json:"-"` // not sent back to the client
|
||||
Name string `json:"name"`
|
||||
Extension string `json:"extension"`
|
||||
Size int64 `json:"size"`
|
||||
MimeType string `json:"mime_type"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
HasPreviewImage bool `json:"has_preview_image,omitempty"`
|
||||
}
|
||||
|
||||
func (info *FileInfo) ToJson() string {
|
||||
b, _ := json.Marshal(info)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func FileInfoFromJson(data io.Reader) *FileInfo {
|
||||
decoder := json.NewDecoder(data)
|
||||
|
||||
var info FileInfo
|
||||
if err := decoder.Decode(&info); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
return &info
|
||||
}
|
||||
}
|
||||
|
||||
func FileInfosToJson(infos []*FileInfo) string {
|
||||
b, _ := json.Marshal(infos)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func FileInfosFromJson(data io.Reader) []*FileInfo {
|
||||
decoder := json.NewDecoder(data)
|
||||
|
||||
var infos []*FileInfo
|
||||
if err := decoder.Decode(&infos); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
return infos
|
||||
}
|
||||
}
|
||||
|
||||
func (o *FileInfo) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
o.CreateAt = GetMillis()
|
||||
}
|
||||
|
||||
if o.UpdateAt < o.CreateAt {
|
||||
o.UpdateAt = o.CreateAt
|
||||
}
|
||||
}
|
||||
|
||||
func (o *FileInfo) IsValid() *AppError {
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) != 26 && o.CreatorId != "nouser" {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.user_id.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.PostId) != 0 && len(o.PostId) != 26 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.post_id.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.Path == "" {
|
||||
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.path.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *FileInfo) IsImage() bool {
|
||||
return strings.HasPrefix(o.MimeType, "image")
|
||||
}
|
||||
|
||||
func GetInfoForBytes(name string, data []byte) (*FileInfo, *AppError) {
|
||||
info := &FileInfo{
|
||||
Name: name,
|
||||
Size: int64(len(data)),
|
||||
}
|
||||
var err *AppError
|
||||
|
||||
extension := strings.ToLower(filepath.Ext(name))
|
||||
info.MimeType = mime.TypeByExtension(extension)
|
||||
|
||||
if extension != "" && extension[0] == '.' {
|
||||
// The client expects a file extension without the leading period
|
||||
info.Extension = extension[1:]
|
||||
} else {
|
||||
info.Extension = extension
|
||||
}
|
||||
|
||||
if info.IsImage() {
|
||||
// Only set the width and height if it's actually an image that we can understand
|
||||
if config, _, err := image.DecodeConfig(bytes.NewReader(data)); err == nil {
|
||||
info.Width = config.Width
|
||||
info.Height = config.Height
|
||||
|
||||
if info.MimeType == "image/gif" {
|
||||
// Just show the gif itself instead of a preview image for animated gifs
|
||||
if gifConfig, err := gif.DecodeAll(bytes.NewReader(data)); err != nil {
|
||||
// Still return the rest of the info even though it doesn't appear to be an actual gif
|
||||
info.HasPreviewImage = true
|
||||
err = NewAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, "name="+name, http.StatusBadRequest)
|
||||
} else {
|
||||
info.HasPreviewImage = len(gifConfig.Image) == 1
|
||||
}
|
||||
} else {
|
||||
info.HasPreviewImage = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return info, err
|
||||
}
|
||||
|
||||
func GetEtagForFileInfos(infos []*FileInfo) string {
|
||||
if len(infos) == 0 {
|
||||
return Etag()
|
||||
}
|
||||
|
||||
var maxUpdateAt int64
|
||||
|
||||
for _, info := range infos {
|
||||
if info.UpdateAt > maxUpdateAt {
|
||||
maxUpdateAt = info.UpdateAt
|
||||
}
|
||||
}
|
||||
|
||||
return Etag(infos[0].PostId, maxUpdateAt)
|
||||
}
|
8
build/manifest/vendor/github.com/mattermost/mattermost-server/model/gitlab.go
generated
vendored
8
build/manifest/vendor/github.com/mattermost/mattermost-server/model/gitlab.go
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
USER_AUTH_SERVICE_GITLAB = "gitlab"
|
||||
)
|
216
build/manifest/vendor/github.com/mattermost/mattermost-server/model/incoming_webhook.go
generated
vendored
216
build/manifest/vendor/github.com/mattermost/mattermost-server/model/incoming_webhook.go
generated
vendored
|
@ -1,216 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_WEBHOOK_USERNAME = "webhook"
|
||||
)
|
||||
|
||||
type IncomingWebhook struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
ChannelLocked bool `json:"channel_locked"`
|
||||
}
|
||||
|
||||
type IncomingWebhookRequest struct {
|
||||
Text string `json:"text"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
ChannelName string `json:"channel"`
|
||||
Props StringInterface `json:"props"`
|
||||
Attachments []*SlackAttachment `json:"attachments"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
func (o *IncomingWebhook) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func IncomingWebhookFromJson(data io.Reader) *IncomingWebhook {
|
||||
var o *IncomingWebhook
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func IncomingWebhookListToJson(l []*IncomingWebhook) string {
|
||||
b, _ := json.Marshal(l)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func IncomingWebhookListFromJson(data io.Reader) []*IncomingWebhook {
|
||||
var o []*IncomingWebhook
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *IncomingWebhook) IsValid() *AppError {
|
||||
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.id.app_error", nil, "", http.StatusBadRequest)
|
||||
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ChannelId) != 26 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.team_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.DisplayName) > 64 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.display_name.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Description) > 500 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.description.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Username) > 64 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.username.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.IconURL) > 1024 {
|
||||
return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.icon_url.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *IncomingWebhook) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
o.CreateAt = GetMillis()
|
||||
o.UpdateAt = o.CreateAt
|
||||
}
|
||||
|
||||
func (o *IncomingWebhook) PreUpdate() {
|
||||
o.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
// escapeControlCharsFromPayload escapes control chars (\n, \t) from a byte slice.
|
||||
// Context:
|
||||
// JSON strings are not supposed to contain control characters such as \n, \t,
|
||||
// ... but some incoming webhooks might still send invalid JSON and we want to
|
||||
// try to handle that. An example invalid JSON string from an incoming webhook
|
||||
// might look like this (strings for both "text" and "fallback" attributes are
|
||||
// invalid JSON strings because they contain unescaped newlines and tabs):
|
||||
// `{
|
||||
// "text": "this is a test
|
||||
// that contains a newline and tabs",
|
||||
// "attachments": [
|
||||
// {
|
||||
// "fallback": "Required plain-text summary of the attachment
|
||||
// that contains a newline and tabs",
|
||||
// "color": "#36a64f",
|
||||
// ...
|
||||
// "text": "Optional text that appears within the attachment
|
||||
// that contains a newline and tabs",
|
||||
// ...
|
||||
// "thumb_url": "http://example.com/path/to/thumb.png"
|
||||
// }
|
||||
// ]
|
||||
// }`
|
||||
// This function will search for `"key": "value"` pairs, and escape \n, \t
|
||||
// from the value.
|
||||
func escapeControlCharsFromPayload(by []byte) []byte {
|
||||
// we'll search for `"text": "..."` or `"fallback": "..."`, ...
|
||||
keys := "text|fallback|pretext|author_name|title|value"
|
||||
|
||||
// the regexp reads like this:
|
||||
// (?s): this flag let . match \n (default is false)
|
||||
// "(keys)": we search for the keys defined above
|
||||
// \s*:\s*: followed by 0..n spaces/tabs, a colon then 0..n spaces/tabs
|
||||
// ": a double-quote
|
||||
// (\\"|[^"])*: any number of times the `\"` string or any char but a double-quote
|
||||
// ": a double-quote
|
||||
r := `(?s)"(` + keys + `)"\s*:\s*"(\\"|[^"])*"`
|
||||
re := regexp.MustCompile(r)
|
||||
|
||||
// the function that will escape \n and \t on the regexp matches
|
||||
repl := func(b []byte) []byte {
|
||||
if bytes.Contains(b, []byte("\n")) {
|
||||
b = bytes.Replace(b, []byte("\n"), []byte("\\n"), -1)
|
||||
}
|
||||
if bytes.Contains(b, []byte("\t")) {
|
||||
b = bytes.Replace(b, []byte("\t"), []byte("\\t"), -1)
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
return re.ReplaceAllFunc(by, repl)
|
||||
}
|
||||
|
||||
func decodeIncomingWebhookRequest(by []byte) (*IncomingWebhookRequest, error) {
|
||||
decoder := json.NewDecoder(bytes.NewReader(by))
|
||||
var o IncomingWebhookRequest
|
||||
err := decoder.Decode(&o)
|
||||
if err == nil {
|
||||
return &o, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func IncomingWebhookRequestFromJson(data io.Reader) (*IncomingWebhookRequest, *AppError) {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(data)
|
||||
by := buf.Bytes()
|
||||
|
||||
// Try to decode the JSON data. Only if it fails, try to escape control
|
||||
// characters from the strings contained in the JSON data.
|
||||
o, err := decodeIncomingWebhookRequest(by)
|
||||
if err != nil {
|
||||
o, err = decodeIncomingWebhookRequest(escapeControlCharsFromPayload(by))
|
||||
if err != nil {
|
||||
return nil, NewAppError("IncomingWebhookRequestFromJson", "model.incoming_hook.parse_data.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
o.Attachments = StringifySlackFieldValue(o.Attachments)
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func (o *IncomingWebhookRequest) ToJson() string {
|
||||
b, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
30
build/manifest/vendor/github.com/mattermost/mattermost-server/model/initial_load.go
generated
vendored
30
build/manifest/vendor/github.com/mattermost/mattermost-server/model/initial_load.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type InitialLoad struct {
|
||||
User *User `json:"user"`
|
||||
TeamMembers []*TeamMember `json:"team_members"`
|
||||
Teams []*Team `json:"teams"`
|
||||
Preferences Preferences `json:"preferences"`
|
||||
ClientCfg map[string]string `json:"client_cfg"`
|
||||
LicenseCfg map[string]string `json:"license_cfg"`
|
||||
NoAccounts bool `json:"no_accounts"`
|
||||
}
|
||||
|
||||
func (me *InitialLoad) ToJson() string {
|
||||
b, _ := json.Marshal(me)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func InitialLoadFromJson(data io.Reader) *InitialLoad {
|
||||
var o *InitialLoad
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
294
build/manifest/vendor/github.com/mattermost/mattermost-server/model/integration_action.go
generated
vendored
294
build/manifest/vendor/github.com/mattermost/mattermost-server/model/integration_action.go
generated
vendored
|
@ -1,294 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
POST_ACTION_TYPE_BUTTON = "button"
|
||||
POST_ACTION_TYPE_SELECT = "select"
|
||||
INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS = 3000
|
||||
)
|
||||
|
||||
type DoPostActionRequest struct {
|
||||
SelectedOption string `json:"selected_option"`
|
||||
}
|
||||
|
||||
type PostAction struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
DataSource string `json:"data_source"`
|
||||
Options []*PostActionOptions `json:"options"`
|
||||
Integration *PostActionIntegration `json:"integration,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionOptions struct {
|
||||
Text string `json:"text"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type PostActionIntegration struct {
|
||||
URL string `json:"url,omitempty"`
|
||||
Context map[string]interface{} `json:"context,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionIntegrationRequest struct {
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
PostId string `json:"post_id"`
|
||||
TriggerId string `json:"trigger_id"`
|
||||
Type string `json:"type"`
|
||||
DataSource string `json:"data_source"`
|
||||
Context map[string]interface{} `json:"context,omitempty"`
|
||||
}
|
||||
|
||||
type PostActionIntegrationResponse struct {
|
||||
Update *Post `json:"update"`
|
||||
EphemeralText string `json:"ephemeral_text"`
|
||||
}
|
||||
|
||||
type PostActionAPIResponse struct {
|
||||
Status string `json:"status"` // needed to maintain backwards compatibility
|
||||
TriggerId string `json:"trigger_id"`
|
||||
}
|
||||
|
||||
type Dialog struct {
|
||||
CallbackId string `json:"callback_id"`
|
||||
Title string `json:"title"`
|
||||
IconURL string `json:"icon_url"`
|
||||
Elements []DialogElement `json:"elements"`
|
||||
SubmitLabel string `json:"submit_label"`
|
||||
NotifyOnCancel bool `json:"notify_on_cancel"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
type DialogElement struct {
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
SubType string `json:"subtype"`
|
||||
Default string `json:"default"`
|
||||
Placeholder string `json:"placeholder"`
|
||||
HelpText string `json:"help_text"`
|
||||
Optional bool `json:"optional"`
|
||||
MinLength int `json:"min_length"`
|
||||
MaxLength int `json:"max_length"`
|
||||
DataSource string `json:"data_source"`
|
||||
Options []*PostActionOptions `json:"options"`
|
||||
}
|
||||
|
||||
type OpenDialogRequest struct {
|
||||
TriggerId string `json:"trigger_id"`
|
||||
URL string `json:"url"`
|
||||
Dialog Dialog `json:"dialog"`
|
||||
}
|
||||
|
||||
type SubmitDialogRequest struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url,omitempty"`
|
||||
CallbackId string `json:"callback_id"`
|
||||
State string `json:"state"`
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
Submission map[string]interface{} `json:"submission"`
|
||||
Cancelled bool `json:"cancelled"`
|
||||
}
|
||||
|
||||
type SubmitDialogResponse struct {
|
||||
Errors map[string]string `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
func GenerateTriggerId(userId string, s crypto.Signer) (string, string, *AppError) {
|
||||
clientTriggerId := NewId()
|
||||
triggerData := strings.Join([]string{clientTriggerId, userId, strconv.FormatInt(GetMillis(), 10)}, ":") + ":"
|
||||
|
||||
h := crypto.SHA256
|
||||
sum := h.New()
|
||||
sum.Write([]byte(triggerData))
|
||||
signature, err := s.Sign(rand.Reader, sum.Sum(nil), h)
|
||||
if err != nil {
|
||||
return "", "", NewAppError("GenerateTriggerId", "interactive_message.generate_trigger_id.signing_failed", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
base64Sig := base64.StdEncoding.EncodeToString(signature)
|
||||
|
||||
triggerId := base64.StdEncoding.EncodeToString([]byte(triggerData + base64Sig))
|
||||
return clientTriggerId, triggerId, nil
|
||||
}
|
||||
|
||||
func (r *PostActionIntegrationRequest) GenerateTriggerId(s crypto.Signer) (string, string, *AppError) {
|
||||
clientTriggerId, triggerId, err := GenerateTriggerId(r.UserId, s)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
r.TriggerId = triggerId
|
||||
return clientTriggerId, triggerId, nil
|
||||
}
|
||||
|
||||
func DecodeAndVerifyTriggerId(triggerId string, s *ecdsa.PrivateKey) (string, string, *AppError) {
|
||||
triggerIdBytes, err := base64.StdEncoding.DecodeString(triggerId)
|
||||
if err != nil {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
split := strings.Split(string(triggerIdBytes), ":")
|
||||
if len(split) != 4 {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.missing_data", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
clientTriggerId := split[0]
|
||||
userId := split[1]
|
||||
timestampStr := split[2]
|
||||
timestamp, _ := strconv.ParseInt(timestampStr, 10, 64)
|
||||
|
||||
now := GetMillis()
|
||||
if now-timestamp > INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.expired", map[string]interface{}{"Seconds": INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS / 1000}, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
signature, err := base64.StdEncoding.DecodeString(split[3])
|
||||
if err != nil {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed_signature", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
var esig struct {
|
||||
R, S *big.Int
|
||||
}
|
||||
|
||||
if _, err := asn1.Unmarshal([]byte(signature), &esig); err != nil {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.signature_decode_failed", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
triggerData := strings.Join([]string{clientTriggerId, userId, timestampStr}, ":") + ":"
|
||||
|
||||
h := crypto.SHA256
|
||||
sum := h.New()
|
||||
sum.Write([]byte(triggerData))
|
||||
|
||||
if !ecdsa.Verify(&s.PublicKey, sum.Sum(nil), esig.R, esig.S) {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.verify_signature_failed", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return clientTriggerId, userId, nil
|
||||
}
|
||||
|
||||
func (r *OpenDialogRequest) DecodeAndVerifyTriggerId(s *ecdsa.PrivateKey) (string, string, *AppError) {
|
||||
return DecodeAndVerifyTriggerId(r.TriggerId, s)
|
||||
}
|
||||
|
||||
func (r *PostActionIntegrationRequest) ToJson() []byte {
|
||||
b, _ := json.Marshal(r)
|
||||
return b
|
||||
}
|
||||
|
||||
func PostActionIntegrationRequestFromJson(data io.Reader) *PostActionIntegrationRequest {
|
||||
var o *PostActionIntegrationRequest
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (r *PostActionIntegrationResponse) ToJson() []byte {
|
||||
b, _ := json.Marshal(r)
|
||||
return b
|
||||
}
|
||||
|
||||
func PostActionIntegrationResponseFromJson(data io.Reader) *PostActionIntegrationResponse {
|
||||
var o *PostActionIntegrationResponse
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func SubmitDialogRequestFromJson(data io.Reader) *SubmitDialogRequest {
|
||||
var o *SubmitDialogRequest
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (r *SubmitDialogRequest) ToJson() []byte {
|
||||
b, _ := json.Marshal(r)
|
||||
return b
|
||||
}
|
||||
|
||||
func SubmitDialogResponseFromJson(data io.Reader) *SubmitDialogResponse {
|
||||
var o *SubmitDialogResponse
|
||||
err := json.NewDecoder(data).Decode(&o)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (r *SubmitDialogResponse) ToJson() []byte {
|
||||
b, _ := json.Marshal(r)
|
||||
return b
|
||||
}
|
||||
|
||||
func (o *Post) StripActionIntegrations() {
|
||||
attachments := o.Attachments()
|
||||
if o.Props["attachments"] != nil {
|
||||
o.Props["attachments"] = attachments
|
||||
}
|
||||
for _, attachment := range attachments {
|
||||
for _, action := range attachment.Actions {
|
||||
action.Integration = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Post) GetAction(id string) *PostAction {
|
||||
for _, attachment := range o.Attachments() {
|
||||
for _, action := range attachment.Actions {
|
||||
if action.Id == id {
|
||||
return action
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Post) GenerateActionIds() {
|
||||
if o.Props["attachments"] != nil {
|
||||
o.Props["attachments"] = o.Attachments()
|
||||
}
|
||||
if attachments, ok := o.Props["attachments"].([]*SlackAttachment); ok {
|
||||
for _, attachment := range attachments {
|
||||
for _, action := range attachment.Actions {
|
||||
if action.Id == "" {
|
||||
action.Id = NewId()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DoPostActionRequestFromJson(data io.Reader) *DoPostActionRequest {
|
||||
var o *DoPostActionRequest
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
121
build/manifest/vendor/github.com/mattermost/mattermost-server/model/job.go
generated
vendored
121
build/manifest/vendor/github.com/mattermost/mattermost-server/model/job.go
generated
vendored
|
@ -1,121 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
JOB_TYPE_DATA_RETENTION = "data_retention"
|
||||
JOB_TYPE_MESSAGE_EXPORT = "message_export"
|
||||
JOB_TYPE_ELASTICSEARCH_POST_INDEXING = "elasticsearch_post_indexing"
|
||||
JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION = "elasticsearch_post_aggregation"
|
||||
JOB_TYPE_LDAP_SYNC = "ldap_sync"
|
||||
JOB_TYPE_MIGRATIONS = "migrations"
|
||||
JOB_TYPE_PLUGINS = "plugins"
|
||||
|
||||
JOB_STATUS_PENDING = "pending"
|
||||
JOB_STATUS_IN_PROGRESS = "in_progress"
|
||||
JOB_STATUS_SUCCESS = "success"
|
||||
JOB_STATUS_ERROR = "error"
|
||||
JOB_STATUS_CANCEL_REQUESTED = "cancel_requested"
|
||||
JOB_STATUS_CANCELED = "canceled"
|
||||
)
|
||||
|
||||
type Job struct {
|
||||
Id string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Priority int64 `json:"priority"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
StartAt int64 `json:"start_at"`
|
||||
LastActivityAt int64 `json:"last_activity_at"`
|
||||
Status string `json:"status"`
|
||||
Progress int64 `json:"progress"`
|
||||
Data map[string]string `json:"data"`
|
||||
}
|
||||
|
||||
func (j *Job) IsValid() *AppError {
|
||||
if len(j.Id) != 26 {
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.id.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if j.CreateAt == 0 {
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.create_at.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
switch j.Type {
|
||||
case JOB_TYPE_DATA_RETENTION:
|
||||
case JOB_TYPE_ELASTICSEARCH_POST_INDEXING:
|
||||
case JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION:
|
||||
case JOB_TYPE_LDAP_SYNC:
|
||||
case JOB_TYPE_MESSAGE_EXPORT:
|
||||
case JOB_TYPE_MIGRATIONS:
|
||||
default:
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.type.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
switch j.Status {
|
||||
case JOB_STATUS_PENDING:
|
||||
case JOB_STATUS_IN_PROGRESS:
|
||||
case JOB_STATUS_SUCCESS:
|
||||
case JOB_STATUS_ERROR:
|
||||
case JOB_STATUS_CANCEL_REQUESTED:
|
||||
case JOB_STATUS_CANCELED:
|
||||
default:
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.status.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (js *Job) ToJson() string {
|
||||
b, _ := json.Marshal(js)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func JobFromJson(data io.Reader) *Job {
|
||||
var job Job
|
||||
if err := json.NewDecoder(data).Decode(&job); err == nil {
|
||||
return &job
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func JobsToJson(jobs []*Job) string {
|
||||
b, _ := json.Marshal(jobs)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func JobsFromJson(data io.Reader) []*Job {
|
||||
var jobs []*Job
|
||||
if err := json.NewDecoder(data).Decode(&jobs); err == nil {
|
||||
return jobs
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (js *Job) DataToJson() string {
|
||||
b, _ := json.Marshal(js.Data)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
type Worker interface {
|
||||
Run()
|
||||
Stop()
|
||||
JobChannel() chan<- Job
|
||||
}
|
||||
|
||||
type Scheduler interface {
|
||||
Name() string
|
||||
JobType() string
|
||||
Enabled(cfg *Config) bool
|
||||
NextScheduleTime(cfg *Config, now time.Time, pendingJobs bool, lastSuccessfulJob *Job) *time.Time
|
||||
ScheduleJob(cfg *Config, pendingJobs bool, lastSuccessfulJob *Job) (*Job, *AppError)
|
||||
}
|
8
build/manifest/vendor/github.com/mattermost/mattermost-server/model/ldap.go
generated
vendored
8
build/manifest/vendor/github.com/mattermost/mattermost-server/model/ldap.go
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
USER_AUTH_SERVICE_LDAP = "ldap"
|
||||
)
|
220
build/manifest/vendor/github.com/mattermost/mattermost-server/model/license.go
generated
vendored
220
build/manifest/vendor/github.com/mattermost/mattermost-server/model/license.go
generated
vendored
|
@ -1,220 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
EXPIRED_LICENSE_ERROR = "api.license.add_license.expired.app_error"
|
||||
INVALID_LICENSE_ERROR = "api.license.add_license.invalid.app_error"
|
||||
)
|
||||
|
||||
type LicenseRecord struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
Bytes string `json:"-"`
|
||||
}
|
||||
|
||||
type License struct {
|
||||
Id string `json:"id"`
|
||||
IssuedAt int64 `json:"issued_at"`
|
||||
StartsAt int64 `json:"starts_at"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
Customer *Customer `json:"customer"`
|
||||
Features *Features `json:"features"`
|
||||
SkuName string `json:"sku_name"`
|
||||
SkuShortName string `json:"sku_short_name"`
|
||||
}
|
||||
|
||||
type Customer struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Company string `json:"company"`
|
||||
PhoneNumber string `json:"phone_number"`
|
||||
}
|
||||
|
||||
type Features struct {
|
||||
Users *int `json:"users"`
|
||||
LDAP *bool `json:"ldap"`
|
||||
MFA *bool `json:"mfa"`
|
||||
GoogleOAuth *bool `json:"google_oauth"`
|
||||
Office365OAuth *bool `json:"office365_oauth"`
|
||||
Compliance *bool `json:"compliance"`
|
||||
Cluster *bool `json:"cluster"`
|
||||
Metrics *bool `json:"metrics"`
|
||||
MHPNS *bool `json:"mhpns"`
|
||||
SAML *bool `json:"saml"`
|
||||
Elasticsearch *bool `json:"elastic_search"`
|
||||
Announcement *bool `json:"announcement"`
|
||||
ThemeManagement *bool `json:"theme_management"`
|
||||
EmailNotificationContents *bool `json:"email_notification_contents"`
|
||||
DataRetention *bool `json:"data_retention"`
|
||||
MessageExport *bool `json:"message_export"`
|
||||
CustomPermissionsSchemes *bool `json:"custom_permissions_schemes"`
|
||||
CustomTermsOfService *bool `json:"custom_terms_of_service"`
|
||||
|
||||
// after we enabled more features we'll need to control them with this
|
||||
FutureFeatures *bool `json:"future_features"`
|
||||
}
|
||||
|
||||
func (f *Features) ToMap() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"ldap": *f.LDAP,
|
||||
"mfa": *f.MFA,
|
||||
"google": *f.GoogleOAuth,
|
||||
"office365": *f.Office365OAuth,
|
||||
"compliance": *f.Compliance,
|
||||
"cluster": *f.Cluster,
|
||||
"metrics": *f.Metrics,
|
||||
"mhpns": *f.MHPNS,
|
||||
"saml": *f.SAML,
|
||||
"elastic_search": *f.Elasticsearch,
|
||||
"email_notification_contents": *f.EmailNotificationContents,
|
||||
"data_retention": *f.DataRetention,
|
||||
"message_export": *f.MessageExport,
|
||||
"custom_permissions_schemes": *f.CustomPermissionsSchemes,
|
||||
"future": *f.FutureFeatures,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Features) SetDefaults() {
|
||||
if f.FutureFeatures == nil {
|
||||
f.FutureFeatures = NewBool(true)
|
||||
}
|
||||
|
||||
if f.Users == nil {
|
||||
f.Users = NewInt(0)
|
||||
}
|
||||
|
||||
if f.LDAP == nil {
|
||||
f.LDAP = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.MFA == nil {
|
||||
f.MFA = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.GoogleOAuth == nil {
|
||||
f.GoogleOAuth = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.Office365OAuth == nil {
|
||||
f.Office365OAuth = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.Compliance == nil {
|
||||
f.Compliance = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.Cluster == nil {
|
||||
f.Cluster = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.Metrics == nil {
|
||||
f.Metrics = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.MHPNS == nil {
|
||||
f.MHPNS = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.SAML == nil {
|
||||
f.SAML = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.Elasticsearch == nil {
|
||||
f.Elasticsearch = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.Announcement == nil {
|
||||
f.Announcement = NewBool(true)
|
||||
}
|
||||
|
||||
if f.ThemeManagement == nil {
|
||||
f.ThemeManagement = NewBool(true)
|
||||
}
|
||||
|
||||
if f.EmailNotificationContents == nil {
|
||||
f.EmailNotificationContents = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.DataRetention == nil {
|
||||
f.DataRetention = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.MessageExport == nil {
|
||||
f.MessageExport = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.CustomPermissionsSchemes == nil {
|
||||
f.CustomPermissionsSchemes = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
|
||||
if f.CustomTermsOfService == nil {
|
||||
f.CustomTermsOfService = NewBool(*f.FutureFeatures)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *License) IsExpired() bool {
|
||||
return l.ExpiresAt < GetMillis()
|
||||
}
|
||||
|
||||
func (l *License) IsStarted() bool {
|
||||
return l.StartsAt < GetMillis()
|
||||
}
|
||||
|
||||
func (l *License) ToJson() string {
|
||||
b, _ := json.Marshal(l)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// NewTestLicense returns a license that expires in the future and has the given features.
|
||||
func NewTestLicense(features ...string) *License {
|
||||
ret := &License{
|
||||
ExpiresAt: GetMillis() + 90*24*60*60*1000,
|
||||
Customer: &Customer{},
|
||||
Features: &Features{},
|
||||
}
|
||||
ret.Features.SetDefaults()
|
||||
|
||||
featureMap := map[string]bool{}
|
||||
for _, feature := range features {
|
||||
featureMap[feature] = true
|
||||
}
|
||||
featureJson, _ := json.Marshal(featureMap)
|
||||
json.Unmarshal(featureJson, &ret.Features)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func LicenseFromJson(data io.Reader) *License {
|
||||
var o *License
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (lr *LicenseRecord) IsValid() *AppError {
|
||||
if len(lr.Id) != 26 {
|
||||
return NewAppError("LicenseRecord.IsValid", "model.license_record.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if lr.CreateAt == 0 {
|
||||
return NewAppError("LicenseRecord.IsValid", "model.license_record.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(lr.Bytes) == 0 || len(lr.Bytes) > 10000 {
|
||||
return NewAppError("LicenseRecord.IsValid", "model.license_record.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lr *LicenseRecord) PreSave() {
|
||||
lr.CreateAt = GetMillis()
|
||||
}
|
312
build/manifest/vendor/github.com/mattermost/mattermost-server/model/manifest.go
generated
vendored
312
build/manifest/vendor/github.com/mattermost/mattermost-server/model/manifest.go
generated
vendored
|
@ -1,312 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type PluginOption struct {
|
||||
// The display name for the option.
|
||||
DisplayName string `json:"display_name" yaml:"display_name"`
|
||||
|
||||
// The string value for the option.
|
||||
Value string `json:"value" yaml:"value"`
|
||||
}
|
||||
|
||||
type PluginSetting struct {
|
||||
// The key that the setting will be assigned to in the configuration file.
|
||||
Key string `json:"key" yaml:"key"`
|
||||
|
||||
// The display name for the setting.
|
||||
DisplayName string `json:"display_name" yaml:"display_name"`
|
||||
|
||||
// The type of the setting.
|
||||
//
|
||||
// "bool" will result in a boolean true or false setting.
|
||||
//
|
||||
// "dropdown" will result in a string setting that allows the user to select from a list of
|
||||
// pre-defined options.
|
||||
//
|
||||
// "generated" will result in a string setting that is set to a random, cryptographically secure
|
||||
// string.
|
||||
//
|
||||
// "radio" will result in a string setting that allows the user to select from a short selection
|
||||
// of pre-defined options.
|
||||
//
|
||||
// "text" will result in a string setting that can be typed in manually.
|
||||
//
|
||||
// "longtext" will result in a multi line string that can be typed in manually.
|
||||
//
|
||||
// "username" will result in a text setting that will autocomplete to a username.
|
||||
Type string `json:"type" yaml:"type"`
|
||||
|
||||
// The help text to display to the user.
|
||||
HelpText string `json:"help_text" yaml:"help_text"`
|
||||
|
||||
// The help text to display alongside the "Regenerate" button for settings of the "generated" type.
|
||||
RegenerateHelpText string `json:"regenerate_help_text,omitempty" yaml:"regenerate_help_text,omitempty"`
|
||||
|
||||
// The placeholder to display for "text", "generated" and "username" types when blank.
|
||||
Placeholder string `json:"placeholder" yaml:"placeholder"`
|
||||
|
||||
// The default value of the setting.
|
||||
Default interface{} `json:"default" yaml:"default"`
|
||||
|
||||
// For "radio" or "dropdown" settings, this is the list of pre-defined options that the user can choose
|
||||
// from.
|
||||
Options []*PluginOption `json:"options,omitempty" yaml:"options,omitempty"`
|
||||
}
|
||||
|
||||
type PluginSettingsSchema struct {
|
||||
// Optional text to display above the settings.
|
||||
Header string `json:"header" yaml:"header"`
|
||||
|
||||
// Optional text to display below the settings.
|
||||
Footer string `json:"footer" yaml:"footer"`
|
||||
|
||||
// A list of setting definitions.
|
||||
Settings []*PluginSetting `json:"settings" yaml:"settings"`
|
||||
}
|
||||
|
||||
// The plugin manifest defines the metadata required to load and present your plugin. The manifest
|
||||
// file should be named plugin.json or plugin.yaml and placed in the top of your
|
||||
// plugin bundle.
|
||||
//
|
||||
// Example plugin.yaml:
|
||||
//
|
||||
// id: com.mycompany.myplugin
|
||||
// name: My Plugin
|
||||
// description: This is my plugin. It does stuff.
|
||||
// server:
|
||||
// executable: myplugin
|
||||
// settings_schema:
|
||||
// settings:
|
||||
// - key: enable_extra_thing
|
||||
// type: bool
|
||||
// display_name: Enable Extra Thing
|
||||
// help_text: When true, an extra thing will be enabled!
|
||||
// default: false
|
||||
type Manifest struct {
|
||||
// The id is a globally unique identifier that represents your plugin. Ids must be at least
|
||||
// 3 characters, at most 190 characters and must match ^[a-zA-Z0-9-_\.]+$.
|
||||
// Reverse-DNS notation using a name you control is a good option, e.g. "com.mycompany.myplugin".
|
||||
Id string `json:"id" yaml:"id"`
|
||||
|
||||
// The name to be displayed for the plugin.
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
|
||||
// A description of what your plugin is and does.
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
|
||||
// A version number for your plugin. Semantic versioning is recommended: http://semver.org
|
||||
Version string `json:"version" yaml:"version"`
|
||||
|
||||
// The minimum Mattermost server version required for your plugin.
|
||||
//
|
||||
// Minimum server version: 5.6
|
||||
MinServerVersion string `json:"min_server_version,omitempty" yaml:"min_server_version,omitempty"`
|
||||
|
||||
// Server defines the server-side portion of your plugin.
|
||||
Server *ManifestServer `json:"server,omitempty" yaml:"server,omitempty"`
|
||||
|
||||
// Backend is a deprecated flag for defining the server-side portion of your plugin. Going forward, use Server instead.
|
||||
Backend *ManifestServer `json:"backend,omitempty" yaml:"backend,omitempty"`
|
||||
|
||||
// If your plugin extends the web app, you'll need to define webapp.
|
||||
Webapp *ManifestWebapp `json:"webapp,omitempty" yaml:"webapp,omitempty"`
|
||||
|
||||
// To allow administrators to configure your plugin via the Mattermost system console, you can
|
||||
// provide your settings schema.
|
||||
SettingsSchema *PluginSettingsSchema `json:"settings_schema,omitempty" yaml:"settings_schema,omitempty"`
|
||||
}
|
||||
|
||||
type ManifestServer struct {
|
||||
// Executables are the paths to your executable binaries, specifying multiple entry points
|
||||
// for different platforms when bundled together in a single plugin.
|
||||
Executables *ManifestExecutables `json:"executables,omitempty" yaml:"executables,omitempty"`
|
||||
|
||||
// Executable is the path to your executable binary. This should be relative to the root
|
||||
// of your bundle and the location of the manifest file.
|
||||
//
|
||||
// On Windows, this file must have a ".exe" extension.
|
||||
//
|
||||
// If your plugin is compiled for multiple platforms, consider bundling them together
|
||||
// and using the Executables field instead.
|
||||
Executable string `json:"executable" yaml:"executable"`
|
||||
}
|
||||
|
||||
type ManifestExecutables struct {
|
||||
// LinuxAmd64 is the path to your executable binary for the corresponding platform
|
||||
LinuxAmd64 string `json:"linux-amd64,omitempty" yaml:"linux-amd64,omitempty"`
|
||||
// DarwinAmd64 is the path to your executable binary for the corresponding platform
|
||||
DarwinAmd64 string `json:"darwin-amd64,omitempty" yaml:"darwin-amd64,omitempty"`
|
||||
// WindowsAmd64 is the path to your executable binary for the corresponding platform
|
||||
// This file must have a ".exe" extension
|
||||
WindowsAmd64 string `json:"windows-amd64,omitempty" yaml:"windows-amd64,omitempty"`
|
||||
}
|
||||
|
||||
type ManifestWebapp struct {
|
||||
// The path to your webapp bundle. This should be relative to the root of your bundle and the
|
||||
// location of the manifest file.
|
||||
BundlePath string `json:"bundle_path" yaml:"bundle_path"`
|
||||
|
||||
// BundleHash is the 64-bit FNV-1a hash of the webapp bundle, computed when the plugin is loaded
|
||||
BundleHash []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Manifest) ToJson() string {
|
||||
b, _ := json.Marshal(m)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ManifestListToJson(m []*Manifest) string {
|
||||
b, _ := json.Marshal(m)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func ManifestFromJson(data io.Reader) *Manifest {
|
||||
var m *Manifest
|
||||
json.NewDecoder(data).Decode(&m)
|
||||
return m
|
||||
}
|
||||
|
||||
func ManifestListFromJson(data io.Reader) []*Manifest {
|
||||
var manifests []*Manifest
|
||||
json.NewDecoder(data).Decode(&manifests)
|
||||
return manifests
|
||||
}
|
||||
|
||||
func (m *Manifest) HasClient() bool {
|
||||
return m.Webapp != nil
|
||||
}
|
||||
|
||||
func (m *Manifest) ClientManifest() *Manifest {
|
||||
cm := new(Manifest)
|
||||
*cm = *m
|
||||
cm.Name = ""
|
||||
cm.Description = ""
|
||||
cm.Server = nil
|
||||
if cm.Webapp != nil {
|
||||
cm.Webapp = new(ManifestWebapp)
|
||||
*cm.Webapp = *m.Webapp
|
||||
cm.Webapp.BundlePath = "/static/" + m.Id + "/" + fmt.Sprintf("%s_%x_bundle.js", m.Id, m.Webapp.BundleHash)
|
||||
}
|
||||
return cm
|
||||
}
|
||||
|
||||
// GetExecutableForRuntime returns the path to the executable for the given runtime architecture.
|
||||
//
|
||||
// If the manifest defines multiple executables, but none match, or if only a single executable
|
||||
// is defined, the Executable field will be returned. This method does not guarantee that the
|
||||
// resulting binary can actually execute on the given platform.
|
||||
func (m *Manifest) GetExecutableForRuntime(goOs, goArch string) string {
|
||||
server := m.Server
|
||||
|
||||
// Support the deprecated backend parameter.
|
||||
if server == nil {
|
||||
server = m.Backend
|
||||
}
|
||||
|
||||
if server == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
var executable string
|
||||
if server.Executables != nil {
|
||||
if goOs == "linux" && goArch == "amd64" {
|
||||
executable = server.Executables.LinuxAmd64
|
||||
} else if goOs == "darwin" && goArch == "amd64" {
|
||||
executable = server.Executables.DarwinAmd64
|
||||
} else if goOs == "windows" && goArch == "amd64" {
|
||||
executable = server.Executables.WindowsAmd64
|
||||
}
|
||||
}
|
||||
|
||||
if executable == "" {
|
||||
executable = server.Executable
|
||||
}
|
||||
|
||||
return executable
|
||||
}
|
||||
|
||||
func (m *Manifest) HasServer() bool {
|
||||
return m.Server != nil || m.Backend != nil
|
||||
}
|
||||
|
||||
func (m *Manifest) HasWebapp() bool {
|
||||
return m.Webapp != nil
|
||||
}
|
||||
|
||||
func (m *Manifest) MeetMinServerVersion(serverVersion string) (bool, error) {
|
||||
minServerVersion, err := semver.Parse(m.MinServerVersion)
|
||||
if err != nil {
|
||||
return false, errors.New("failed to parse MinServerVersion")
|
||||
}
|
||||
sv := semver.MustParse(serverVersion)
|
||||
if sv.LT(minServerVersion) {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// FindManifest will find and parse the manifest in a given directory.
|
||||
//
|
||||
// In all cases other than a does-not-exist error, path is set to the path of the manifest file that was
|
||||
// found.
|
||||
//
|
||||
// Manifests are JSON or YAML files named plugin.json, plugin.yaml, or plugin.yml.
|
||||
func FindManifest(dir string) (manifest *Manifest, path string, err error) {
|
||||
for _, name := range []string{"plugin.yml", "plugin.yaml"} {
|
||||
path = filepath.Join(dir, name)
|
||||
f, ferr := os.Open(path)
|
||||
if ferr != nil {
|
||||
if !os.IsNotExist(ferr) {
|
||||
return nil, "", ferr
|
||||
}
|
||||
continue
|
||||
}
|
||||
b, ioerr := ioutil.ReadAll(f)
|
||||
f.Close()
|
||||
if ioerr != nil {
|
||||
return nil, path, ioerr
|
||||
}
|
||||
var parsed Manifest
|
||||
err = yaml.Unmarshal(b, &parsed)
|
||||
if err != nil {
|
||||
return nil, path, err
|
||||
}
|
||||
manifest = &parsed
|
||||
manifest.Id = strings.ToLower(manifest.Id)
|
||||
return manifest, path, nil
|
||||
}
|
||||
|
||||
path = filepath.Join(dir, "plugin.json")
|
||||
f, ferr := os.Open(path)
|
||||
if ferr != nil {
|
||||
if os.IsNotExist(ferr) {
|
||||
path = ""
|
||||
}
|
||||
return nil, path, ferr
|
||||
}
|
||||
defer f.Close()
|
||||
var parsed Manifest
|
||||
err = json.NewDecoder(f).Decode(&parsed)
|
||||
if err != nil {
|
||||
return nil, path, err
|
||||
}
|
||||
manifest = &parsed
|
||||
manifest.Id = strings.ToLower(manifest.Id)
|
||||
return manifest, path, nil
|
||||
}
|
27
build/manifest/vendor/github.com/mattermost/mattermost-server/model/message_export.go
generated
vendored
27
build/manifest/vendor/github.com/mattermost/mattermost-server/model/message_export.go
generated
vendored
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
type MessageExport struct {
|
||||
TeamId *string
|
||||
TeamName *string
|
||||
TeamDisplayName *string
|
||||
|
||||
ChannelId *string
|
||||
ChannelName *string
|
||||
ChannelDisplayName *string
|
||||
ChannelType *string
|
||||
|
||||
UserId *string
|
||||
UserEmail *string
|
||||
Username *string
|
||||
|
||||
PostId *string
|
||||
PostCreateAt *int64
|
||||
PostMessage *string
|
||||
PostType *string
|
||||
PostRootId *string
|
||||
PostOriginalId *string
|
||||
PostFileIds StringArray
|
||||
}
|
25
build/manifest/vendor/github.com/mattermost/mattermost-server/model/mfa_secret.go
generated
vendored
25
build/manifest/vendor/github.com/mattermost/mattermost-server/model/mfa_secret.go
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type MfaSecret struct {
|
||||
Secret string `json:"secret"`
|
||||
QRCode string `json:"qr_code"`
|
||||
}
|
||||
|
||||
func (me *MfaSecret) ToJson() string {
|
||||
b, _ := json.Marshal(me)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func MfaSecretFromJson(data io.Reader) *MfaSecret {
|
||||
var me *MfaSecret
|
||||
json.NewDecoder(data).Decode(&me)
|
||||
return me
|
||||
}
|
8
build/manifest/vendor/github.com/mattermost/mattermost-server/model/migration.go
generated
vendored
8
build/manifest/vendor/github.com/mattermost/mattermost-server/model/migration.go
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2 = "migration_advanced_permissions_phase_2"
|
||||
)
|
152
build/manifest/vendor/github.com/mattermost/mattermost-server/model/oauth.go
generated
vendored
152
build/manifest/vendor/github.com/mattermost/mattermost-server/model/oauth.go
generated
vendored
|
@ -1,152 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
OAUTH_ACTION_SIGNUP = "signup"
|
||||
OAUTH_ACTION_LOGIN = "login"
|
||||
OAUTH_ACTION_EMAIL_TO_SSO = "email_to_sso"
|
||||
OAUTH_ACTION_SSO_TO_EMAIL = "sso_to_email"
|
||||
OAUTH_ACTION_MOBILE = "mobile"
|
||||
OAUTH_ACTION_CLIENT = "client"
|
||||
)
|
||||
|
||||
type OAuthApp struct {
|
||||
Id string `json:"id"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
IconURL string `json:"icon_url"`
|
||||
CallbackUrls StringArray `json:"callback_urls"`
|
||||
Homepage string `json:"homepage"`
|
||||
IsTrusted bool `json:"is_trusted"`
|
||||
}
|
||||
|
||||
// IsValid validates the app and returns an error if it isn't configured
|
||||
// correctly.
|
||||
func (a *OAuthApp) IsValid() *AppError {
|
||||
|
||||
if len(a.Id) != 26 {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.app_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if a.CreateAt == 0 {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.create_at.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if a.UpdateAt == 0 {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.update_at.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(a.CreatorId) != 26 {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.creator_id.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(a.ClientSecret) == 0 || len(a.ClientSecret) > 128 {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.client_secret.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(a.Name) == 0 || len(a.Name) > 64 {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.name.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(a.CallbackUrls) == 0 || len(fmt.Sprintf("%s", a.CallbackUrls)) > 1024 {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.callback.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
for _, callback := range a.CallbackUrls {
|
||||
if !IsValidHttpUrl(callback) {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.callback.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
if len(a.Homepage) == 0 || len(a.Homepage) > 256 || !IsValidHttpUrl(a.Homepage) {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.homepage.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(a.Description) > 512 {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.description.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(a.IconURL) > 0 {
|
||||
if len(a.IconURL) > 512 || !IsValidHttpUrl(a.IconURL) {
|
||||
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.icon_url.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PreSave will set the Id and ClientSecret if missing. It will also fill
|
||||
// in the CreateAt, UpdateAt times. It should be run before saving the app to the db.
|
||||
func (a *OAuthApp) PreSave() {
|
||||
if a.Id == "" {
|
||||
a.Id = NewId()
|
||||
}
|
||||
|
||||
if a.ClientSecret == "" {
|
||||
a.ClientSecret = NewId()
|
||||
}
|
||||
|
||||
a.CreateAt = GetMillis()
|
||||
a.UpdateAt = a.CreateAt
|
||||
}
|
||||
|
||||
// PreUpdate should be run before updating the app in the db.
|
||||
func (a *OAuthApp) PreUpdate() {
|
||||
a.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (a *OAuthApp) ToJson() string {
|
||||
b, _ := json.Marshal(a)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// Generate a valid strong etag so the browser can cache the results
|
||||
func (a *OAuthApp) Etag() string {
|
||||
return Etag(a.Id, a.UpdateAt)
|
||||
}
|
||||
|
||||
// Remove any private data from the app object
|
||||
func (a *OAuthApp) Sanitize() {
|
||||
a.ClientSecret = ""
|
||||
}
|
||||
|
||||
func (a *OAuthApp) IsValidRedirectURL(url string) bool {
|
||||
for _, u := range a.CallbackUrls {
|
||||
if u == url {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func OAuthAppFromJson(data io.Reader) *OAuthApp {
|
||||
var app *OAuthApp
|
||||
json.NewDecoder(data).Decode(&app)
|
||||
return app
|
||||
}
|
||||
|
||||
func OAuthAppListToJson(l []*OAuthApp) string {
|
||||
b, _ := json.Marshal(l)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func OAuthAppListFromJson(data io.Reader) []*OAuthApp {
|
||||
var o []*OAuthApp
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
264
build/manifest/vendor/github.com/mattermost/mattermost-server/model/outgoing_webhook.go
generated
vendored
264
build/manifest/vendor/github.com/mattermost/mattermost-server/model/outgoing_webhook.go
generated
vendored
|
@ -1,264 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type OutgoingWebhook struct {
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
TriggerWords StringArray `json:"trigger_words"`
|
||||
TriggerWhen int `json:"trigger_when"`
|
||||
CallbackURLs StringArray `json:"callback_urls"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
ContentType string `json:"content_type"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
}
|
||||
|
||||
type OutgoingWebhookPayload struct {
|
||||
Token string `json:"token"`
|
||||
TeamId string `json:"team_id"`
|
||||
TeamDomain string `json:"team_domain"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
ChannelName string `json:"channel_name"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
UserId string `json:"user_id"`
|
||||
UserName string `json:"user_name"`
|
||||
PostId string `json:"post_id"`
|
||||
Text string `json:"text"`
|
||||
TriggerWord string `json:"trigger_word"`
|
||||
FileIds string `json:"file_ids"`
|
||||
}
|
||||
|
||||
type OutgoingWebhookResponse struct {
|
||||
Text *string `json:"text"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
Props StringInterface `json:"props"`
|
||||
Attachments []*SlackAttachment `json:"attachments"`
|
||||
Type string `json:"type"`
|
||||
ResponseType string `json:"response_type"`
|
||||
}
|
||||
|
||||
const OUTGOING_HOOK_RESPONSE_TYPE_COMMENT = "comment"
|
||||
|
||||
func (o *OutgoingWebhookPayload) ToJSON() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhookPayload) ToFormValues() string {
|
||||
v := url.Values{}
|
||||
v.Set("token", o.Token)
|
||||
v.Set("team_id", o.TeamId)
|
||||
v.Set("team_domain", o.TeamDomain)
|
||||
v.Set("channel_id", o.ChannelId)
|
||||
v.Set("channel_name", o.ChannelName)
|
||||
v.Set("timestamp", strconv.FormatInt(o.Timestamp/1000, 10))
|
||||
v.Set("user_id", o.UserId)
|
||||
v.Set("user_name", o.UserName)
|
||||
v.Set("post_id", o.PostId)
|
||||
v.Set("text", o.Text)
|
||||
v.Set("trigger_word", o.TriggerWord)
|
||||
v.Set("file_ids", o.FileIds)
|
||||
|
||||
return v.Encode()
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhook) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func OutgoingWebhookFromJson(data io.Reader) *OutgoingWebhook {
|
||||
var o *OutgoingWebhook
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func OutgoingWebhookListToJson(l []*OutgoingWebhook) string {
|
||||
b, _ := json.Marshal(l)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func OutgoingWebhookListFromJson(data io.Reader) []*OutgoingWebhook {
|
||||
var o []*OutgoingWebhook
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhookResponse) ToJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func OutgoingWebhookResponseFromJson(data io.Reader) *OutgoingWebhookResponse {
|
||||
var o *OutgoingWebhookResponse
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhook) IsValid() *AppError {
|
||||
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Token) != 26 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.token.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.CreatorId) != 26 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ChannelId) != 0 && len(o.ChannelId) != 26 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.team_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(fmt.Sprintf("%s", o.TriggerWords)) > 1024 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.words.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.TriggerWords) != 0 {
|
||||
for _, triggerWord := range o.TriggerWords {
|
||||
if len(triggerWord) == 0 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(o.CallbackURLs) == 0 || len(fmt.Sprintf("%s", o.CallbackURLs)) > 1024 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.callback.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
for _, callback := range o.CallbackURLs {
|
||||
if !IsValidHttpUrl(callback) {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.url.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
if len(o.DisplayName) > 64 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.display_name.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Description) > 500 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.description.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ContentType) > 128 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.TriggerWhen > 1 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.Username) > 64 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.username.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.IconURL) > 1024 {
|
||||
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.icon_url.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhook) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
if o.Token == "" {
|
||||
o.Token = NewId()
|
||||
}
|
||||
|
||||
o.CreateAt = GetMillis()
|
||||
o.UpdateAt = o.CreateAt
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhook) PreUpdate() {
|
||||
o.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhook) TriggerWordExactMatch(word string) bool {
|
||||
if len(word) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, trigger := range o.TriggerWords {
|
||||
if trigger == word {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool {
|
||||
if len(word) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, trigger := range o.TriggerWords {
|
||||
if strings.HasPrefix(word, trigger) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *OutgoingWebhook) GetTriggerWord(word string, isExactMatch bool) (triggerWord string) {
|
||||
if len(word) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if isExactMatch {
|
||||
for _, trigger := range o.TriggerWords {
|
||||
if trigger == word {
|
||||
triggerWord = trigger
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, trigger := range o.TriggerWords {
|
||||
if strings.HasPrefix(word, trigger) {
|
||||
triggerWord = trigger
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return triggerWord
|
||||
}
|
466
build/manifest/vendor/github.com/mattermost/mattermost-server/model/permission.go
generated
vendored
466
build/manifest/vendor/github.com/mattermost/mattermost-server/model/permission.go
generated
vendored
|
@ -1,466 +0,0 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
PERMISSION_SCOPE_SYSTEM = "system_scope"
|
||||
PERMISSION_SCOPE_TEAM = "team_scope"
|
||||
PERMISSION_SCOPE_CHANNEL = "channel_scope"
|
||||
)
|
||||
|
||||
type Permission struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
||||
var PERMISSION_INVITE_USER *Permission
|
||||
var PERMISSION_ADD_USER_TO_TEAM *Permission
|
||||
var PERMISSION_USE_SLASH_COMMANDS *Permission
|
||||
var PERMISSION_MANAGE_SLASH_COMMANDS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS *Permission
|
||||
var PERMISSION_CREATE_PUBLIC_CHANNEL *Permission
|
||||
var PERMISSION_CREATE_PRIVATE_CHANNEL *Permission
|
||||
var PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS *Permission
|
||||
var PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS *Permission
|
||||
var PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE *Permission
|
||||
var PERMISSION_MANAGE_ROLES *Permission
|
||||
var PERMISSION_MANAGE_TEAM_ROLES *Permission
|
||||
var PERMISSION_MANAGE_CHANNEL_ROLES *Permission
|
||||
var PERMISSION_CREATE_DIRECT_CHANNEL *Permission
|
||||
var PERMISSION_CREATE_GROUP_CHANNEL *Permission
|
||||
var PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES *Permission
|
||||
var PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES *Permission
|
||||
var PERMISSION_LIST_TEAM_CHANNELS *Permission
|
||||
var PERMISSION_JOIN_PUBLIC_CHANNELS *Permission
|
||||
var PERMISSION_DELETE_PUBLIC_CHANNEL *Permission
|
||||
var PERMISSION_DELETE_PRIVATE_CHANNEL *Permission
|
||||
var PERMISSION_EDIT_OTHER_USERS *Permission
|
||||
var PERMISSION_READ_CHANNEL *Permission
|
||||
var PERMISSION_READ_PUBLIC_CHANNEL *Permission
|
||||
var PERMISSION_ADD_REACTION *Permission
|
||||
var PERMISSION_REMOVE_REACTION *Permission
|
||||
var PERMISSION_REMOVE_OTHERS_REACTIONS *Permission
|
||||
var PERMISSION_PERMANENT_DELETE_USER *Permission
|
||||
var PERMISSION_UPLOAD_FILE *Permission
|
||||
var PERMISSION_GET_PUBLIC_LINK *Permission
|
||||
var PERMISSION_MANAGE_WEBHOOKS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_WEBHOOKS *Permission
|
||||
var PERMISSION_MANAGE_OAUTH *Permission
|
||||
var PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH *Permission
|
||||
var PERMISSION_MANAGE_EMOJIS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_EMOJIS *Permission
|
||||
var PERMISSION_CREATE_POST *Permission
|
||||
var PERMISSION_CREATE_POST_PUBLIC *Permission
|
||||
var PERMISSION_CREATE_POST_EPHEMERAL *Permission
|
||||
var PERMISSION_EDIT_POST *Permission
|
||||
var PERMISSION_EDIT_OTHERS_POSTS *Permission
|
||||
var PERMISSION_DELETE_POST *Permission
|
||||
var PERMISSION_DELETE_OTHERS_POSTS *Permission
|
||||
var PERMISSION_REMOVE_USER_FROM_TEAM *Permission
|
||||
var PERMISSION_CREATE_TEAM *Permission
|
||||
var PERMISSION_MANAGE_TEAM *Permission
|
||||
var PERMISSION_IMPORT_TEAM *Permission
|
||||
var PERMISSION_VIEW_TEAM *Permission
|
||||
var PERMISSION_LIST_USERS_WITHOUT_TEAM *Permission
|
||||
var PERMISSION_MANAGE_JOBS *Permission
|
||||
var PERMISSION_CREATE_USER_ACCESS_TOKEN *Permission
|
||||
var PERMISSION_READ_USER_ACCESS_TOKEN *Permission
|
||||
var PERMISSION_REVOKE_USER_ACCESS_TOKEN *Permission
|
||||
|
||||
// General permission that encompasses all system admin functions
|
||||
// in the future this could be broken up to allow access to some
|
||||
// admin functions but not others
|
||||
var PERMISSION_MANAGE_SYSTEM *Permission
|
||||
|
||||
var ALL_PERMISSIONS []*Permission
|
||||
|
||||
func initializePermissions() {
|
||||
PERMISSION_INVITE_USER = &Permission{
|
||||
"invite_user",
|
||||
"authentication.permissions.team_invite_user.name",
|
||||
"authentication.permissions.team_invite_user.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_ADD_USER_TO_TEAM = &Permission{
|
||||
"add_user_to_team",
|
||||
"authentication.permissions.add_user_to_team.name",
|
||||
"authentication.permissions.add_user_to_team.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_USE_SLASH_COMMANDS = &Permission{
|
||||
"use_slash_commands",
|
||||
"authentication.permissions.team_use_slash_commands.name",
|
||||
"authentication.permissions.team_use_slash_commands.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_MANAGE_SLASH_COMMANDS = &Permission{
|
||||
"manage_slash_commands",
|
||||
"authentication.permissions.manage_slash_commands.name",
|
||||
"authentication.permissions.manage_slash_commands.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS = &Permission{
|
||||
"manage_others_slash_commands",
|
||||
"authentication.permissions.manage_others_slash_commands.name",
|
||||
"authentication.permissions.manage_others_slash_commands.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_CREATE_PUBLIC_CHANNEL = &Permission{
|
||||
"create_public_channel",
|
||||
"authentication.permissions.create_public_channel.name",
|
||||
"authentication.permissions.create_public_channel.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_CREATE_PRIVATE_CHANNEL = &Permission{
|
||||
"create_private_channel",
|
||||
"authentication.permissions.create_private_channel.name",
|
||||
"authentication.permissions.create_private_channel.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS = &Permission{
|
||||
"manage_public_channel_members",
|
||||
"authentication.permissions.manage_public_channel_members.name",
|
||||
"authentication.permissions.manage_public_channel_members.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS = &Permission{
|
||||
"manage_private_channel_members",
|
||||
"authentication.permissions.manage_private_channel_members.name",
|
||||
"authentication.permissions.manage_private_channel_members.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE = &Permission{
|
||||
"assign_system_admin_role",
|
||||
"authentication.permissions.assign_system_admin_role.name",
|
||||
"authentication.permissions.assign_system_admin_role.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_ROLES = &Permission{
|
||||
"manage_roles",
|
||||
"authentication.permissions.manage_roles.name",
|
||||
"authentication.permissions.manage_roles.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_TEAM_ROLES = &Permission{
|
||||
"manage_team_roles",
|
||||
"authentication.permissions.manage_team_roles.name",
|
||||
"authentication.permissions.manage_team_roles.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_CHANNEL_ROLES = &Permission{
|
||||
"manage_channel_roles",
|
||||
"authentication.permissions.manage_channel_roles.name",
|
||||
"authentication.permissions.manage_channel_roles.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_MANAGE_SYSTEM = &Permission{
|
||||
"manage_system",
|
||||
"authentication.permissions.manage_system.name",
|
||||
"authentication.permissions.manage_system.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_CREATE_DIRECT_CHANNEL = &Permission{
|
||||
"create_direct_channel",
|
||||
"authentication.permissions.create_direct_channel.name",
|
||||
"authentication.permissions.create_direct_channel.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_CREATE_GROUP_CHANNEL = &Permission{
|
||||
"create_group_channel",
|
||||
"authentication.permissions.create_group_channel.name",
|
||||
"authentication.permissions.create_group_channel.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES = &Permission{
|
||||
"manage_public_channel_properties",
|
||||
"authentication.permissions.manage_public_channel_properties.name",
|
||||
"authentication.permissions.manage_public_channel_properties.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES = &Permission{
|
||||
"manage_private_channel_properties",
|
||||
"authentication.permissions.manage_private_channel_properties.name",
|
||||
"authentication.permissions.manage_private_channel_properties.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_LIST_TEAM_CHANNELS = &Permission{
|
||||
"list_team_channels",
|
||||
"authentication.permissions.list_team_channels.name",
|
||||
"authentication.permissions.list_team_channels.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_JOIN_PUBLIC_CHANNELS = &Permission{
|
||||
"join_public_channels",
|
||||
"authentication.permissions.join_public_channels.name",
|
||||
"authentication.permissions.join_public_channels.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_DELETE_PUBLIC_CHANNEL = &Permission{
|
||||
"delete_public_channel",
|
||||
"authentication.permissions.delete_public_channel.name",
|
||||
"authentication.permissions.delete_public_channel.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_DELETE_PRIVATE_CHANNEL = &Permission{
|
||||
"delete_private_channel",
|
||||
"authentication.permissions.delete_private_channel.name",
|
||||
"authentication.permissions.delete_private_channel.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_EDIT_OTHER_USERS = &Permission{
|
||||
"edit_other_users",
|
||||
"authentication.permissions.edit_other_users.name",
|
||||
"authentication.permissions.edit_other_users.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_READ_CHANNEL = &Permission{
|
||||
"read_channel",
|
||||
"authentication.permissions.read_channel.name",
|
||||
"authentication.permissions.read_channel.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_READ_PUBLIC_CHANNEL = &Permission{
|
||||
"read_public_channel",
|
||||
"authentication.permissions.read_public_channel.name",
|
||||
"authentication.permissions.read_public_channel.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_ADD_REACTION = &Permission{
|
||||
"add_reaction",
|
||||
"authentication.permissions.add_reaction.name",
|
||||
"authentication.permissions.add_reaction.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_REMOVE_REACTION = &Permission{
|
||||
"remove_reaction",
|
||||
"authentication.permissions.remove_reaction.name",
|
||||
"authentication.permissions.remove_reaction.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_REMOVE_OTHERS_REACTIONS = &Permission{
|
||||
"remove_others_reactions",
|
||||
"authentication.permissions.remove_others_reactions.name",
|
||||
"authentication.permissions.remove_others_reactions.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_PERMANENT_DELETE_USER = &Permission{
|
||||
"permanent_delete_user",
|
||||
"authentication.permissions.permanent_delete_user.name",
|
||||
"authentication.permissions.permanent_delete_user.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_UPLOAD_FILE = &Permission{
|
||||
"upload_file",
|
||||
"authentication.permissions.upload_file.name",
|
||||
"authentication.permissions.upload_file.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_GET_PUBLIC_LINK = &Permission{
|
||||
"get_public_link",
|
||||
"authentication.permissions.get_public_link.name",
|
||||
"authentication.permissions.get_public_link.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_WEBHOOKS = &Permission{
|
||||
"manage_webhooks",
|
||||
"authentication.permissions.manage_webhooks.name",
|
||||
"authentication.permissions.manage_webhooks.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_OTHERS_WEBHOOKS = &Permission{
|
||||
"manage_others_webhooks",
|
||||
"authentication.permissions.manage_others_webhooks.name",
|
||||
"authentication.permissions.manage_others_webhooks.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_OAUTH = &Permission{
|
||||
"manage_oauth",
|
||||
"authentication.permissions.manage_oauth.name",
|
||||
"authentication.permissions.manage_oauth.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH = &Permission{
|
||||
"manage_system_wide_oauth",
|
||||
"authentication.permissions.manage_system_wide_oauth.name",
|
||||
"authentication.permissions.manage_system_wide_oauth.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_EMOJIS = &Permission{
|
||||
"manage_emojis",
|
||||
"authentication.permissions.manage_emojis.name",
|
||||
"authentication.permissions.manage_emojis.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_MANAGE_OTHERS_EMOJIS = &Permission{
|
||||
"manage_others_emojis",
|
||||
"authentication.permissions.manage_others_emojis.name",
|
||||
"authentication.permissions.manage_others_emojis.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_CREATE_POST = &Permission{
|
||||
"create_post",
|
||||
"authentication.permissions.create_post.name",
|
||||
"authentication.permissions.create_post.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_CREATE_POST_PUBLIC = &Permission{
|
||||
"create_post_public",
|
||||
"authentication.permissions.create_post_public.name",
|
||||
"authentication.permissions.create_post_public.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_CREATE_POST_EPHEMERAL = &Permission{
|
||||
"create_post_ephemeral",
|
||||
"authentication.permissions.create_post_ephemeral.name",
|
||||
"authentication.permissions.create_post_ephemeral.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_EDIT_POST = &Permission{
|
||||
"edit_post",
|
||||
"authentication.permissions.edit_post.name",
|
||||
"authentication.permissions.edit_post.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_EDIT_OTHERS_POSTS = &Permission{
|
||||
"edit_others_posts",
|
||||
"authentication.permissions.edit_others_posts.name",
|
||||
"authentication.permissions.edit_others_posts.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_DELETE_POST = &Permission{
|
||||
"delete_post",
|
||||
"authentication.permissions.delete_post.name",
|
||||
"authentication.permissions.delete_post.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_DELETE_OTHERS_POSTS = &Permission{
|
||||
"delete_others_posts",
|
||||
"authentication.permissions.delete_others_posts.name",
|
||||
"authentication.permissions.delete_others_posts.description",
|
||||
PERMISSION_SCOPE_CHANNEL,
|
||||
}
|
||||
PERMISSION_REMOVE_USER_FROM_TEAM = &Permission{
|
||||
"remove_user_from_team",
|
||||
"authentication.permissions.remove_user_from_team.name",
|
||||
"authentication.permissions.remove_user_from_team.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_CREATE_TEAM = &Permission{
|
||||
"create_team",
|
||||
"authentication.permissions.create_team.name",
|
||||
"authentication.permissions.create_team.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_TEAM = &Permission{
|
||||
"manage_team",
|
||||
"authentication.permissions.manage_team.name",
|
||||
"authentication.permissions.manage_team.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_IMPORT_TEAM = &Permission{
|
||||
"import_team",
|
||||
"authentication.permissions.import_team.name",
|
||||
"authentication.permissions.import_team.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_VIEW_TEAM = &Permission{
|
||||
"view_team",
|
||||
"authentication.permissions.view_team.name",
|
||||
"authentication.permissions.view_team.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
PERMISSION_LIST_USERS_WITHOUT_TEAM = &Permission{
|
||||
"list_users_without_team",
|
||||
"authentication.permissions.list_users_without_team.name",
|
||||
"authentication.permissions.list_users_without_team.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_CREATE_USER_ACCESS_TOKEN = &Permission{
|
||||
"create_user_access_token",
|
||||
"authentication.permissions.create_user_access_token.name",
|
||||
"authentication.permissions.create_user_access_token.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_READ_USER_ACCESS_TOKEN = &Permission{
|
||||
"read_user_access_token",
|
||||
"authentication.permissions.read_user_access_token.name",
|
||||
"authentication.permissions.read_user_access_token.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_REVOKE_USER_ACCESS_TOKEN = &Permission{
|
||||
"revoke_user_access_token",
|
||||
"authentication.permissions.revoke_user_access_token.name",
|
||||
"authentication.permissions.revoke_user_access_token.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_MANAGE_JOBS = &Permission{
|
||||
"manage_jobs",
|
||||
"authentication.permisssions.manage_jobs.name",
|
||||
"authentication.permisssions.manage_jobs.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
|
||||
ALL_PERMISSIONS = []*Permission{
|
||||
PERMISSION_INVITE_USER,
|
||||
PERMISSION_ADD_USER_TO_TEAM,
|
||||
PERMISSION_USE_SLASH_COMMANDS,
|
||||
PERMISSION_MANAGE_SLASH_COMMANDS,
|
||||
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS,
|
||||
PERMISSION_CREATE_PUBLIC_CHANNEL,
|
||||
PERMISSION_CREATE_PRIVATE_CHANNEL,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS,
|
||||
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE,
|
||||
PERMISSION_MANAGE_ROLES,
|
||||
PERMISSION_MANAGE_TEAM_ROLES,
|
||||
PERMISSION_MANAGE_CHANNEL_ROLES,
|
||||
PERMISSION_CREATE_DIRECT_CHANNEL,
|
||||
PERMISSION_CREATE_GROUP_CHANNEL,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES,
|
||||
PERMISSION_LIST_TEAM_CHANNELS,
|
||||
PERMISSION_JOIN_PUBLIC_CHANNELS,
|
||||
PERMISSION_DELETE_PUBLIC_CHANNEL,
|
||||
PERMISSION_DELETE_PRIVATE_CHANNEL,
|
||||
PERMISSION_EDIT_OTHER_USERS,
|
||||
PERMISSION_READ_CHANNEL,
|
||||
PERMISSION_READ_PUBLIC_CHANNEL,
|
||||
PERMISSION_ADD_REACTION,
|
||||
PERMISSION_REMOVE_REACTION,
|
||||
PERMISSION_REMOVE_OTHERS_REACTIONS,
|
||||
PERMISSION_PERMANENT_DELETE_USER,
|
||||
PERMISSION_UPLOAD_FILE,
|
||||
PERMISSION_GET_PUBLIC_LINK,
|
||||
PERMISSION_MANAGE_WEBHOOKS,
|
||||
PERMISSION_MANAGE_OTHERS_WEBHOOKS,
|
||||
PERMISSION_MANAGE_OAUTH,
|
||||
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH,
|
||||
PERMISSION_MANAGE_EMOJIS,
|
||||
PERMISSION_MANAGE_OTHERS_EMOJIS,
|
||||
PERMISSION_CREATE_POST,
|
||||
PERMISSION_CREATE_POST_PUBLIC,
|
||||
PERMISSION_CREATE_POST_EPHEMERAL,
|
||||
PERMISSION_EDIT_POST,
|
||||
PERMISSION_EDIT_OTHERS_POSTS,
|
||||
PERMISSION_DELETE_POST,
|
||||
PERMISSION_DELETE_OTHERS_POSTS,
|
||||
PERMISSION_REMOVE_USER_FROM_TEAM,
|
||||
PERMISSION_CREATE_TEAM,
|
||||
PERMISSION_MANAGE_TEAM,
|
||||
PERMISSION_IMPORT_TEAM,
|
||||
PERMISSION_VIEW_TEAM,
|
||||
PERMISSION_LIST_USERS_WITHOUT_TEAM,
|
||||
PERMISSION_MANAGE_JOBS,
|
||||
PERMISSION_CREATE_USER_ACCESS_TOKEN,
|
||||
PERMISSION_READ_USER_ACCESS_TOKEN,
|
||||
PERMISSION_REVOKE_USER_ACCESS_TOKEN,
|
||||
PERMISSION_MANAGE_SYSTEM,
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
initializePermissions()
|
||||
}
|
33
build/manifest/vendor/github.com/mattermost/mattermost-server/model/plugin_key_value.go
generated
vendored
33
build/manifest/vendor/github.com/mattermost/mattermost-server/model/plugin_key_value.go
generated
vendored
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
KEY_VALUE_PLUGIN_ID_MAX_RUNES = 190
|
||||
KEY_VALUE_KEY_MAX_RUNES = 50
|
||||
)
|
||||
|
||||
type PluginKeyValue struct {
|
||||
PluginId string `json:"plugin_id"`
|
||||
Key string `json:"key" db:"PKey"`
|
||||
Value []byte `json:"value" db:"PValue"`
|
||||
ExpireAt int64 `json:"expire_at"`
|
||||
}
|
||||
|
||||
func (kv *PluginKeyValue) IsValid() *AppError {
|
||||
if len(kv.PluginId) == 0 || utf8.RuneCountInString(kv.PluginId) > KEY_VALUE_PLUGIN_ID_MAX_RUNES {
|
||||
return NewAppError("PluginKeyValue.IsValid", "model.plugin_key_value.is_valid.plugin_id.app_error", map[string]interface{}{"Max": KEY_VALUE_KEY_MAX_RUNES, "Min": 0}, "key="+kv.Key, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(kv.Key) == 0 || utf8.RuneCountInString(kv.Key) > KEY_VALUE_KEY_MAX_RUNES {
|
||||
return NewAppError("PluginKeyValue.IsValid", "model.plugin_key_value.is_valid.key.app_error", map[string]interface{}{"Max": KEY_VALUE_KEY_MAX_RUNES, "Min": 0}, "key="+kv.Key, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
42
build/manifest/vendor/github.com/mattermost/mattermost-server/model/plugin_status.go
generated
vendored
42
build/manifest/vendor/github.com/mattermost/mattermost-server/model/plugin_status.go
generated
vendored
|
@ -1,42 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
PluginStateNotRunning = 0
|
||||
PluginStateStarting = 1 // unused by server
|
||||
PluginStateRunning = 2
|
||||
PluginStateFailedToStart = 3
|
||||
PluginStateFailedToStayRunning = 4 // unused by server
|
||||
PluginStateStopping = 5 // unused by server
|
||||
)
|
||||
|
||||
// PluginStatus provides a cluster-aware view of installed plugins.
|
||||
type PluginStatus struct {
|
||||
PluginId string `json:"plugin_id"`
|
||||
ClusterId string `json:"cluster_id"`
|
||||
PluginPath string `json:"plugin_path"`
|
||||
State int `json:"state"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type PluginStatuses []*PluginStatus
|
||||
|
||||
func (m *PluginStatuses) ToJson() string {
|
||||
b, _ := json.Marshal(m)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func PluginStatusesFromJson(data io.Reader) PluginStatuses {
|
||||
var m PluginStatuses
|
||||
json.NewDecoder(data).Decode(&m)
|
||||
return m
|
||||
}
|
29
build/manifest/vendor/github.com/mattermost/mattermost-server/model/plugins_response.go
generated
vendored
29
build/manifest/vendor/github.com/mattermost/mattermost-server/model/plugins_response.go
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type PluginInfo struct {
|
||||
Manifest
|
||||
}
|
||||
|
||||
type PluginsResponse struct {
|
||||
Active []*PluginInfo `json:"active"`
|
||||
Inactive []*PluginInfo `json:"inactive"`
|
||||
}
|
||||
|
||||
func (m *PluginsResponse) ToJson() string {
|
||||
b, _ := json.Marshal(m)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func PluginsResponseFromJson(data io.Reader) *PluginsResponse {
|
||||
var m *PluginsResponse
|
||||
json.NewDecoder(data).Decode(&m)
|
||||
return m
|
||||
}
|
484
build/manifest/vendor/github.com/mattermost/mattermost-server/model/post.go
generated
vendored
484
build/manifest/vendor/github.com/mattermost/mattermost-server/model/post.go
generated
vendored
|
@ -1,484 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/mattermost/mattermost-server/utils/markdown"
|
||||
)
|
||||
|
||||
const (
|
||||
POST_SYSTEM_MESSAGE_PREFIX = "system_"
|
||||
POST_DEFAULT = ""
|
||||
POST_SLACK_ATTACHMENT = "slack_attachment"
|
||||
POST_SYSTEM_GENERIC = "system_generic"
|
||||
POST_JOIN_LEAVE = "system_join_leave" // Deprecated, use POST_JOIN_CHANNEL or POST_LEAVE_CHANNEL instead
|
||||
POST_JOIN_CHANNEL = "system_join_channel"
|
||||
POST_LEAVE_CHANNEL = "system_leave_channel"
|
||||
POST_JOIN_TEAM = "system_join_team"
|
||||
POST_LEAVE_TEAM = "system_leave_team"
|
||||
POST_AUTO_RESPONDER = "system_auto_responder"
|
||||
POST_ADD_REMOVE = "system_add_remove" // Deprecated, use POST_ADD_TO_CHANNEL or POST_REMOVE_FROM_CHANNEL instead
|
||||
POST_ADD_TO_CHANNEL = "system_add_to_channel"
|
||||
POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel"
|
||||
POST_MOVE_CHANNEL = "system_move_channel"
|
||||
POST_ADD_TO_TEAM = "system_add_to_team"
|
||||
POST_REMOVE_FROM_TEAM = "system_remove_from_team"
|
||||
POST_HEADER_CHANGE = "system_header_change"
|
||||
POST_DISPLAYNAME_CHANGE = "system_displayname_change"
|
||||
POST_CONVERT_CHANNEL = "system_convert_channel"
|
||||
POST_PURPOSE_CHANGE = "system_purpose_change"
|
||||
POST_CHANNEL_DELETED = "system_channel_deleted"
|
||||
POST_EPHEMERAL = "system_ephemeral"
|
||||
POST_CHANGE_CHANNEL_PRIVACY = "system_change_chan_privacy"
|
||||
POST_FILEIDS_MAX_RUNES = 150
|
||||
POST_FILENAMES_MAX_RUNES = 4000
|
||||
POST_HASHTAGS_MAX_RUNES = 1000
|
||||
POST_MESSAGE_MAX_RUNES_V1 = 4000
|
||||
POST_MESSAGE_MAX_BYTES_V2 = 65535 // Maximum size of a TEXT column in MySQL
|
||||
POST_MESSAGE_MAX_RUNES_V2 = POST_MESSAGE_MAX_BYTES_V2 / 4 // Assume a worst-case representation
|
||||
POST_PROPS_MAX_RUNES = 8000
|
||||
POST_PROPS_MAX_USER_RUNES = POST_PROPS_MAX_RUNES - 400 // Leave some room for system / pre-save modifications
|
||||
POST_CUSTOM_TYPE_PREFIX = "custom_"
|
||||
PROPS_ADD_CHANNEL_MEMBER = "add_channel_member"
|
||||
POST_PROPS_ADDED_USER_ID = "addedUserId"
|
||||
POST_PROPS_DELETE_BY = "deleteBy"
|
||||
)
|
||||
|
||||
type Post struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
EditAt int64 `json:"edit_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
IsPinned bool `json:"is_pinned"`
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
RootId string `json:"root_id"`
|
||||
ParentId string `json:"parent_id"`
|
||||
OriginalId string `json:"original_id"`
|
||||
|
||||
Message string `json:"message"`
|
||||
|
||||
// MessageSource will contain the message as submitted by the user if Message has been modified
|
||||
// by Mattermost for presentation (e.g if an image proxy is being used). It should be used to
|
||||
// populate edit boxes if present.
|
||||
MessageSource string `json:"message_source,omitempty" db:"-"`
|
||||
|
||||
Type string `json:"type"`
|
||||
Props StringInterface `json:"props"`
|
||||
Hashtags string `json:"hashtags"`
|
||||
Filenames StringArray `json:"filenames,omitempty"` // Deprecated, do not use this field any more
|
||||
FileIds StringArray `json:"file_ids,omitempty"`
|
||||
PendingPostId string `json:"pending_post_id" db:"-"`
|
||||
HasReactions bool `json:"has_reactions,omitempty"`
|
||||
|
||||
// Transient data populated before sending a post to the client
|
||||
Metadata *PostMetadata `json:"metadata,omitempty" db:"-"`
|
||||
}
|
||||
|
||||
type PostEphemeral struct {
|
||||
UserID string `json:"user_id"`
|
||||
Post *Post `json:"post"`
|
||||
}
|
||||
|
||||
type PostPatch struct {
|
||||
IsPinned *bool `json:"is_pinned"`
|
||||
Message *string `json:"message"`
|
||||
Props *StringInterface `json:"props"`
|
||||
FileIds *StringArray `json:"file_ids"`
|
||||
HasReactions *bool `json:"has_reactions"`
|
||||
}
|
||||
|
||||
type SearchParameter struct {
|
||||
Terms *string `json:"terms"`
|
||||
IsOrSearch *bool `json:"is_or_search"`
|
||||
TimeZoneOffset *int `json:"time_zone_offset"`
|
||||
Page *int `json:"page"`
|
||||
PerPage *int `json:"per_page"`
|
||||
IncludeDeletedChannels *bool `json:"include_deleted_channels"`
|
||||
}
|
||||
|
||||
func (o *PostPatch) WithRewrittenImageURLs(f func(string) string) *PostPatch {
|
||||
copy := *o
|
||||
if copy.Message != nil {
|
||||
*copy.Message = RewriteImageURLs(*o.Message, f)
|
||||
}
|
||||
return ©
|
||||
}
|
||||
|
||||
type PostForExport struct {
|
||||
Post
|
||||
TeamName string
|
||||
ChannelName string
|
||||
Username string
|
||||
ReplyCount int
|
||||
}
|
||||
|
||||
type ReplyForExport struct {
|
||||
Post
|
||||
Username string
|
||||
}
|
||||
|
||||
type PostForIndexing struct {
|
||||
Post
|
||||
TeamId string `json:"team_id"`
|
||||
ParentCreateAt *int64 `json:"parent_create_at"`
|
||||
}
|
||||
|
||||
// Clone shallowly copies the post.
|
||||
func (o *Post) Clone() *Post {
|
||||
copy := *o
|
||||
return ©
|
||||
}
|
||||
|
||||
func (o *Post) ToJson() string {
|
||||
copy := o.Clone()
|
||||
copy.StripActionIntegrations()
|
||||
b, _ := json.Marshal(copy)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (o *Post) ToUnsanitizedJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func PostFromJson(data io.Reader) *Post {
|
||||
var o *Post
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Post) Etag() string {
|
||||
return Etag(o.Id, o.UpdateAt)
|
||||
}
|
||||
|
||||
func (o *Post) IsValid(maxPostSize int) *AppError {
|
||||
|
||||
if len(o.Id) != 26 {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if o.UpdateAt == 0 {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ChannelId) != 26 {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(len(o.RootId) == 26 || len(o.RootId) == 0) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.root_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(len(o.ParentId) == 26 || len(o.ParentId) == 0) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.parent_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(o.ParentId) == 26 && len(o.RootId) == 0 {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.root_parent.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !(len(o.OriginalId) == 26 || len(o.OriginalId) == 0) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.original_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.Message) > maxPostSize {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.msg.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(o.Hashtags) > POST_HASHTAGS_MAX_RUNES {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.hashtags.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
switch o.Type {
|
||||
case
|
||||
POST_DEFAULT,
|
||||
POST_JOIN_LEAVE,
|
||||
POST_AUTO_RESPONDER,
|
||||
POST_ADD_REMOVE,
|
||||
POST_JOIN_CHANNEL,
|
||||
POST_LEAVE_CHANNEL,
|
||||
POST_JOIN_TEAM,
|
||||
POST_LEAVE_TEAM,
|
||||
POST_ADD_TO_CHANNEL,
|
||||
POST_REMOVE_FROM_CHANNEL,
|
||||
POST_MOVE_CHANNEL,
|
||||
POST_ADD_TO_TEAM,
|
||||
POST_REMOVE_FROM_TEAM,
|
||||
POST_SLACK_ATTACHMENT,
|
||||
POST_HEADER_CHANGE,
|
||||
POST_PURPOSE_CHANGE,
|
||||
POST_DISPLAYNAME_CHANGE,
|
||||
POST_CONVERT_CHANNEL,
|
||||
POST_CHANNEL_DELETED,
|
||||
POST_CHANGE_CHANNEL_PRIVACY:
|
||||
default:
|
||||
if !strings.HasPrefix(o.Type, POST_CUSTOM_TYPE_PREFIX) {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.type.app_error", nil, "id="+o.Type, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(ArrayToJson(o.Filenames)) > POST_FILENAMES_MAX_RUNES {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.filenames.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(ArrayToJson(o.FileIds)) > POST_FILEIDS_MAX_RUNES {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.file_ids.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(StringInterfaceToJson(o.Props)) > POST_PROPS_MAX_RUNES {
|
||||
return NewAppError("Post.IsValid", "model.post.is_valid.props.app_error", nil, "id="+o.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Post) SanitizeProps() {
|
||||
membersToSanitize := []string{
|
||||
PROPS_ADD_CHANNEL_MEMBER,
|
||||
}
|
||||
|
||||
for _, member := range membersToSanitize {
|
||||
if _, ok := o.Props[member]; ok {
|
||||
delete(o.Props, member)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Post) PreSave() {
|
||||
if o.Id == "" {
|
||||
o.Id = NewId()
|
||||
}
|
||||
|
||||
o.OriginalId = ""
|
||||
|
||||
if o.CreateAt == 0 {
|
||||
o.CreateAt = GetMillis()
|
||||
}
|
||||
|
||||
o.UpdateAt = o.CreateAt
|
||||
o.PreCommit()
|
||||
}
|
||||
|
||||
func (o *Post) PreCommit() {
|
||||
if o.Props == nil {
|
||||
o.Props = make(map[string]interface{})
|
||||
}
|
||||
|
||||
if o.Filenames == nil {
|
||||
o.Filenames = []string{}
|
||||
}
|
||||
|
||||
if o.FileIds == nil {
|
||||
o.FileIds = []string{}
|
||||
}
|
||||
|
||||
o.GenerateActionIds()
|
||||
}
|
||||
|
||||
func (o *Post) MakeNonNil() {
|
||||
if o.Props == nil {
|
||||
o.Props = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Post) AddProp(key string, value interface{}) {
|
||||
|
||||
o.MakeNonNil()
|
||||
|
||||
o.Props[key] = value
|
||||
}
|
||||
|
||||
func (o *Post) IsSystemMessage() bool {
|
||||
return len(o.Type) >= len(POST_SYSTEM_MESSAGE_PREFIX) && o.Type[:len(POST_SYSTEM_MESSAGE_PREFIX)] == POST_SYSTEM_MESSAGE_PREFIX
|
||||
}
|
||||
|
||||
func (p *Post) Patch(patch *PostPatch) {
|
||||
if patch.IsPinned != nil {
|
||||
p.IsPinned = *patch.IsPinned
|
||||
}
|
||||
|
||||
if patch.Message != nil {
|
||||
p.Message = *patch.Message
|
||||
}
|
||||
|
||||
if patch.Props != nil {
|
||||
p.Props = *patch.Props
|
||||
}
|
||||
|
||||
if patch.FileIds != nil {
|
||||
p.FileIds = *patch.FileIds
|
||||
}
|
||||
|
||||
if patch.HasReactions != nil {
|
||||
p.HasReactions = *patch.HasReactions
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PostPatch) ToJson() string {
|
||||
b, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func PostPatchFromJson(data io.Reader) *PostPatch {
|
||||
decoder := json.NewDecoder(data)
|
||||
var post PostPatch
|
||||
err := decoder.Decode(&post)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &post
|
||||
}
|
||||
|
||||
func (o *SearchParameter) SearchParameterToJson() string {
|
||||
b, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func SearchParameterFromJson(data io.Reader) *SearchParameter {
|
||||
decoder := json.NewDecoder(data)
|
||||
var searchParam SearchParameter
|
||||
err := decoder.Decode(&searchParam)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &searchParam
|
||||
}
|
||||
|
||||
func (o *Post) ChannelMentions() []string {
|
||||
return ChannelMentions(o.Message)
|
||||
}
|
||||
|
||||
func (o *Post) Attachments() []*SlackAttachment {
|
||||
if attachments, ok := o.Props["attachments"].([]*SlackAttachment); ok {
|
||||
return attachments
|
||||
}
|
||||
var ret []*SlackAttachment
|
||||
if attachments, ok := o.Props["attachments"].([]interface{}); ok {
|
||||
for _, attachment := range attachments {
|
||||
if enc, err := json.Marshal(attachment); err == nil {
|
||||
var decoded SlackAttachment
|
||||
if json.Unmarshal(enc, &decoded) == nil {
|
||||
ret = append(ret, &decoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
var markdownDestinationEscaper = strings.NewReplacer(
|
||||
`\`, `\\`,
|
||||
`<`, `\<`,
|
||||
`>`, `\>`,
|
||||
`(`, `\(`,
|
||||
`)`, `\)`,
|
||||
)
|
||||
|
||||
// WithRewrittenImageURLs returns a new shallow copy of the post where the message has been
|
||||
// rewritten via RewriteImageURLs.
|
||||
func (o *Post) WithRewrittenImageURLs(f func(string) string) *Post {
|
||||
copy := o.Clone()
|
||||
copy.Message = RewriteImageURLs(o.Message, f)
|
||||
if copy.MessageSource == "" && copy.Message != o.Message {
|
||||
copy.MessageSource = o.Message
|
||||
}
|
||||
return copy
|
||||
}
|
||||
|
||||
func (o *PostEphemeral) ToUnsanitizedJson() string {
|
||||
b, _ := json.Marshal(o)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// RewriteImageURLs takes a message and returns a copy that has all of the image URLs replaced
|
||||
// according to the function f. For each image URL, f will be invoked, and the resulting markdown
|
||||
// will contain the URL returned by that invocation instead.
|
||||
//
|
||||
// Image URLs are destination URLs used in inline images or reference definitions that are used
|
||||
// anywhere in the input markdown as an image.
|
||||
func RewriteImageURLs(message string, f func(string) string) string {
|
||||
if !strings.Contains(message, "![") {
|
||||
return message
|
||||
}
|
||||
|
||||
var ranges []markdown.Range
|
||||
|
||||
markdown.Inspect(message, func(blockOrInline interface{}) bool {
|
||||
switch v := blockOrInline.(type) {
|
||||
case *markdown.ReferenceImage:
|
||||
ranges = append(ranges, v.ReferenceDefinition.RawDestination)
|
||||
case *markdown.InlineImage:
|
||||
ranges = append(ranges, v.RawDestination)
|
||||
default:
|
||||
return true
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if ranges == nil {
|
||||
return message
|
||||
}
|
||||
|
||||
sort.Slice(ranges, func(i, j int) bool {
|
||||
return ranges[i].Position < ranges[j].Position
|
||||
})
|
||||
|
||||
copyRanges := make([]markdown.Range, 0, len(ranges))
|
||||
urls := make([]string, 0, len(ranges))
|
||||
resultLength := len(message)
|
||||
|
||||
start := 0
|
||||
for i, r := range ranges {
|
||||
switch {
|
||||
case i == 0:
|
||||
case r.Position != ranges[i-1].Position:
|
||||
start = ranges[i-1].End
|
||||
default:
|
||||
continue
|
||||
}
|
||||
original := message[r.Position:r.End]
|
||||
replacement := markdownDestinationEscaper.Replace(f(markdown.Unescape(original)))
|
||||
resultLength += len(replacement) - len(original)
|
||||
copyRanges = append(copyRanges, markdown.Range{Position: start, End: r.Position})
|
||||
urls = append(urls, replacement)
|
||||
}
|
||||
|
||||
result := make([]byte, resultLength)
|
||||
|
||||
offset := 0
|
||||
for i, r := range copyRanges {
|
||||
offset += copy(result[offset:], message[r.Position:r.End])
|
||||
offset += copy(result[offset:], urls[i])
|
||||
}
|
||||
copy(result[offset:], message[ranges[len(ranges)-1].End:])
|
||||
|
||||
return string(result)
|
||||
}
|
22
build/manifest/vendor/github.com/mattermost/mattermost-server/model/post_embed.go
generated
vendored
22
build/manifest/vendor/github.com/mattermost/mattermost-server/model/post_embed.go
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
POST_EMBED_IMAGE PostEmbedType = "image"
|
||||
POST_EMBED_MESSAGE_ATTACHMENT PostEmbedType = "message_attachment"
|
||||
POST_EMBED_OPENGRAPH PostEmbedType = "opengraph"
|
||||
)
|
||||
|
||||
type PostEmbedType string
|
||||
|
||||
type PostEmbed struct {
|
||||
Type PostEmbedType `json:"type"`
|
||||
|
||||
// The URL of the embedded content. Used for image and OpenGraph embeds.
|
||||
URL string `json:"url,omitempty"`
|
||||
|
||||
// Any additional data for the embedded content. Only used for OpenGraph embeds.
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
138
build/manifest/vendor/github.com/mattermost/mattermost-server/model/post_list.go
generated
vendored
138
build/manifest/vendor/github.com/mattermost/mattermost-server/model/post_list.go
generated
vendored
|
@ -1,138 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type PostList struct {
|
||||
Order []string `json:"order"`
|
||||
Posts map[string]*Post `json:"posts"`
|
||||
}
|
||||
|
||||
func NewPostList() *PostList {
|
||||
return &PostList{
|
||||
Order: make([]string, 0),
|
||||
Posts: make(map[string]*Post),
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PostList) WithRewrittenImageURLs(f func(string) string) *PostList {
|
||||
copy := *o
|
||||
copy.Posts = make(map[string]*Post)
|
||||
for id, post := range o.Posts {
|
||||
copy.Posts[id] = post.WithRewrittenImageURLs(f)
|
||||
}
|
||||
return ©
|
||||
}
|
||||
|
||||
func (o *PostList) StripActionIntegrations() {
|
||||
posts := o.Posts
|
||||
o.Posts = make(map[string]*Post)
|
||||
for id, post := range posts {
|
||||
pcopy := *post
|
||||
pcopy.StripActionIntegrations()
|
||||
o.Posts[id] = &pcopy
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PostList) ToJson() string {
|
||||
copy := *o
|
||||
copy.StripActionIntegrations()
|
||||
b, err := json.Marshal(©)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PostList) MakeNonNil() {
|
||||
if o.Order == nil {
|
||||
o.Order = make([]string, 0)
|
||||
}
|
||||
|
||||
if o.Posts == nil {
|
||||
o.Posts = make(map[string]*Post)
|
||||
}
|
||||
|
||||
for _, v := range o.Posts {
|
||||
v.MakeNonNil()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PostList) AddOrder(id string) {
|
||||
|
||||
if o.Order == nil {
|
||||
o.Order = make([]string, 0, 128)
|
||||
}
|
||||
|
||||
o.Order = append(o.Order, id)
|
||||
}
|
||||
|
||||
func (o *PostList) AddPost(post *Post) {
|
||||
|
||||
if o.Posts == nil {
|
||||
o.Posts = make(map[string]*Post)
|
||||
}
|
||||
|
||||
o.Posts[post.Id] = post
|
||||
}
|
||||
|
||||
func (o *PostList) Extend(other *PostList) {
|
||||
for _, postId := range other.Order {
|
||||
if _, ok := o.Posts[postId]; !ok {
|
||||
o.AddPost(other.Posts[postId])
|
||||
o.AddOrder(postId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PostList) SortByCreateAt() {
|
||||
sort.Slice(o.Order, func(i, j int) bool {
|
||||
return o.Posts[o.Order[i]].CreateAt > o.Posts[o.Order[j]].CreateAt
|
||||
})
|
||||
}
|
||||
|
||||
func (o *PostList) Etag() string {
|
||||
|
||||
id := "0"
|
||||
var t int64 = 0
|
||||
|
||||
for _, v := range o.Posts {
|
||||
if v.UpdateAt > t {
|
||||
t = v.UpdateAt
|
||||
id = v.Id
|
||||
} else if v.UpdateAt == t && v.Id > id {
|
||||
t = v.UpdateAt
|
||||
id = v.Id
|
||||
}
|
||||
}
|
||||
|
||||
orderId := ""
|
||||
if len(o.Order) > 0 {
|
||||
orderId = o.Order[0]
|
||||
}
|
||||
|
||||
return Etag(orderId, id, t)
|
||||
}
|
||||
|
||||
func (o *PostList) IsChannelId(channelId string) bool {
|
||||
for _, v := range o.Posts {
|
||||
if v.ChannelId != channelId {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func PostListFromJson(data io.Reader) *PostList {
|
||||
var o *PostList
|
||||
json.NewDecoder(data).Decode(&o)
|
||||
return o
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue