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
|
version: 2.1
|
||||||
jobs:
|
executors:
|
||||||
lint:
|
default:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.12-node
|
- image: circleci/golang:1.12-node
|
||||||
|
|
||||||
working_directory: /go/src/github.com/mattermost/mattermost-plugin-sample
|
jobs:
|
||||||
|
lint:
|
||||||
|
executor:
|
||||||
|
name: default
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
|
||||||
- run: curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
|
||||||
- run: make check-style
|
- run: make check-style
|
||||||
|
|
||||||
test:
|
test:
|
||||||
docker:
|
executor:
|
||||||
- image: circleci/golang:1.12-node
|
name: default
|
||||||
|
|
||||||
working_directory: /go/src/github.com/mattermost/mattermost-plugin-sample
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
|
||||||
- run: curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
|
||||||
- run: make test
|
- run: make test
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
|
|
29
Makefile
29
Makefile
|
@ -1,8 +1,8 @@
|
||||||
GO ?= $(shell command -v go 2> /dev/null)
|
GO ?= $(shell command -v go 2> /dev/null)
|
||||||
DEP ?= $(shell command -v dep 2> /dev/null)
|
|
||||||
NPM ?= $(shell command -v npm 2> /dev/null)
|
NPM ?= $(shell command -v npm 2> /dev/null)
|
||||||
CURL ?= $(shell command -v curl 2> /dev/null)
|
CURL ?= $(shell command -v curl 2> /dev/null)
|
||||||
MANIFEST_FILE ?= plugin.json
|
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.
|
# You can include assets this directory into the bundle. This can be e.g. used to include profile pictures.
|
||||||
ASSETS_DIR ?= assets
|
ASSETS_DIR ?= assets
|
||||||
|
@ -22,7 +22,7 @@ apply:
|
||||||
|
|
||||||
## Runs govet and gofmt against all packages.
|
## Runs govet and gofmt against all packages.
|
||||||
.PHONY: check-style
|
.PHONY: check-style
|
||||||
check-style: server/.depensure webapp/.npminstall gofmt govet
|
check-style: webapp/.npminstall gofmt govet
|
||||||
@echo Checking for style guide compliance
|
@echo Checking for style guide compliance
|
||||||
|
|
||||||
ifneq ($(HAS_WEBAPP),)
|
ifneq ($(HAS_WEBAPP),)
|
||||||
|
@ -54,22 +54,16 @@ endif
|
||||||
govet:
|
govet:
|
||||||
ifneq ($(HAS_SERVER),)
|
ifneq ($(HAS_SERVER),)
|
||||||
@echo Running govet
|
@echo Running govet
|
||||||
$(GO) get golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
|
@# Workaroung because you can't install binaries without adding them to go.mod
|
||||||
$(GO) vet $$(go list ./server/...)
|
env GO111MODULE=off $(GO) get golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
|
||||||
$(GO) vet -vettool=$(GOPATH)/bin/shadow $$(go list ./server/...)
|
$(GO) vet ./server/...
|
||||||
|
$(GO) vet -vettool=$(GOPATH)/bin/shadow ./server/...
|
||||||
@echo Govet success
|
@echo Govet success
|
||||||
endif
|
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.
|
## Builds the server, if it exists, including support for multiple architectures.
|
||||||
.PHONY: server
|
.PHONY: server
|
||||||
server: server/.depensure
|
server:
|
||||||
ifneq ($(HAS_SERVER),)
|
ifneq ($(HAS_SERVER),)
|
||||||
mkdir -p server/dist;
|
mkdir -p server/dist;
|
||||||
cd server && env GOOS=linux GOARCH=amd64 $(GO) build -o dist/plugin-linux-amd64;
|
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.
|
## Runs any lints and unit tests defined for the server and webapp, if they exist.
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: server/.depensure webapp/.npminstall
|
test: webapp/.npminstall
|
||||||
ifneq ($(HAS_SERVER),)
|
ifneq ($(HAS_SERVER),)
|
||||||
cd server && $(GO) test -race -v ./...
|
$(GO) test -race -v ./server/...
|
||||||
endif
|
endif
|
||||||
ifneq ($(HAS_WEBAPP),)
|
ifneq ($(HAS_WEBAPP),)
|
||||||
cd webapp && $(NPM) run fix;
|
cd webapp && $(NPM) run fix;
|
||||||
|
@ -152,8 +146,8 @@ endif
|
||||||
.PHONY: coverage
|
.PHONY: coverage
|
||||||
coverage: server/.depensure webapp/.npminstall
|
coverage: server/.depensure webapp/.npminstall
|
||||||
ifneq ($(HAS_SERVER),)
|
ifneq ($(HAS_SERVER),)
|
||||||
cd server && $(GO) test -race -coverprofile=coverage.txt ./...
|
$(GO) test -race -coverprofile=server/coverage.txt ./server/...
|
||||||
@cd server && $(GO) tool cover -html=coverage.txt
|
$(GO) tool cover -html=server/coverage.txt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
## Clean removes all build artifacts.
|
## Clean removes all build artifacts.
|
||||||
|
@ -162,7 +156,6 @@ clean:
|
||||||
rm -fr dist/
|
rm -fr dist/
|
||||||
ifneq ($(HAS_SERVER),)
|
ifneq ($(HAS_SERVER),)
|
||||||
rm -fr server/dist
|
rm -fr server/dist
|
||||||
rm -fr server/.depensure
|
|
||||||
endif
|
endif
|
||||||
ifneq ($(HAS_WEBAPP),)
|
ifneq ($(HAS_WEBAPP),)
|
||||||
rm -fr webapp/.npminstall
|
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.
|
This plugin serves as a starting point for writing a Mattermost plugin. Feel free to base your own plugin off this repository.
|
||||||
|
|
||||||
## Getting Started
|
## 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
|
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