mirror of
https://github.com/mattermost/mattermost.git
synced 2026-05-28 04:35:04 -04:00
PLT-2057 User as a first class object (#2648)
* Adding TeamMember to system * Fixing all unit tests on the backend * Fixing merge conflicts * Fixing merge conflict * Adding javascript unit tests * Adding TeamMember to system * Fixing all unit tests on the backend * Fixing merge conflicts * Fixing merge conflict * Adding javascript unit tests * Adding client side unit test * Cleaning up the clint side tests * Fixing msg * Adding more client side unit tests * Adding more using tests * Adding last bit of client side unit tests and adding make cmd * Fixing bad merge * Fixing libraries * Updating to new client side API * Fixing borken unit test * Fixing unit tests * ugg...trying to beat gofmt * ugg...trying to beat gofmt * Cleaning up remainder of the server side routes * Adding inital load api * Increased coverage of webhook unit tests (#2660) * Adding loading ... to root html * Fixing bad merge * Removing explicit content type so superagent will guess corectly (#2685) * Fixing merge and unit tests * Adding create team UI * Fixing signup flows * Adding LDAP unit tests and enterprise unit test helper (#2702) * Add the ability to reset MFA from the commandline (#2706) * Fixing compliance unit tests * Fixing client side tests * Adding open server to system console * Moving websocket connection * Fixing unit test * Fixing unit tests * Fixing unit tests * Adding nickname and more LDAP unit tests (#2717) * Adding join open teams * Cleaning up all TODOs in the code * Fixing web sockets * Removing unused webockets file * PLT-2533 Add the ability to reset a user's MFA from the system console (#2715) * Add the ability to reset a user's MFA from the system console * Add client side unit test for adminResetMfa * Reorganizing authentication to fix LDAP error message (#2723) * Fixing failing unit test * Initial upgrade db code * Adding upgrade script * Fixing upgrade script after running on core * Update OAuth and Claim routes to work with user model changes (#2739) * Fixing perminant deletion. Adding ability to delete all user and the entire database (#2740) * Fixing team invite ldap login call (#2741) * Fixing bluebar and some img stuff * Fix all the different file upload web utils (#2743) * Fixing invalid session redirect (#2744) * Redirect on bad channel name (#2746) * Fixing a bunch of issue and removing dead code * Patch to fix error message on leave channel (#2747) * Setting EnableOpenServer to false by default * Fixing config * Fixing upgrade * Fixing reported bugs * Bug fixes for PLT-2057 * PLT-2563 Redo password recovery to use a database table (#2745) * Redo password recovery to use a database table * Update reset password audits * Split out admin and user reset password APIs to be separate * Delete password recovery when user is permanently deleted * Consolidate password resetting into a single function * Removed private channels as an option for outgoing webhooks (#2752) * PLT-2577/PLT-2552 Fixes for backstage (#2753) * Added URL to incoming webhook list * Fixed client functions for adding/removing integrations * Disallowed slash commands without trigger words * Fixed clientside handling of errors on AddCommand page * Minor auth cleanup (#2758) * Changed EditPostModal to just close if you save without making any changes (#2759) * Renamed client -> Client in async_client.jsx and fixed eslint warnings (#2756) * Fixed url in channel info modal (#2755) * Fixing reported issues * Moving to version 3 of the apis * Fixing command unit tests (#2760) * Adding team admins * Fixing DM issue * Fixing eslint error * Properly set EditPostModal's originalText state in all cases (#2762) * Update client config check to assume features is defined if server is licensed (#2772) * Fixing url link * Fixing issue with websocket crashing when sending messages to different teams
This commit is contained in:
parent
5c755463ed
commit
2e5617c29b
268 changed files with 13214 additions and 9686 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -47,6 +47,8 @@ _testmain.go
|
|||
*mattermost.log
|
||||
*npm-debug.log*
|
||||
|
||||
.tmp
|
||||
|
||||
# Vim temporary files
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
|
|
|
|||
5
Godeps/Godeps.json
generated
5
Godeps/Godeps.json
generated
|
|
@ -9,6 +9,11 @@
|
|||
"ImportPath": "github.com/NYTimes/gziphandler",
|
||||
"Rev": "a88790d49798560db24af70fb6a10a66e2549a72"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/handlers",
|
||||
"Comment": "v1.1-4-gd0f2612",
|
||||
"Rev": "d0f261246491e3a8613039e90764460448dc05f5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/alecthomas/log4go",
|
||||
"Rev": "8e9057c3b25c409a34c0b9737cdc82cbcafeabce"
|
||||
|
|
|
|||
17
Godeps/_workspace/src/github.com/gorilla/handlers/.travis.yml
generated
vendored
Normal file
17
Godeps/_workspace/src/github.com/gorilla/handlers/.travis.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
language: go
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.4
|
||||
- go: 1.5
|
||||
- go: 1.6
|
||||
|
||||
install:
|
||||
- go get golang.org/x/tools/cmd/vet
|
||||
|
||||
script:
|
||||
- go get -t -v ./...
|
||||
- diff -u <(echo -n) <(gofmt -d .)
|
||||
- go tool vet .
|
||||
- go test -v -race ./...
|
||||
22
Godeps/_workspace/src/github.com/gorilla/handlers/LICENSE
generated
vendored
Normal file
22
Godeps/_workspace/src/github.com/gorilla/handlers/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2013 The Gorilla Handlers 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.
|
||||
53
Godeps/_workspace/src/github.com/gorilla/handlers/README.md
generated
vendored
Normal file
53
Godeps/_workspace/src/github.com/gorilla/handlers/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
gorilla/handlers
|
||||
================
|
||||
[](https://godoc.org/github.com/gorilla/handlers) [](https://travis-ci.org/gorilla/handlers)
|
||||
|
||||
Package handlers is a collection of handlers (aka "HTTP middleware") for use
|
||||
with Go's `net/http` package (or any framework supporting `http.Handler`), including:
|
||||
|
||||
* [**LoggingHandler**](https://godoc.org/github.com/gorilla/handlers#LoggingHandler) for logging HTTP requests in the Apache [Common Log
|
||||
Format](http://httpd.apache.org/docs/2.2/logs.html#common).
|
||||
* [**CombinedLoggingHandler**](https://godoc.org/github.com/gorilla/handlers#CombinedLoggingHandler) for logging HTTP requests in the Apache [Combined Log
|
||||
Format](http://httpd.apache.org/docs/2.2/logs.html#combined) commonly used by
|
||||
both Apache and nginx.
|
||||
* [**CompressHandler**](https://godoc.org/github.com/gorilla/handlers#CompressHandler) for gzipping responses.
|
||||
* [**ContentTypeHandler**](https://godoc.org/github.com/gorilla/handlers#ContentTypeHandler) for validating requests against a list of accepted
|
||||
content types.
|
||||
* [**MethodHandler**](https://godoc.org/github.com/gorilla/handlers#MethodHandler) for matching HTTP methods against handlers in a
|
||||
`map[string]http.Handler`
|
||||
* [**ProxyHeaders**](https://godoc.org/github.com/gorilla/handlers#ProxyHeaders) for populating `r.RemoteAddr` and `r.URL.Scheme` based on the
|
||||
`X-Forwarded-For`, `X-Real-IP`, `X-Forwarded-Proto` and RFC7239 `Forwarded`
|
||||
headers when running a Go server behind a HTTP reverse proxy.
|
||||
* [**CanonicalHost**](https://godoc.org/github.com/gorilla/handlers#CanonicalHost) for re-directing to the preferred host when handling multiple
|
||||
domains (i.e. multiple CNAME aliases).
|
||||
* [**RecoveryHandler**](https://godoc.org/github.com/gorilla/handlers#RecoveryHandler) for recovering from unexpected panics.
|
||||
|
||||
Other handlers are documented [on the Gorilla
|
||||
website](http://www.gorillatoolkit.org/pkg/handlers).
|
||||
|
||||
## Example
|
||||
|
||||
A simple example using `handlers.LoggingHandler` and `handlers.CompressHandler`:
|
||||
|
||||
```go
|
||||
import (
|
||||
"net/http"
|
||||
"github.com/gorilla/handlers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := http.NewServeMux()
|
||||
|
||||
// Only log requests to our admin dashboard to stdout
|
||||
r.Handle("/admin", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(ShowAdminDashboard)))
|
||||
r.HandleFunc("/", ShowIndex)
|
||||
|
||||
// Wrap our server with our gzip handler to gzip compress all responses.
|
||||
http.ListenAndServe(":8000", handlers.CompressHandler(r))
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
BSD licensed. See the included LICENSE file for details.
|
||||
|
||||
74
Godeps/_workspace/src/github.com/gorilla/handlers/canonical.go
generated
vendored
Normal file
74
Godeps/_workspace/src/github.com/gorilla/handlers/canonical.go
generated
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type canonical struct {
|
||||
h http.Handler
|
||||
domain string
|
||||
code int
|
||||
}
|
||||
|
||||
// CanonicalHost is HTTP middleware that re-directs requests to the canonical
|
||||
// domain. It accepts a domain and a status code (e.g. 301 or 302) and
|
||||
// re-directs clients to this domain. The existing request path is maintained.
|
||||
//
|
||||
// Note: If the provided domain is considered invalid by url.Parse or otherwise
|
||||
// returns an empty scheme or host, clients are not re-directed.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302)
|
||||
// r.HandleFunc("/route", YourHandler)
|
||||
//
|
||||
// log.Fatal(http.ListenAndServe(":7000", canonical(r)))
|
||||
//
|
||||
func CanonicalHost(domain string, code int) func(h http.Handler) http.Handler {
|
||||
fn := func(h http.Handler) http.Handler {
|
||||
return canonical{h, domain, code}
|
||||
}
|
||||
|
||||
return fn
|
||||
}
|
||||
|
||||
func (c canonical) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
dest, err := url.Parse(c.domain)
|
||||
if err != nil {
|
||||
// Call the next handler if the provided domain fails to parse.
|
||||
c.h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if dest.Scheme == "" || dest.Host == "" {
|
||||
// Call the next handler if the scheme or host are empty.
|
||||
// Note that url.Parse won't fail on in this case.
|
||||
c.h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.EqualFold(cleanHost(r.Host), dest.Host) {
|
||||
// Re-build the destination URL
|
||||
dest := dest.Scheme + "://" + dest.Host + r.URL.Path
|
||||
if r.URL.RawQuery != "" {
|
||||
dest += "?" + r.URL.RawQuery
|
||||
}
|
||||
http.Redirect(w, r, dest, c.code)
|
||||
return
|
||||
}
|
||||
|
||||
c.h.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// cleanHost cleans invalid Host headers by stripping anything after '/' or ' '.
|
||||
// This is backported from Go 1.5 (in response to issue #11206) and attempts to
|
||||
// mitigate malformed Host headers that do not match the format in RFC7230.
|
||||
func cleanHost(in string) string {
|
||||
if i := strings.IndexAny(in, " /"); i != -1 {
|
||||
return in[:i]
|
||||
}
|
||||
return in
|
||||
}
|
||||
145
Godeps/_workspace/src/github.com/gorilla/handlers/compress.go
generated
vendored
Normal file
145
Godeps/_workspace/src/github.com/gorilla/handlers/compress.go
generated
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
// Copyright 2013 The Gorilla 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 handlers
|
||||
|
||||
import (
|
||||
"compress/flate"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type compressResponseWriter struct {
|
||||
io.Writer
|
||||
http.ResponseWriter
|
||||
http.Hijacker
|
||||
http.Flusher
|
||||
http.CloseNotifier
|
||||
}
|
||||
|
||||
func (w *compressResponseWriter) WriteHeader(c int) {
|
||||
w.ResponseWriter.Header().Del("Content-Length")
|
||||
w.ResponseWriter.WriteHeader(c)
|
||||
}
|
||||
|
||||
func (w *compressResponseWriter) Header() http.Header {
|
||||
return w.ResponseWriter.Header()
|
||||
}
|
||||
|
||||
func (w *compressResponseWriter) Write(b []byte) (int, error) {
|
||||
h := w.ResponseWriter.Header()
|
||||
if h.Get("Content-Type") == "" {
|
||||
h.Set("Content-Type", http.DetectContentType(b))
|
||||
}
|
||||
h.Del("Content-Length")
|
||||
|
||||
return w.Writer.Write(b)
|
||||
}
|
||||
|
||||
type flusher interface {
|
||||
Flush() error
|
||||
}
|
||||
|
||||
func (w *compressResponseWriter) Flush() {
|
||||
// Flush compressed data if compressor supports it.
|
||||
if f, ok := w.Writer.(flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
// Flush HTTP response.
|
||||
if w.Flusher != nil {
|
||||
w.Flusher.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
// CompressHandler gzip compresses HTTP responses for clients that support it
|
||||
// via the 'Accept-Encoding' header.
|
||||
func CompressHandler(h http.Handler) http.Handler {
|
||||
return CompressHandlerLevel(h, gzip.DefaultCompression)
|
||||
}
|
||||
|
||||
// CompressHandlerLevel gzip compresses HTTP responses with specified compression level
|
||||
// for clients that support it via the 'Accept-Encoding' header.
|
||||
//
|
||||
// The compression level should be gzip.DefaultCompression, gzip.NoCompression,
|
||||
// or any integer value between gzip.BestSpeed and gzip.BestCompression inclusive.
|
||||
// gzip.DefaultCompression is used in case of invalid compression level.
|
||||
func CompressHandlerLevel(h http.Handler, level int) http.Handler {
|
||||
if level < gzip.DefaultCompression || level > gzip.BestCompression {
|
||||
level = gzip.DefaultCompression
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
L:
|
||||
for _, enc := range strings.Split(r.Header.Get("Accept-Encoding"), ",") {
|
||||
switch strings.TrimSpace(enc) {
|
||||
case "gzip":
|
||||
w.Header().Set("Content-Encoding", "gzip")
|
||||
w.Header().Add("Vary", "Accept-Encoding")
|
||||
|
||||
gw, _ := gzip.NewWriterLevel(w, level)
|
||||
defer gw.Close()
|
||||
|
||||
h, hok := w.(http.Hijacker)
|
||||
if !hok { /* w is not Hijacker... oh well... */
|
||||
h = nil
|
||||
}
|
||||
|
||||
f, fok := w.(http.Flusher)
|
||||
if !fok {
|
||||
f = nil
|
||||
}
|
||||
|
||||
cn, cnok := w.(http.CloseNotifier)
|
||||
if !cnok {
|
||||
cn = nil
|
||||
}
|
||||
|
||||
w = &compressResponseWriter{
|
||||
Writer: gw,
|
||||
ResponseWriter: w,
|
||||
Hijacker: h,
|
||||
Flusher: f,
|
||||
CloseNotifier: cn,
|
||||
}
|
||||
|
||||
break L
|
||||
case "deflate":
|
||||
w.Header().Set("Content-Encoding", "deflate")
|
||||
w.Header().Add("Vary", "Accept-Encoding")
|
||||
|
||||
fw, _ := flate.NewWriter(w, level)
|
||||
defer fw.Close()
|
||||
|
||||
h, hok := w.(http.Hijacker)
|
||||
if !hok { /* w is not Hijacker... oh well... */
|
||||
h = nil
|
||||
}
|
||||
|
||||
f, fok := w.(http.Flusher)
|
||||
if !fok {
|
||||
f = nil
|
||||
}
|
||||
|
||||
cn, cnok := w.(http.CloseNotifier)
|
||||
if !cnok {
|
||||
cn = nil
|
||||
}
|
||||
|
||||
w = &compressResponseWriter{
|
||||
Writer: fw,
|
||||
ResponseWriter: w,
|
||||
Hijacker: h,
|
||||
Flusher: f,
|
||||
CloseNotifier: cn,
|
||||
}
|
||||
|
||||
break L
|
||||
}
|
||||
}
|
||||
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
317
Godeps/_workspace/src/github.com/gorilla/handlers/cors.go
generated
vendored
Normal file
317
Godeps/_workspace/src/github.com/gorilla/handlers/cors.go
generated
vendored
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CORSOption represents a functional option for configuring the CORS middleware.
|
||||
type CORSOption func(*cors) error
|
||||
|
||||
type cors struct {
|
||||
h http.Handler
|
||||
allowedHeaders []string
|
||||
allowedMethods []string
|
||||
allowedOrigins []string
|
||||
allowedOriginValidator OriginValidator
|
||||
exposedHeaders []string
|
||||
maxAge int
|
||||
ignoreOptions bool
|
||||
allowCredentials bool
|
||||
}
|
||||
|
||||
// OriginValidator takes an origin string and returns whether or not that origin is allowed.
|
||||
type OriginValidator func(string) bool
|
||||
|
||||
var (
|
||||
defaultCorsMethods = []string{"GET", "HEAD", "POST"}
|
||||
defaultCorsHeaders = []string{"Accept", "Accept-Language", "Content-Language", "Origin"}
|
||||
// (WebKit/Safari v9 sends the Origin header by default in AJAX requests)
|
||||
)
|
||||
|
||||
const (
|
||||
corsOptionMethod string = "OPTIONS"
|
||||
corsAllowOriginHeader string = "Access-Control-Allow-Origin"
|
||||
corsExposeHeadersHeader string = "Access-Control-Expose-Headers"
|
||||
corsMaxAgeHeader string = "Access-Control-Max-Age"
|
||||
corsAllowMethodsHeader string = "Access-Control-Allow-Methods"
|
||||
corsAllowHeadersHeader string = "Access-Control-Allow-Headers"
|
||||
corsAllowCredentialsHeader string = "Access-Control-Allow-Credentials"
|
||||
corsRequestMethodHeader string = "Access-Control-Request-Method"
|
||||
corsRequestHeadersHeader string = "Access-Control-Request-Headers"
|
||||
corsOriginHeader string = "Origin"
|
||||
corsVaryHeader string = "Vary"
|
||||
corsOriginMatchAll string = "*"
|
||||
)
|
||||
|
||||
func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
origin := r.Header.Get(corsOriginHeader)
|
||||
if !ch.isOriginAllowed(origin) {
|
||||
ch.h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Method == corsOptionMethod {
|
||||
if ch.ignoreOptions {
|
||||
ch.h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := r.Header[corsRequestMethodHeader]; !ok {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
method := r.Header.Get(corsRequestMethodHeader)
|
||||
if !ch.isMatch(method, ch.allowedMethods) {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
requestHeaders := strings.Split(r.Header.Get(corsRequestHeadersHeader), ",")
|
||||
allowedHeaders := []string{}
|
||||
for _, v := range requestHeaders {
|
||||
canonicalHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
|
||||
if canonicalHeader == "" || ch.isMatch(canonicalHeader, defaultCorsHeaders) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !ch.isMatch(canonicalHeader, ch.allowedHeaders) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
allowedHeaders = append(allowedHeaders, canonicalHeader)
|
||||
}
|
||||
|
||||
if len(allowedHeaders) > 0 {
|
||||
w.Header().Set(corsAllowHeadersHeader, strings.Join(allowedHeaders, ","))
|
||||
}
|
||||
|
||||
if ch.maxAge > 0 {
|
||||
w.Header().Set(corsMaxAgeHeader, strconv.Itoa(ch.maxAge))
|
||||
}
|
||||
|
||||
if !ch.isMatch(method, defaultCorsMethods) {
|
||||
w.Header().Set(corsAllowMethodsHeader, method)
|
||||
}
|
||||
} else {
|
||||
if len(ch.exposedHeaders) > 0 {
|
||||
w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
|
||||
}
|
||||
}
|
||||
|
||||
if ch.allowCredentials {
|
||||
w.Header().Set(corsAllowCredentialsHeader, "true")
|
||||
}
|
||||
|
||||
if len(ch.allowedOrigins) > 1 {
|
||||
w.Header().Set(corsVaryHeader, corsOriginHeader)
|
||||
}
|
||||
|
||||
w.Header().Set(corsAllowOriginHeader, origin)
|
||||
|
||||
if r.Method == corsOptionMethod {
|
||||
return
|
||||
}
|
||||
ch.h.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// CORS provides Cross-Origin Resource Sharing middleware.
|
||||
// Example:
|
||||
//
|
||||
// import (
|
||||
// "net/http"
|
||||
//
|
||||
// "github.com/gorilla/handlers"
|
||||
// "github.com/gorilla/mux"
|
||||
// )
|
||||
//
|
||||
// func main() {
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/users", UserEndpoint)
|
||||
// r.HandleFunc("/projects", ProjectEndpoint)
|
||||
//
|
||||
// // Apply the CORS middleware to our top-level router, with the defaults.
|
||||
// http.ListenAndServe(":8000", handlers.CORS()(r))
|
||||
// }
|
||||
//
|
||||
func CORS(opts ...CORSOption) func(http.Handler) http.Handler {
|
||||
return func(h http.Handler) http.Handler {
|
||||
ch := parseCORSOptions(opts...)
|
||||
ch.h = h
|
||||
return ch
|
||||
}
|
||||
}
|
||||
|
||||
func parseCORSOptions(opts ...CORSOption) *cors {
|
||||
ch := &cors{
|
||||
allowedMethods: defaultCorsMethods,
|
||||
allowedHeaders: defaultCorsHeaders,
|
||||
allowedOrigins: []string{corsOriginMatchAll},
|
||||
}
|
||||
|
||||
for _, option := range opts {
|
||||
option(ch)
|
||||
}
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
//
|
||||
// Functional options for configuring CORS.
|
||||
//
|
||||
|
||||
// AllowedHeaders adds the provided headers to the list of allowed headers in a
|
||||
// CORS request.
|
||||
// This is an append operation so the headers Accept, Accept-Language,
|
||||
// and Content-Language are always allowed.
|
||||
// Content-Type must be explicitly declared if accepting Content-Types other than
|
||||
// application/x-www-form-urlencoded, multipart/form-data, or text/plain.
|
||||
func AllowedHeaders(headers []string) CORSOption {
|
||||
return func(ch *cors) error {
|
||||
for _, v := range headers {
|
||||
normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
|
||||
if normalizedHeader == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if !ch.isMatch(normalizedHeader, ch.allowedHeaders) {
|
||||
ch.allowedHeaders = append(ch.allowedHeaders, normalizedHeader)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// AllowedMethods can be used to explicitly allow methods in the
|
||||
// Access-Control-Allow-Methods header.
|
||||
// This is a replacement operation so you must also
|
||||
// pass GET, HEAD, and POST if you wish to support those methods.
|
||||
func AllowedMethods(methods []string) CORSOption {
|
||||
return func(ch *cors) error {
|
||||
ch.allowedMethods = []string{}
|
||||
for _, v := range methods {
|
||||
normalizedMethod := strings.ToUpper(strings.TrimSpace(v))
|
||||
if normalizedMethod == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if !ch.isMatch(normalizedMethod, ch.allowedMethods) {
|
||||
ch.allowedMethods = append(ch.allowedMethods, normalizedMethod)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// AllowedOrigins sets the allowed origins for CORS requests, as used in the
|
||||
// 'Allow-Access-Control-Origin' HTTP header.
|
||||
// Note: Passing in a []string{"*"} will allow any domain.
|
||||
func AllowedOrigins(origins []string) CORSOption {
|
||||
return func(ch *cors) error {
|
||||
for _, v := range origins {
|
||||
if v == corsOriginMatchAll {
|
||||
ch.allowedOrigins = []string{corsOriginMatchAll}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
ch.allowedOrigins = origins
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// AllowedOriginValidator sets a function for evaluating allowed origins in CORS requests, represented by the
|
||||
// 'Allow-Access-Control-Origin' HTTP header.
|
||||
func AllowedOriginValidator(fn OriginValidator) CORSOption {
|
||||
return func(ch *cors) error {
|
||||
ch.allowedOriginValidator = fn
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExposeHeaders can be used to specify headers that are available
|
||||
// and will not be stripped out by the user-agent.
|
||||
func ExposedHeaders(headers []string) CORSOption {
|
||||
return func(ch *cors) error {
|
||||
ch.exposedHeaders = []string{}
|
||||
for _, v := range headers {
|
||||
normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
|
||||
if normalizedHeader == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if !ch.isMatch(normalizedHeader, ch.exposedHeaders) {
|
||||
ch.exposedHeaders = append(ch.exposedHeaders, normalizedHeader)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// MaxAge determines the maximum age (in seconds) between preflight requests. A
|
||||
// maximum of 10 minutes is allowed. An age above this value will default to 10
|
||||
// minutes.
|
||||
func MaxAge(age int) CORSOption {
|
||||
return func(ch *cors) error {
|
||||
// Maximum of 10 minutes.
|
||||
if age > 600 {
|
||||
age = 600
|
||||
}
|
||||
|
||||
ch.maxAge = age
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// IgnoreOptions causes the CORS middleware to ignore OPTIONS requests, instead
|
||||
// passing them through to the next handler. This is useful when your application
|
||||
// or framework has a pre-existing mechanism for responding to OPTIONS requests.
|
||||
func IgnoreOptions() CORSOption {
|
||||
return func(ch *cors) error {
|
||||
ch.ignoreOptions = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// AllowCredentials can be used to specify that the user agent may pass
|
||||
// authentication details along with the request.
|
||||
func AllowCredentials() CORSOption {
|
||||
return func(ch *cors) error {
|
||||
ch.allowCredentials = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (ch *cors) isOriginAllowed(origin string) bool {
|
||||
if origin == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if ch.allowedOriginValidator != nil {
|
||||
return ch.allowedOriginValidator(origin)
|
||||
}
|
||||
|
||||
for _, allowedOrigin := range ch.allowedOrigins {
|
||||
if allowedOrigin == origin || allowedOrigin == corsOriginMatchAll {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (ch *cors) isMatch(needle string, haystack []string) bool {
|
||||
for _, v := range haystack {
|
||||
if v == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
9
Godeps/_workspace/src/github.com/gorilla/handlers/doc.go
generated
vendored
Normal file
9
Godeps/_workspace/src/github.com/gorilla/handlers/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
Package handlers is a collection of handlers (aka "HTTP middleware") for use
|
||||
with Go's net/http package (or any framework supporting http.Handler).
|
||||
|
||||
The package includes handlers for logging in standardised formats, compressing
|
||||
HTTP responses, validating content types and other useful tools for manipulating
|
||||
requests and responses.
|
||||
*/
|
||||
package handlers
|
||||
403
Godeps/_workspace/src/github.com/gorilla/handlers/handlers.go
generated
vendored
Normal file
403
Godeps/_workspace/src/github.com/gorilla/handlers/handlers.go
generated
vendored
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
// Copyright 2013 The Gorilla 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 handlers
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// MethodHandler is an http.Handler that dispatches to a handler whose key in the
|
||||
// MethodHandler's map matches the name of the HTTP request's method, eg: GET
|
||||
//
|
||||
// If the request's method is OPTIONS and OPTIONS is not a key in the map then
|
||||
// the handler responds with a status of 200 and sets the Allow header to a
|
||||
// comma-separated list of available methods.
|
||||
//
|
||||
// If the request's method doesn't match any of its keys the handler responds
|
||||
// with a status of HTTP 405 "Method Not Allowed" and sets the Allow header to a
|
||||
// comma-separated list of available methods.
|
||||
type MethodHandler map[string]http.Handler
|
||||
|
||||
func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
if handler, ok := h[req.Method]; ok {
|
||||
handler.ServeHTTP(w, req)
|
||||
} else {
|
||||
allow := []string{}
|
||||
for k := range h {
|
||||
allow = append(allow, k)
|
||||
}
|
||||
sort.Strings(allow)
|
||||
w.Header().Set("Allow", strings.Join(allow, ", "))
|
||||
if req.Method == "OPTIONS" {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
} else {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loggingHandler is the http.Handler implementation for LoggingHandlerTo and its
|
||||
// friends
|
||||
type loggingHandler struct {
|
||||
writer io.Writer
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
// combinedLoggingHandler is the http.Handler implementation for LoggingHandlerTo
|
||||
// and its friends
|
||||
type combinedLoggingHandler struct {
|
||||
writer io.Writer
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
t := time.Now()
|
||||
logger := makeLogger(w)
|
||||
url := *req.URL
|
||||
h.handler.ServeHTTP(logger, req)
|
||||
writeLog(h.writer, req, url, t, logger.Status(), logger.Size())
|
||||
}
|
||||
|
||||
func (h combinedLoggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
t := time.Now()
|
||||
logger := makeLogger(w)
|
||||
url := *req.URL
|
||||
h.handler.ServeHTTP(logger, req)
|
||||
writeCombinedLog(h.writer, req, url, t, logger.Status(), logger.Size())
|
||||
}
|
||||
|
||||
func makeLogger(w http.ResponseWriter) loggingResponseWriter {
|
||||
var logger loggingResponseWriter = &responseLogger{w: w}
|
||||
if _, ok := w.(http.Hijacker); ok {
|
||||
logger = &hijackLogger{responseLogger{w: w}}
|
||||
}
|
||||
h, ok1 := logger.(http.Hijacker)
|
||||
c, ok2 := w.(http.CloseNotifier)
|
||||
if ok1 && ok2 {
|
||||
return hijackCloseNotifier{logger, h, c}
|
||||
}
|
||||
if ok2 {
|
||||
return &closeNotifyWriter{logger, c}
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
type loggingResponseWriter interface {
|
||||
http.ResponseWriter
|
||||
http.Flusher
|
||||
Status() int
|
||||
Size() int
|
||||
}
|
||||
|
||||
// responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP
|
||||
// status code and body size
|
||||
type responseLogger struct {
|
||||
w http.ResponseWriter
|
||||
status int
|
||||
size int
|
||||
}
|
||||
|
||||
func (l *responseLogger) Header() http.Header {
|
||||
return l.w.Header()
|
||||
}
|
||||
|
||||
func (l *responseLogger) Write(b []byte) (int, error) {
|
||||
if l.status == 0 {
|
||||
// The status will be StatusOK if WriteHeader has not been called yet
|
||||
l.status = http.StatusOK
|
||||
}
|
||||
size, err := l.w.Write(b)
|
||||
l.size += size
|
||||
return size, err
|
||||
}
|
||||
|
||||
func (l *responseLogger) WriteHeader(s int) {
|
||||
l.w.WriteHeader(s)
|
||||
l.status = s
|
||||
}
|
||||
|
||||
func (l *responseLogger) Status() int {
|
||||
return l.status
|
||||
}
|
||||
|
||||
func (l *responseLogger) Size() int {
|
||||
return l.size
|
||||
}
|
||||
|
||||
func (l *responseLogger) Flush() {
|
||||
f, ok := l.w.(http.Flusher)
|
||||
if ok {
|
||||
f.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
type hijackLogger struct {
|
||||
responseLogger
|
||||
}
|
||||
|
||||
func (l *hijackLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
h := l.responseLogger.w.(http.Hijacker)
|
||||
conn, rw, err := h.Hijack()
|
||||
if err == nil && l.responseLogger.status == 0 {
|
||||
// The status will be StatusSwitchingProtocols if there was no error and
|
||||
// WriteHeader has not been called yet
|
||||
l.responseLogger.status = http.StatusSwitchingProtocols
|
||||
}
|
||||
return conn, rw, err
|
||||
}
|
||||
|
||||
type closeNotifyWriter struct {
|
||||
loggingResponseWriter
|
||||
http.CloseNotifier
|
||||
}
|
||||
|
||||
type hijackCloseNotifier struct {
|
||||
loggingResponseWriter
|
||||
http.Hijacker
|
||||
http.CloseNotifier
|
||||
}
|
||||
|
||||
const lowerhex = "0123456789abcdef"
|
||||
|
||||
func appendQuoted(buf []byte, s string) []byte {
|
||||
var runeTmp [utf8.UTFMax]byte
|
||||
for width := 0; len(s) > 0; s = s[width:] {
|
||||
r := rune(s[0])
|
||||
width = 1
|
||||
if r >= utf8.RuneSelf {
|
||||
r, width = utf8.DecodeRuneInString(s)
|
||||
}
|
||||
if width == 1 && r == utf8.RuneError {
|
||||
buf = append(buf, `\x`...)
|
||||
buf = append(buf, lowerhex[s[0]>>4])
|
||||
buf = append(buf, lowerhex[s[0]&0xF])
|
||||
continue
|
||||
}
|
||||
if r == rune('"') || r == '\\' { // always backslashed
|
||||
buf = append(buf, '\\')
|
||||
buf = append(buf, byte(r))
|
||||
continue
|
||||
}
|
||||
if strconv.IsPrint(r) {
|
||||
n := utf8.EncodeRune(runeTmp[:], r)
|
||||
buf = append(buf, runeTmp[:n]...)
|
||||
continue
|
||||
}
|
||||
switch r {
|
||||
case '\a':
|
||||
buf = append(buf, `\a`...)
|
||||
case '\b':
|
||||
buf = append(buf, `\b`...)
|
||||
case '\f':
|
||||
buf = append(buf, `\f`...)
|
||||
case '\n':
|
||||
buf = append(buf, `\n`...)
|
||||
case '\r':
|
||||
buf = append(buf, `\r`...)
|
||||
case '\t':
|
||||
buf = append(buf, `\t`...)
|
||||
case '\v':
|
||||
buf = append(buf, `\v`...)
|
||||
default:
|
||||
switch {
|
||||
case r < ' ':
|
||||
buf = append(buf, `\x`...)
|
||||
buf = append(buf, lowerhex[s[0]>>4])
|
||||
buf = append(buf, lowerhex[s[0]&0xF])
|
||||
case r > utf8.MaxRune:
|
||||
r = 0xFFFD
|
||||
fallthrough
|
||||
case r < 0x10000:
|
||||
buf = append(buf, `\u`...)
|
||||
for s := 12; s >= 0; s -= 4 {
|
||||
buf = append(buf, lowerhex[r>>uint(s)&0xF])
|
||||
}
|
||||
default:
|
||||
buf = append(buf, `\U`...)
|
||||
for s := 28; s >= 0; s -= 4 {
|
||||
buf = append(buf, lowerhex[r>>uint(s)&0xF])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf
|
||||
|
||||
}
|
||||
|
||||
// buildCommonLogLine builds a log entry for req in Apache Common Log Format.
|
||||
// ts is the timestamp with which the entry should be logged.
|
||||
// status and size are used to provide the response HTTP status and size.
|
||||
func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) []byte {
|
||||
username := "-"
|
||||
if url.User != nil {
|
||||
if name := url.User.Username(); name != "" {
|
||||
username = name
|
||||
}
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(req.RemoteAddr)
|
||||
|
||||
if err != nil {
|
||||
host = req.RemoteAddr
|
||||
}
|
||||
|
||||
uri := req.RequestURI
|
||||
|
||||
// Requests using the CONNECT method over HTTP/2.0 must use
|
||||
// the authority field (aka r.Host) to identify the target.
|
||||
// Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT
|
||||
if req.ProtoMajor == 2 && req.Method == "CONNECT" {
|
||||
uri = req.Host
|
||||
}
|
||||
if uri == "" {
|
||||
uri = url.RequestURI()
|
||||
}
|
||||
|
||||
buf := make([]byte, 0, 3*(len(host)+len(username)+len(req.Method)+len(uri)+len(req.Proto)+50)/2)
|
||||
buf = append(buf, host...)
|
||||
buf = append(buf, " - "...)
|
||||
buf = append(buf, username...)
|
||||
buf = append(buf, " ["...)
|
||||
buf = append(buf, ts.Format("02/Jan/2006:15:04:05 -0700")...)
|
||||
buf = append(buf, `] "`...)
|
||||
buf = append(buf, req.Method...)
|
||||
buf = append(buf, " "...)
|
||||
buf = appendQuoted(buf, uri)
|
||||
buf = append(buf, " "...)
|
||||
buf = append(buf, req.Proto...)
|
||||
buf = append(buf, `" `...)
|
||||
buf = append(buf, strconv.Itoa(status)...)
|
||||
buf = append(buf, " "...)
|
||||
buf = append(buf, strconv.Itoa(size)...)
|
||||
return buf
|
||||
}
|
||||
|
||||
// writeLog writes a log entry for req to w in Apache Common Log Format.
|
||||
// ts is the timestamp with which the entry should be logged.
|
||||
// status and size are used to provide the response HTTP status and size.
|
||||
func writeLog(w io.Writer, req *http.Request, url url.URL, ts time.Time, status, size int) {
|
||||
buf := buildCommonLogLine(req, url, ts, status, size)
|
||||
buf = append(buf, '\n')
|
||||
w.Write(buf)
|
||||
}
|
||||
|
||||
// writeCombinedLog writes a log entry for req to w in Apache Combined Log Format.
|
||||
// ts is the timestamp with which the entry should be logged.
|
||||
// status and size are used to provide the response HTTP status and size.
|
||||
func writeCombinedLog(w io.Writer, req *http.Request, url url.URL, ts time.Time, status, size int) {
|
||||
buf := buildCommonLogLine(req, url, ts, status, size)
|
||||
buf = append(buf, ` "`...)
|
||||
buf = appendQuoted(buf, req.Referer())
|
||||
buf = append(buf, `" "`...)
|
||||
buf = appendQuoted(buf, req.UserAgent())
|
||||
buf = append(buf, '"', '\n')
|
||||
w.Write(buf)
|
||||
}
|
||||
|
||||
// CombinedLoggingHandler return a http.Handler that wraps h and logs requests to out in
|
||||
// Apache Combined Log Format.
|
||||
//
|
||||
// See http://httpd.apache.org/docs/2.2/logs.html#combined for a description of this format.
|
||||
//
|
||||
// LoggingHandler always sets the ident field of the log to -
|
||||
func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler {
|
||||
return combinedLoggingHandler{out, h}
|
||||
}
|
||||
|
||||
// LoggingHandler return a http.Handler that wraps h and logs requests to out in
|
||||
// Apache Common Log Format (CLF).
|
||||
//
|
||||
// See http://httpd.apache.org/docs/2.2/logs.html#common for a description of this format.
|
||||
//
|
||||
// LoggingHandler always sets the ident field of the log to -
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// w.Write([]byte("This is a catch-all route"))
|
||||
// })
|
||||
// loggedRouter := handlers.LoggingHandler(os.Stdout, r)
|
||||
// http.ListenAndServe(":1123", loggedRouter)
|
||||
//
|
||||
func LoggingHandler(out io.Writer, h http.Handler) http.Handler {
|
||||
return loggingHandler{out, h}
|
||||
}
|
||||
|
||||
// isContentType validates the Content-Type header matches the supplied
|
||||
// contentType. That is, its type and subtype match.
|
||||
func isContentType(h http.Header, contentType string) bool {
|
||||
ct := h.Get("Content-Type")
|
||||
if i := strings.IndexRune(ct, ';'); i != -1 {
|
||||
ct = ct[0:i]
|
||||
}
|
||||
return ct == contentType
|
||||
}
|
||||
|
||||
// ContentTypeHandler wraps and returns a http.Handler, validating the request
|
||||
// content type is compatible with the contentTypes list. It writes a HTTP 415
|
||||
// error if that fails.
|
||||
//
|
||||
// Only PUT, POST, and PATCH requests are considered.
|
||||
func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !(r.Method == "PUT" || r.Method == "POST" || r.Method == "PATCH") {
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
for _, ct := range contentTypes {
|
||||
if isContentType(r.Header, ct) {
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q", r.Header.Get("Content-Type"), contentTypes), http.StatusUnsupportedMediaType)
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
// HTTPMethodOverrideHeader is a commonly used
|
||||
// http header to override a request method.
|
||||
HTTPMethodOverrideHeader = "X-HTTP-Method-Override"
|
||||
// HTTPMethodOverrideFormKey is a commonly used
|
||||
// HTML form key to override a request method.
|
||||
HTTPMethodOverrideFormKey = "_method"
|
||||
)
|
||||
|
||||
// HTTPMethodOverrideHandler wraps and returns a http.Handler which checks for
|
||||
// the X-HTTP-Method-Override header or the _method form key, and overrides (if
|
||||
// valid) request.Method with its value.
|
||||
//
|
||||
// This is especially useful for HTTP clients that don't support many http verbs.
|
||||
// It isn't secure to override e.g a GET to a POST, so only POST requests are
|
||||
// considered. Likewise, the override method can only be a "write" method: PUT,
|
||||
// PATCH or DELETE.
|
||||
//
|
||||
// Form method takes precedence over header method.
|
||||
func HTTPMethodOverrideHandler(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "POST" {
|
||||
om := r.FormValue(HTTPMethodOverrideFormKey)
|
||||
if om == "" {
|
||||
om = r.Header.Get(HTTPMethodOverrideHeader)
|
||||
}
|
||||
if om == "PUT" || om == "PATCH" || om == "DELETE" {
|
||||
r.Method = om
|
||||
}
|
||||
}
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
113
Godeps/_workspace/src/github.com/gorilla/handlers/proxy_headers.go
generated
vendored
Normal file
113
Godeps/_workspace/src/github.com/gorilla/handlers/proxy_headers.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// De-facto standard header keys.
|
||||
xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For")
|
||||
xRealIP = http.CanonicalHeaderKey("X-Real-IP")
|
||||
xForwardedProto = http.CanonicalHeaderKey("X-Forwarded-Scheme")
|
||||
)
|
||||
|
||||
var (
|
||||
// RFC7239 defines a new "Forwarded: " header designed to replace the
|
||||
// existing use of X-Forwarded-* headers.
|
||||
// e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43
|
||||
forwarded = http.CanonicalHeaderKey("Forwarded")
|
||||
// Allows for a sub-match of the first value after 'for=' to the next
|
||||
// comma, semi-colon or space. The match is case-insensitive.
|
||||
forRegex = regexp.MustCompile(`(?i)(?:for=)([^(;|,| )]+)`)
|
||||
// Allows for a sub-match for the first instance of scheme (http|https)
|
||||
// prefixed by 'proto='. The match is case-insensitive.
|
||||
protoRegex = regexp.MustCompile(`(?i)(?:proto=)(https|http)`)
|
||||
)
|
||||
|
||||
// ProxyHeaders inspects common reverse proxy headers and sets the corresponding
|
||||
// fields in the HTTP request struct. These are X-Forwarded-For and X-Real-IP
|
||||
// for the remote (client) IP address, X-Forwarded-Proto for the scheme
|
||||
// (http|https) and the RFC7239 Forwarded header, which may include both client
|
||||
// IPs and schemes.
|
||||
//
|
||||
// NOTE: This middleware should only be used when behind a reverse
|
||||
// proxy like nginx, HAProxy or Apache. Reverse proxies that don't (or are
|
||||
// configured not to) strip these headers from client requests, or where these
|
||||
// headers are accepted "as is" from a remote client (e.g. when Go is not behind
|
||||
// a proxy), can manifest as a vulnerability if your application uses these
|
||||
// headers for validating the 'trustworthiness' of a request.
|
||||
func ProxyHeaders(h http.Handler) http.Handler {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
// Set the remote IP with the value passed from the proxy.
|
||||
if fwd := getIP(r); fwd != "" {
|
||||
r.RemoteAddr = fwd
|
||||
}
|
||||
|
||||
// Set the scheme (proto) with the value passed from the proxy.
|
||||
if scheme := getScheme(r); scheme != "" {
|
||||
r.URL.Scheme = scheme
|
||||
}
|
||||
|
||||
// Call the next handler in the chain.
|
||||
h.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
||||
// getIP retrieves the IP from the X-Forwarded-For, X-Real-IP and RFC7239
|
||||
// Forwarded headers (in that order).
|
||||
func getIP(r *http.Request) string {
|
||||
var addr string
|
||||
|
||||
if fwd := r.Header.Get(xForwardedFor); fwd != "" {
|
||||
// Only grab the first (client) address. Note that '192.168.0.1,
|
||||
// 10.1.1.1' is a valid key for X-Forwarded-For where addresses after
|
||||
// the first may represent forwarding proxies earlier in the chain.
|
||||
s := strings.Index(fwd, ", ")
|
||||
if s == -1 {
|
||||
s = len(fwd)
|
||||
}
|
||||
addr = fwd[:s]
|
||||
} else if fwd := r.Header.Get(xRealIP); fwd != "" {
|
||||
// X-Real-IP should only contain one IP address (the client making the
|
||||
// request).
|
||||
addr = fwd
|
||||
} else if fwd := r.Header.Get(forwarded); fwd != "" {
|
||||
// match should contain at least two elements if the protocol was
|
||||
// specified in the Forwarded header. The first element will always be
|
||||
// the 'for=' capture, which we ignore. In the case of multiple IP
|
||||
// addresses (for=8.8.8.8, 8.8.4.4,172.16.1.20 is valid) we only
|
||||
// extract the first, which should be the client IP.
|
||||
if match := forRegex.FindStringSubmatch(fwd); len(match) > 1 {
|
||||
// IPv6 addresses in Forwarded headers are quoted-strings. We strip
|
||||
// these quotes.
|
||||
addr = strings.Trim(match[1], `"`)
|
||||
}
|
||||
}
|
||||
|
||||
return addr
|
||||
}
|
||||
|
||||
// getScheme retrieves the scheme from the X-Forwarded-Proto and RFC7239
|
||||
// Forwarded headers (in that order).
|
||||
func getScheme(r *http.Request) string {
|
||||
var scheme string
|
||||
|
||||
// Retrieve the scheme from X-Forwarded-Proto.
|
||||
if proto := r.Header.Get(xForwardedProto); proto != "" {
|
||||
scheme = strings.ToLower(proto)
|
||||
} else if proto := r.Header.Get(forwarded); proto != "" {
|
||||
// match should contain at least two elements if the protocol was
|
||||
// specified in the Forwarded header. The first element will always be
|
||||
// the 'proto=' capture, which we ignore. In the case of multiple proto
|
||||
// parameters (invalid) we only extract the first.
|
||||
if match := protoRegex.FindStringSubmatch(proto); len(match) > 1 {
|
||||
scheme = strings.ToLower(match[1])
|
||||
}
|
||||
}
|
||||
|
||||
return scheme
|
||||
}
|
||||
86
Godeps/_workspace/src/github.com/gorilla/handlers/recovery.go
generated
vendored
Normal file
86
Godeps/_workspace/src/github.com/gorilla/handlers/recovery.go
generated
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
type recoveryHandler struct {
|
||||
handler http.Handler
|
||||
logger *log.Logger
|
||||
printStack bool
|
||||
}
|
||||
|
||||
// RecoveryOption provides a functional approach to define
|
||||
// configuration for a handler; such as setting the logging
|
||||
// whether or not to print strack traces on panic.
|
||||
type RecoveryOption func(http.Handler)
|
||||
|
||||
func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler {
|
||||
for _, option := range opts {
|
||||
option(h)
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// RecoveryHandler is HTTP middleware that recovers from a panic,
|
||||
// logs the panic, writes http.StatusInternalServerError, and
|
||||
// continues to the next handler.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// r := mux.NewRouter()
|
||||
// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// panic("Unexpected error!")
|
||||
// })
|
||||
//
|
||||
// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r))
|
||||
func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler {
|
||||
return func(h http.Handler) http.Handler {
|
||||
r := &recoveryHandler{handler: h}
|
||||
return parseRecoveryOptions(r, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// RecoveryLogger is a functional option to override
|
||||
// the default logger
|
||||
func RecoveryLogger(logger *log.Logger) RecoveryOption {
|
||||
return func(h http.Handler) {
|
||||
r := h.(*recoveryHandler)
|
||||
r.logger = logger
|
||||
}
|
||||
}
|
||||
|
||||
// PrintRecoveryStack is a functional option to enable
|
||||
// or disable printing stack traces on panic.
|
||||
func PrintRecoveryStack(print bool) RecoveryOption {
|
||||
return func(h http.Handler) {
|
||||
r := h.(*recoveryHandler)
|
||||
r.printStack = print
|
||||
}
|
||||
}
|
||||
|
||||
func (h recoveryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
h.log(err)
|
||||
}
|
||||
}()
|
||||
|
||||
h.handler.ServeHTTP(w, req)
|
||||
}
|
||||
|
||||
func (h recoveryHandler) log(message interface{}) {
|
||||
if h.logger != nil {
|
||||
h.logger.Println(message)
|
||||
} else {
|
||||
log.Println(message)
|
||||
}
|
||||
|
||||
if h.printStack {
|
||||
debug.PrintStack()
|
||||
}
|
||||
}
|
||||
64
Makefile
64
Makefile
|
|
@ -1,4 +1,4 @@
|
|||
.PHONY: build package run stop run-client run-server stop-client stop-server restart-server restart-client start-docker clean-dist clean nuke check-style check-unit-tests test dist setup-mac prepare-enteprise build-linux build-osx build-windows
|
||||
.PHONY: build package run stop run-client run-server stop-client stop-server restart-server restart-client start-docker clean-dist clean nuke check-style check-unit-tests test dist setup-mac prepare-enteprise run-client-tests setup-run-client-tests cleanup-run-client-tests test-client build-linux build-osx build-windows
|
||||
|
||||
# Build Flags
|
||||
BUILD_NUMBER ?= $(BUILD_NUMBER:)
|
||||
|
|
@ -63,10 +63,30 @@ start-docker:
|
|||
echo starting mattermost-postgres; \
|
||||
docker run --name mattermost-postgres -p 5432:5432 -e POSTGRES_USER=mmuser -e POSTGRES_PASSWORD=mostest \
|
||||
-d postgres:9.4 > /dev/null; \
|
||||
sleep 10; \
|
||||
elif [ $(shell docker ps | grep -ci mattermost-postgres) -eq 0 ]; then \
|
||||
echo restarting mattermost-postgres; \
|
||||
docker start mattermost-postgres > /dev/null; \
|
||||
fi
|
||||
|
||||
@echo Ldap test user test.one
|
||||
@if [ $(shell docker ps -a | grep -ci mattermost-openldap) -eq 0 ]; then \
|
||||
echo starting mattermost-openldap; \
|
||||
docker run --name mattermost-openldap -p 389:389 -p 636:636 \
|
||||
-e LDAP_TLS_VERIFY_CLIENT="never" \
|
||||
-e LDAP_ORGANISATION="Mattermost Test" \
|
||||
-e LDAP_DOMAIN="mm.test.com" \
|
||||
-e LDAP_ADMIN_PASSWORD="mostest" \
|
||||
-d osixia/openldap:1.1.2 > /dev/null;\
|
||||
sleep 10; \
|
||||
docker exec -ti mattermost-openldap bash -c 'echo -e "dn: ou=testusers,dc=mm,dc=test,dc=com\nobjectclass: organizationalunit" | ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest';\
|
||||
docker exec -ti mattermost-openldap bash -c 'echo -e "dn: uid=test.one,ou=testusers,dc=mm,dc=test,dc=com\nobjectclass: iNetOrgPerson\nsn: User\ncn: Test1\nmail: success+testone@simulator.amazonses.com" | ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest';\
|
||||
docker exec -ti mattermost-openldap bash -c 'ldappasswd -s Password1 -D "cn=admin,dc=mm,dc=test,dc=com" -x "uid=test.one,ou=testusers,dc=mm,dc=test,dc=com" -w mostest';\
|
||||
docker exec -ti mattermost-openldap bash -c 'echo -e "dn: uid=test.two,ou=testusers,dc=mm,dc=test,dc=com\nobjectclass: iNetOrgPerson\nsn: User\ncn: Test2\nmail: success+testtwo@simulator.amazonses.com" | ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest';\
|
||||
docker exec -ti mattermost-openldap bash -c 'ldappasswd -s Password1 -D "cn=admin,dc=mm,dc=test,dc=com" -x "uid=test.two,ou=testusers,dc=mm,dc=test,dc=com" -w mostest';\
|
||||
docker exec -ti mattermost-openldap bash -c 'echo -e "dn: cn=tgroup,ou=testusers,dc=mm,dc=test,dc=com\nobjectclass: groupOfUniqueNames\nuniqueMember: uid=test.one,ou=testusers,dc=mm,dc=test,dc=com" | ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest';\
|
||||
elif [ $(shell docker ps | grep -ci mattermost-openldap) -eq 0 ]; then \
|
||||
echo restarting mattermost-openldap; \
|
||||
docker start mattermost-openldap > /dev/null; \
|
||||
sleep 10; \
|
||||
fi
|
||||
|
||||
|
|
@ -82,22 +102,33 @@ stop-docker:
|
|||
echo stopping mattermost-postgres; \
|
||||
docker stop mattermost-postgres > /dev/null; \
|
||||
fi
|
||||
|
||||
@if [ $(shell docker ps -a | grep -ci mattermost-openldap) -eq 1 ]; then \
|
||||
echo stopping mattermost-openldap; \
|
||||
docker stop mattermost-openldap > /dev/null; \
|
||||
fi
|
||||
|
||||
clean-docker:
|
||||
@echo Removing docker containers
|
||||
|
||||
@if [ $(shell docker ps -a | grep -ci mattermost-mysql) -eq 1 ]; then \
|
||||
echo stopping mattermost-mysql; \
|
||||
echo removing mattermost-mysql; \
|
||||
docker stop mattermost-mysql > /dev/null; \
|
||||
docker rm -v mattermost-mysql > /dev/null; \
|
||||
fi
|
||||
|
||||
@if [ $(shell docker ps -a | grep -ci mattermost-postgres) -eq 1 ]; then \
|
||||
echo stopping mattermost-postgres; \
|
||||
echo removing mattermost-postgres; \
|
||||
docker stop mattermost-postgres > /dev/null; \
|
||||
docker rm -v mattermost-postgres > /dev/null; \
|
||||
fi
|
||||
|
||||
@if [ $(shell docker ps -a | grep -ci mattermost-openldap) -eq 1 ]; then \
|
||||
echo removing mattermost-openldap; \
|
||||
docker stop mattermost-openldap > /dev/null; \
|
||||
docker rm -v mattermost-openldap > /dev/null; \
|
||||
fi
|
||||
|
||||
check-style:
|
||||
@echo Running GOFMT
|
||||
$(eval GOFMT_OUTPUT := $(shell gofmt -d -s api/ model/ store/ utils/ manualtesting/ einterfaces/ mattermost.go 2>&1))
|
||||
|
|
@ -110,11 +141,32 @@ check-style:
|
|||
fi
|
||||
|
||||
test: start-docker
|
||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1
|
||||
@echo Running tests
|
||||
|
||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=240s ./api || exit 1
|
||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=12s ./model || exit 1
|
||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./store || exit 1
|
||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./utils || exit 1
|
||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./web || exit 1
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
@echo Running Enterprise tests
|
||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s $(BUILD_ENTERPRISE_DIR)/ldap || exit 1
|
||||
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s $(BUILD_ENTERPRISE_DIR)/compliance || exit 1
|
||||
endif
|
||||
|
||||
setup-run-client-tests:
|
||||
sed -i'.bak' 's|"EnableOpenServer": false,|"EnableOpenServer": true,|g' config/config.json
|
||||
|
||||
cleanup-run-client-tests:
|
||||
sed -i'.bak' 's|"EnableOpenServer": true,|"EnableOpenServer": false,|g' config/config.json
|
||||
|
||||
run-client-tests:
|
||||
cd $(BUILD_WEBAPP_DIR) && $(MAKE) test
|
||||
sleep 10
|
||||
@echo Running client side unit tests
|
||||
cd $(BUILD_WEBAPP_DIR) && npm test
|
||||
|
||||
test-client: setup-run-client-tests run-server run-client-tests stop-server cleanup-run-client-tests
|
||||
|
||||
.prebuild:
|
||||
@echo Preparation for running go code
|
||||
|
|
@ -124,7 +176,7 @@ test: start-docker
|
|||
|
||||
prepare-enterprise:
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
@echo Enterprise build selected, perparing
|
||||
@echo Enterprise build selected, preparing
|
||||
cp $(BUILD_ENTERPRISE_DIR)/imports.go .
|
||||
endif
|
||||
|
||||
|
|
|
|||
83
api/admin.go
83
api/admin.go
|
|
@ -19,24 +19,25 @@ import (
|
|||
"github.com/mssola/user_agent"
|
||||
)
|
||||
|
||||
func InitAdmin(r *mux.Router) {
|
||||
func InitAdmin() {
|
||||
l4g.Debug(utils.T("api.admin.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/admin").Subrouter()
|
||||
sr.Handle("/logs", ApiUserRequired(getLogs)).Methods("GET")
|
||||
sr.Handle("/audits", ApiUserRequired(getAllAudits)).Methods("GET")
|
||||
sr.Handle("/config", ApiUserRequired(getConfig)).Methods("GET")
|
||||
sr.Handle("/save_config", ApiUserRequired(saveConfig)).Methods("POST")
|
||||
sr.Handle("/test_email", ApiUserRequired(testEmail)).Methods("POST")
|
||||
sr.Handle("/client_props", ApiAppHandler(getClientConfig)).Methods("GET")
|
||||
sr.Handle("/log_client", ApiAppHandler(logClient)).Methods("POST")
|
||||
sr.Handle("/analytics/{id:[A-Za-z0-9]+}/{name:[A-Za-z0-9_]+}", ApiUserRequired(getAnalytics)).Methods("GET")
|
||||
sr.Handle("/analytics/{name:[A-Za-z0-9_]+}", ApiUserRequired(getAnalytics)).Methods("GET")
|
||||
sr.Handle("/save_compliance_report", ApiUserRequired(saveComplianceReport)).Methods("POST")
|
||||
sr.Handle("/compliance_reports", ApiUserRequired(getComplianceReports)).Methods("GET")
|
||||
sr.Handle("/download_compliance_report/{id:[A-Za-z0-9]+}", ApiUserRequired(downloadComplianceReport)).Methods("GET")
|
||||
sr.Handle("/upload_brand_image", ApiAdminSystemRequired(uploadBrandImage)).Methods("POST")
|
||||
sr.Handle("/get_brand_image", ApiAppHandlerTrustRequester(getBrandImage)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/logs", ApiUserRequired(getLogs)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/audits", ApiUserRequired(getAllAudits)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/config", ApiUserRequired(getConfig)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/save_config", ApiUserRequired(saveConfig)).Methods("POST")
|
||||
BaseRoutes.Admin.Handle("/test_email", ApiUserRequired(testEmail)).Methods("POST")
|
||||
BaseRoutes.Admin.Handle("/client_props", ApiAppHandler(getClientConfig)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/log_client", ApiAppHandler(logClient)).Methods("POST")
|
||||
BaseRoutes.Admin.Handle("/analytics/{id:[A-Za-z0-9]+}/{name:[A-Za-z0-9_]+}", ApiUserRequired(getAnalytics)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/analytics/{name:[A-Za-z0-9_]+}", ApiUserRequired(getAnalytics)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/save_compliance_report", ApiUserRequired(saveComplianceReport)).Methods("POST")
|
||||
BaseRoutes.Admin.Handle("/compliance_reports", ApiUserRequired(getComplianceReports)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/download_compliance_report/{id:[A-Za-z0-9]+}", ApiUserRequired(downloadComplianceReport)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/upload_brand_image", ApiAdminSystemRequired(uploadBrandImage)).Methods("POST")
|
||||
BaseRoutes.Admin.Handle("/get_brand_image", ApiAppHandlerTrustRequester(getBrandImage)).Methods("GET")
|
||||
BaseRoutes.Admin.Handle("/reset_mfa", ApiAdminSystemRequired(adminResetMfa)).Methods("POST")
|
||||
BaseRoutes.Admin.Handle("/reset_password", ApiAdminSystemRequired(adminResetPassword)).Methods("POST")
|
||||
}
|
||||
|
||||
func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -374,7 +375,7 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
iHookChan := Srv.Store.Webhook().AnalyticsIncomingCount(teamId)
|
||||
oHookChan := Srv.Store.Webhook().AnalyticsOutgoingCount(teamId)
|
||||
commandChan := Srv.Store.Command().AnalyticsCommandCount(teamId)
|
||||
sessionChan := Srv.Store.Session().AnalyticsSessionCount(teamId)
|
||||
sessionChan := Srv.Store.Session().AnalyticsSessionCount()
|
||||
|
||||
if r := <-fileChan; r.Err != nil {
|
||||
c.Err = r.Err
|
||||
|
|
@ -498,3 +499,51 @@ func getBrandImage(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
w.Write(img)
|
||||
}
|
||||
}
|
||||
|
||||
func adminResetMfa(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
props := model.MapFromJson(r.Body)
|
||||
|
||||
userId := props["user_id"]
|
||||
if len(userId) != 26 {
|
||||
c.SetInvalidParam("adminResetMfa", "user_id")
|
||||
return
|
||||
}
|
||||
|
||||
if err := DeactivateMfa(userId); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
c.LogAudit("")
|
||||
|
||||
rdata := map[string]string{}
|
||||
rdata["status"] = "ok"
|
||||
w.Write([]byte(model.MapToJson(rdata)))
|
||||
}
|
||||
|
||||
func adminResetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
props := model.MapFromJson(r.Body)
|
||||
|
||||
userId := props["user_id"]
|
||||
if len(userId) != 26 {
|
||||
c.SetInvalidParam("adminResetPassword", "user_id")
|
||||
return
|
||||
}
|
||||
|
||||
newPassword := props["new_password"]
|
||||
if len(newPassword) < model.MIN_PASSWORD_LENGTH {
|
||||
c.SetInvalidParam("adminResetPassword", "new_password")
|
||||
return
|
||||
}
|
||||
|
||||
if err := ResetPassword(c, userId, newPassword); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
c.LogAudit("")
|
||||
|
||||
rdata := map[string]string{}
|
||||
rdata["status"] = "ok"
|
||||
w.Write([]byte(model.MapToJson(rdata)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,33 +7,18 @@ import (
|
|||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetLogs(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitSystemAdmin().InitBasic()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if _, err := Client.GetLogs(); err == nil {
|
||||
if _, err := th.BasicClient.GetLogs(); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if logs, err := Client.GetLogs(); err != nil {
|
||||
if logs, err := th.SystemAdminClient.GetLogs(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(logs.Data.([]string)) <= 0 {
|
||||
t.Fatal()
|
||||
|
|
@ -41,29 +26,13 @@ func TestGetLogs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetAllAudits(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if _, err := Client.GetAllAudits(); err == nil {
|
||||
if _, err := th.BasicClient.GetAllAudits(); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if audits, err := Client.GetAllAudits(); err != nil {
|
||||
if audits, err := th.SystemAdminClient.GetAllAudits(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(audits.Data.(model.Audits)) <= 0 {
|
||||
t.Fatal()
|
||||
|
|
@ -71,9 +40,9 @@ func TestGetAllAudits(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetClientProperties(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
|
||||
if result, err := Client.GetClientProperties(); err != nil {
|
||||
if result, err := th.BasicClient.GetClientProperties(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
props := result.Data.(map[string]string)
|
||||
|
|
@ -85,29 +54,13 @@ func TestGetClientProperties(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetConfig(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if _, err := Client.GetConfig(); err == nil {
|
||||
if _, err := th.BasicClient.GetConfig(); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if result, err := Client.GetConfig(); err != nil {
|
||||
if result, err := th.SystemAdminClient.GetConfig(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
cfg := result.Data.(*model.Config)
|
||||
|
|
@ -119,29 +72,15 @@ func TestGetConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSaveConfig(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if _, err := Client.SaveConfig(utils.Cfg); err == nil {
|
||||
if _, err := th.BasicClient.SaveConfig(utils.Cfg); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
*utils.Cfg.TeamSettings.EnableOpenServer = false
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if result, err := Client.SaveConfig(utils.Cfg); err != nil {
|
||||
if result, err := th.SystemAdminClient.SaveConfig(utils.Cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
cfg := result.Data.(*model.Config)
|
||||
|
|
@ -150,66 +89,31 @@ func TestSaveConfig(t *testing.T) {
|
|||
t.Fatal()
|
||||
}
|
||||
}
|
||||
|
||||
*utils.Cfg.TeamSettings.EnableOpenServer = true
|
||||
}
|
||||
|
||||
func TestEmailTest(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if _, err := Client.TestEmail(utils.Cfg); err == nil {
|
||||
if _, err := th.BasicClient.TestEmail(utils.Cfg); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if _, err := Client.TestEmail(utils.Cfg); err != nil {
|
||||
if _, err := th.SystemAdminClient.TestEmail(utils.Cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTeamAnalyticsStandard(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
th.CreatePrivateChannel(th.BasicClient, th.BasicTeam)
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
|
||||
if _, err := Client.GetTeamAnalytics(team.Id, "standard"); err == nil {
|
||||
if _, err := th.BasicClient.GetTeamAnalytics(th.BasicTeam.Id, "standard"); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if result, err := Client.GetTeamAnalytics(team.Id, "standard"); err != nil {
|
||||
if result, err := th.SystemAdminClient.GetTeamAnalytics(th.BasicTeam.Id, "standard"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rows := result.Data.(model.AnalyticsRows)
|
||||
|
|
@ -219,7 +123,7 @@ func TestGetTeamAnalyticsStandard(t *testing.T) {
|
|||
t.Fatal()
|
||||
}
|
||||
|
||||
if rows[0].Value != 2 {
|
||||
if rows[0].Value != 3 {
|
||||
t.Log(rows.ToJson())
|
||||
t.Fatal()
|
||||
}
|
||||
|
|
@ -249,7 +153,7 @@ func TestGetTeamAnalyticsStandard(t *testing.T) {
|
|||
t.Fatal()
|
||||
}
|
||||
|
||||
if rows[3].Value != 1 {
|
||||
if rows[3].Value != 2 {
|
||||
t.Log(rows.ToJson())
|
||||
t.Fatal()
|
||||
}
|
||||
|
|
@ -265,7 +169,7 @@ func TestGetTeamAnalyticsStandard(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
if result, err := Client.GetSystemAnalytics("standard"); err != nil {
|
||||
if result, err := th.SystemAdminClient.GetSystemAnalytics("standard"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rows := result.Data.(model.AnalyticsRows)
|
||||
|
|
@ -275,7 +179,7 @@ func TestGetTeamAnalyticsStandard(t *testing.T) {
|
|||
t.Fatal()
|
||||
}
|
||||
|
||||
if rows[0].Value < 2 {
|
||||
if rows[0].Value < 3 {
|
||||
t.Log(rows.ToJson())
|
||||
t.Fatal()
|
||||
}
|
||||
|
|
@ -323,39 +227,17 @@ func TestGetTeamAnalyticsStandard(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetPostCount(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
|
||||
// manually update creation time, since it's always set to 0 upon saving and we only retrieve posts < today
|
||||
Srv.Store.(*store.SqlStore).GetMaster().Exec("UPDATE Posts SET CreateAt = :CreateAt WHERE ChannelId = :ChannelId",
|
||||
map[string]interface{}{"ChannelId": channel1.Id, "CreateAt": utils.MillisFromTime(utils.Yesterday())})
|
||||
map[string]interface{}{"ChannelId": th.BasicChannel.Id, "CreateAt": utils.MillisFromTime(utils.Yesterday())})
|
||||
|
||||
if _, err := Client.GetTeamAnalytics(team.Id, "post_counts_day"); err == nil {
|
||||
if _, err := th.BasicClient.GetTeamAnalytics(th.BasicTeam.Id, "post_counts_day"); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if result, err := Client.GetTeamAnalytics(team.Id, "post_counts_day"); err != nil {
|
||||
if result, err := th.SystemAdminClient.GetTeamAnalytics(th.BasicTeam.Id, "post_counts_day"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rows := result.Data.(model.AnalyticsRows)
|
||||
|
|
@ -368,39 +250,17 @@ func TestGetPostCount(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUserCountsWithPostsByDay(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
|
||||
// manually update creation time, since it's always set to 0 upon saving and we only retrieve posts < today
|
||||
Srv.Store.(*store.SqlStore).GetMaster().Exec("UPDATE Posts SET CreateAt = :CreateAt WHERE ChannelId = :ChannelId",
|
||||
map[string]interface{}{"ChannelId": channel1.Id, "CreateAt": utils.MillisFromTime(utils.Yesterday())})
|
||||
map[string]interface{}{"ChannelId": th.BasicChannel.Id, "CreateAt": utils.MillisFromTime(utils.Yesterday())})
|
||||
|
||||
if _, err := Client.GetTeamAnalytics(team.Id, "user_counts_with_posts_day"); err == nil {
|
||||
if _, err := th.BasicClient.GetTeamAnalytics(th.BasicTeam.Id, "user_counts_with_posts_day"); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if result, err := Client.GetTeamAnalytics(team.Id, "user_counts_with_posts_day"); err != nil {
|
||||
if result, err := th.SystemAdminClient.GetTeamAnalytics(th.BasicTeam.Id, "user_counts_with_posts_day"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rows := result.Data.(model.AnalyticsRows)
|
||||
|
|
@ -413,38 +273,15 @@ func TestUserCountsWithPostsByDay(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetTeamAnalyticsExtra(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
th.CreatePost(th.BasicClient, th.BasicChannel)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
|
||||
post2 := &model.Post{ChannelId: channel1.Id, Message: "#test a" + model.NewId() + "a"}
|
||||
post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
|
||||
|
||||
if _, err := Client.GetTeamAnalytics("", "extra_counts"); err == nil {
|
||||
if _, err := th.BasicClient.GetTeamAnalytics("", "extra_counts"); err == nil {
|
||||
t.Fatal("Shouldn't have permissions")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
if result, err := Client.GetTeamAnalytics(team.Id, "extra_counts"); err != nil {
|
||||
if result, err := th.SystemAdminClient.GetTeamAnalytics(th.BasicTeam.Id, "extra_counts"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rows := result.Data.(model.AnalyticsRows)
|
||||
|
|
@ -464,7 +301,7 @@ func TestGetTeamAnalyticsExtra(t *testing.T) {
|
|||
t.Fatal()
|
||||
}
|
||||
|
||||
if rows[1].Value != 1 {
|
||||
if rows[1].Value != 0 {
|
||||
t.Log(rows.ToJson())
|
||||
t.Fatal()
|
||||
}
|
||||
|
|
@ -510,7 +347,7 @@ func TestGetTeamAnalyticsExtra(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
if result, err := Client.GetSystemAnalytics("extra_counts"); err != nil {
|
||||
if result, err := th.SystemAdminClient.GetSystemAnalytics("extra_counts"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rows := result.Data.(model.AnalyticsRows)
|
||||
|
|
@ -525,11 +362,6 @@ func TestGetTeamAnalyticsExtra(t *testing.T) {
|
|||
t.Fatal()
|
||||
}
|
||||
|
||||
if rows[1].Value < 1 {
|
||||
t.Log(rows.ToJson())
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
if rows[2].Name != "incoming_webhook_count" {
|
||||
t.Log(rows.ToJson())
|
||||
t.Fatal()
|
||||
|
|
@ -551,3 +383,73 @@ func TestGetTeamAnalyticsExtra(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminResetMfa(t *testing.T) {
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
|
||||
if _, err := th.BasicClient.AdminResetMfa("12345678901234567890123456"); err == nil {
|
||||
t.Fatal("should have failed - not an admin")
|
||||
}
|
||||
|
||||
if _, err := th.SystemAdminClient.AdminResetMfa(""); err == nil {
|
||||
t.Fatal("should have failed - empty user id")
|
||||
}
|
||||
|
||||
if _, err := th.SystemAdminClient.AdminResetMfa("12345678901234567890123456"); err == nil {
|
||||
t.Fatal("should have failed - bad user id")
|
||||
}
|
||||
|
||||
if _, err := th.SystemAdminClient.AdminResetMfa(th.BasicUser.Id); err == nil {
|
||||
t.Fatal("should have failed - not licensed or configured")
|
||||
}
|
||||
|
||||
// need to add more test cases when enterprise bits can be loaded into tests
|
||||
}
|
||||
|
||||
func TestAdminResetPassword(t *testing.T) {
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
team := th.SystemAdminTeam
|
||||
|
||||
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user, team)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
if _, err := Client.AdminResetPassword("", "newpwd"); err == nil {
|
||||
t.Fatal("Should have errored - empty user id")
|
||||
}
|
||||
|
||||
if _, err := Client.AdminResetPassword("123", "newpwd"); err == nil {
|
||||
t.Fatal("Should have errored - bad user id")
|
||||
}
|
||||
|
||||
if _, err := Client.AdminResetPassword("12345678901234567890123456", "newpwd"); err == nil {
|
||||
t.Fatal("Should have errored - bad user id")
|
||||
}
|
||||
|
||||
if _, err := Client.AdminResetPassword("12345678901234567890123456", "newp"); err == nil {
|
||||
t.Fatal("Should have errored - password too short")
|
||||
}
|
||||
|
||||
user2 := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", AuthData: "1", AuthService: "random"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user2, team)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
if _, err := Client.AdminResetPassword(user2.Id, "newpwd"); err == nil {
|
||||
t.Fatal("should have errored - SSO user can't reset password")
|
||||
}
|
||||
|
||||
if _, err := Client.AdminResetPassword(user.Id, "newpwd"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user.Id, "newpwd"))
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if _, err := Client.AdminResetPassword(user.Id, "newpwd"); err == nil {
|
||||
t.Fatal("Should have errored - not sytem admin")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
78
api/api.go
78
api/api.go
|
|
@ -6,6 +6,7 @@ package api
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
|
||||
|
|
@ -13,20 +14,71 @@ import (
|
|||
_ "github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
||||
type Routes struct {
|
||||
Root *mux.Router // ''
|
||||
ApiRoot *mux.Router // 'api/v3'
|
||||
|
||||
Users *mux.Router // 'api/v3/users'
|
||||
NeedUser *mux.Router // 'api/v3/users/{user_id:[A-Za-z0-9]+}'
|
||||
|
||||
Teams *mux.Router // 'api/v3/teams'
|
||||
NeedTeam *mux.Router // 'api/v3/teams/{team_id:[A-Za-z0-9]+}'
|
||||
|
||||
Channels *mux.Router // 'api/v3/teams/{team_id:[A-Za-z0-9]+}/channels'
|
||||
NeedChannel *mux.Router // 'api/v3/teams/{team_id:[A-Za-z0-9]+}/channels/{channel_id:[A-Za-z0-9]+}'
|
||||
|
||||
Posts *mux.Router // 'api/v3/teams/{team_id:[A-Za-z0-9]+}/channels/{channel_id:[A-Za-z0-9]+}/posts'
|
||||
NeedPost *mux.Router // 'api/v3/teams/{team_id:[A-Za-z0-9]+}/channels/{channel_id:[A-Za-z0-9]+}/posts/{post_id:[A-Za-z0-9]+}'
|
||||
|
||||
Commands *mux.Router // 'api/v3/teams/{team_id:[A-Za-z0-9]+}/commands'
|
||||
Hooks *mux.Router // 'api/v3/teams/{team_id:[A-Za-z0-9]+}/hooks'
|
||||
|
||||
Files *mux.Router // 'api/v3/teams/{team_id:[A-Za-z0-9]+}/files'
|
||||
|
||||
OAuth *mux.Router // 'api/v3/oauth'
|
||||
|
||||
Admin *mux.Router // 'api/v3/admin'
|
||||
|
||||
Preferences *mux.Router // 'api/v3/preferences'
|
||||
|
||||
License *mux.Router // 'api/v3/license'
|
||||
}
|
||||
|
||||
var BaseRoutes *Routes
|
||||
|
||||
func InitApi() {
|
||||
r := Srv.Router.PathPrefix("/api/v1").Subrouter()
|
||||
InitUser(r)
|
||||
InitTeam(r)
|
||||
InitChannel(r)
|
||||
InitPost(r)
|
||||
InitWebSocket(r)
|
||||
InitFile(r)
|
||||
InitCommand(r)
|
||||
InitAdmin(r)
|
||||
InitOAuth(r)
|
||||
InitWebhook(r)
|
||||
InitPreference(r)
|
||||
InitLicense(r)
|
||||
BaseRoutes = &Routes{}
|
||||
BaseRoutes.Root = Srv.Router
|
||||
BaseRoutes.ApiRoot = Srv.Router.PathPrefix(model.API_URL_SUFFIX).Subrouter()
|
||||
BaseRoutes.Users = BaseRoutes.ApiRoot.PathPrefix("/users").Subrouter()
|
||||
BaseRoutes.NeedUser = BaseRoutes.Users.PathPrefix("/{user_id:[A-Za-z0-9]+}").Subrouter()
|
||||
BaseRoutes.Teams = BaseRoutes.ApiRoot.PathPrefix("/teams").Subrouter()
|
||||
BaseRoutes.NeedTeam = BaseRoutes.Teams.PathPrefix("/{team_id:[A-Za-z0-9]+}").Subrouter()
|
||||
BaseRoutes.Channels = BaseRoutes.NeedTeam.PathPrefix("/channels").Subrouter()
|
||||
BaseRoutes.NeedChannel = BaseRoutes.Channels.PathPrefix("/{channel_id:[A-Za-z0-9]+}").Subrouter()
|
||||
BaseRoutes.Posts = BaseRoutes.NeedChannel.PathPrefix("/posts").Subrouter()
|
||||
BaseRoutes.NeedPost = BaseRoutes.Posts.PathPrefix("/{post_id:[A-Za-z0-9]+}").Subrouter()
|
||||
BaseRoutes.Commands = BaseRoutes.NeedTeam.PathPrefix("/commands").Subrouter()
|
||||
BaseRoutes.Files = BaseRoutes.NeedTeam.PathPrefix("/files").Subrouter()
|
||||
BaseRoutes.Hooks = BaseRoutes.NeedTeam.PathPrefix("/hooks").Subrouter()
|
||||
BaseRoutes.OAuth = BaseRoutes.ApiRoot.PathPrefix("/oauth").Subrouter()
|
||||
BaseRoutes.Admin = BaseRoutes.ApiRoot.PathPrefix("/admin").Subrouter()
|
||||
BaseRoutes.Preferences = BaseRoutes.ApiRoot.PathPrefix("/preferences").Subrouter()
|
||||
BaseRoutes.License = BaseRoutes.ApiRoot.PathPrefix("/license").Subrouter()
|
||||
|
||||
InitUser()
|
||||
InitTeam()
|
||||
InitChannel()
|
||||
InitPost()
|
||||
InitWebSocket()
|
||||
InitFile()
|
||||
InitCommand()
|
||||
InitAdmin()
|
||||
InitOAuth()
|
||||
InitWebhook()
|
||||
InitPreference()
|
||||
InitLicense()
|
||||
|
||||
// 404 on any api route before web.go has a chance to serve it
|
||||
Srv.Router.Handle("/api/{anything:.*}", http.HandlerFunc(Handle404))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
var Client *model.Client
|
||||
|
||||
func Setup() {
|
||||
if Srv == nil {
|
||||
utils.LoadConfig("config.json")
|
||||
utils.InitTranslations()
|
||||
utils.Cfg.TeamSettings.MaxUsersPerTeam = 50
|
||||
NewServer()
|
||||
StartServer()
|
||||
InitApi()
|
||||
Client = model.NewClient("http://localhost" + utils.Cfg.ServiceSettings.ListenAddress)
|
||||
|
||||
Srv.Store.MarkSystemRanUnitTests()
|
||||
}
|
||||
}
|
||||
|
||||
func SetupBenchmark() (*model.Team, *model.User, *model.Channel) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Benchmark Team", Name: "z-z-" + model.NewId() + "a", Email: "benchmark@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Mr. Benchmarker", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
channel := &model.Channel{DisplayName: "Benchmark Channel", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
return team, user, channel
|
||||
}
|
||||
|
||||
func TearDown() {
|
||||
if Srv != nil {
|
||||
StopServer()
|
||||
}
|
||||
}
|
||||
223
api/apitestlib.go
Normal file
223
api/apitestlib.go
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
)
|
||||
|
||||
type TestHelper struct {
|
||||
BasicClient *model.Client
|
||||
BasicTeam *model.Team
|
||||
BasicUser *model.User
|
||||
BasicUser2 *model.User
|
||||
BasicChannel *model.Channel
|
||||
BasicPost *model.Post
|
||||
|
||||
SystemAdminClient *model.Client
|
||||
SystemAdminTeam *model.Team
|
||||
SystemAdminUser *model.User
|
||||
SystemAdminChannel *model.Channel
|
||||
}
|
||||
|
||||
func SetupEnterprise(platformDir string) *TestHelper {
|
||||
if Srv == nil {
|
||||
utils.LoadConfig(platformDir + "/config/config.json")
|
||||
utils.InitTranslationsWithDir(platformDir + "/i18n")
|
||||
utils.Cfg.TeamSettings.MaxUsersPerTeam = 50
|
||||
utils.DisableDebugLogForTest()
|
||||
utils.License.Features.SetDefaults()
|
||||
NewServer()
|
||||
StartServer()
|
||||
utils.InitHTMLWithDir(platformDir + "/templates")
|
||||
InitApi()
|
||||
utils.EnableDebugLogForTest()
|
||||
Srv.Store.MarkSystemRanUnitTests()
|
||||
|
||||
*utils.Cfg.TeamSettings.EnableOpenServer = true
|
||||
}
|
||||
|
||||
return &TestHelper{}
|
||||
}
|
||||
|
||||
func Setup() *TestHelper {
|
||||
if Srv == nil {
|
||||
utils.LoadConfig("config.json")
|
||||
utils.InitTranslations()
|
||||
utils.Cfg.TeamSettings.MaxUsersPerTeam = 50
|
||||
utils.DisableDebugLogForTest()
|
||||
NewServer()
|
||||
StartServer()
|
||||
InitApi()
|
||||
utils.EnableDebugLogForTest()
|
||||
Srv.Store.MarkSystemRanUnitTests()
|
||||
|
||||
*utils.Cfg.TeamSettings.EnableOpenServer = true
|
||||
}
|
||||
|
||||
return &TestHelper{}
|
||||
}
|
||||
|
||||
func (me *TestHelper) InitBasic() *TestHelper {
|
||||
me.BasicClient = me.CreateClient()
|
||||
me.BasicTeam = me.CreateTeam(me.BasicClient)
|
||||
me.BasicUser = me.CreateUser(me.BasicClient)
|
||||
LinkUserToTeam(me.BasicUser, me.BasicTeam)
|
||||
me.BasicUser2 = me.CreateUser(me.BasicClient)
|
||||
LinkUserToTeam(me.BasicUser2, me.BasicTeam)
|
||||
me.BasicClient.SetTeamId(me.BasicTeam.Id)
|
||||
me.LoginBasic()
|
||||
me.BasicChannel = me.CreateChannel(me.BasicClient, me.BasicTeam)
|
||||
me.BasicPost = me.CreatePost(me.BasicClient, me.BasicChannel)
|
||||
|
||||
return me
|
||||
}
|
||||
|
||||
func (me *TestHelper) InitSystemAdmin() *TestHelper {
|
||||
me.SystemAdminClient = me.CreateClient()
|
||||
me.SystemAdminTeam = me.CreateTeam(me.SystemAdminClient)
|
||||
me.SystemAdminUser = me.CreateUser(me.SystemAdminClient)
|
||||
LinkUserToTeam(me.SystemAdminUser, me.SystemAdminTeam)
|
||||
me.SystemAdminClient.SetTeamId(me.SystemAdminTeam.Id)
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, me.SystemAdminUser, model.ROLE_SYSTEM_ADMIN)
|
||||
me.SystemAdminUser.Password = "Password1"
|
||||
me.LoginSystemAdmin()
|
||||
me.SystemAdminChannel = me.CreateChannel(me.SystemAdminClient, me.SystemAdminTeam)
|
||||
|
||||
return me
|
||||
}
|
||||
|
||||
func (me *TestHelper) CreateClient() *model.Client {
|
||||
return model.NewClient("http://localhost" + utils.Cfg.ServiceSettings.ListenAddress)
|
||||
}
|
||||
|
||||
func (me *TestHelper) CreateTeam(client *model.Client) *model.Team {
|
||||
id := model.NewId()
|
||||
team := &model.Team{
|
||||
DisplayName: "dn_" + id,
|
||||
Name: "name" + id,
|
||||
Email: "success+" + id + "@simulator.amazonses.com",
|
||||
Type: model.TEAM_OPEN,
|
||||
}
|
||||
|
||||
utils.DisableDebugLogForTest()
|
||||
r := client.Must(client.CreateTeam(team)).Data.(*model.Team)
|
||||
utils.EnableDebugLogForTest()
|
||||
return r
|
||||
}
|
||||
|
||||
func (me *TestHelper) CreateUser(client *model.Client) *model.User {
|
||||
id := model.NewId()
|
||||
|
||||
user := &model.User{
|
||||
Email: "success+" + id + "@simulator.amazonses.com",
|
||||
Username: "un_" + id,
|
||||
Nickname: "nn_" + id,
|
||||
Password: "Password1",
|
||||
}
|
||||
|
||||
utils.DisableDebugLogForTest()
|
||||
ruser := client.Must(client.CreateUser(user, "")).Data.(*model.User)
|
||||
ruser.Password = "Password1"
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
|
||||
utils.EnableDebugLogForTest()
|
||||
return ruser
|
||||
}
|
||||
|
||||
func LinkUserToTeam(user *model.User, team *model.Team) {
|
||||
utils.DisableDebugLogForTest()
|
||||
|
||||
err := JoinUserToTeam(team, user)
|
||||
if err != nil {
|
||||
l4g.Error(err.Error())
|
||||
l4g.Close()
|
||||
time.Sleep(time.Second)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
utils.EnableDebugLogForTest()
|
||||
}
|
||||
|
||||
func UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
|
||||
utils.DisableDebugLogForTest()
|
||||
|
||||
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.ROLE_TEAM_ADMIN}
|
||||
if tmr := <-Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
|
||||
l4g.Error(tmr.Err.Error())
|
||||
l4g.Close()
|
||||
time.Sleep(time.Second)
|
||||
panic(tmr.Err)
|
||||
}
|
||||
}
|
||||
|
||||
func (me *TestHelper) CreateChannel(client *model.Client, team *model.Team) *model.Channel {
|
||||
return me.createChannel(client, team, model.CHANNEL_OPEN)
|
||||
}
|
||||
|
||||
func (me *TestHelper) CreatePrivateChannel(client *model.Client, team *model.Team) *model.Channel {
|
||||
return me.createChannel(client, team, model.CHANNEL_PRIVATE)
|
||||
}
|
||||
|
||||
func (me *TestHelper) createChannel(client *model.Client, team *model.Team, channelType string) *model.Channel {
|
||||
id := model.NewId()
|
||||
|
||||
channel := &model.Channel{
|
||||
DisplayName: "dn_" + id,
|
||||
Name: "name_" + id,
|
||||
Type: channelType,
|
||||
TeamId: team.Id,
|
||||
}
|
||||
|
||||
utils.DisableDebugLogForTest()
|
||||
r := client.Must(client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
utils.EnableDebugLogForTest()
|
||||
return r
|
||||
}
|
||||
|
||||
func (me *TestHelper) CreatePost(client *model.Client, channel *model.Channel) *model.Post {
|
||||
id := model.NewId()
|
||||
|
||||
post := &model.Post{
|
||||
ChannelId: channel.Id,
|
||||
Message: "message_" + id,
|
||||
}
|
||||
|
||||
utils.DisableDebugLogForTest()
|
||||
r := client.Must(client.CreatePost(post)).Data.(*model.Post)
|
||||
utils.EnableDebugLogForTest()
|
||||
return r
|
||||
}
|
||||
|
||||
func (me *TestHelper) LoginBasic() {
|
||||
utils.DisableDebugLogForTest()
|
||||
me.BasicClient.Must(me.BasicClient.LoginByEmail(me.BasicTeam.Name, me.BasicUser.Email, me.BasicUser.Password))
|
||||
utils.EnableDebugLogForTest()
|
||||
}
|
||||
|
||||
func (me *TestHelper) LoginBasic2() {
|
||||
utils.DisableDebugLogForTest()
|
||||
me.BasicClient.Must(me.BasicClient.LoginByEmail(me.BasicTeam.Name, me.BasicUser2.Email, me.BasicUser2.Password))
|
||||
utils.EnableDebugLogForTest()
|
||||
}
|
||||
|
||||
func (me *TestHelper) LoginSystemAdmin() {
|
||||
utils.DisableDebugLogForTest()
|
||||
me.SystemAdminClient.Must(me.SystemAdminClient.LoginByEmail(me.SystemAdminTeam.Name, me.SystemAdminUser.Email, me.SystemAdminUser.Password))
|
||||
utils.EnableDebugLogForTest()
|
||||
}
|
||||
|
||||
func TearDown() {
|
||||
if Srv != nil {
|
||||
StopServer()
|
||||
}
|
||||
}
|
||||
99
api/authentication.go
Normal file
99
api/authentication.go
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/einterfaces"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
func checkPasswordAndAllCriteria(user *model.User, password string, mfaToken string) *model.AppError {
|
||||
if err := checkUserPassword(user, password); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkUserAdditionalAuthenticationCriteria(user, mfaToken); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkUserPassword(user *model.User, password string) *model.AppError {
|
||||
if !model.ComparePassword(user.Password, password) {
|
||||
if result := <-Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, user.FailedAttempts+1); result.Err != nil {
|
||||
return result.Err
|
||||
}
|
||||
|
||||
return model.NewLocAppError("checkUserPassword", "api.user.check_user_password.invalid.app_error", nil, "user_id="+user.Id)
|
||||
} else {
|
||||
if result := <-Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, 0); result.Err != nil {
|
||||
return result.Err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func checkUserAdditionalAuthenticationCriteria(user *model.User, mfaToken string) *model.AppError {
|
||||
if err := checkUserMfa(user, mfaToken); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkEmailVerified(user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkUserNotDisabled(user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkUserLoginAttempts(user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkUserMfa(user *model.User, token string) *model.AppError {
|
||||
if !user.MfaActive || !utils.IsLicensed || !*utils.License.Features.MFA || !*utils.Cfg.ServiceSettings.EnableMultifactorAuthentication {
|
||||
return nil
|
||||
}
|
||||
|
||||
mfaInterface := einterfaces.GetMfaInterface()
|
||||
if mfaInterface == nil {
|
||||
return model.NewLocAppError("checkUserMfa", "api.user.check_user_mfa.not_available.app_error", nil, "")
|
||||
}
|
||||
|
||||
if ok, err := mfaInterface.ValidateToken(user.MfaSecret, token); err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
return model.NewLocAppError("checkUserMfa", "api.user.check_user_mfa.bad_code.app_error", nil, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkUserLoginAttempts(user *model.User) *model.AppError {
|
||||
if user.FailedAttempts >= utils.Cfg.ServiceSettings.MaximumLoginAttempts {
|
||||
return model.NewLocAppError("checkUserLoginAttempts", "api.user.check_user_login_attempts.too_many.app_error", nil, "user_id="+user.Id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkEmailVerified(user *model.User) *model.AppError {
|
||||
if !user.EmailVerified && utils.Cfg.EmailSettings.RequireEmailVerification {
|
||||
return model.NewLocAppError("Login", "api.user.login.not_verified.app_error", nil, "user_id="+user.Id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkUserNotDisabled(user *model.User) *model.AppError {
|
||||
if user.DeleteAt > 0 {
|
||||
return model.NewLocAppError("Login", "api.user.login.inactive.app_error", nil, "user_id="+user.Id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
type AutoChannelCreator struct {
|
||||
client *model.Client
|
||||
teamID string
|
||||
team *model.Team
|
||||
Fuzzy bool
|
||||
DisplayNameLen utils.Range
|
||||
DisplayNameCharset string
|
||||
|
|
@ -19,10 +19,10 @@ type AutoChannelCreator struct {
|
|||
ChannelType string
|
||||
}
|
||||
|
||||
func NewAutoChannelCreator(client *model.Client, teamID string) *AutoChannelCreator {
|
||||
func NewAutoChannelCreator(client *model.Client, team *model.Team) *AutoChannelCreator {
|
||||
return &AutoChannelCreator{
|
||||
client: client,
|
||||
teamID: teamID,
|
||||
team: team,
|
||||
Fuzzy: false,
|
||||
DisplayNameLen: CHANNEL_DISPLAY_NAME_LEN,
|
||||
DisplayNameCharset: utils.ALPHANUMERIC,
|
||||
|
|
@ -42,13 +42,17 @@ func (cfg *AutoChannelCreator) createRandomChannel() (*model.Channel, bool) {
|
|||
name := utils.RandomName(cfg.NameLen, cfg.NameCharset)
|
||||
|
||||
channel := &model.Channel{
|
||||
TeamId: cfg.teamID,
|
||||
TeamId: cfg.team.Id,
|
||||
DisplayName: displayName,
|
||||
Name: name,
|
||||
Type: cfg.ChannelType}
|
||||
|
||||
println(cfg.client.GetTeamRoute())
|
||||
result, err := cfg.client.CreateChannel(channel)
|
||||
if err != nil {
|
||||
err.Translate(utils.T)
|
||||
println(err.Error())
|
||||
println(err.DetailedError)
|
||||
return nil, false
|
||||
}
|
||||
return result.Data.(*model.Channel), true
|
||||
|
|
|
|||
|
|
@ -28,14 +28,15 @@ func CreateTestEnvironmentWithTeams(client *model.Client, rangeTeams utils.Range
|
|||
environment := TestEnvironment{teams, make([]TeamEnvironment, len(teams))}
|
||||
|
||||
for i, team := range teams {
|
||||
userCreator := NewAutoUserCreator(client, team.Id)
|
||||
userCreator := NewAutoUserCreator(client, team)
|
||||
userCreator.Fuzzy = fuzzy
|
||||
randomUser, err := userCreator.createRandomUser()
|
||||
if err != true {
|
||||
return TestEnvironment{}, false
|
||||
}
|
||||
client.LoginById(randomUser.Id, USER_PASSWORD)
|
||||
teamEnvironment, err := CreateTestEnvironmentInTeam(client, team.Id, rangeChannels, rangeUsers, rangePosts, fuzzy)
|
||||
client.SetTeamId(team.Id)
|
||||
teamEnvironment, err := CreateTestEnvironmentInTeam(client, team, rangeChannels, rangeUsers, rangePosts, fuzzy)
|
||||
if err != true {
|
||||
return TestEnvironment{}, false
|
||||
}
|
||||
|
|
@ -45,7 +46,7 @@ func CreateTestEnvironmentWithTeams(client *model.Client, rangeTeams utils.Range
|
|||
return environment, true
|
||||
}
|
||||
|
||||
func CreateTestEnvironmentInTeam(client *model.Client, teamID string, rangeChannels utils.Range, rangeUsers utils.Range, rangePosts utils.Range, fuzzy bool) (TeamEnvironment, bool) {
|
||||
func CreateTestEnvironmentInTeam(client *model.Client, team *model.Team, rangeChannels utils.Range, rangeUsers utils.Range, rangePosts utils.Range, fuzzy bool) (TeamEnvironment, bool) {
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
|
||||
// We need to create at least one user
|
||||
|
|
@ -53,7 +54,7 @@ func CreateTestEnvironmentInTeam(client *model.Client, teamID string, rangeChann
|
|||
rangeUsers.Begin = 1
|
||||
}
|
||||
|
||||
userCreator := NewAutoUserCreator(client, teamID)
|
||||
userCreator := NewAutoUserCreator(client, team)
|
||||
userCreator.Fuzzy = fuzzy
|
||||
users, err := userCreator.CreateTestUsers(rangeUsers)
|
||||
if err != true {
|
||||
|
|
@ -64,7 +65,7 @@ func CreateTestEnvironmentInTeam(client *model.Client, teamID string, rangeChann
|
|||
usernames[i] = user.Username
|
||||
}
|
||||
|
||||
channelCreator := NewAutoChannelCreator(client, teamID)
|
||||
channelCreator := NewAutoChannelCreator(client, team)
|
||||
channelCreator.Fuzzy = fuzzy
|
||||
channels, err := channelCreator.CreateTestChannels(rangeChannels)
|
||||
|
||||
|
|
@ -79,6 +80,7 @@ func CreateTestEnvironmentInTeam(client *model.Client, teamID string, rangeChann
|
|||
if err != true {
|
||||
return TeamEnvironment{}, false
|
||||
}
|
||||
|
||||
numPosts := utils.RandIntFromRange(rangePosts)
|
||||
numImages := utils.RandIntFromRange(rangePosts) / 4
|
||||
for j := 0; j < numPosts; j++ {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func (cfg *AutoPostCreator) UploadTestFile() ([]string, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
resp, appErr := cfg.client.UploadFile("/files/upload", body.Bytes(), writer.FormDataContentType())
|
||||
resp, appErr := cfg.client.UploadPostAttachment(body.Bytes(), writer.FormDataContentType())
|
||||
if appErr != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ func (cfg *AutoTeamCreator) createRandomTeam() (*model.Team, bool) {
|
|||
var teamDisplayName string
|
||||
var teamName string
|
||||
if cfg.Fuzzy {
|
||||
teamEmail = utils.FuzzEmail()
|
||||
teamEmail = "success+" + model.NewId() + "simulator.amazonses.com"
|
||||
teamDisplayName = utils.FuzzName()
|
||||
teamName = utils.FuzzName()
|
||||
} else {
|
||||
teamEmail = utils.RandomEmail(cfg.EmailLength, cfg.EmailCharset)
|
||||
teamEmail = "success+" + model.NewId() + "simulator.amazonses.com"
|
||||
teamDisplayName = utils.RandomName(cfg.NameLength, cfg.NameCharset)
|
||||
teamName = utils.RandomName(cfg.NameLength, cfg.NameCharset) + model.NewId()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ import (
|
|||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
)
|
||||
|
||||
type AutoUserCreator struct {
|
||||
client *model.Client
|
||||
teamID string
|
||||
team *model.Team
|
||||
EmailLength utils.Range
|
||||
EmailCharset string
|
||||
NameLength utils.Range
|
||||
|
|
@ -19,10 +21,10 @@ type AutoUserCreator struct {
|
|||
Fuzzy bool
|
||||
}
|
||||
|
||||
func NewAutoUserCreator(client *model.Client, teamID string) *AutoUserCreator {
|
||||
func NewAutoUserCreator(client *model.Client, team *model.Team) *AutoUserCreator {
|
||||
return &AutoUserCreator{
|
||||
client: client,
|
||||
teamID: teamID,
|
||||
team: team,
|
||||
EmailLength: USER_EMAIL_LEN,
|
||||
EmailCharset: utils.LOWERCASE,
|
||||
NameLength: USER_NAME_LEN,
|
||||
|
|
@ -33,7 +35,7 @@ func NewAutoUserCreator(client *model.Client, teamID string) *AutoUserCreator {
|
|||
|
||||
// Basic test team and user so you always know one
|
||||
func CreateBasicUser(client *model.Client) *model.AppError {
|
||||
result, _ := client.FindTeamByName(BTEST_TEAM_NAME, true)
|
||||
result, _ := client.FindTeamByName(BTEST_TEAM_NAME)
|
||||
if result.Data.(bool) == false {
|
||||
newteam := &model.Team{DisplayName: BTEST_TEAM_DISPLAY_NAME, Name: BTEST_TEAM_NAME, Email: BTEST_TEAM_EMAIL, Type: BTEST_TEAM_TYPE}
|
||||
result, err := client.CreateTeam(newteam)
|
||||
|
|
@ -41,12 +43,14 @@ func CreateBasicUser(client *model.Client) *model.AppError {
|
|||
return err
|
||||
}
|
||||
basicteam := result.Data.(*model.Team)
|
||||
newuser := &model.User{TeamId: basicteam.Id, Email: BTEST_USER_EMAIL, Nickname: BTEST_USER_NAME, Password: BTEST_USER_PASSWORD}
|
||||
newuser := &model.User{Email: BTEST_USER_EMAIL, Nickname: BTEST_USER_NAME, Password: BTEST_USER_PASSWORD}
|
||||
result, err = client.CreateUser(newuser, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
store.Must(Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id))
|
||||
ruser := result.Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
|
||||
store.Must(Srv.Store.Team().SaveMember(&model.TeamMember{TeamId: basicteam.Id, UserId: ruser.Id}))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -55,25 +59,30 @@ func (cfg *AutoUserCreator) createRandomUser() (*model.User, bool) {
|
|||
var userEmail string
|
||||
var userName string
|
||||
if cfg.Fuzzy {
|
||||
userEmail = utils.RandString(FUZZ_USER_EMAIL_PREFIX_LEN, utils.LOWERCASE) + "-" + utils.FuzzEmail()
|
||||
userEmail = "success+" + model.NewId() + "simulator.amazonses.com"
|
||||
userName = utils.FuzzName()
|
||||
} else {
|
||||
userEmail = utils.RandomEmail(cfg.EmailLength, cfg.EmailCharset)
|
||||
userEmail = "success+" + model.NewId() + "simulator.amazonses.com"
|
||||
userName = utils.RandomName(cfg.NameLength, cfg.NameCharset)
|
||||
}
|
||||
|
||||
user := &model.User{
|
||||
TeamId: cfg.teamID,
|
||||
Email: userEmail,
|
||||
Nickname: userName,
|
||||
Password: USER_PASSWORD}
|
||||
|
||||
result, err := cfg.client.CreateUser(user, "")
|
||||
result, err := cfg.client.CreateUserWithInvite(user, "", "", cfg.team.InviteId)
|
||||
if err != nil {
|
||||
err.Translate(utils.T)
|
||||
l4g.Error(err.Error())
|
||||
return nil, false
|
||||
}
|
||||
|
||||
ruser := result.Data.(*model.User)
|
||||
|
||||
// We need to cheat to verify the user's email
|
||||
store.Must(Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id))
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
|
||||
|
||||
return result.Data.(*model.User), true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,29 +18,28 @@ const (
|
|||
defaultExtraMemberLimit = 100
|
||||
)
|
||||
|
||||
func InitChannel(r *mux.Router) {
|
||||
func InitChannel() {
|
||||
l4g.Debug(utils.T("api.channel.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/channels").Subrouter()
|
||||
sr.Handle("/", ApiUserRequiredActivity(getChannels, false)).Methods("GET")
|
||||
sr.Handle("/more", ApiUserRequired(getMoreChannels)).Methods("GET")
|
||||
sr.Handle("/counts", ApiUserRequiredActivity(getChannelCounts, false)).Methods("GET")
|
||||
sr.Handle("/create", ApiUserRequired(createChannel)).Methods("POST")
|
||||
sr.Handle("/create_direct", ApiUserRequired(createDirectChannel)).Methods("POST")
|
||||
sr.Handle("/update", ApiUserRequired(updateChannel)).Methods("POST")
|
||||
sr.Handle("/update_header", ApiUserRequired(updateChannelHeader)).Methods("POST")
|
||||
sr.Handle("/update_purpose", ApiUserRequired(updateChannelPurpose)).Methods("POST")
|
||||
sr.Handle("/update_notify_props", ApiUserRequired(updateNotifyProps)).Methods("POST")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/", ApiUserRequiredActivity(getChannel, false)).Methods("GET")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/extra_info", ApiUserRequired(getChannelExtraInfo)).Methods("GET")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/extra_info/{member_limit:-?[0-9]+}", ApiUserRequired(getChannelExtraInfo)).Methods("GET")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/join", ApiUserRequired(join)).Methods("POST")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/leave", ApiUserRequired(leave)).Methods("POST")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/delete", ApiUserRequired(deleteChannel)).Methods("POST")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/add", ApiUserRequired(addMember)).Methods("POST")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/remove", ApiUserRequired(removeMember)).Methods("POST")
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}/update_last_viewed_at", ApiUserRequired(updateLastViewedAt)).Methods("POST")
|
||||
BaseRoutes.Channels.Handle("/", ApiUserRequiredActivity(getChannels, false)).Methods("GET")
|
||||
BaseRoutes.Channels.Handle("/more", ApiUserRequired(getMoreChannels)).Methods("GET")
|
||||
BaseRoutes.Channels.Handle("/counts", ApiUserRequiredActivity(getChannelCounts, false)).Methods("GET")
|
||||
BaseRoutes.Channels.Handle("/create", ApiUserRequired(createChannel)).Methods("POST")
|
||||
BaseRoutes.Channels.Handle("/create_direct", ApiUserRequired(createDirectChannel)).Methods("POST")
|
||||
BaseRoutes.Channels.Handle("/update", ApiUserRequired(updateChannel)).Methods("POST")
|
||||
BaseRoutes.Channels.Handle("/update_header", ApiUserRequired(updateChannelHeader)).Methods("POST")
|
||||
BaseRoutes.Channels.Handle("/update_purpose", ApiUserRequired(updateChannelPurpose)).Methods("POST")
|
||||
BaseRoutes.Channels.Handle("/update_notify_props", ApiUserRequired(updateNotifyProps)).Methods("POST")
|
||||
|
||||
BaseRoutes.NeedChannel.Handle("/", ApiUserRequiredActivity(getChannel, false)).Methods("GET")
|
||||
BaseRoutes.NeedChannel.Handle("/extra_info", ApiUserRequired(getChannelExtraInfo)).Methods("GET")
|
||||
BaseRoutes.NeedChannel.Handle("/extra_info/{member_limit:-?[0-9]+}", ApiUserRequired(getChannelExtraInfo)).Methods("GET")
|
||||
BaseRoutes.NeedChannel.Handle("/join", ApiUserRequired(join)).Methods("POST")
|
||||
BaseRoutes.NeedChannel.Handle("/leave", ApiUserRequired(leave)).Methods("POST")
|
||||
BaseRoutes.NeedChannel.Handle("/delete", ApiUserRequired(deleteChannel)).Methods("POST")
|
||||
BaseRoutes.NeedChannel.Handle("/add", ApiUserRequired(addMember)).Methods("POST")
|
||||
BaseRoutes.NeedChannel.Handle("/remove", ApiUserRequired(removeMember)).Methods("POST")
|
||||
BaseRoutes.NeedChannel.Handle("/update_last_viewed_at", ApiUserRequired(updateLastViewedAt)).Methods("POST")
|
||||
}
|
||||
|
||||
func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -52,6 +51,10 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if len(channel.TeamId) == 0 {
|
||||
channel.TeamId = c.TeamId
|
||||
}
|
||||
|
||||
if !c.HasPermissionsToTeam(channel.TeamId, "createChannel") {
|
||||
return
|
||||
}
|
||||
|
|
@ -107,10 +110,6 @@ func createDirectChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if !c.HasPermissionsToTeam(c.Session.TeamId, "createDirectChannel") {
|
||||
return
|
||||
}
|
||||
|
||||
if sc, err := CreateDirectChannel(c, userId); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
|
|
@ -131,7 +130,7 @@ func CreateDirectChannel(c *Context, otherUserId string) (*model.Channel, *model
|
|||
channel.DisplayName = ""
|
||||
channel.Name = model.GetDMNameFromIds(otherUserId, c.Session.UserId)
|
||||
|
||||
channel.TeamId = c.Session.TeamId
|
||||
channel.TeamId = c.TeamId
|
||||
channel.Header = ""
|
||||
channel.Type = model.CHANNEL_DIRECT
|
||||
|
||||
|
|
@ -214,7 +213,7 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
if oldChannel.Name == model.DEFAULT_CHANNEL {
|
||||
if (len(channel.Name) > 0 && channel.Name != oldChannel.Name) || (len(channel.Type) > 0 && channel.Type != oldChannel.Type) {
|
||||
c.Err = model.NewLocAppError("updateChannel", "api.channel.update_channel.tried.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -367,7 +366,7 @@ func getChannels(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// user is already in the team
|
||||
|
||||
if result := <-Srv.Store.Channel().GetChannels(c.Session.TeamId, c.Session.UserId); result.Err != nil {
|
||||
if result := <-Srv.Store.Channel().GetChannels(c.TeamId, c.Session.UserId); result.Err != nil {
|
||||
if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" {
|
||||
// lets make sure the user is valid
|
||||
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
|
||||
|
|
@ -392,7 +391,7 @@ func getMoreChannels(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// user is already in the team
|
||||
|
||||
if result := <-Srv.Store.Channel().GetMoreChannels(c.Session.TeamId, c.Session.UserId); result.Err != nil {
|
||||
if result := <-Srv.Store.Channel().GetMoreChannels(c.TeamId, c.Session.UserId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else if HandleEtag(result.Data.(*model.ChannelList).Etag(), w, r) {
|
||||
|
|
@ -408,7 +407,7 @@ func getChannelCounts(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// user is already in the team
|
||||
|
||||
if result := <-Srv.Store.Channel().GetChannelCounts(c.Session.TeamId, c.Session.UserId); result.Err != nil {
|
||||
if result := <-Srv.Store.Channel().GetChannelCounts(c.TeamId, c.Session.UserId); result.Err != nil {
|
||||
c.Err = model.NewLocAppError("getChannelCounts", "api.channel.get_channel_counts.app_error", nil, result.Err.Message)
|
||||
return
|
||||
} else if HandleEtag(result.Data.(*model.ChannelCounts).Etag(), w, r) {
|
||||
|
|
@ -423,7 +422,7 @@ func getChannelCounts(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
func join(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
params := mux.Vars(r)
|
||||
channelId := params["id"]
|
||||
channelId := params["channel_id"]
|
||||
|
||||
JoinChannel(c, channelId, "")
|
||||
|
||||
|
|
@ -498,7 +497,7 @@ func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelM
|
|||
}
|
||||
|
||||
go func() {
|
||||
UpdateChannelAccessCache(channel.TeamId, user.Id, channel.Id)
|
||||
InvalidateCacheForUser(user.Id)
|
||||
|
||||
message := model.NewMessage(channel.TeamId, channel.Id, user.Id, model.ACTION_USER_ADDED)
|
||||
PublishAndForget(message)
|
||||
|
|
@ -507,12 +506,12 @@ func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelM
|
|||
return newMember, nil
|
||||
}
|
||||
|
||||
func JoinDefaultChannels(user *model.User, channelRole string) *model.AppError {
|
||||
func JoinDefaultChannels(teamId string, user *model.User, channelRole string) *model.AppError {
|
||||
// We don't call JoinChannel here since c.Session is not populated on user creation
|
||||
|
||||
var err *model.AppError = nil
|
||||
|
||||
if result := <-Srv.Store.Channel().GetByName(user.TeamId, "town-square"); result.Err != nil {
|
||||
if result := <-Srv.Store.Channel().GetByName(teamId, "town-square"); result.Err != nil {
|
||||
err = result.Err
|
||||
} else {
|
||||
cm := &model.ChannelMember{ChannelId: result.Data.(*model.Channel).Id, UserId: user.Id,
|
||||
|
|
@ -523,7 +522,7 @@ func JoinDefaultChannels(user *model.User, channelRole string) *model.AppError {
|
|||
}
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Channel().GetByName(user.TeamId, "off-topic"); result.Err != nil {
|
||||
if result := <-Srv.Store.Channel().GetByName(teamId, "off-topic"); result.Err != nil {
|
||||
err = result.Err
|
||||
} else {
|
||||
cm := &model.ChannelMember{ChannelId: result.Data.(*model.Channel).Id, UserId: user.Id,
|
||||
|
|
@ -540,7 +539,7 @@ func JoinDefaultChannels(user *model.User, channelRole string) *model.AppError {
|
|||
func leave(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
params := mux.Vars(r)
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
|
||||
sc := Srv.Store.Channel().Get(id)
|
||||
uc := Srv.Store.User().Get(c.Session.UserId)
|
||||
|
|
@ -561,13 +560,13 @@ func leave(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
c.Err = model.NewLocAppError("leave", "api.channel.leave.direct.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
if channel.Name == model.DEFAULT_CHANNEL {
|
||||
c.Err = model.NewLocAppError("leave", "api.channel.leave.default.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -589,7 +588,7 @@ func leave(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
params := mux.Vars(r)
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
|
||||
sc := Srv.Store.Channel().Get(id)
|
||||
scm := Srv.Store.Channel().GetMember(id, c.Session.UserId)
|
||||
|
|
@ -637,7 +636,7 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if channel.Name == model.DEFAULT_CHANNEL {
|
||||
c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.cannot.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -682,7 +681,7 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
|
||||
Srv.Store.Channel().UpdateLastViewedAt(id, c.Session.UserId)
|
||||
|
||||
|
|
@ -695,7 +694,7 @@ func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
Srv.Store.Preference().Save(&model.Preferences{preference})
|
||||
|
||||
message := model.NewMessage(c.Session.TeamId, id, c.Session.UserId, model.ACTION_CHANNEL_VIEWED)
|
||||
message := model.NewMessage(c.TeamId, id, c.Session.UserId, model.ACTION_CHANNEL_VIEWED)
|
||||
message.Add("channel_id", id)
|
||||
|
||||
PublishAndForget(message)
|
||||
|
|
@ -707,9 +706,9 @@ func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func getChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
|
||||
//pchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId)
|
||||
//pchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().Get(id)
|
||||
cmchan := Srv.Store.Channel().GetMember(id, c.Session.UserId)
|
||||
|
||||
|
|
@ -737,7 +736,7 @@ func getChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
|
||||
var memberLimit int
|
||||
if memberLimitString, ok := params["member_limit"]; !ok {
|
||||
|
|
@ -781,7 +780,7 @@ func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
extraMembers := ecmresult.Data.([]model.ExtraMember)
|
||||
memberCount := ccmresult.Data.(int64)
|
||||
|
||||
if !c.HasPermissionsToTeam(channel.TeamId, "getChannelExtraInfo") {
|
||||
if len(channel.TeamId) > 0 && !c.HasPermissionsToTeam(channel.TeamId, "getChannelExtraInfo") {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -803,7 +802,7 @@ func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
|
||||
data := model.MapFromJson(r.Body)
|
||||
userId := data["user_id"]
|
||||
|
|
@ -813,7 +812,7 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
|
||||
sc := Srv.Store.Channel().Get(id)
|
||||
ouc := Srv.Store.User().Get(c.Session.UserId)
|
||||
nuc := Srv.Store.User().Get(userId)
|
||||
|
|
@ -857,7 +856,7 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func removeMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
channelId := params["id"]
|
||||
channelId := params["channel_id"]
|
||||
|
||||
data := model.MapFromJson(r.Body)
|
||||
userIdToRemove := data["user_id"]
|
||||
|
|
@ -914,7 +913,7 @@ func RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel
|
|||
return cmresult.Err
|
||||
}
|
||||
|
||||
UpdateChannelAccessCacheAndForget(channel.TeamId, userIdToRemove, channel.Id)
|
||||
InvalidateCacheForUser(userIdToRemove)
|
||||
|
||||
message := model.NewMessage(channel.TeamId, channel.Id, userIdToRemove, model.ACTION_USER_REMOVED)
|
||||
message.Add("remover_id", removerUserId)
|
||||
|
|
@ -938,7 +937,7 @@ func updateNotifyProps(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
|
||||
|
||||
if !c.HasPermissionsToUser(userId, "updateNotifyLevel") {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -12,61 +12,47 @@ import (
|
|||
|
||||
const (
|
||||
NUM_CHANNELS = 140
|
||||
NUM_USERS = 40
|
||||
)
|
||||
|
||||
func BenchmarkCreateChannel(b *testing.B) {
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
th := Setup().InitBasic()
|
||||
|
||||
channelCreator := NewAutoChannelCreator(Client, team.Id)
|
||||
channelCreator := NewAutoChannelCreator(th.BasicClient, th.BasicTeam)
|
||||
|
||||
// Benchmark Start
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
channelCreator.CreateTestChannels(NUM_CHANNELS_RANGE)
|
||||
channelCreator.CreateTestChannels(utils.Range{NUM_CHANNELS, NUM_CHANNELS})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCreateDirectChannel(b *testing.B) {
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
th := Setup().InitBasic()
|
||||
|
||||
userCreator := NewAutoUserCreator(Client, team.Id)
|
||||
users, err := userCreator.CreateTestUsers(NUM_CHANNELS_RANGE)
|
||||
userCreator := NewAutoUserCreator(th.BasicClient, th.BasicTeam)
|
||||
users, err := userCreator.CreateTestUsers(utils.Range{NUM_USERS, NUM_USERS})
|
||||
if err == false {
|
||||
b.Fatal("Could not create users")
|
||||
}
|
||||
|
||||
data := make([]map[string]string, len(users))
|
||||
|
||||
for i := range data {
|
||||
newmap := map[string]string{
|
||||
"user_id": users[i].Id,
|
||||
}
|
||||
data[i] = newmap
|
||||
}
|
||||
|
||||
// Benchmark Start
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := 0; j < NUM_CHANNELS; j++ {
|
||||
Client.CreateDirectChannel(data[j])
|
||||
for j := 0; j < NUM_USERS; j++ {
|
||||
th.BasicClient.CreateDirectChannel(users[j].Id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUpdateChannel(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
CHANNEL_HEADER_LEN = 50
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
|
||||
channelCreator := NewAutoChannelCreator(Client, team.Id)
|
||||
channelCreator := NewAutoChannelCreator(th.BasicClient, th.BasicTeam)
|
||||
channels, valid := channelCreator.CreateTestChannels(NUM_CHANNELS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test channels")
|
||||
|
|
@ -80,7 +66,7 @@ func BenchmarkUpdateChannel(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := range channels {
|
||||
if _, err := Client.UpdateChannel(channels[j]); err != nil {
|
||||
if _, err := th.BasicClient.UpdateChannel(channels[j]); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -88,12 +74,13 @@ func BenchmarkUpdateChannel(b *testing.B) {
|
|||
}
|
||||
|
||||
func BenchmarkGetChannels(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
|
||||
channelCreator := NewAutoChannelCreator(Client, team.Id)
|
||||
channelCreator := NewAutoChannelCreator(th.BasicClient, th.BasicTeam)
|
||||
_, valid := channelCreator.CreateTestChannels(NUM_CHANNELS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test channels")
|
||||
|
|
@ -102,17 +89,18 @@ func BenchmarkGetChannels(b *testing.B) {
|
|||
// Benchmark Start
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Client.Must(Client.GetChannels(""))
|
||||
th.BasicClient.Must(th.BasicClient.GetChannels(""))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetMoreChannels(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
|
||||
channelCreator := NewAutoChannelCreator(Client, team.Id)
|
||||
channelCreator := NewAutoChannelCreator(th.BasicClient, th.BasicTeam)
|
||||
_, valid := channelCreator.CreateTestChannels(NUM_CHANNELS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test channels")
|
||||
|
|
@ -121,44 +109,47 @@ func BenchmarkGetMoreChannels(b *testing.B) {
|
|||
// Benchmark Start
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Client.Must(Client.GetMoreChannels(""))
|
||||
th.BasicClient.Must(th.BasicClient.GetMoreChannels(""))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkJoinChannel(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
|
||||
channelCreator := NewAutoChannelCreator(Client, team.Id)
|
||||
channelCreator := NewAutoChannelCreator(th.BasicClient, th.BasicTeam)
|
||||
channels, valid := channelCreator.CreateTestChannels(NUM_CHANNELS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test channels")
|
||||
}
|
||||
|
||||
// Secondary test user to join channels created by primary test user
|
||||
user := &model.User{TeamId: team.Id, Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "That Guy", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
user := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "That Guy", Password: "pwd"}
|
||||
user = th.BasicClient.Must(th.BasicClient.CreateUser(user, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user, th.BasicTeam)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th.BasicClient.LoginByEmail(th.BasicTeam.Name, user.Email, "pwd")
|
||||
|
||||
// Benchmark Start
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := range channels {
|
||||
Client.Must(Client.JoinChannel(channels[j].Id))
|
||||
th.BasicClient.Must(th.BasicClient.JoinChannel(channels[j].Id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDeleteChannel(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
|
||||
channelCreator := NewAutoChannelCreator(Client, team.Id)
|
||||
channelCreator := NewAutoChannelCreator(th.BasicClient, th.BasicTeam)
|
||||
channels, valid := channelCreator.CreateTestChannels(NUM_CHANNELS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test channels")
|
||||
|
|
@ -168,18 +159,19 @@ func BenchmarkDeleteChannel(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := range channels {
|
||||
Client.Must(Client.DeleteChannel(channels[j].Id))
|
||||
th.BasicClient.Must(th.BasicClient.DeleteChannel(channels[j].Id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetChannelExtraInfo(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
|
||||
channelCreator := NewAutoChannelCreator(Client, team.Id)
|
||||
channelCreator := NewAutoChannelCreator(th.BasicClient, th.BasicTeam)
|
||||
channels, valid := channelCreator.CreateTestChannels(NUM_CHANNELS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test channels")
|
||||
|
|
@ -189,22 +181,23 @@ func BenchmarkGetChannelExtraInfo(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := range channels {
|
||||
Client.Must(Client.GetChannelExtraInfo(channels[j].Id, -1, ""))
|
||||
th.BasicClient.Must(th.BasicClient.GetChannelExtraInfo(channels[j].Id, -1, ""))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAddChannelMember(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_USERS = 100
|
||||
NUM_USERS_RANGE = utils.Range{NUM_USERS, NUM_USERS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
|
||||
channel := &model.Channel{DisplayName: "Test Channel", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
channel := &model.Channel{DisplayName: "Test Channel", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}
|
||||
channel = th.BasicClient.Must(th.BasicClient.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
userCreator := NewAutoUserCreator(Client, team.Id)
|
||||
userCreator := NewAutoUserCreator(th.BasicClient, th.BasicTeam)
|
||||
users, valid := userCreator.CreateTestUsers(NUM_USERS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test users")
|
||||
|
|
@ -214,7 +207,7 @@ func BenchmarkAddChannelMember(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := range users {
|
||||
if _, err := Client.AddChannelMember(channel.Id, users[j].Id); err != nil {
|
||||
if _, err := th.BasicClient.AddChannelMember(channel.Id, users[j].Id); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -223,23 +216,24 @@ func BenchmarkAddChannelMember(b *testing.B) {
|
|||
|
||||
// Is this benchmark failing? Raise your file ulimit! 2048 worked for me.
|
||||
func BenchmarkRemoveChannelMember(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_USERS = 140
|
||||
NUM_USERS_RANGE = utils.Range{NUM_USERS, NUM_USERS}
|
||||
)
|
||||
team, _, _ := SetupBenchmark()
|
||||
|
||||
channel := &model.Channel{DisplayName: "Test Channel", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
channel := &model.Channel{DisplayName: "Test Channel", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}
|
||||
channel = th.BasicClient.Must(th.BasicClient.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
userCreator := NewAutoUserCreator(Client, team.Id)
|
||||
userCreator := NewAutoUserCreator(th.BasicClient, th.BasicTeam)
|
||||
users, valid := userCreator.CreateTestUsers(NUM_USERS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test users")
|
||||
}
|
||||
|
||||
for i := range users {
|
||||
if _, err := Client.AddChannelMember(channel.Id, users[i].Id); err != nil {
|
||||
if _, err := th.BasicClient.AddChannelMember(channel.Id, users[i].Id); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -248,7 +242,7 @@ func BenchmarkRemoveChannelMember(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := range users {
|
||||
if _, err := Client.RemoveChannelMember(channel.Id, users[j].Id); err != nil {
|
||||
if _, err := th.BasicClient.RemoveChannelMember(channel.Id, users[j].Id); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -256,12 +250,13 @@ func BenchmarkRemoveChannelMember(b *testing.B) {
|
|||
}
|
||||
|
||||
func BenchmarkUpdateNotifyProps(b *testing.B) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
var (
|
||||
NUM_CHANNELS_RANGE = utils.Range{NUM_CHANNELS, NUM_CHANNELS}
|
||||
)
|
||||
team, user, _ := SetupBenchmark()
|
||||
|
||||
channelCreator := NewAutoChannelCreator(Client, team.Id)
|
||||
channelCreator := NewAutoChannelCreator(th.BasicClient, th.BasicTeam)
|
||||
channels, valid := channelCreator.CreateTestChannels(NUM_CHANNELS_RANGE)
|
||||
if valid == false {
|
||||
b.Fatal("Unable to create test channels")
|
||||
|
|
@ -272,7 +267,7 @@ func BenchmarkUpdateNotifyProps(b *testing.B) {
|
|||
for i := range data {
|
||||
newmap := map[string]string{
|
||||
"channel_id": channels[i].Id,
|
||||
"user_id": user.Id,
|
||||
"user_id": th.BasicUser.Id,
|
||||
"desktop": model.CHANNEL_NOTIFY_MENTION,
|
||||
"mark_unread": model.CHANNEL_MARK_UNREAD_MENTION,
|
||||
}
|
||||
|
|
@ -283,7 +278,7 @@ func BenchmarkUpdateNotifyProps(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := range channels {
|
||||
Client.Must(Client.UpdateNotifyProps(data[j]))
|
||||
th.BasicClient.Must(th.BasicClient.UpdateNotifyProps(data[j]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,19 +14,13 @@ import (
|
|||
)
|
||||
|
||||
func TestCreateChannel(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
team2 := &model.Team{DisplayName: "Name Team 2", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
Client.Must(Client.Logout())
|
||||
team2 := th.CreateTeam(th.BasicClient)
|
||||
th.LoginBasic()
|
||||
th.BasicClient.SetTeamId(team.Id)
|
||||
|
||||
channel := model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
rchannel, err := Client.CreateChannel(&channel)
|
||||
|
|
@ -63,7 +57,7 @@ func TestCreateChannel(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
if _, err := Client.DoApiPost("/channels/create", "garbage"); err == nil {
|
||||
if _, err := Client.DoApiPost(Client.GetTeamRoute()+"/channels/create", "garbage"); err == nil {
|
||||
t.Fatal("should have been an error")
|
||||
}
|
||||
|
||||
|
|
@ -94,25 +88,12 @@ func TestCreateChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateDirectChannel(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
user := th.BasicUser
|
||||
user2 := th.BasicUser2
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user2.Id
|
||||
|
||||
rchannel, err := Client.CreateDirectChannel(data)
|
||||
rchannel, err := Client.CreateDirectChannel(th.BasicUser2.Id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -132,47 +113,31 @@ func TestCreateDirectChannel(t *testing.T) {
|
|||
t.Fatal("channel type was not direct")
|
||||
}
|
||||
|
||||
if _, err := Client.CreateDirectChannel(data); err == nil {
|
||||
if _, err := Client.CreateDirectChannel(th.BasicUser2.Id); err == nil {
|
||||
t.Fatal("channel already exists and should have failed")
|
||||
}
|
||||
|
||||
data["user_id"] = "junk"
|
||||
if _, err := Client.CreateDirectChannel(data); err == nil {
|
||||
if _, err := Client.CreateDirectChannel("junk"); err == nil {
|
||||
t.Fatal("should have failed with bad user id")
|
||||
}
|
||||
|
||||
data["user_id"] = "12345678901234567890123456"
|
||||
if _, err := Client.CreateDirectChannel(data); err == nil {
|
||||
if _, err := Client.CreateDirectChannel("12345678901234567890123456"); err == nil {
|
||||
t.Fatal("should have failed with non-existent user")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestUpdateChannel(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
|
||||
|
||||
userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
|
||||
|
||||
userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
|
||||
userStd.Roles = ""
|
||||
|
||||
Client.LoginByEmail(team.Name, userChannelAdmin.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user := th.BasicUser
|
||||
user2 := th.CreateUser(th.BasicClient)
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
Client.AddChannelMember(channel1.Id, userTeamAdmin.Id)
|
||||
Client.AddChannelMember(channel1.Id, user.Id)
|
||||
|
||||
header := "a" + model.NewId() + "a"
|
||||
purpose := "a" + model.NewId() + "a"
|
||||
|
|
@ -191,25 +156,6 @@ func TestUpdateChannel(t *testing.T) {
|
|||
t.Fatal("Channel admin failed to skip displayName")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, userTeamAdmin.Email, "pwd")
|
||||
|
||||
header = "b" + model.NewId() + "b"
|
||||
purpose = "b" + model.NewId() + "b"
|
||||
upChannel1 = &model.Channel{Id: channel1.Id, Header: header, Purpose: purpose}
|
||||
upChannel1 = Client.Must(Client.UpdateChannel(upChannel1)).Data.(*model.Channel)
|
||||
|
||||
if upChannel1.Header != header {
|
||||
t.Fatal("Team admin failed to update header")
|
||||
}
|
||||
|
||||
if upChannel1.Purpose != purpose {
|
||||
t.Fatal("Team admin failed to update purpose")
|
||||
}
|
||||
|
||||
if upChannel1.DisplayName != channel1.DisplayName {
|
||||
t.Fatal("Team admin failed to skip displayName")
|
||||
}
|
||||
|
||||
rget := Client.Must(Client.GetChannels(""))
|
||||
data := rget.Data.(*model.ChannelList)
|
||||
for _, c := range data.Channels {
|
||||
|
|
@ -223,7 +169,7 @@ func TestUpdateChannel(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, userStd.Email, "pwd")
|
||||
Client.LoginByEmail(team.Name, user2.Email, user2.Password)
|
||||
|
||||
if _, err := Client.UpdateChannel(upChannel1); err == nil {
|
||||
t.Fatal("Standard User should have failed to update")
|
||||
|
|
@ -231,16 +177,9 @@ func TestUpdateChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateChannelHeader(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -276,11 +215,7 @@ func TestUpdateChannelHeader(t *testing.T) {
|
|||
t.Fatal("should have errored on bad channel header")
|
||||
}
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
data["channel_id"] = channel1.Id
|
||||
data["channel_header"] = "new header"
|
||||
|
|
@ -290,16 +225,9 @@ func TestUpdateChannelHeader(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateChannelPurpose(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -335,11 +263,7 @@ func TestUpdateChannelPurpose(t *testing.T) {
|
|||
t.Fatal("should have errored on bad channel purpose")
|
||||
}
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
data["channel_id"] = channel1.Id
|
||||
data["channel_purpose"] = "new purpose"
|
||||
|
|
@ -349,16 +273,9 @@ func TestUpdateChannelPurpose(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetChannel(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -412,16 +329,9 @@ func TestGetChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetMoreChannel(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -429,11 +339,7 @@ func TestGetMoreChannel(t *testing.T) {
|
|||
channel2 := &model.Channel{DisplayName: "B Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
rget := Client.Must(Client.GetMoreChannels(""))
|
||||
data := rget.Data.(*model.ChannelList)
|
||||
|
|
@ -456,16 +362,9 @@ func TestGetMoreChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetChannelCounts(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -478,11 +377,11 @@ func TestGetChannelCounts(t *testing.T) {
|
|||
} else {
|
||||
counts := result.Data.(*model.ChannelCounts)
|
||||
|
||||
if len(counts.Counts) != 4 {
|
||||
if len(counts.Counts) != 5 {
|
||||
t.Fatal("wrong number of channel counts")
|
||||
}
|
||||
|
||||
if len(counts.UpdateTimes) != 4 {
|
||||
if len(counts.UpdateTimes) != 5 {
|
||||
t.Fatal("wrong number of channel update times")
|
||||
}
|
||||
|
||||
|
|
@ -497,16 +396,9 @@ func TestGetChannelCounts(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestJoinChannel(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -514,11 +406,7 @@ func TestJoinChannel(t *testing.T) {
|
|||
channel3 := &model.Channel{DisplayName: "B Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
|
||||
channel3 = Client.Must(Client.CreateChannel(channel3)).Data.(*model.Channel)
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
Client.Must(Client.JoinChannel(channel1.Id))
|
||||
|
||||
|
|
@ -526,13 +414,10 @@ func TestJoinChannel(t *testing.T) {
|
|||
t.Fatal("shouldn't be able to join secret group")
|
||||
}
|
||||
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user1.Id
|
||||
rchannel := Client.Must(Client.CreateDirectChannel(data)).Data.(*model.Channel)
|
||||
|
||||
user3 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
rchannel := Client.Must(Client.CreateDirectChannel(th.BasicUser.Id)).Data.(*model.Channel)
|
||||
|
||||
user3 := th.CreateUser(th.BasicClient)
|
||||
LinkUserToTeam(user3, team)
|
||||
Client.LoginByEmail(team.Name, user3.Email, "pwd")
|
||||
|
||||
if _, err := Client.JoinChannel(rchannel.Id); err == nil {
|
||||
|
|
@ -541,16 +426,9 @@ func TestJoinChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLeaveChannel(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -558,20 +436,14 @@ func TestLeaveChannel(t *testing.T) {
|
|||
channel3 := &model.Channel{DisplayName: "B Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
|
||||
channel3 = Client.Must(Client.CreateChannel(channel3)).Data.(*model.Channel)
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
Client.Must(Client.JoinChannel(channel1.Id))
|
||||
|
||||
// No error if you leave a channel you cannot see
|
||||
Client.Must(Client.LeaveChannel(channel3.Id))
|
||||
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user1.Id
|
||||
rchannel := Client.Must(Client.CreateDirectChannel(data)).Data.(*model.Channel)
|
||||
rchannel := Client.Must(Client.CreateDirectChannel(th.BasicUser.Id)).Data.(*model.Channel)
|
||||
|
||||
if _, err := Client.LeaveChannel(rchannel.Id); err == nil {
|
||||
t.Fatal("should have errored, cannot leave direct channel")
|
||||
|
|
@ -590,20 +462,12 @@ func TestLeaveChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteChannel(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
userTeamAdmin := th.BasicUser
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
|
||||
|
||||
userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, userChannelAdmin.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
channelMadeByCA := &model.Channel{DisplayName: "C Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channelMadeByCA = Client.Must(Client.CreateChannel(channelMadeByCA)).Data.(*model.Channel)
|
||||
|
|
@ -631,11 +495,9 @@ func TestDeleteChannel(t *testing.T) {
|
|||
t.Fatal("should have failed to post to deleted channel")
|
||||
}
|
||||
|
||||
userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, userStd.Email, "pwd")
|
||||
userStd := th.CreateUser(th.BasicClient)
|
||||
LinkUserToTeam(userStd, team)
|
||||
Client.LoginByEmail(team.Name, userStd.Email, userStd.Password)
|
||||
|
||||
if _, err := Client.JoinChannel(channel1.Id); err == nil {
|
||||
t.Fatal("should have failed to join deleted channel")
|
||||
|
|
@ -660,16 +522,9 @@ func TestDeleteChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetChannelExtraInfo(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -701,8 +556,10 @@ func TestGetChannelExtraInfo(t *testing.T) {
|
|||
|
||||
Client2 := model.NewClient("http://localhost" + utils.Cfg.ServiceSettings.ListenAddress)
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Tester 2", Password: "pwd"}
|
||||
user2 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Tester 2", Password: "pwd"}
|
||||
user2 = Client2.Must(Client2.CreateUser(user2, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user2, team)
|
||||
Client2.SetTeamId(team.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client2.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
|
|
@ -784,24 +641,14 @@ func TestGetChannelExtraInfo(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAddChannelMember(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user2 := th.BasicUser2
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
if _, err := Client.AddChannelMember(channel1.Id, user2.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -825,13 +672,13 @@ func TestAddChannelMember(t *testing.T) {
|
|||
channel2 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
if _, err := Client.AddChannelMember(channel2.Id, user2.Id); err == nil {
|
||||
t.Fatal("Should have errored, user not in channel")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
th.LoginBasic()
|
||||
|
||||
Client.Must(Client.DeleteChannel(channel2.Id))
|
||||
|
||||
|
|
@ -842,34 +689,24 @@ func TestAddChannelMember(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRemoveChannelMember(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
|
||||
|
||||
userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, userChannelAdmin.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user2 := th.BasicUser2
|
||||
UpdateUserToTeamAdmin(user2, team)
|
||||
|
||||
channelMadeByCA := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channelMadeByCA = Client.Must(Client.CreateChannel(channelMadeByCA)).Data.(*model.Channel)
|
||||
|
||||
Client.Must(Client.AddChannelMember(channelMadeByCA.Id, userTeamAdmin.Id))
|
||||
Client.Must(Client.AddChannelMember(channelMadeByCA.Id, user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, userTeamAdmin.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
|
||||
userStd := th.CreateUser(th.BasicClient)
|
||||
LinkUserToTeam(userStd, team)
|
||||
|
||||
Client.Must(Client.AddChannelMember(channel1.Id, userStd.Id))
|
||||
|
||||
|
|
@ -894,13 +731,13 @@ func TestRemoveChannelMember(t *testing.T) {
|
|||
channel2 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
|
||||
Client.LoginByEmail(team.Name, userStd.Email, "pwd")
|
||||
Client.LoginByEmail(team.Name, userStd.Email, userStd.Password)
|
||||
|
||||
if _, err := Client.RemoveChannelMember(channel2.Id, userStd.Id); err == nil {
|
||||
t.Fatal("Should have errored, user not channel admin")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, userTeamAdmin.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
Client.Must(Client.AddChannelMember(channel2.Id, userStd.Id))
|
||||
|
||||
Client.Must(Client.DeleteChannel(channel2.Id))
|
||||
|
|
@ -912,16 +749,11 @@ func TestRemoveChannelMember(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateNotifyProps(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user := th.BasicUser
|
||||
user2 := th.BasicUser2
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -1019,10 +851,7 @@ func TestUpdateNotifyProps(t *testing.T) {
|
|||
t.Fatal("Should have errored - bad mark unread level")
|
||||
}
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
data["channel_id"] = channel1.Id
|
||||
data["user_id"] = user2.Id
|
||||
|
|
@ -1034,16 +863,9 @@ func TestUpdateNotifyProps(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFuzzyChannel(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
// Strings that should pass as acceptable channel names
|
||||
var fuzzyStringsPass = []string{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
"strings"
|
||||
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
|
@ -38,23 +38,21 @@ func GetCommandProvider(name string) CommandProvider {
|
|||
return nil
|
||||
}
|
||||
|
||||
func InitCommand(r *mux.Router) {
|
||||
func InitCommand() {
|
||||
l4g.Debug(utils.T("api.command.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/commands").Subrouter()
|
||||
BaseRoutes.Commands.Handle("/execute", ApiUserRequired(executeCommand)).Methods("POST")
|
||||
BaseRoutes.Commands.Handle("/list", ApiUserRequired(listCommands)).Methods("GET")
|
||||
|
||||
sr.Handle("/execute", ApiUserRequired(executeCommand)).Methods("POST")
|
||||
sr.Handle("/list", ApiUserRequired(listCommands)).Methods("GET")
|
||||
BaseRoutes.Commands.Handle("/create", ApiUserRequired(createCommand)).Methods("POST")
|
||||
BaseRoutes.Commands.Handle("/list_team_commands", ApiUserRequired(listTeamCommands)).Methods("GET")
|
||||
BaseRoutes.Commands.Handle("/regen_token", ApiUserRequired(regenCommandToken)).Methods("POST")
|
||||
BaseRoutes.Commands.Handle("/delete", ApiUserRequired(deleteCommand)).Methods("POST")
|
||||
|
||||
sr.Handle("/create", ApiUserRequired(createCommand)).Methods("POST")
|
||||
sr.Handle("/list_team_commands", ApiUserRequired(listTeamCommands)).Methods("GET")
|
||||
sr.Handle("/regen_token", ApiUserRequired(regenCommandToken)).Methods("POST")
|
||||
sr.Handle("/delete", ApiUserRequired(deleteCommand)).Methods("POST")
|
||||
|
||||
sr.Handle("/test", ApiAppHandler(testCommand)).Methods("POST")
|
||||
sr.Handle("/test", ApiAppHandler(testCommand)).Methods("GET")
|
||||
sr.Handle("/test_e", ApiAppHandler(testEphemeralCommand)).Methods("POST")
|
||||
sr.Handle("/test_e", ApiAppHandler(testEphemeralCommand)).Methods("GET")
|
||||
BaseRoutes.Teams.Handle("/command_test", ApiAppHandler(testCommand)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/command_test", ApiAppHandler(testCommand)).Methods("GET")
|
||||
BaseRoutes.Teams.Handle("/command_test_e", ApiAppHandler(testEphemeralCommand)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/command_test_e", ApiAppHandler(testEphemeralCommand)).Methods("GET")
|
||||
}
|
||||
|
||||
func listCommands(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -70,7 +68,7 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
if *utils.Cfg.ServiceSettings.EnableCommands {
|
||||
if result := <-Srv.Store.Command().GetByTeam(c.Session.TeamId); result.Err != nil {
|
||||
if result := <-Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
|
|
@ -99,7 +97,7 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
if len(channelId) > 0 {
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
|
||||
|
||||
if !c.HasPermissionsToChannel(cchan, "checkCommand") {
|
||||
return
|
||||
|
|
@ -124,10 +122,10 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
chanChan := Srv.Store.Channel().Get(channelId)
|
||||
teamChan := Srv.Store.Team().Get(c.Session.TeamId)
|
||||
teamChan := Srv.Store.Team().Get(c.TeamId)
|
||||
userChan := Srv.Store.User().Get(c.Session.UserId)
|
||||
|
||||
if result := <-Srv.Store.Command().GetByTeam(c.Session.TeamId); result.Err != nil {
|
||||
if result := <-Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
|
|
@ -254,7 +252,7 @@ func handleResponse(c *Context, w http.ResponseWriter, response *model.CommandRe
|
|||
post.Message = response.Text
|
||||
post.CreateAt = model.GetMillis()
|
||||
SendEphemeralPost(
|
||||
c.Session.TeamId,
|
||||
c.TeamId,
|
||||
c.Session.UserId,
|
||||
post,
|
||||
)
|
||||
|
|
@ -288,7 +286,7 @@ func createCommand(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
cmd.CreatorId = c.Session.UserId
|
||||
cmd.TeamId = c.Session.TeamId
|
||||
cmd.TeamId = c.TeamId
|
||||
|
||||
if result := <-Srv.Store.Command().Save(cmd); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
|
|
@ -315,7 +313,7 @@ func listTeamCommands(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Command().GetByTeam(c.Session.TeamId); result.Err != nil {
|
||||
if result := <-Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
|
|
@ -356,7 +354,7 @@ func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
} else {
|
||||
cmd = result.Data.(*model.Command)
|
||||
|
||||
if c.Session.TeamId != cmd.TeamId || (c.Session.UserId != cmd.CreatorId && !c.IsTeamAdmin()) {
|
||||
if c.TeamId != cmd.TeamId || (c.Session.UserId != cmd.CreatorId && !c.IsTeamAdmin()) {
|
||||
c.LogAudit("fail - inappropriate permissions")
|
||||
c.Err = model.NewLocAppError("regenToken", "api.command.regen.app_error", nil, "user_id="+c.Session.UserId)
|
||||
return
|
||||
|
|
@ -402,7 +400,7 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
if c.Session.TeamId != result.Data.(*model.Command).TeamId || (c.Session.UserId != result.Data.(*model.Command).CreatorId && !c.IsTeamAdmin()) {
|
||||
if c.TeamId != result.Data.(*model.Command).TeamId || (c.Session.UserId != result.Data.(*model.Command).CreatorId && !c.IsTeamAdmin()) {
|
||||
c.LogAudit("fail - inappropriate permissions")
|
||||
c.Err = model.NewLocAppError("deleteCommand", "api.command.delete.app_error", nil, "user_id="+c.Session.UserId)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -8,23 +8,12 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
)
|
||||
|
||||
func TestEchoCommand(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "AA", Name: "aa" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
echoTestString := "/echo test"
|
||||
|
||||
|
|
@ -36,7 +25,7 @@ func TestEchoCommand(t *testing.T) {
|
|||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
p1 := Client.Must(Client.GetPosts(channel1.Id, 0, 2, "")).Data.(*model.PostList)
|
||||
if len(p1.Order) != 1 {
|
||||
if len(p1.Order) != 2 {
|
||||
t.Fatal("Echo command failed to send")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ func (me *JoinProvider) GetCommand(c *Context) *model.Command {
|
|||
}
|
||||
|
||||
func (me *JoinProvider) DoCommand(c *Context, channelId string, message string) *model.CommandResponse {
|
||||
if result := <-Srv.Store.Channel().GetMoreChannels(c.Session.TeamId, c.Session.UserId); result.Err != nil {
|
||||
if result := <-Srv.Store.Channel().GetMoreChannels(c.TeamId, c.Session.UserId); result.Err != nil {
|
||||
return &model.CommandResponse{Text: c.T("api.command_join.list.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||
} else {
|
||||
channels := result.Data.(*model.ChannelList)
|
||||
|
|
|
|||
|
|
@ -8,20 +8,13 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
)
|
||||
|
||||
func TestJoinCommands(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user2 := th.BasicUser2
|
||||
|
||||
channel0 := &model.Channel{DisplayName: "00", Name: "00" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel0 = Client.Must(Client.CreateChannel(channel0)).Data.(*model.Channel)
|
||||
|
|
@ -34,13 +27,7 @@ func TestJoinCommands(t *testing.T) {
|
|||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
Client.Must(Client.LeaveChannel(channel2.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user2.Id
|
||||
channel3 := Client.Must(Client.CreateDirectChannel(data)).Data.(*model.Channel)
|
||||
channel3 := Client.Must(Client.CreateDirectChannel(user2.Id)).Data.(*model.Channel)
|
||||
|
||||
rs5 := Client.Must(Client.Command(channel0.Id, "/join "+channel2.Name, false)).Data.(*model.CommandResponse)
|
||||
if !strings.HasSuffix(rs5.GotoLocation, "/"+team.Name+"/channels/"+channel2.Name) {
|
||||
|
|
@ -54,7 +41,7 @@ func TestJoinCommands(t *testing.T) {
|
|||
|
||||
c1 := Client.Must(Client.GetChannels("")).Data.(*model.ChannelList)
|
||||
|
||||
if len(c1.Channels) != 5 { // 4 because of town-square, off-topic and direct
|
||||
if len(c1.Channels) != 6 { // 4 because of town-square, off-topic and direct
|
||||
t.Fatal("didn't join channel")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -182,10 +182,19 @@ func (me *LoadTestProvider) SetupCommand(c *Context, channelId string, message s
|
|||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
var team *model.Team
|
||||
if tr := <-Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
|
||||
return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||
} else {
|
||||
team = tr.Data.(*model.Team)
|
||||
}
|
||||
|
||||
client.MockSession(c.Session.Token)
|
||||
client.SetTeamId(c.TeamId)
|
||||
CreateTestEnvironmentInTeam(
|
||||
client,
|
||||
c.Session.TeamId,
|
||||
team,
|
||||
utils.Range{numChannels, numChannels},
|
||||
utils.Range{numUsers, numUsers},
|
||||
utils.Range{numPosts, numPosts},
|
||||
|
|
@ -209,8 +218,16 @@ func (me *LoadTestProvider) UsersCommand(c *Context, channelId string, message s
|
|||
usersr = utils.Range{2, 5}
|
||||
}
|
||||
|
||||
var team *model.Team
|
||||
if tr := <-Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
|
||||
return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||
} else {
|
||||
team = tr.Data.(*model.Team)
|
||||
}
|
||||
|
||||
client := model.NewClient(c.GetSiteURL())
|
||||
userCreator := NewAutoUserCreator(client, c.Session.TeamId)
|
||||
client.SetTeamId(team.Id)
|
||||
userCreator := NewAutoUserCreator(client, team)
|
||||
userCreator.Fuzzy = doFuzz
|
||||
userCreator.CreateTestUsers(usersr)
|
||||
|
||||
|
|
@ -230,9 +247,18 @@ func (me *LoadTestProvider) ChannelsCommand(c *Context, channelId string, messag
|
|||
if err == false {
|
||||
channelsr = utils.Range{2, 5}
|
||||
}
|
||||
|
||||
var team *model.Team
|
||||
if tr := <-Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
|
||||
return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||
} else {
|
||||
team = tr.Data.(*model.Team)
|
||||
}
|
||||
|
||||
client := model.NewClient(c.GetSiteURL())
|
||||
client.SetTeamId(team.Id)
|
||||
client.MockSession(c.Session.Token)
|
||||
channelCreator := NewAutoChannelCreator(client, c.Session.TeamId)
|
||||
channelCreator := NewAutoChannelCreator(client, team)
|
||||
channelCreator.Fuzzy = doFuzz
|
||||
channelCreator.CreateTestChannels(channelsr)
|
||||
|
||||
|
|
@ -262,7 +288,7 @@ func (me *LoadTestProvider) PostsCommand(c *Context, channelId string, message s
|
|||
}
|
||||
|
||||
var usernames []string
|
||||
if result := <-Srv.Store.User().GetProfiles(c.Session.TeamId); result.Err == nil {
|
||||
if result := <-Srv.Store.User().GetProfiles(c.TeamId); result.Err == nil {
|
||||
profileUsers := result.Data.(map[string]*model.User)
|
||||
usernames = make([]string, len(profileUsers))
|
||||
i := 0
|
||||
|
|
@ -273,6 +299,7 @@ func (me *LoadTestProvider) PostsCommand(c *Context, channelId string, message s
|
|||
}
|
||||
|
||||
client := model.NewClient(c.GetSiteURL())
|
||||
client.SetTeamId(c.TeamId)
|
||||
client.MockSession(c.Session.Token)
|
||||
testPoster := NewAutoPostCreator(client, channelId)
|
||||
testPoster.Fuzzy = doFuzz
|
||||
|
|
|
|||
|
|
@ -9,12 +9,14 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
func TestLoadTestHelpCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
// enable testing to use /loadtest but don't save it since we don't want to overwrite config.json
|
||||
enableTesting := utils.Cfg.ServiceSettings.EnableTesting
|
||||
defer func() {
|
||||
|
|
@ -23,18 +25,6 @@ func TestLoadTestHelpCommands(t *testing.T) {
|
|||
|
||||
utils.Cfg.ServiceSettings.EnableTesting = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel := &model.Channel{DisplayName: "00", Name: "00" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
rs := Client.Must(Client.Command(channel.Id, "/loadtest help", false)).Data.(*model.CommandResponse)
|
||||
if !strings.Contains(rs.Text, "Mattermost load testing commands to help") {
|
||||
t.Fatal(rs.Text)
|
||||
|
|
@ -44,7 +34,10 @@ func TestLoadTestHelpCommands(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoadTestSetupCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
// enable testing to use /loadtest but don't save it since we don't want to overwrite config.json
|
||||
enableTesting := utils.Cfg.ServiceSettings.EnableTesting
|
||||
defer func() {
|
||||
|
|
@ -53,18 +46,6 @@ func TestLoadTestSetupCommands(t *testing.T) {
|
|||
|
||||
utils.Cfg.ServiceSettings.EnableTesting = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel := &model.Channel{DisplayName: "00", Name: "00" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
rs := Client.Must(Client.Command(channel.Id, "/loadtest setup fuzz 1 1 1", false)).Data.(*model.CommandResponse)
|
||||
if rs.Text != "Creating enviroment..." {
|
||||
t.Fatal(rs.Text)
|
||||
|
|
@ -74,7 +55,10 @@ func TestLoadTestSetupCommands(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoadTestUsersCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
// enable testing to use /loadtest but don't save it since we don't want to overwrite config.json
|
||||
enableTesting := utils.Cfg.ServiceSettings.EnableTesting
|
||||
defer func() {
|
||||
|
|
@ -83,18 +67,6 @@ func TestLoadTestUsersCommands(t *testing.T) {
|
|||
|
||||
utils.Cfg.ServiceSettings.EnableTesting = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel := &model.Channel{DisplayName: "00", Name: "00" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
rs := Client.Must(Client.Command(channel.Id, "/loadtest users fuzz 1 2", false)).Data.(*model.CommandResponse)
|
||||
if rs.Text != "Adding users..." {
|
||||
t.Fatal(rs.Text)
|
||||
|
|
@ -104,7 +76,10 @@ func TestLoadTestUsersCommands(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoadTestChannelsCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
// enable testing to use /loadtest but don't save it since we don't want to overwrite config.json
|
||||
enableTesting := utils.Cfg.ServiceSettings.EnableTesting
|
||||
defer func() {
|
||||
|
|
@ -113,18 +88,6 @@ func TestLoadTestChannelsCommands(t *testing.T) {
|
|||
|
||||
utils.Cfg.ServiceSettings.EnableTesting = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel := &model.Channel{DisplayName: "00", Name: "00" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
rs := Client.Must(Client.Command(channel.Id, "/loadtest channels fuzz 1 2", false)).Data.(*model.CommandResponse)
|
||||
if rs.Text != "Adding channels..." {
|
||||
t.Fatal(rs.Text)
|
||||
|
|
@ -134,7 +97,10 @@ func TestLoadTestChannelsCommands(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoadTestPostsCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
// enable testing to use /loadtest but don't save it since we don't want to overwrite config.json
|
||||
enableTesting := utils.Cfg.ServiceSettings.EnableTesting
|
||||
defer func() {
|
||||
|
|
@ -143,18 +109,6 @@ func TestLoadTestPostsCommands(t *testing.T) {
|
|||
|
||||
utils.Cfg.ServiceSettings.EnableTesting = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel := &model.Channel{DisplayName: "00", Name: "00" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
rs := Client.Must(Client.Command(channel.Id, "/loadtest posts fuzz 2 3 2", false)).Data.(*model.CommandResponse)
|
||||
if rs.Text != "Adding posts..." {
|
||||
t.Fatal(rs.Text)
|
||||
|
|
@ -164,7 +118,10 @@ func TestLoadTestPostsCommands(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoadTestUrlCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
// enable testing to use /loadtest but don't save it since we don't want to overwrite config.json
|
||||
enableTesting := utils.Cfg.ServiceSettings.EnableTesting
|
||||
defer func() {
|
||||
|
|
@ -173,18 +130,6 @@ func TestLoadTestUrlCommands(t *testing.T) {
|
|||
|
||||
utils.Cfg.ServiceSettings.EnableTesting = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel := &model.Channel{DisplayName: "00", Name: "00" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
command := "/loadtest url "
|
||||
if r := Client.Must(Client.Command(channel.Id, command, false)).Data.(*model.CommandResponse); r.Text != "Command must contain a url" {
|
||||
t.Fatal("/loadtest url with no url should've failed")
|
||||
|
|
@ -223,7 +168,10 @@ func TestLoadTestUrlCommands(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoadTestJsonCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
// enable testing to use /loadtest but don't save it since we don't want to overwrite config.json
|
||||
enableTesting := utils.Cfg.ServiceSettings.EnableTesting
|
||||
defer func() {
|
||||
|
|
@ -232,18 +180,6 @@ func TestLoadTestJsonCommands(t *testing.T) {
|
|||
|
||||
utils.Cfg.ServiceSettings.EnableTesting = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel := &model.Channel{DisplayName: "00", Name: "00" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel = Client.Must(Client.CreateChannel(channel)).Data.(*model.Channel)
|
||||
|
||||
command := "/loadtest json "
|
||||
if r := Client.Must(Client.Command(channel.Id, command, false)).Data.(*model.CommandResponse); r.Text != "Command must contain a url" {
|
||||
t.Fatal("/loadtest url with no url should've failed")
|
||||
|
|
@ -255,9 +191,9 @@ func TestLoadTestJsonCommands(t *testing.T) {
|
|||
t.Fatal("/loadtest url with invalid url should've failed")
|
||||
}
|
||||
|
||||
command = "/loadtest url https://secure.beldienst.nl/test.json" // Chicken-egg so will replace with mattermost/platform URL soon
|
||||
command = "/loadtest json test-slack-attachments"
|
||||
if r := Client.Must(Client.Command(channel.Id, command, false)).Data.(*model.CommandResponse); r.Text != "Loading data..." {
|
||||
t.Fatal("/loadtest url for README.md should've executed")
|
||||
t.Fatal("/loadtest json should've executed")
|
||||
}
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
|
|
|||
|
|
@ -8,25 +8,12 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
)
|
||||
|
||||
func TestLogoutTestCommand(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "AA", Name: "aa" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
rs1 := Client.Must(Client.Command(channel1.Id, "/logout", false)).Data.(*model.CommandResponse)
|
||||
rs1 := th.BasicClient.Must(th.BasicClient.Command(th.BasicChannel.Id, "/logout", false)).Data.(*model.CommandResponse)
|
||||
if !strings.HasSuffix(rs1.GotoLocation, "logout") {
|
||||
t.Fatal("failed to logout")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,35 +8,24 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
)
|
||||
|
||||
func TestMeCommand(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "AA", Name: "aa" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testString := "/me hello"
|
||||
|
||||
r1 := Client.Must(Client.Command(channel1.Id, testString, false)).Data.(*model.CommandResponse)
|
||||
r1 := Client.Must(Client.Command(channel.Id, testString, false)).Data.(*model.CommandResponse)
|
||||
if r1 == nil {
|
||||
t.Fatal("Command failed to execute")
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
p1 := Client.Must(Client.GetPosts(channel1.Id, 0, 2, "")).Data.(*model.PostList)
|
||||
if len(p1.Order) != 1 {
|
||||
p1 := Client.Must(Client.GetPosts(channel.Id, 0, 2, "")).Data.(*model.PostList)
|
||||
if len(p1.Order) != 2 {
|
||||
t.Fatal("Command failed to send")
|
||||
} else {
|
||||
if p1.Posts[p1.Order[0]].Message != `*hello*` {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func (me *msgProvider) DoCommand(c *Context, channelId string, message string) *
|
|||
targetUser = strings.SplitN(message, " ", 2)[0]
|
||||
targetUser = strings.TrimPrefix(targetUser, "@")
|
||||
|
||||
if profileList := <-Srv.Store.User().GetProfiles(c.Session.TeamId); profileList.Err != nil {
|
||||
if profileList := <-Srv.Store.User().GetProfiles(c.TeamId); profileList.Err != nil {
|
||||
c.Err = profileList.Err
|
||||
return &model.CommandResponse{Text: c.T("api.command_msg.list.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||
} else {
|
||||
|
|
@ -62,7 +62,7 @@ func (me *msgProvider) DoCommand(c *Context, channelId string, message string) *
|
|||
//Find the channel based on this user
|
||||
channelName := model.GetDMNameFromIds(c.Session.UserId, userProfile.Id)
|
||||
|
||||
if channel := <-Srv.Store.Channel().GetByName(c.Session.TeamId, channelName); channel.Err != nil {
|
||||
if channel := <-Srv.Store.Channel().GetByName(c.TeamId, channelName); channel.Err != nil {
|
||||
if channel.Err.Id == "store.sql_channel.get_by_name.missing.app_error" {
|
||||
if directChannel, err := CreateDirectChannel(c, userProfile.Id); err != nil {
|
||||
c.Err = err
|
||||
|
|
@ -78,7 +78,7 @@ func (me *msgProvider) DoCommand(c *Context, channelId string, message string) *
|
|||
targetChannelId = channel.Data.(*model.Channel).Id
|
||||
}
|
||||
|
||||
makeDirectChannelVisible(c.Session.TeamId, targetChannelId)
|
||||
makeDirectChannelVisible(c.TeamId, targetChannelId)
|
||||
if len(parsedMessage) > 0 {
|
||||
post := &model.Post{}
|
||||
post.Message = parsedMessage
|
||||
|
|
@ -87,9 +87,11 @@ func (me *msgProvider) DoCommand(c *Context, channelId string, message string) *
|
|||
return &model.CommandResponse{Text: c.T("api.command_msg.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||
}
|
||||
}
|
||||
|
||||
return &model.CommandResponse{GotoLocation: c.GetTeamURL() + "/channels/" + channelName, Text: c.T("api.command_msg.success"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &model.CommandResponse{Text: c.T("api.command_msg.missing.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,39 +4,29 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
)
|
||||
|
||||
func TestMsgCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user1 := th.BasicUser
|
||||
user2 := th.BasicUser2
|
||||
user3 := th.CreateUser(th.BasicClient)
|
||||
LinkUserToTeam(user3, team)
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "success+test@simulator.amazonses.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
Client.Must(Client.CreateDirectChannel(user2.Id))
|
||||
Client.Must(Client.CreateDirectChannel(user3.Id))
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Username: "user1", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test2@simulator.amazonses.com", Nickname: "Corey Hulen 2", Username: "user2", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
user3 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test3@simulator.amazonses.com", Nickname: "Corey Hulen 3", Username: "user3", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
rs1 := Client.Must(Client.Command("", "/msg user2", false)).Data.(*model.CommandResponse)
|
||||
rs1 := Client.Must(Client.Command("", "/msg "+user2.Username, false)).Data.(*model.CommandResponse)
|
||||
if !strings.HasSuffix(rs1.GotoLocation, "/"+team.Name+"/channels/"+user1.Id+"__"+user2.Id) && !strings.HasSuffix(rs1.GotoLocation, "/"+team.Name+"/channels/"+user2.Id+"__"+user1.Id) {
|
||||
t.Fatal("failed to create direct channel")
|
||||
}
|
||||
|
||||
rs2 := Client.Must(Client.Command("", "/msg user3 foobar", false)).Data.(*model.CommandResponse)
|
||||
rs2 := Client.Must(Client.Command("", "/msg "+user3.Username+" foobar", false)).Data.(*model.CommandResponse)
|
||||
if !strings.HasSuffix(rs2.GotoLocation, "/"+team.Name+"/channels/"+user1.Id+"__"+user3.Id) && !strings.HasSuffix(rs2.GotoLocation, "/"+team.Name+"/channels/"+user3.Id+"__"+user1.Id) {
|
||||
t.Fatal("failed to create second direct channel")
|
||||
}
|
||||
|
|
@ -44,7 +34,7 @@ func TestMsgCommands(t *testing.T) {
|
|||
t.Fatalf("post did not get sent to direct message")
|
||||
}
|
||||
|
||||
rs3 := Client.Must(Client.Command("", "/msg user2", false)).Data.(*model.CommandResponse)
|
||||
rs3 := Client.Must(Client.Command("", "/msg "+user2.Username, false)).Data.(*model.CommandResponse)
|
||||
if !strings.HasSuffix(rs3.GotoLocation, "/"+team.Name+"/channels/"+user1.Id+"__"+user2.Id) && !strings.HasSuffix(rs3.GotoLocation, "/"+team.Name+"/channels/"+user2.Id+"__"+user1.Id) {
|
||||
t.Fatal("failed to go back to existing direct channel")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,35 +8,24 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
)
|
||||
|
||||
func TestShrugCommand(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "AA", Name: "aa" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testString := "/shrug"
|
||||
|
||||
r1 := Client.Must(Client.Command(channel1.Id, testString, false)).Data.(*model.CommandResponse)
|
||||
r1 := Client.Must(Client.Command(channel.Id, testString, false)).Data.(*model.CommandResponse)
|
||||
if r1 == nil {
|
||||
t.Fatal("Command failed to execute")
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
p1 := Client.Must(Client.GetPosts(channel1.Id, 0, 2, "")).Data.(*model.PostList)
|
||||
if len(p1.Order) != 1 {
|
||||
p1 := Client.Must(Client.GetPosts(channel.Id, 0, 2, "")).Data.(*model.PostList)
|
||||
if len(p1.Order) != 2 {
|
||||
t.Fatal("Command failed to send")
|
||||
} else {
|
||||
if p1.Posts[p1.Order[0]].Message != `¯\\\_(ツ)\_/¯` {
|
||||
|
|
|
|||
|
|
@ -8,21 +8,12 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
func TestListCommands(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
|
||||
if results, err := Client.ListCommands(); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -43,7 +34,10 @@ func TestListCommands(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateCommand(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
Client := th.BasicClient
|
||||
user := th.SystemAdminUser
|
||||
team := th.SystemAdminTeam
|
||||
|
||||
enableCommands := *utils.Cfg.ServiceSettings.EnableCommands
|
||||
defer func() {
|
||||
|
|
@ -51,26 +45,13 @@ func TestCreateCommand(t *testing.T) {
|
|||
}()
|
||||
*utils.Cfg.ServiceSettings.EnableCommands = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
cmd := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST}
|
||||
cmd := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST, Trigger: "trigger"}
|
||||
|
||||
if _, err := Client.CreateCommand(cmd); err == nil {
|
||||
t.Fatal("should have failed because not admin")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
Client = th.SystemAdminClient
|
||||
|
||||
var rcmd *model.Command
|
||||
if result, err := Client.CreateCommand(cmd); err != nil {
|
||||
|
|
@ -87,7 +68,7 @@ func TestCreateCommand(t *testing.T) {
|
|||
t.Fatal("team ids didn't match")
|
||||
}
|
||||
|
||||
cmd = &model.Command{CreatorId: "123", TeamId: "456", URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST}
|
||||
cmd = &model.Command{CreatorId: "123", TeamId: "456", URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST, Trigger: "trigger"}
|
||||
if result, err := Client.CreateCommand(cmd); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
|
|
@ -101,27 +82,16 @@ func TestCreateCommand(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestListTeamCommands(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
|
||||
enableCommands := *utils.Cfg.ServiceSettings.EnableCommands
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableCommands = &enableCommands
|
||||
}()
|
||||
*utils.Cfg.ServiceSettings.EnableCommands = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
cmd1 := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST}
|
||||
cmd1 := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST, Trigger: "trigger"}
|
||||
cmd1 = Client.Must(Client.CreateCommand(cmd1)).Data.(*model.Command)
|
||||
|
||||
if result, err := Client.ListTeamCommands(); err != nil {
|
||||
|
|
@ -136,27 +106,16 @@ func TestListTeamCommands(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRegenToken(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
|
||||
enableCommands := *utils.Cfg.ServiceSettings.EnableCommands
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableCommands = &enableCommands
|
||||
}()
|
||||
*utils.Cfg.ServiceSettings.EnableCommands = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey+test@test.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
cmd := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST}
|
||||
cmd := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST, Trigger: "trigger"}
|
||||
cmd = Client.Must(Client.CreateCommand(cmd)).Data.(*model.Command)
|
||||
|
||||
data := make(map[string]string)
|
||||
|
|
@ -172,27 +131,16 @@ func TestRegenToken(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteCommand(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
|
||||
enableCommands := *utils.Cfg.ServiceSettings.EnableCommands
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableCommands = &enableCommands
|
||||
}()
|
||||
*utils.Cfg.ServiceSettings.EnableCommands = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
cmd := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST}
|
||||
cmd := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST, Trigger: "trigger"}
|
||||
cmd = Client.Must(Client.CreateCommand(cmd)).Data.(*model.Command)
|
||||
|
||||
data := make(map[string]string)
|
||||
|
|
@ -209,31 +157,18 @@ func TestDeleteCommand(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTestCommand(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
channel1 := th.SystemAdminChannel
|
||||
|
||||
enableCommands := *utils.Cfg.ServiceSettings.EnableCommands
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableCommands = &enableCommands
|
||||
}()
|
||||
*utils.Cfg.ServiceSettings.EnableCommands = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "AA", Name: "aa" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
cmd1 := &model.Command{
|
||||
URL: "http://localhost" + utils.Cfg.ServiceSettings.ListenAddress + "/api/v1/commands/test",
|
||||
URL: "http://localhost" + utils.Cfg.ServiceSettings.ListenAddress + model.API_URL_SUFFIX + "/teams/command_test",
|
||||
Method: model.COMMAND_METHOD_POST,
|
||||
Trigger: "test",
|
||||
}
|
||||
|
|
@ -253,7 +188,7 @@ func TestTestCommand(t *testing.T) {
|
|||
}
|
||||
|
||||
cmd2 := &model.Command{
|
||||
URL: "http://localhost" + utils.Cfg.ServiceSettings.ListenAddress + "/api/v1/commands/test",
|
||||
URL: "http://localhost" + utils.Cfg.ServiceSettings.ListenAddress + model.API_URL_SUFFIX + "/teams/command_test",
|
||||
Method: model.COMMAND_METHOD_GET,
|
||||
Trigger: "test2",
|
||||
}
|
||||
|
|
|
|||
157
api/context.go
157
api/context.go
|
|
@ -11,10 +11,12 @@ import (
|
|||
"strings"
|
||||
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
goi18n "github.com/nicksnyder/go-i18n/i18n"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
goi18n "github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
||||
var sessionCache *utils.Cache = utils.NewLru(model.SESSION_CACHE_SIZE)
|
||||
|
|
@ -39,6 +41,7 @@ type Context struct {
|
|||
siteURL string
|
||||
T goi18n.TranslateFunc
|
||||
Locale string
|
||||
TeamId string
|
||||
}
|
||||
|
||||
func ApiAppHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
|
|
@ -94,6 +97,8 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
c.T, c.Locale = utils.GetTranslationsAndLocale(w, r)
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = GetIpAddress(r)
|
||||
c.TeamId = mux.Vars(r)["team_id"]
|
||||
h.isApi = IsApiCall(r)
|
||||
|
||||
token := ""
|
||||
isTokenFromQueryString := false
|
||||
|
|
@ -116,7 +121,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if (h.requireSystemAdmin || h.requireUser) && !h.trustRequester {
|
||||
if r.Header.Get(model.HEADER_REQUESTED_WITH) != model.HEADER_REQUESTED_WITH_XML {
|
||||
c.Err = model.NewLocAppError("ServeHTTP", "api.context.session_expired.app_error", nil, "token="+token)
|
||||
c.Err = model.NewLocAppError("ServeHTTP", "api.context.session_expired.app_error", nil, "token="+token+" Appears to bea CSRF attempt")
|
||||
token = ""
|
||||
}
|
||||
}
|
||||
|
|
@ -182,6 +187,10 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
c.SystemAdminRequired()
|
||||
}
|
||||
|
||||
if c.Err == nil && len(c.TeamId) > 0 {
|
||||
c.HasPermissionsToTeam(c.TeamId, "TeamRoute")
|
||||
}
|
||||
|
||||
if c.Err == nil && h.isUserActivity && token != "" && len(c.Session.UserId) > 0 {
|
||||
go func() {
|
||||
if err := (<-Srv.Store.User().UpdateUserAndSessionActivity(c.Session.UserId, c.Session.Id, model.GetMillis())).Err; err != nil {
|
||||
|
|
@ -308,13 +317,14 @@ func (c *Context) HasPermissionsToUser(userId string, where string) bool {
|
|||
}
|
||||
|
||||
func (c *Context) HasPermissionsToTeam(teamId string, where string) bool {
|
||||
if c.Session.TeamId == teamId {
|
||||
if c.IsSystemAdmin() {
|
||||
return true
|
||||
}
|
||||
|
||||
// You're a mattermost system admin and you're on the VPN
|
||||
if c.IsSystemAdmin() {
|
||||
return true
|
||||
for _, teamMember := range c.Session.TeamMembers {
|
||||
if teamId == teamMember.TeamId {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
c.Err = model.NewLocAppError(where, "api.context.permissions.app_error", nil, "userId="+c.Session.UserId+", teamId="+teamId)
|
||||
|
|
@ -353,10 +363,17 @@ func (c *Context) IsSystemAdmin() bool {
|
|||
}
|
||||
|
||||
func (c *Context) IsTeamAdmin() bool {
|
||||
if model.IsInRole(c.Session.Roles, model.ROLE_TEAM_ADMIN) || c.IsSystemAdmin() {
|
||||
|
||||
if c.IsSystemAdmin() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
team := c.Session.GetTeamByTeamId(c.TeamId)
|
||||
if team == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return model.IsInRole(team.Roles, model.ROLE_TEAM_ADMIN)
|
||||
}
|
||||
|
||||
func (c *Context) RemoveSessionCookie(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -386,7 +403,7 @@ func (c *Context) setTeamURL(url string, valid bool) {
|
|||
}
|
||||
|
||||
func (c *Context) SetTeamURLFromSession() {
|
||||
if result := <-Srv.Store.Team().Get(c.Session.TeamId); result.Err == nil {
|
||||
if result := <-Srv.Store.Team().Get(c.TeamId); result.Err == nil {
|
||||
c.setTeamURL(c.GetSiteURL()+"/"+result.Data.(*model.Team).Name, true)
|
||||
}
|
||||
}
|
||||
|
|
@ -413,6 +430,10 @@ func (c *Context) GetSiteURL() string {
|
|||
return c.siteURL
|
||||
}
|
||||
|
||||
func IsApiCall(r *http.Request) bool {
|
||||
return strings.Index(r.URL.Path, "/api/") == 0
|
||||
}
|
||||
|
||||
func GetIpAddress(r *http.Request) string {
|
||||
address := r.Header.Get(model.HEADER_FORWARDED)
|
||||
|
||||
|
|
@ -427,69 +448,69 @@ func GetIpAddress(r *http.Request) string {
|
|||
return address
|
||||
}
|
||||
|
||||
func IsTestDomain(r *http.Request) bool {
|
||||
// func IsTestDomain(r *http.Request) bool {
|
||||
|
||||
if strings.Index(r.Host, "localhost") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "localhost") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
if strings.Index(r.Host, "dockerhost") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "dockerhost") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
if strings.Index(r.Host, "test") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "test") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
if strings.Index(r.Host, "127.0.") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "127.0.") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
if strings.Index(r.Host, "192.168.") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "192.168.") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
if strings.Index(r.Host, "10.") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "10.") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
if strings.Index(r.Host, "176.") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "176.") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
return false
|
||||
}
|
||||
// return false
|
||||
// }
|
||||
|
||||
func IsBetaDomain(r *http.Request) bool {
|
||||
// func IsBetaDomain(r *http.Request) bool {
|
||||
|
||||
if strings.Index(r.Host, "beta") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "beta") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
if strings.Index(r.Host, "ci") == 0 {
|
||||
return true
|
||||
}
|
||||
// if strings.Index(r.Host, "ci") == 0 {
|
||||
// return true
|
||||
// }
|
||||
|
||||
return false
|
||||
}
|
||||
// return false
|
||||
// }
|
||||
|
||||
var privateIpAddress = []*net.IPNet{
|
||||
{IP: net.IPv4(10, 0, 0, 1), Mask: net.IPv4Mask(255, 0, 0, 0)},
|
||||
{IP: net.IPv4(176, 16, 0, 1), Mask: net.IPv4Mask(255, 255, 0, 0)},
|
||||
{IP: net.IPv4(192, 168, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 0)},
|
||||
{IP: net.IPv4(127, 0, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 252)},
|
||||
}
|
||||
// var privateIpAddress = []*net.IPNet{
|
||||
// {IP: net.IPv4(10, 0, 0, 1), Mask: net.IPv4Mask(255, 0, 0, 0)},
|
||||
// {IP: net.IPv4(176, 16, 0, 1), Mask: net.IPv4Mask(255, 255, 0, 0)},
|
||||
// {IP: net.IPv4(192, 168, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 0)},
|
||||
// {IP: net.IPv4(127, 0, 0, 1), Mask: net.IPv4Mask(255, 255, 255, 252)},
|
||||
// }
|
||||
|
||||
func IsPrivateIpAddress(ipAddress string) bool {
|
||||
// func IsPrivateIpAddress(ipAddress string) bool {
|
||||
|
||||
for _, pips := range privateIpAddress {
|
||||
if pips.Contains(net.ParseIP(ipAddress)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// for _, pips := range privateIpAddress {
|
||||
// if pips.Contains(net.ParseIP(ipAddress)) {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
|
||||
return false
|
||||
}
|
||||
// return false
|
||||
// }
|
||||
|
||||
func RenderWebError(err *model.AppError, w http.ResponseWriter, r *http.Request) {
|
||||
T, _ := utils.GetTranslationsAndLocale(w, r)
|
||||
|
|
@ -513,9 +534,17 @@ func RenderWebError(err *model.AppError, w http.ResponseWriter, r *http.Request)
|
|||
|
||||
func Handle404(w http.ResponseWriter, r *http.Request) {
|
||||
err := model.NewLocAppError("Handle404", "api.context.404.app_error", nil, "")
|
||||
err.Translate(utils.T)
|
||||
err.StatusCode = http.StatusNotFound
|
||||
l4g.Error("%v: code=404 ip=%v", r.URL.Path, GetIpAddress(r))
|
||||
RenderWebError(err, w, r)
|
||||
|
||||
if IsApiCall(r) {
|
||||
w.WriteHeader(err.StatusCode)
|
||||
err.DetailedError = "There doesn't appear to be an api call for the url='" + r.URL.Path + "'. Typo? are you missing a team_id or user_id as part of the url?"
|
||||
w.Write([]byte(err.ToJson()))
|
||||
} else {
|
||||
RenderWebError(err, w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func GetSession(token string) *model.Session {
|
||||
|
|
@ -542,6 +571,20 @@ func GetSession(token string) *model.Session {
|
|||
return session
|
||||
}
|
||||
|
||||
func RemoveAllSessionsForUserId(userId string) {
|
||||
|
||||
keys := sessionCache.Keys()
|
||||
|
||||
for _, key := range keys {
|
||||
if ts, ok := sessionCache.Get(key); ok {
|
||||
session := ts.(*model.Session)
|
||||
if session.UserId == userId {
|
||||
sessionCache.Remove(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AddSessionToCache(session *model.Session) {
|
||||
sessionCache.AddWithExpiresInSecs(session.Token, session, int64(*utils.Cfg.ServiceSettings.SessionCacheInMinutes*60))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,32 +8,6 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
var ipAddressTests = []struct {
|
||||
address string
|
||||
expected bool
|
||||
}{
|
||||
{"126.255.255.255", false},
|
||||
{"127.0.0.1", true},
|
||||
{"127.0.0.4", false},
|
||||
{"9.255.255.255", false},
|
||||
{"10.0.0.1", true},
|
||||
{"11.0.0.1", false},
|
||||
{"176.15.155.255", false},
|
||||
{"176.16.0.1", true},
|
||||
{"176.31.0.1", false},
|
||||
{"192.167.255.255", false},
|
||||
{"192.168.0.1", true},
|
||||
{"192.169.0.1", false},
|
||||
}
|
||||
|
||||
func TestIpAddress(t *testing.T) {
|
||||
for _, v := range ipAddressTests {
|
||||
if IsPrivateIpAddress(v.address) != v.expected {
|
||||
t.Errorf("expect %v as %v", v.address, v.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext(t *testing.T) {
|
||||
context := Context{}
|
||||
|
||||
|
|
@ -52,9 +26,26 @@ func TestContext(t *testing.T) {
|
|||
if !context.HasPermissionsToUser("6", "") {
|
||||
t.Fatal("should have permissions")
|
||||
}
|
||||
|
||||
// context.IpAddress = "125.0.0.1"
|
||||
// if context.HasPermissionsToUser("6", "") {
|
||||
// t.Fatal("shouldn't have permissions")
|
||||
// }
|
||||
}
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
session := &model.Session{
|
||||
Id: model.NewId(),
|
||||
Token: model.NewId(),
|
||||
UserId: model.NewId(),
|
||||
}
|
||||
|
||||
sessionCache.AddWithExpiresInSecs(session.Token, session, 5*60)
|
||||
|
||||
keys := sessionCache.Keys()
|
||||
if len(keys) <= 0 {
|
||||
t.Fatal("should have items")
|
||||
}
|
||||
|
||||
RemoveAllSessionsForUserId(session.UserId)
|
||||
|
||||
rkeys := sessionCache.Keys()
|
||||
if len(rkeys) != len(keys)-1 {
|
||||
t.Fatal("should have one less")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ func ExportToFile(options *ExportOptions) (link string, err *model.AppError) {
|
|||
ExportToWriter(file, options)
|
||||
}
|
||||
|
||||
return "/api/v1/files/get_export", nil
|
||||
return model.API_URL_SUFFIX + "/files/get_export", nil
|
||||
}
|
||||
|
||||
func ExportToWriter(w io.Writer, options *ExportOptions) *model.AppError {
|
||||
|
|
|
|||
34
api/file.go
34
api/file.go
|
|
@ -57,15 +57,14 @@ const (
|
|||
|
||||
var fileInfoCache *utils.Cache = utils.NewLru(1000)
|
||||
|
||||
func InitFile(r *mux.Router) {
|
||||
func InitFile() {
|
||||
l4g.Debug(utils.T("api.file.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/files").Subrouter()
|
||||
sr.Handle("/upload", ApiUserRequired(uploadFile)).Methods("POST")
|
||||
sr.Handle("/get/{channel_id:[A-Za-z0-9]+}/{user_id:[A-Za-z0-9]+}/{filename:([A-Za-z0-9]+/)?.+(\\.[A-Za-z0-9]{3,})?}", ApiAppHandlerTrustRequester(getFile)).Methods("GET")
|
||||
sr.Handle("/get_info/{channel_id:[A-Za-z0-9]+}/{user_id:[A-Za-z0-9]+}/{filename:([A-Za-z0-9]+/)?.+(\\.[A-Za-z0-9]{3,})?}", ApiAppHandler(getFileInfo)).Methods("GET")
|
||||
sr.Handle("/get_public_link", ApiUserRequired(getPublicLink)).Methods("POST")
|
||||
sr.Handle("/get_export", ApiUserRequired(getExport)).Methods("GET")
|
||||
BaseRoutes.Files.Handle("/upload", ApiUserRequired(uploadFile)).Methods("POST")
|
||||
BaseRoutes.Files.Handle("/get/{channel_id:[A-Za-z0-9]+}/{user_id:[A-Za-z0-9]+}/{filename:([A-Za-z0-9]+/)?.+(\\.[A-Za-z0-9]{3,})?}", ApiAppHandlerTrustRequester(getFile)).Methods("GET")
|
||||
BaseRoutes.Files.Handle("/get_info/{channel_id:[A-Za-z0-9]+}/{user_id:[A-Za-z0-9]+}/{filename:([A-Za-z0-9]+/)?.+(\\.[A-Za-z0-9]{3,})?}", ApiAppHandler(getFileInfo)).Methods("GET")
|
||||
BaseRoutes.Files.Handle("/get_public_link", ApiUserRequired(getPublicLink)).Methods("POST")
|
||||
BaseRoutes.Files.Handle("/get_export", ApiUserRequired(getExport)).Methods("GET")
|
||||
}
|
||||
|
||||
func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -101,7 +100,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
|
||||
|
||||
files := m.File["files"]
|
||||
|
||||
|
|
@ -147,7 +146,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
path := "teams/" + c.Session.TeamId + "/channels/" + channelId + "/users/" + c.Session.UserId + "/" + uid + "/" + filename
|
||||
path := "teams/" + c.TeamId + "/channels/" + channelId + "/users/" + c.Session.UserId + "/" + uid + "/" + filename
|
||||
|
||||
if err := WriteFile(buf.Bytes(), path); err != nil {
|
||||
c.Err = err
|
||||
|
|
@ -164,7 +163,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
resStruct.ClientIds = append(resStruct.ClientIds, clientId)
|
||||
}
|
||||
|
||||
handleImagesAndForget(imageNameList, imageDataList, c.Session.TeamId, channelId, c.Session.UserId)
|
||||
handleImagesAndForget(imageNameList, imageDataList, c.TeamId, channelId, c.Session.UserId)
|
||||
|
||||
w.Write([]byte(resStruct.ToJson()))
|
||||
}
|
||||
|
|
@ -319,9 +318,9 @@ func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
|
||||
|
||||
path := "teams/" + c.Session.TeamId + "/channels/" + channelId + "/users/" + userId + "/" + filename
|
||||
path := "teams/" + c.TeamId + "/channels/" + channelId + "/users/" + userId + "/" + filename
|
||||
var info *model.FileInfo
|
||||
|
||||
if cached, ok := fileInfoCache.Get(path); ok {
|
||||
|
|
@ -380,13 +379,13 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
data := r.URL.Query().Get("d")
|
||||
teamId := r.URL.Query().Get("t")
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
|
||||
|
||||
path := ""
|
||||
if len(teamId) == 26 {
|
||||
path = "teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/" + filename
|
||||
} else {
|
||||
path = "teams/" + c.Session.TeamId + "/channels/" + channelId + "/users/" + userId + "/" + filename
|
||||
path = "teams/" + c.TeamId + "/channels/" + channelId + "/users/" + userId + "/" + filename
|
||||
}
|
||||
|
||||
fileData := make(chan []byte)
|
||||
|
|
@ -460,6 +459,7 @@ func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
if !utils.Cfg.FileSettings.EnablePublicLink {
|
||||
c.Err = model.NewLocAppError("getPublicLink", "api.file.get_public_link.disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
props := model.MapFromJson(r.Body)
|
||||
|
|
@ -480,7 +480,7 @@ func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
userId := matches[0][2]
|
||||
filename = matches[0][3]
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
|
||||
|
||||
newProps := make(map[string]string)
|
||||
newProps["filename"] = filename
|
||||
|
|
@ -488,7 +488,7 @@ func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
data := model.MapToJson(newProps)
|
||||
hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.FileSettings.PublicLinkSalt))
|
||||
|
||||
url := fmt.Sprintf("%s/api/v1/files/get/%s/%s/%s?d=%s&h=%s&t=%s", c.GetSiteURL(), channelId, userId, filename, url.QueryEscape(data), url.QueryEscape(hash), c.Session.TeamId)
|
||||
url := fmt.Sprintf("%s/files/get/%s/%s/%s?d=%s&h=%s&t=%s", c.GetSiteURL()+model.API_URL_SUFFIX, channelId, userId, filename, url.QueryEscape(data), url.QueryEscape(hash), c.TeamId)
|
||||
|
||||
if !c.HasPermissionsToChannel(cchan, "getPublicLink") {
|
||||
return
|
||||
|
|
@ -501,7 +501,7 @@ func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func getExport(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.HasPermissionsToTeam(c.Session.TeamId, "export") || !c.IsTeamAdmin() {
|
||||
if !c.HasPermissionsToTeam(c.TeamId, "export") || !c.IsTeamAdmin() {
|
||||
c.Err = model.NewLocAppError("getExport", "api.file.get_export.team_admin.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ import (
|
|||
)
|
||||
|
||||
func BenchmarkUploadFile(b *testing.B) {
|
||||
_, _, channel := SetupBenchmark()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
|
||||
|
|
@ -25,7 +27,10 @@ func BenchmarkUploadFile(b *testing.B) {
|
|||
}
|
||||
|
||||
func BenchmarkGetFile(b *testing.B) {
|
||||
team, _, channel := SetupBenchmark()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
filenames, err := testPoster.UploadTestFile()
|
||||
|
|
@ -53,7 +58,9 @@ func BenchmarkGetFile(b *testing.B) {
|
|||
}
|
||||
|
||||
func BenchmarkGetPublicLink(b *testing.B) {
|
||||
_, _, channel := SetupBenchmark()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
filenames, err := testPoster.UploadTestFile()
|
||||
|
|
|
|||
124
api/file_test.go
124
api/file_test.go
|
|
@ -22,19 +22,11 @@ import (
|
|||
)
|
||||
|
||||
func TestUploadFile(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user := th.BasicUser
|
||||
channel := th.BasicChannel
|
||||
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
|
@ -45,6 +37,9 @@ func TestUploadFile(t *testing.T) {
|
|||
|
||||
path := utils.FindDir("tests")
|
||||
file, err := os.Open(path + "/test.png")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(part, file)
|
||||
|
|
@ -57,7 +52,7 @@ func TestUploadFile(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = field.Write([]byte(channel1.Id))
|
||||
_, err = field.Write([]byte(channel.Id))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -67,7 +62,7 @@ func TestUploadFile(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, appErr := Client.UploadFile("/files/upload", body.Bytes(), writer.FormDataContentType())
|
||||
resp, appErr := Client.UploadPostAttachment(body.Bytes(), writer.FormDataContentType())
|
||||
if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_S3 {
|
||||
if appErr != nil {
|
||||
t.Fatal(appErr)
|
||||
|
|
@ -90,17 +85,17 @@ func TestUploadFile(t *testing.T) {
|
|||
// wait a bit for files to ready
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + filename)
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_thumb.jpg")
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_thumb.jpg")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_preview.jpg")
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_preview.jpg")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -115,17 +110,17 @@ func TestUploadFile(t *testing.T) {
|
|||
// wait a bit for files to ready
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
path := utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + filename
|
||||
path := utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + filename
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_thumb.jpg"
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_thumb.jpg"
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_preview.jpg"
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_preview.jpg"
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
|
@ -137,25 +132,18 @@ func TestUploadFile(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetFile(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user := th.BasicUser
|
||||
channel := th.BasicChannel
|
||||
|
||||
enablePublicLink := utils.Cfg.FileSettings.EnablePublicLink
|
||||
defer func() {
|
||||
utils.Cfg.FileSettings.EnablePublicLink = enablePublicLink
|
||||
}()
|
||||
utils.Cfg.FileSettings.EnablePublicLink = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
if utils.Cfg.FileSettings.DriverName != "" {
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
|
@ -181,7 +169,7 @@ func TestGetFile(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = field.Write([]byte(channel1.Id))
|
||||
_, err = field.Write([]byte(channel.Id))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -191,7 +179,7 @@ func TestGetFile(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, upErr := Client.UploadFile("/files/upload", body.Bytes(), writer.FormDataContentType())
|
||||
resp, upErr := Client.UploadPostAttachment(body.Bytes(), writer.FormDataContentType())
|
||||
if upErr != nil {
|
||||
t.Fatal(upErr)
|
||||
}
|
||||
|
|
@ -217,8 +205,9 @@ func TestGetFile(t *testing.T) {
|
|||
team2 := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
|
||||
|
||||
user2 := &model.User{TeamId: team2.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user2, team2)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
newProps := make(map[string]string)
|
||||
|
|
@ -229,6 +218,7 @@ func TestGetFile(t *testing.T) {
|
|||
hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.FileSettings.PublicLinkSalt))
|
||||
|
||||
Client.LoginByEmail(team2.Name, user2.Email, "pwd")
|
||||
Client.SetTeamId(team2.Id)
|
||||
|
||||
if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&h="+url.QueryEscape(hash)+"&t="+team.Id, false); downErr != nil {
|
||||
t.Fatal(downErr)
|
||||
|
|
@ -278,17 +268,17 @@ func TestGetFile(t *testing.T) {
|
|||
filename := filenames[len(filenames)-2] + "/" + filenames[len(filenames)-1]
|
||||
fileId := strings.Split(filename, ".")[0]
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + filename)
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_thumb.jpg")
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_thumb.jpg")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_preview.jpg")
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_preview.jpg")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -297,17 +287,17 @@ func TestGetFile(t *testing.T) {
|
|||
filename := filenames[len(filenames)-2] + "/" + filenames[len(filenames)-1]
|
||||
fileId := strings.Split(filename, ".")[0]
|
||||
|
||||
path := utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + filename
|
||||
path := utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + filename
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_thumb.jpg"
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_thumb.jpg"
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_preview.jpg"
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_preview.jpg"
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
|
@ -320,25 +310,18 @@ func TestGetFile(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetPublicLink(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user := th.BasicUser
|
||||
channel := th.BasicChannel
|
||||
|
||||
if utils.Cfg.FileSettings.DriverName != "" {
|
||||
enablePublicLink := utils.Cfg.FileSettings.EnablePublicLink
|
||||
defer func() {
|
||||
utils.Cfg.FileSettings.EnablePublicLink = enablePublicLink
|
||||
}()
|
||||
utils.Cfg.FileSettings.EnablePublicLink = true
|
||||
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
|
@ -364,7 +347,7 @@ func TestGetPublicLink(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = field.Write([]byte(channel1.Id))
|
||||
_, err = field.Write([]byte(channel.Id))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -374,14 +357,14 @@ func TestGetPublicLink(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, upErr := Client.UploadFile("/files/upload", body.Bytes(), writer.FormDataContentType())
|
||||
resp, upErr := Client.UploadPostAttachment(body.Bytes(), writer.FormDataContentType())
|
||||
if upErr != nil {
|
||||
t.Fatal(upErr)
|
||||
}
|
||||
|
||||
filenames := resp.Data.(*model.FileUploadResponse).Filenames
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a", Filenames: filenames}
|
||||
post1 := &model.Post{ChannelId: channel.Id, Message: "a" + model.NewId() + "a", Filenames: filenames}
|
||||
|
||||
rpost1, postErr := Client.CreatePost(post1)
|
||||
if postErr != nil {
|
||||
|
|
@ -408,7 +391,8 @@ func TestGetPublicLink(t *testing.T) {
|
|||
t.Fatal("Should have errored - bad file path")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
data["filename"] = filenames[0]
|
||||
if _, err := Client.GetPublicLink(data); err == nil {
|
||||
t.Fatal("should have errored, user not member of channel")
|
||||
|
|
@ -427,17 +411,17 @@ func TestGetPublicLink(t *testing.T) {
|
|||
filename := filenames[len(filenames)-2] + "/" + filenames[len(filenames)-1]
|
||||
fileId := strings.Split(filename, ".")[0]
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + filename)
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_thumb.jpg")
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_thumb.jpg")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_preview.jpg")
|
||||
err = bucket.Del("teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_preview.jpg")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -446,17 +430,17 @@ func TestGetPublicLink(t *testing.T) {
|
|||
filename := filenames[len(filenames)-2] + "/" + filenames[len(filenames)-1]
|
||||
fileId := strings.Split(filename, ".")[0]
|
||||
|
||||
path := utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + filename
|
||||
path := utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + filename
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_thumb.jpg"
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_thumb.jpg"
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_preview.jpg"
|
||||
path = utils.Cfg.FileSettings.Directory + "teams/" + team.Id + "/channels/" + channel.Id + "/users/" + user.Id + "/" + fileId + "_preview.jpg"
|
||||
if err := os.Remove(path); err != nil {
|
||||
t.Fatal("Couldn't remove file at " + path)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ func ImportPost(post *model.Post) {
|
|||
}
|
||||
}
|
||||
|
||||
func ImportUser(user *model.User) *model.User {
|
||||
func ImportUser(teamId string, user *model.User) *model.User {
|
||||
user.MakeNonNil()
|
||||
|
||||
if result := <-Srv.Store.User().Save(user); result.Err != nil {
|
||||
|
|
@ -31,8 +31,8 @@ func ImportUser(user *model.User) *model.User {
|
|||
} else {
|
||||
ruser := result.Data.(*model.User)
|
||||
|
||||
if err := JoinDefaultChannels(ruser, ""); err != nil {
|
||||
l4g.Error(utils.T("api.import.import_user.joining_default.error"), ruser.Id, ruser.TeamId, err)
|
||||
if err := JoinDefaultChannels(teamId, ruser, ""); err != nil {
|
||||
l4g.Error(utils.T("api.import.import_user.joining_default.error"), ruser.Id, teamId, err)
|
||||
}
|
||||
|
||||
if cresult := <-Srv.Store.User().VerifyEmail(ruser.Id); cresult.Err != nil {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ package api
|
|||
import (
|
||||
"bytes"
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"io"
|
||||
|
|
@ -19,13 +18,12 @@ const (
|
|||
INVALID_LICENSE_ERROR = "api.license.add_license.invalid.app_error"
|
||||
)
|
||||
|
||||
func InitLicense(r *mux.Router) {
|
||||
func InitLicense() {
|
||||
l4g.Debug(utils.T("api.license.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/license").Subrouter()
|
||||
sr.Handle("/add", ApiAdminSystemRequired(addLicense)).Methods("POST")
|
||||
sr.Handle("/remove", ApiAdminSystemRequired(removeLicense)).Methods("POST")
|
||||
sr.Handle("/client_config", ApiAppHandler(getClientLicenceConfig)).Methods("GET")
|
||||
BaseRoutes.License.Handle("/add", ApiAdminSystemRequired(addLicense)).Methods("POST")
|
||||
BaseRoutes.License.Handle("/remove", ApiAdminSystemRequired(removeLicense)).Methods("POST")
|
||||
BaseRoutes.License.Handle("/client_config", ApiAppHandler(getClientLicenceConfig)).Methods("GET")
|
||||
}
|
||||
|
||||
func LoadLicense() {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ import (
|
|||
)
|
||||
|
||||
func TestGetLicenceConfig(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
|
||||
if result, err := Client.GetClientLicenceConfig(""); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
|||
256
api/oauth.go
256
api/oauth.go
|
|
@ -4,7 +4,10 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
b64 "encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
|
@ -12,31 +15,29 @@ import (
|
|||
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/platform/einterfaces"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
func InitOAuth(r *mux.Router) {
|
||||
func InitOAuth() {
|
||||
l4g.Debug(utils.T("api.oauth.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/oauth").Subrouter()
|
||||
BaseRoutes.OAuth.Handle("/register", ApiUserRequired(registerOAuthApp)).Methods("POST")
|
||||
BaseRoutes.OAuth.Handle("/allow", ApiUserRequired(allowOAuth)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/{service:[A-Za-z]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/{service:[A-Za-z]+}/login", AppHandlerIndependent(loginWithOAuth)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/{service:[A-Za-z]+}/signup", AppHandlerIndependent(signupWithOAuth)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/authorize", ApiUserRequired(authorizeOAuth)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/access_token", ApiAppHandler(getAccessToken)).Methods("POST")
|
||||
|
||||
sr.Handle("/register", ApiUserRequired(registerOAuthApp)).Methods("POST")
|
||||
sr.Handle("/allow", ApiUserRequired(allowOAuth)).Methods("GET")
|
||||
sr.Handle("/{service:[A-Za-z]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
sr.Handle("/{service:[A-Za-z]+}/login", AppHandlerIndependent(loginWithOAuth)).Methods("GET")
|
||||
sr.Handle("/{service:[A-Za-z]+}/signup", AppHandlerIndependent(signupWithOAuth)).Methods("GET")
|
||||
sr.Handle("/authorize", ApiUserRequired(authorizeOAuth)).Methods("GET")
|
||||
sr.Handle("/access_token", ApiAppHandler(getAccessToken)).Methods("POST")
|
||||
|
||||
mr := Srv.Router
|
||||
mr.Handle("/authorize", ApiUserRequired(authorizeOAuth)).Methods("GET")
|
||||
mr.Handle("/access_token", ApiAppHandler(getAccessToken)).Methods("POST")
|
||||
BaseRoutes.Root.Handle("/authorize", ApiUserRequired(authorizeOAuth)).Methods("GET")
|
||||
BaseRoutes.Root.Handle("/access_token", ApiAppHandler(getAccessToken)).Methods("POST")
|
||||
|
||||
// Handle all the old routes, to be later removed
|
||||
mr.Handle("/{service:[A-Za-z]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
mr.Handle("/signup/{service:[A-Za-z]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
mr.Handle("/login/{service:[A-Za-z]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
BaseRoutes.Root.Handle("/{service:[A-Za-z]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
BaseRoutes.Root.Handle("/signup/{service:[A-Za-z]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
BaseRoutes.Root.Handle("/login/{service:[A-Za-z]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
}
|
||||
|
||||
func registerOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -190,40 +191,40 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
uri := c.GetSiteURL() + "/signup/" + service + "/complete"
|
||||
|
||||
if body, team, props, err := AuthorizeOAuthUser(service, code, state, uri); err != nil {
|
||||
if body, teamId, props, err := AuthorizeOAuthUser(service, code, state, uri); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
} else {
|
||||
action := props["action"]
|
||||
switch action {
|
||||
case model.OAUTH_ACTION_SIGNUP:
|
||||
CreateOAuthUser(c, w, r, service, body, team)
|
||||
CreateOAuthUser(c, w, r, service, body, teamId)
|
||||
if c.Err == nil {
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host+"/"+team.Name, http.StatusTemporaryRedirect)
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host, http.StatusTemporaryRedirect)
|
||||
}
|
||||
break
|
||||
case model.OAUTH_ACTION_LOGIN:
|
||||
LoginByOAuth(c, w, r, service, body, team)
|
||||
LoginByOAuth(c, w, r, service, body)
|
||||
if c.Err == nil {
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host+"/"+team.Name, http.StatusTemporaryRedirect)
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host, http.StatusTemporaryRedirect)
|
||||
}
|
||||
break
|
||||
case model.OAUTH_ACTION_EMAIL_TO_SSO:
|
||||
CompleteSwitchWithOAuth(c, w, r, service, body, team, props["email"])
|
||||
CompleteSwitchWithOAuth(c, w, r, service, body, props["email"])
|
||||
if c.Err == nil {
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host+"/"+team.Name+"/login?extra=signin_change", http.StatusTemporaryRedirect)
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host+"/login?extra=signin_change", http.StatusTemporaryRedirect)
|
||||
}
|
||||
break
|
||||
case model.OAUTH_ACTION_SSO_TO_EMAIL:
|
||||
LoginByOAuth(c, w, r, service, body, team)
|
||||
LoginByOAuth(c, w, r, service, body)
|
||||
if c.Err == nil {
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host+"/"+team.Name+"/"+"/claim?email="+url.QueryEscape(props["email"]), http.StatusTemporaryRedirect)
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host+"/claim?email="+url.QueryEscape(props["email"]), http.StatusTemporaryRedirect)
|
||||
}
|
||||
break
|
||||
default:
|
||||
LoginByOAuth(c, w, r, service, body, team)
|
||||
LoginByOAuth(c, w, r, service, body)
|
||||
if c.Err == nil {
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host+"/"+team.Name, http.StatusTemporaryRedirect)
|
||||
http.Redirect(w, r, GetProtocol(r)+"://"+r.Host, http.StatusTemporaryRedirect)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
|
@ -257,7 +258,7 @@ func authorizeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
var team *model.Team
|
||||
if result := <-Srv.Store.Team().Get(c.Session.TeamId); result.Err != nil {
|
||||
if result := <-Srv.Store.Team().Get(c.TeamId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
|
|
@ -389,7 +390,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
user = result.Data.(*model.User)
|
||||
}
|
||||
|
||||
session := &model.Session{UserId: user.Id, TeamId: user.TeamId, Roles: user.Roles, IsOAuth: true}
|
||||
session := &model.Session{UserId: user.Id, Roles: user.Roles, IsOAuth: true}
|
||||
|
||||
if result := <-Srv.Store.Session().Save(session); result.Err != nil {
|
||||
c.Err = model.NewLocAppError("getAccessToken", "web.get_access_token.internal_session.app_error", nil, "")
|
||||
|
|
@ -422,24 +423,11 @@ func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
params := mux.Vars(r)
|
||||
service := params["service"]
|
||||
loginHint := r.URL.Query().Get("login_hint")
|
||||
teamName := r.URL.Query().Get("team")
|
||||
|
||||
if len(teamName) == 0 {
|
||||
c.Err = model.NewLocAppError("loginWithOAuth", "web.login_with_oauth.invalid_team.app_error", nil, "team_name="+teamName)
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
// Make sure team exists
|
||||
if result := <-Srv.Store.Team().GetByName(teamName); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
}
|
||||
|
||||
stateProps := map[string]string{}
|
||||
stateProps["action"] = model.OAUTH_ACTION_LOGIN
|
||||
|
||||
if authUrl, err := GetAuthorizationCode(c, service, teamName, stateProps, loginHint); err != nil {
|
||||
if authUrl, err := GetAuthorizationCode(c, service, stateProps, loginHint); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
} else {
|
||||
|
|
@ -450,31 +438,19 @@ func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
service := params["service"]
|
||||
teamName := r.URL.Query().Get("team")
|
||||
|
||||
if !utils.Cfg.TeamSettings.EnableUserCreation {
|
||||
c.Err = model.NewLocAppError("signupTeam", "web.singup_with_oauth.disabled.app_error", nil, "")
|
||||
c.Err = model.NewLocAppError("signupWithOAuth", "web.singup_with_oauth.disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
|
||||
if len(teamName) == 0 {
|
||||
c.Err = model.NewLocAppError("signupWithOAuth", "web.singup_with_oauth.invalid_team.app_error", nil, "team_name="+teamName)
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
hash := r.URL.Query().Get("h")
|
||||
|
||||
var team *model.Team
|
||||
if result := <-Srv.Store.Team().GetByName(teamName); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
teamId := ""
|
||||
inviteId := r.URL.Query().Get("id")
|
||||
|
||||
if IsVerifyHashRequired(nil, team, hash) {
|
||||
if len(hash) > 0 {
|
||||
data := r.URL.Query().Get("d")
|
||||
props := model.MapFromJson(strings.NewReader(data))
|
||||
|
||||
|
|
@ -489,19 +465,173 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if team.Id != props["id"] {
|
||||
c.Err = model.NewLocAppError("signupWithOAuth", "web.singup_with_oauth.invalid_team.app_error", nil, data)
|
||||
return
|
||||
teamId = props["id"]
|
||||
} else if len(inviteId) != 0 {
|
||||
if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
|
||||
// soft fail, so we still create user but don't auto-join team
|
||||
l4g.Error("%v", result.Err)
|
||||
} else {
|
||||
teamId = result.Data.(*model.Team).Id
|
||||
}
|
||||
}
|
||||
|
||||
stateProps := map[string]string{}
|
||||
stateProps["action"] = model.OAUTH_ACTION_SIGNUP
|
||||
if len(teamId) != 0 {
|
||||
stateProps["team_id"] = teamId
|
||||
}
|
||||
|
||||
if authUrl, err := GetAuthorizationCode(c, service, teamName, stateProps, ""); err != nil {
|
||||
if authUrl, err := GetAuthorizationCode(c, service, stateProps, ""); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
} else {
|
||||
http.Redirect(w, r, authUrl, http.StatusFound)
|
||||
}
|
||||
}
|
||||
|
||||
func GetAuthorizationCode(c *Context, service string, props map[string]string, loginHint string) (string, *model.AppError) {
|
||||
|
||||
sso := utils.Cfg.GetSSOService(service)
|
||||
if sso != nil && !sso.Enable {
|
||||
return "", model.NewLocAppError("GetAuthorizationCode", "api.user.get_authorization_code.unsupported.app_error", nil, "service="+service)
|
||||
}
|
||||
|
||||
clientId := sso.Id
|
||||
endpoint := sso.AuthEndpoint
|
||||
scope := sso.Scope
|
||||
|
||||
props["hash"] = model.HashPassword(clientId)
|
||||
state := b64.StdEncoding.EncodeToString([]byte(model.MapToJson(props)))
|
||||
|
||||
redirectUri := c.GetSiteURL() + "/signup/" + service + "/complete"
|
||||
|
||||
authUrl := endpoint + "?response_type=code&client_id=" + clientId + "&redirect_uri=" + url.QueryEscape(redirectUri) + "&state=" + url.QueryEscape(state)
|
||||
|
||||
if len(scope) > 0 {
|
||||
authUrl += "&scope=" + utils.UrlEncode(scope)
|
||||
}
|
||||
|
||||
if len(loginHint) > 0 {
|
||||
authUrl += "&login_hint=" + utils.UrlEncode(loginHint)
|
||||
}
|
||||
|
||||
return authUrl, nil
|
||||
}
|
||||
|
||||
func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser, string, map[string]string, *model.AppError) {
|
||||
sso := utils.Cfg.GetSSOService(service)
|
||||
if sso == nil || !sso.Enable {
|
||||
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.unsupported.app_error", nil, "service="+service)
|
||||
}
|
||||
|
||||
stateStr := ""
|
||||
if b, err := b64.StdEncoding.DecodeString(state); err != nil {
|
||||
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, err.Error())
|
||||
} else {
|
||||
stateStr = string(b)
|
||||
}
|
||||
|
||||
stateProps := model.MapFromJson(strings.NewReader(stateStr))
|
||||
|
||||
if !model.ComparePassword(stateProps["hash"], sso.Id) {
|
||||
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, "")
|
||||
}
|
||||
|
||||
teamId := stateProps["team_id"]
|
||||
|
||||
p := url.Values{}
|
||||
p.Set("client_id", sso.Id)
|
||||
p.Set("client_secret", sso.Secret)
|
||||
p.Set("code", code)
|
||||
p.Set("grant_type", model.ACCESS_TOKEN_GRANT_TYPE)
|
||||
p.Set("redirect_uri", redirectUri)
|
||||
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
req, _ := http.NewRequest("POST", sso.TokenEndpoint, strings.NewReader(p.Encode()))
|
||||
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
var ar *model.AccessResponse
|
||||
if resp, err := client.Do(req); err != nil {
|
||||
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.token_failed.app_error", nil, err.Error())
|
||||
} else {
|
||||
ar = model.AccessResponseFromJson(resp.Body)
|
||||
if ar == nil {
|
||||
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_response.app_error", nil, "")
|
||||
}
|
||||
}
|
||||
|
||||
if strings.ToLower(ar.TokenType) != model.ACCESS_TOKEN_TYPE {
|
||||
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_token.app_error", nil, "token_type="+ar.TokenType)
|
||||
}
|
||||
|
||||
if len(ar.AccessToken) == 0 {
|
||||
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.missing.app_error", nil, "")
|
||||
}
|
||||
|
||||
p = url.Values{}
|
||||
p.Set("access_token", ar.AccessToken)
|
||||
req, _ = http.NewRequest("GET", sso.UserApiEndpoint, strings.NewReader(""))
|
||||
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer "+ar.AccessToken)
|
||||
|
||||
if resp, err := client.Do(req); err != nil {
|
||||
return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.service.app_error",
|
||||
map[string]interface{}{"Service": service}, err.Error())
|
||||
} else {
|
||||
return resp.Body, teamId, stateProps, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func CompleteSwitchWithOAuth(c *Context, w http.ResponseWriter, r *http.Request, service string, userData io.ReadCloser, email string) {
|
||||
authData := ""
|
||||
ssoEmail := ""
|
||||
provider := einterfaces.GetOauthProvider(service)
|
||||
if provider == nil {
|
||||
c.Err = model.NewLocAppError("CompleteClaimWithOAuth", "api.user.complete_switch_with_oauth.unavailable.app_error",
|
||||
map[string]interface{}{"Service": service}, "")
|
||||
return
|
||||
} else {
|
||||
ssoUser := provider.GetUserFromJson(userData)
|
||||
authData = ssoUser.AuthData
|
||||
ssoEmail = ssoUser.Email
|
||||
}
|
||||
|
||||
if len(authData) == 0 {
|
||||
c.Err = model.NewLocAppError("CompleteClaimWithOAuth", "api.user.complete_switch_with_oauth.parse.app_error",
|
||||
map[string]interface{}{"Service": service}, "")
|
||||
return
|
||||
}
|
||||
|
||||
if len(email) == 0 {
|
||||
c.Err = model.NewLocAppError("CompleteClaimWithOAuth", "api.user.complete_switch_with_oauth.blank_email.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
|
||||
RevokeAllSession(c, user.Id)
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.User().UpdateAuthData(user.Id, service, authData, ssoEmail); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
}
|
||||
|
||||
sendSignInChangeEmailAndForget(c, user.Email, c.GetSiteURL(), strings.Title(service)+" SSO")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,22 +5,14 @@ package api
|
|||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegisterApp(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
rteam, _ := Client.CreateTeam(&team)
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Password: "pwd"}
|
||||
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
|
||||
app := &model.OAuthApp{Name: "TestApp" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
|
||||
|
||||
|
|
@ -38,7 +30,7 @@ func TestRegisterApp(t *testing.T) {
|
|||
t.Fatal("not logged in - should have failed")
|
||||
}
|
||||
|
||||
Client.Must(Client.LoginById(ruser.Id, "pwd"))
|
||||
th.LoginBasic()
|
||||
|
||||
if result, err := Client.RegisterApp(app); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -70,19 +62,11 @@ func TestRegisterApp(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAllowOAuth(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
rteam, _ := Client.CreateTeam(&team)
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Password: "pwd"}
|
||||
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
|
||||
app := &model.OAuthApp{Name: "TestApp" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
|
||||
|
||||
Client.Must(Client.LoginById(ruser.Id, "pwd"))
|
||||
|
||||
state := "123"
|
||||
|
||||
if !utils.Cfg.ServiceSettings.EnableOAuthServiceProvider {
|
||||
|
|
|
|||
108
api/post.go
108
api/post.go
|
|
@ -22,21 +22,21 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func InitPost(r *mux.Router) {
|
||||
func InitPost() {
|
||||
l4g.Debug(utils.T("api.post.init.debug"))
|
||||
|
||||
r.Handle("/posts/search", ApiUserRequired(searchPosts)).Methods("GET")
|
||||
r.Handle("/posts/{post_id}", ApiUserRequired(getPostById)).Methods("GET")
|
||||
BaseRoutes.NeedTeam.Handle("/posts/search", ApiUserRequired(searchPosts)).Methods("GET")
|
||||
BaseRoutes.NeedTeam.Handle("/posts/{post_id}", ApiUserRequired(getPostById)).Methods("GET")
|
||||
|
||||
sr := r.PathPrefix("/channels/{id:[A-Za-z0-9]+}").Subrouter()
|
||||
sr.Handle("/create", ApiUserRequired(createPost)).Methods("POST")
|
||||
sr.Handle("/update", ApiUserRequired(updatePost)).Methods("POST")
|
||||
sr.Handle("/posts/{offset:[0-9]+}/{limit:[0-9]+}", ApiUserRequiredActivity(getPosts, false)).Methods("GET")
|
||||
sr.Handle("/posts/{time:[0-9]+}", ApiUserRequiredActivity(getPostsSince, false)).Methods("GET")
|
||||
sr.Handle("/post/{post_id:[A-Za-z0-9]+}", ApiUserRequired(getPost)).Methods("GET")
|
||||
sr.Handle("/post/{post_id:[A-Za-z0-9]+}/delete", ApiUserRequired(deletePost)).Methods("POST")
|
||||
sr.Handle("/post/{post_id:[A-Za-z0-9]+}/before/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsBefore)).Methods("GET")
|
||||
sr.Handle("/post/{post_id:[A-Za-z0-9]+}/after/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsAfter)).Methods("GET")
|
||||
BaseRoutes.Posts.Handle("/create", ApiUserRequired(createPost)).Methods("POST")
|
||||
BaseRoutes.Posts.Handle("/update", ApiUserRequired(updatePost)).Methods("POST")
|
||||
BaseRoutes.Posts.Handle("/page/{offset:[0-9]+}/{limit:[0-9]+}", ApiUserRequiredActivity(getPosts, false)).Methods("GET")
|
||||
BaseRoutes.Posts.Handle("/since/{time:[0-9]+}", ApiUserRequiredActivity(getPostsSince, false)).Methods("GET")
|
||||
|
||||
BaseRoutes.NeedPost.Handle("/get", ApiUserRequired(getPost)).Methods("GET")
|
||||
BaseRoutes.NeedPost.Handle("/delete", ApiUserRequired(deletePost)).Methods("POST")
|
||||
BaseRoutes.NeedPost.Handle("/before/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsBefore)).Methods("GET")
|
||||
BaseRoutes.NeedPost.Handle("/after/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsAfter)).Methods("GET")
|
||||
}
|
||||
|
||||
func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -47,7 +47,7 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
// Create and save post object to channel
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, post.ChannelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
|
||||
|
||||
if !c.HasPermissionsToChannel(cchan, "createPost") {
|
||||
return
|
||||
|
|
@ -228,15 +228,16 @@ func CreateWebhookPost(c *Context, channelId, text, overrideUsername, overrideIc
|
|||
|
||||
func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks bool) {
|
||||
go func() {
|
||||
tchan := Srv.Store.Team().Get(c.Session.TeamId)
|
||||
tchan := Srv.Store.Team().Get(c.TeamId)
|
||||
cchan := Srv.Store.Channel().Get(post.ChannelId)
|
||||
uchan := Srv.Store.User().Get(post.UserId)
|
||||
pchan := Srv.Store.User().GetProfiles(c.Session.TeamId)
|
||||
pchan := Srv.Store.User().GetProfiles(c.TeamId)
|
||||
dpchan := Srv.Store.User().GetDirectProfiles(c.Session.UserId)
|
||||
mchan := Srv.Store.Channel().GetMembers(post.ChannelId)
|
||||
|
||||
var team *model.Team
|
||||
if result := <-tchan; result.Err != nil {
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.team.error"), c.Session.TeamId, result.Err)
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.team.error"), c.TeamId, result.Err)
|
||||
return
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
|
|
@ -252,12 +253,22 @@ func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks boo
|
|||
|
||||
var profiles map[string]*model.User
|
||||
if result := <-pchan; result.Err != nil {
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.profiles.error"), c.Session.TeamId, result.Err)
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.profiles.error"), c.TeamId, result.Err)
|
||||
return
|
||||
} else {
|
||||
profiles = result.Data.(map[string]*model.User)
|
||||
}
|
||||
|
||||
if result := <-dpchan; result.Err != nil {
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.profiles.error"), c.TeamId, result.Err)
|
||||
return
|
||||
} else {
|
||||
dps := result.Data.(map[string]*model.User)
|
||||
for k, v := range dps {
|
||||
profiles[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
var members []model.ChannelMember
|
||||
if result := <-mchan; result.Err != nil {
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.members.error"), post.ChannelId, result.Err)
|
||||
|
|
@ -282,7 +293,7 @@ func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks boo
|
|||
}
|
||||
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
go makeDirectChannelVisible(c.Session.TeamId, post.ChannelId)
|
||||
go makeDirectChannelVisible(c.TeamId, post.ChannelId)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
@ -352,7 +363,7 @@ func handleWebhookEventsAndForget(c *Context, post *model.Post, team *model.Team
|
|||
return
|
||||
}
|
||||
|
||||
hchan := Srv.Store.Webhook().GetOutgoingByTeam(c.Session.TeamId)
|
||||
hchan := Srv.Store.Webhook().GetOutgoingByTeam(c.TeamId)
|
||||
|
||||
hooks := []*model.OutgoingWebhook{}
|
||||
|
||||
|
|
@ -416,8 +427,25 @@ func handleWebhookEventsAndForget(c *Context, post *model.Post, team *model.Team
|
|||
respProps := model.MapFromJson(resp.Body)
|
||||
|
||||
// copy the context and create a mock session for posting the message
|
||||
mockSession := model.Session{UserId: hook.CreatorId, TeamId: hook.TeamId, IsOAuth: false}
|
||||
newContext := &Context{mockSession, model.NewId(), "", c.Path, nil, c.teamURLValid, c.teamURL, c.siteURL, c.T, c.Locale}
|
||||
mockSession := model.Session{
|
||||
UserId: hook.CreatorId,
|
||||
TeamMembers: []*model.TeamMember{{TeamId: hook.TeamId, UserId: hook.CreatorId}},
|
||||
IsOAuth: false,
|
||||
}
|
||||
|
||||
newContext := &Context{
|
||||
Session: mockSession,
|
||||
RequestId: model.NewId(),
|
||||
IpAddress: "",
|
||||
Path: c.Path,
|
||||
Err: nil,
|
||||
teamURLValid: c.teamURLValid,
|
||||
teamURL: c.teamURL,
|
||||
siteURL: c.siteURL,
|
||||
T: c.T,
|
||||
Locale: c.Locale,
|
||||
TeamId: hook.TeamId,
|
||||
}
|
||||
|
||||
if text, ok := respProps["text"]; ok {
|
||||
if _, err := CreateWebhookPost(newContext, post.ChannelId, text, respProps["username"], respProps["icon_url"], post.Props, post.Type); err != nil {
|
||||
|
|
@ -706,7 +734,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
|
|||
TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections},
|
||||
}
|
||||
httpClient := &http.Client{Transport: tr}
|
||||
request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+"/api/v1/send_push", strings.NewReader(msg.ToJson()))
|
||||
request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+model.API_URL_SUFFIX_V1+"/send_push", strings.NewReader(msg.ToJson()))
|
||||
|
||||
l4g.Debug(utils.T("api.post.send_notifications_and_forget.push_notification.debug"), msg.DeviceId, msg.Message)
|
||||
if _, err := httpClient.Do(request); err != nil {
|
||||
|
|
@ -719,7 +747,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
|
|||
}
|
||||
}
|
||||
|
||||
message := model.NewMessage(c.Session.TeamId, post.ChannelId, post.UserId, model.ACTION_POSTED)
|
||||
message := model.NewMessage(c.TeamId, post.ChannelId, post.UserId, model.ACTION_POSTED)
|
||||
message.Add("post", post.ToJson())
|
||||
message.Add("channel_type", channel.Type)
|
||||
|
||||
|
|
@ -780,7 +808,7 @@ func checkForOutOfChannelMentions(c *Context, post *model.Post, channel *model.C
|
|||
}
|
||||
|
||||
SendEphemeralPost(
|
||||
c.Session.TeamId,
|
||||
c.TeamId,
|
||||
post.UserId,
|
||||
&model.Post{
|
||||
ChannelId: post.ChannelId,
|
||||
|
|
@ -847,7 +875,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, post.ChannelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
|
||||
pchan := Srv.Store.Post().Get(post.Id)
|
||||
|
||||
if !c.HasPermissionsToChannel(cchan, "updatePost") {
|
||||
|
|
@ -889,7 +917,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
} else {
|
||||
rpost := result.Data.(*model.Post)
|
||||
|
||||
message := model.NewMessage(c.Session.TeamId, rpost.ChannelId, c.Session.UserId, model.ACTION_POST_EDITED)
|
||||
message := model.NewMessage(c.TeamId, rpost.ChannelId, c.Session.UserId, model.ACTION_POST_EDITED)
|
||||
message.Add("post", rpost.ToJson())
|
||||
|
||||
PublishAndForget(message)
|
||||
|
|
@ -901,7 +929,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
func getPosts(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
if len(id) != 26 {
|
||||
c.SetInvalidParam("getPosts", "channelId")
|
||||
return
|
||||
|
|
@ -919,7 +947,7 @@ func getPosts(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
|
||||
etagChan := Srv.Store.Post().GetEtag(id)
|
||||
|
||||
if !c.HasPermissionsToChannel(cchan, "getPosts") {
|
||||
|
|
@ -949,7 +977,7 @@ func getPosts(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
func getPostsSince(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
if len(id) != 26 {
|
||||
c.SetInvalidParam("getPostsSince", "channelId")
|
||||
return
|
||||
|
|
@ -961,7 +989,7 @@ func getPostsSince(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
|
||||
pchan := Srv.Store.Post().GetPostsSince(id, time)
|
||||
|
||||
if !c.HasPermissionsToChannel(cchan, "getPostsSince") {
|
||||
|
|
@ -982,7 +1010,7 @@ func getPostsSince(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
|
||||
channelId := params["id"]
|
||||
channelId := params["channel_id"]
|
||||
if len(channelId) != 26 {
|
||||
c.SetInvalidParam("getPost", "channelId")
|
||||
return
|
||||
|
|
@ -994,7 +1022,7 @@ func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
|
||||
pchan := Srv.Store.Post().Get(postId)
|
||||
|
||||
if !c.HasPermissionsToChannel(cchan, "getPost") {
|
||||
|
|
@ -1041,7 +1069,7 @@ func getPostById(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
post := list.Posts[list.Order[0]]
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, post.ChannelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
|
||||
if !c.HasPermissionsToChannel(cchan, "getPostById") {
|
||||
return
|
||||
}
|
||||
|
|
@ -1058,7 +1086,7 @@ func getPostById(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
|
||||
channelId := params["id"]
|
||||
channelId := params["channel_id"]
|
||||
if len(channelId) != 26 {
|
||||
c.SetInvalidParam("deletePost", "channelId")
|
||||
return
|
||||
|
|
@ -1070,7 +1098,7 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
|
||||
pchan := Srv.Store.Post().Get(postId)
|
||||
|
||||
if result := <-pchan; result.Err != nil {
|
||||
|
|
@ -1106,11 +1134,11 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
message := model.NewMessage(c.Session.TeamId, post.ChannelId, c.Session.UserId, model.ACTION_POST_DELETED)
|
||||
message := model.NewMessage(c.TeamId, post.ChannelId, c.Session.UserId, model.ACTION_POST_DELETED)
|
||||
message.Add("post", post.ToJson())
|
||||
|
||||
PublishAndForget(message)
|
||||
DeletePostFilesAndForget(c.Session.TeamId, post)
|
||||
DeletePostFilesAndForget(c.TeamId, post)
|
||||
|
||||
result := make(map[string]string)
|
||||
result["id"] = postId
|
||||
|
|
@ -1146,7 +1174,7 @@ func getPostsAfter(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
func getPostsBeforeOrAfter(c *Context, w http.ResponseWriter, r *http.Request, before bool) {
|
||||
params := mux.Vars(r)
|
||||
|
||||
id := params["id"]
|
||||
id := params["channel_id"]
|
||||
if len(id) != 26 {
|
||||
c.SetInvalidParam("getPostsBeforeOrAfter", "channelId")
|
||||
return
|
||||
|
|
@ -1170,7 +1198,7 @@ func getPostsBeforeOrAfter(c *Context, w http.ResponseWriter, r *http.Request, b
|
|||
return
|
||||
}
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId)
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
|
||||
// We can do better than this etag in this situation
|
||||
etagChan := Srv.Store.Post().GetEtag(id)
|
||||
|
||||
|
|
@ -1215,7 +1243,7 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
for _, params := range paramsList {
|
||||
// don't allow users to search for everything
|
||||
if params.Terms != "*" {
|
||||
channels = append(channels, Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, params))
|
||||
channels = append(channels, Srv.Store.Post().Search(c.TeamId, c.Session.UserId, params))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@ func BenchmarkCreatePost(b *testing.B) {
|
|||
var (
|
||||
NUM_POSTS_RANGE = utils.Range{NUM_POSTS, NUM_POSTS}
|
||||
)
|
||||
_, _, channel := SetupBenchmark()
|
||||
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
|
||||
|
|
@ -32,7 +35,10 @@ func BenchmarkUpdatePost(b *testing.B) {
|
|||
NUM_POSTS_RANGE = utils.Range{NUM_POSTS, NUM_POSTS}
|
||||
UPDATE_POST_LEN = 100
|
||||
)
|
||||
_, _, channel := SetupBenchmark()
|
||||
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
posts, valid := testPoster.CreateTestPosts(NUM_POSTS_RANGE)
|
||||
|
|
@ -59,7 +65,10 @@ func BenchmarkGetPosts(b *testing.B) {
|
|||
var (
|
||||
NUM_POSTS_RANGE = utils.Range{NUM_POSTS, NUM_POSTS}
|
||||
)
|
||||
_, _, channel := SetupBenchmark()
|
||||
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
testPoster.CreateTestPosts(NUM_POSTS_RANGE)
|
||||
|
|
@ -75,7 +84,10 @@ func BenchmarkSearchPosts(b *testing.B) {
|
|||
var (
|
||||
NUM_POSTS_RANGE = utils.Range{NUM_POSTS, NUM_POSTS}
|
||||
)
|
||||
_, _, channel := SetupBenchmark()
|
||||
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
testPoster.CreateTestPosts(NUM_POSTS_RANGE)
|
||||
|
|
@ -93,7 +105,10 @@ func BenchmarkEtagCache(b *testing.B) {
|
|||
var (
|
||||
NUM_POSTS_RANGE = utils.Range{NUM_POSTS, NUM_POSTS}
|
||||
)
|
||||
_, _, channel := SetupBenchmark()
|
||||
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
testPoster.CreateTestPosts(NUM_POSTS_RANGE)
|
||||
|
|
@ -111,7 +126,10 @@ func BenchmarkDeletePosts(b *testing.B) {
|
|||
var (
|
||||
NUM_POSTS_RANGE = utils.Range{NUM_POSTS, NUM_POSTS}
|
||||
)
|
||||
_, _, channel := SetupBenchmark()
|
||||
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel := th.BasicChannel
|
||||
|
||||
testPoster := NewAutoPostCreator(Client, channel.Id)
|
||||
posts, valid := testPoster.CreateTestPosts(NUM_POSTS_RANGE)
|
||||
|
|
|
|||
385
api/post_test.go
385
api/post_test.go
|
|
@ -5,38 +5,24 @@ package api
|
|||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"net/http"
|
||||
"strings"
|
||||
//"strings"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCreatePost(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
team2 := &model.Team{DisplayName: "Name Team 2", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
team2 := th.CreateTeam(th.BasicClient)
|
||||
user1 := th.BasicUser
|
||||
user3 := th.CreateUser(th.BasicClient)
|
||||
LinkUserToTeam(user3, team2)
|
||||
channel1 := th.BasicChannel
|
||||
channel2 := th.CreateChannel(Client, team)
|
||||
|
||||
filenames := []string{"/12345678901234567890123456/12345678901234567890123456/12345678901234567890123456/test.png", "/" + channel1.Id + "/" + user1.Id + "/test.png", "www.mattermost.com/fake/url", "junk"}
|
||||
|
||||
|
|
@ -97,21 +83,17 @@ func TestCreatePost(t *testing.T) {
|
|||
t.Fatal("Should have been forbidden")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
post7 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
_, err = Client.CreatePost(post7)
|
||||
if err.StatusCode != http.StatusForbidden {
|
||||
t.Fatal("Should have been forbidden")
|
||||
}
|
||||
|
||||
user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
Client.LoginByEmail(team2.Name, user3.Email, "pwd")
|
||||
|
||||
channel3 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team2.Id}
|
||||
channel3 = Client.Must(Client.CreateChannel(channel3)).Data.(*model.Channel)
|
||||
Client.LoginByEmail(team2.Name, user3.Email, user3.Password)
|
||||
Client.SetTeamId(team2.Id)
|
||||
channel3 := th.CreateChannel(Client, team2)
|
||||
|
||||
post8 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
_, err = Client.CreatePost(post8)
|
||||
|
|
@ -125,29 +107,9 @@ func TestCreatePost(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdatePost(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
team2 := &model.Team{DisplayName: "Name Team 2", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
rpost1, err := Client.CreatePost(post1)
|
||||
|
|
@ -196,19 +158,9 @@ func TestUpdatePost(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetPosts(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
|
|
@ -261,19 +213,9 @@ func TestGetPosts(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetPostsSince(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
post0 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
|
|
@ -331,19 +273,9 @@ func TestGetPostsSince(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetPostsBeforeAfter(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
post0 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
|
|
@ -379,7 +311,8 @@ func TestGetPostsBeforeAfter(t *testing.T) {
|
|||
t.Fatal("wrong order")
|
||||
}
|
||||
|
||||
if len(r1.Posts) != 2 {
|
||||
if len(r1.Posts) != 3 {
|
||||
t.Log(r1.Posts)
|
||||
t.Fatal("wrong size")
|
||||
}
|
||||
|
||||
|
|
@ -408,19 +341,9 @@ func TestGetPostsBeforeAfter(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSearchPosts(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "search for post1"}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
|
|
@ -458,19 +381,9 @@ func TestSearchPosts(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSearchHashtagPosts(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "#sgtitlereview with space"}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
|
|
@ -489,19 +402,10 @@ func TestSearchHashtagPosts(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSearchPostsInChannel(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
team := th.BasicTeam
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "sgtitlereview with space"}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
|
|
@ -529,7 +433,7 @@ func TestSearchPostsInChannel(t *testing.T) {
|
|||
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||
}
|
||||
|
||||
if result := Client.Must(Client.SearchPosts("channel:" + channel1.Name)).Data.(*model.PostList); len(result.Order) != 1 {
|
||||
if result := Client.Must(Client.SearchPosts("channel:" + channel1.Name)).Data.(*model.PostList); len(result.Order) != 2 {
|
||||
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||
}
|
||||
|
||||
|
|
@ -567,38 +471,29 @@ func TestSearchPostsInChannel(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSearchPostsFromUser(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
channel2 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
team := th.BasicTeam
|
||||
user1 := th.BasicUser
|
||||
user2 := th.BasicUser2
|
||||
channel2 := th.CreateChannel(Client, team)
|
||||
Client.Must(Client.AddChannelMember(channel1.Id, th.BasicUser2.Id))
|
||||
Client.Must(Client.AddChannelMember(channel2.Id, th.BasicUser2.Id))
|
||||
user3 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user3, team)
|
||||
Client.Must(Client.AddChannelMember(channel1.Id, user3.Id))
|
||||
Client.Must(Client.AddChannelMember(channel2.Id, user3.Id))
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "sgtitlereview with space"}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
Client.Must(Client.JoinChannel(channel1.Id))
|
||||
Client.Must(Client.JoinChannel(channel2.Id))
|
||||
th.LoginBasic2()
|
||||
|
||||
post2 := &model.Post{ChannelId: channel2.Id, Message: "sgtitlereview\n with return"}
|
||||
post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
|
||||
|
||||
if result := Client.Must(Client.SearchPosts("from: " + user1.Username)).Data.(*model.PostList); len(result.Order) != 1 {
|
||||
if result := Client.Must(Client.SearchPosts("from: " + user1.Username)).Data.(*model.PostList); len(result.Order) != 2 {
|
||||
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||
}
|
||||
|
||||
|
|
@ -617,13 +512,7 @@ func TestSearchPostsFromUser(t *testing.T) {
|
|||
t.Fatalf("wrong number of posts returned %v", len(result.Order))
|
||||
}
|
||||
|
||||
user3 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user3.Email, "pwd")
|
||||
Client.Must(Client.JoinChannel(channel1.Id))
|
||||
Client.Must(Client.JoinChannel(channel2.Id))
|
||||
Client.LoginByEmail(team.Name, user3.Email, user3.Password)
|
||||
|
||||
// wait for the join/leave messages to be created for user3 since they're done asynchronously
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
|
@ -649,19 +538,9 @@ func TestSearchPostsFromUser(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetPostsCache(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
|
|
@ -698,23 +577,10 @@ func TestGetPostsCache(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeletePosts(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
userAdmin := &model.User{TeamId: team.Id, Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
|
||||
userAdmin = Client.Must(Client.CreateUser(userAdmin, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userAdmin.Id))
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
|
|
@ -745,7 +611,7 @@ func TestDeletePosts(t *testing.T) {
|
|||
|
||||
r2 := Client.Must(Client.GetPosts(channel1.Id, 0, 10, "")).Data.(*model.PostList)
|
||||
|
||||
if len(r2.Posts) != 4 {
|
||||
if len(r2.Posts) != 5 {
|
||||
t.Fatal("should have returned 4 items")
|
||||
}
|
||||
|
||||
|
|
@ -753,27 +619,17 @@ func TestDeletePosts(t *testing.T) {
|
|||
post4 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
post4 = Client.Must(Client.CreatePost(post4)).Data.(*model.Post)
|
||||
|
||||
Client.LoginByEmail(team.Name, userAdmin.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
Client.Must(Client.DeletePost(channel1.Id, post4.Id))
|
||||
}
|
||||
|
||||
func TestEmailMention(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: "success+test@simulator.amazonses.com", Nickname: "Bob Bobby", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "bob"}
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: th.BasicUser.Username}
|
||||
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
|
||||
|
||||
// No easy way to verify the email was sent, but this will at least cause the server to throw errors if the code is broken
|
||||
|
|
@ -781,19 +637,9 @@ func TestEmailMention(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFuzzyPosts(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
|
||||
filenames := []string{"junk"}
|
||||
|
||||
|
|
@ -808,21 +654,13 @@ func TestFuzzyPosts(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMakeDirectChannelVisible(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
user1 := th.BasicUser
|
||||
user2 := th.BasicUser2
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
// user2 will be created with prefs created to show user1 in the sidebar so set that to false to get rid of it
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
preferences := &model.Preferences{
|
||||
{
|
||||
|
|
@ -834,9 +672,11 @@ func TestMakeDirectChannelVisible(t *testing.T) {
|
|||
}
|
||||
Client.Must(Client.SetPreferences(preferences))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
Client.Must(Client.Logout())
|
||||
th.LoginBasic()
|
||||
th.BasicClient.SetTeamId(team.Id)
|
||||
|
||||
channel := Client.Must(Client.CreateDirectChannel(map[string]string{"user_id": user2.Id})).Data.(*model.Channel)
|
||||
channel := Client.Must(Client.CreateDirectChannel(user2.Id)).Data.(*model.Channel)
|
||||
|
||||
makeDirectChannelVisible(team.Id, channel.Id)
|
||||
|
||||
|
|
@ -845,38 +685,17 @@ func TestMakeDirectChannelVisible(t *testing.T) {
|
|||
} else if pref := result.Data.(*model.Preference); pref.Value != "true" {
|
||||
t.Fatal("Failed to set direct channel to be visible for user1")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
|
||||
if result, err := Client.GetPreference(model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, user1.Id); err != nil {
|
||||
t.Fatal("Errored trying to set direct channel to be visible for user2")
|
||||
} else if pref := result.Data.(*model.Preference); pref.Value != "true" {
|
||||
t.Fatal("Failed to set direct channel to be visible for user2")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOutOfChannelMentions(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team1 := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Type: model.TEAM_OPEN}
|
||||
team1 = Client.Must(Client.CreateTeam(team1)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team1.Id, Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd", Username: "user1"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team1.Id, Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd", Username: "user2"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
user3 := &model.User{TeamId: team1.Id, Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd", Username: "user3"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
Client.Must(Client.LoginByEmail(team1.Name, user1.Email, "pwd"))
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team1.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
channel1 := th.BasicChannel
|
||||
team1 := th.BasicTeam
|
||||
user1 := th.BasicUser
|
||||
user2 := th.BasicUser2
|
||||
user3 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user3, team1)
|
||||
|
||||
var allProfiles map[string]*model.User
|
||||
if result := <-Srv.Store.User().GetProfiles(team1.Id); result.Err != nil {
|
||||
|
|
@ -893,39 +712,37 @@ func TestGetOutOfChannelMentions(t *testing.T) {
|
|||
}
|
||||
|
||||
// test a post that doesn't @mention anybody
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "user1 user2 user3"}
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: fmt.Sprintf("%v %v %v", user1.Username, user2.Username, user3.Username)}
|
||||
if mentioned := getOutOfChannelMentions(post1, allProfiles, members); len(mentioned) != 0 {
|
||||
t.Fatalf("getOutOfChannelMentions returned %v when no users were mentioned", mentioned)
|
||||
}
|
||||
|
||||
// test a post that @mentions someone in the channel
|
||||
post2 := &model.Post{ChannelId: channel1.Id, Message: "@user1 is user1"}
|
||||
post2 := &model.Post{ChannelId: channel1.Id, Message: fmt.Sprintf("@%v is %v", user1.Username, user1.Username)}
|
||||
if mentioned := getOutOfChannelMentions(post2, allProfiles, members); len(mentioned) != 0 {
|
||||
t.Fatalf("getOutOfChannelMentions returned %v when only users in the channel were mentioned", mentioned)
|
||||
}
|
||||
|
||||
// test a post that @mentions someone not in the channel
|
||||
post3 := &model.Post{ChannelId: channel1.Id, Message: "@user2 and @user3 aren't in the channel"}
|
||||
post3 := &model.Post{ChannelId: channel1.Id, Message: fmt.Sprintf("@%v and @%v aren't in the channel", user2.Username, user3.Username)}
|
||||
if mentioned := getOutOfChannelMentions(post3, allProfiles, members); len(mentioned) != 2 || (mentioned[0].Id != user2.Id && mentioned[0].Id != user3.Id) || (mentioned[1].Id != user2.Id && mentioned[1].Id != user3.Id) {
|
||||
t.Fatalf("getOutOfChannelMentions returned %v when two users outside the channel were mentioned", mentioned)
|
||||
}
|
||||
|
||||
// test a post that @mentions someone not in the channel as well as someone in the channel
|
||||
post4 := &model.Post{ChannelId: channel1.Id, Message: "@user2 and @user1 might be in the channel"}
|
||||
post4 := &model.Post{ChannelId: channel1.Id, Message: fmt.Sprintf("@%v and @%v might be in the channel", user2.Username, user1.Username)}
|
||||
if mentioned := getOutOfChannelMentions(post4, allProfiles, members); len(mentioned) != 1 || mentioned[0].Id != user2.Id {
|
||||
t.Fatalf("getOutOfChannelMentions returned %v when someone in the channel and someone outside the channel were mentioned", mentioned)
|
||||
}
|
||||
|
||||
Client.Must(Client.Logout())
|
||||
|
||||
team2 := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Type: model.TEAM_OPEN}
|
||||
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
|
||||
team2 := th.CreateTeam(Client)
|
||||
user4 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user4, team2)
|
||||
|
||||
user4 := &model.User{TeamId: team2.Id, Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd", Username: "user4"}
|
||||
user4 = Client.Must(Client.CreateUser(user4, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user4.Id))
|
||||
|
||||
Client.Must(Client.LoginByEmail(team2.Name, user4.Email, "pwd"))
|
||||
Client.Must(Client.LoginByEmail(team2.Name, user4.Email, user4.Password))
|
||||
Client.SetTeamId(team2.Id)
|
||||
|
||||
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team2.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
|
|
@ -943,7 +760,7 @@ func TestGetOutOfChannelMentions(t *testing.T) {
|
|||
}
|
||||
|
||||
// test a post that @mentions someone on a different team
|
||||
post5 := &model.Post{ChannelId: channel2.Id, Message: "@user2 and @user3 might be in the channel"}
|
||||
post5 := &model.Post{ChannelId: channel2.Id, Message: fmt.Sprintf("@%v and @%v might be in the channel", user2.Username, user3.Username)}
|
||||
if mentioned := getOutOfChannelMentions(post5, allProfiles, members); len(mentioned) != 0 {
|
||||
t.Fatalf("getOutOfChannelMentions returned %v when two users on a different team were mentioned", mentioned)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@ import (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
func InitPreference(r *mux.Router) {
|
||||
func InitPreference() {
|
||||
l4g.Debug(utils.T("api.preference.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/preferences").Subrouter()
|
||||
sr.Handle("/", ApiUserRequired(getAllPreferences)).Methods("GET")
|
||||
sr.Handle("/save", ApiUserRequired(savePreferences)).Methods("POST")
|
||||
sr.Handle("/{category:[A-Za-z0-9_]+}", ApiUserRequired(getPreferenceCategory)).Methods("GET")
|
||||
sr.Handle("/{category:[A-Za-z0-9_]+}/{name:[A-Za-z0-9_]+}", ApiUserRequired(getPreference)).Methods("GET")
|
||||
BaseRoutes.Preferences.Handle("/", ApiUserRequired(getAllPreferences)).Methods("GET")
|
||||
BaseRoutes.Preferences.Handle("/save", ApiUserRequired(savePreferences)).Methods("POST")
|
||||
BaseRoutes.Preferences.Handle("/{category:[A-Za-z0-9_]+}", ApiUserRequired(getPreferenceCategory)).Methods("GET")
|
||||
BaseRoutes.Preferences.Handle("/{category:[A-Za-z0-9_]+}/{name:[A-Za-z0-9_]+}", ApiUserRequired(getPreference)).Methods("GET")
|
||||
}
|
||||
|
||||
func getAllPreferences(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -44,7 +43,7 @@ func savePreferences(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
c.Err = model.NewLocAppError("savePreferences", "api.preference.save_preferences.set.app_error", nil,
|
||||
c.T("api.preference.save_preferences.set_details.app_error",
|
||||
map[string]interface{}{"SessionUserId": c.Session.UserId, "PreferenceUserId": preference.UserId}))
|
||||
c.Err.StatusCode = http.StatusUnauthorized
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,23 +5,13 @@ package api
|
|||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetAllPreferences(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
user1 := th.BasicUser
|
||||
|
||||
category := model.NewId()
|
||||
|
||||
|
|
@ -43,7 +33,6 @@ func TestGetAllPreferences(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
Client.Must(Client.SetPreferences(&preferences1))
|
||||
|
||||
if result, err := Client.GetAllPreferences(); err != nil {
|
||||
|
|
@ -52,27 +41,19 @@ func TestGetAllPreferences(t *testing.T) {
|
|||
t.Fatal("received the wrong number of preferences")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
// note that user2 will automatically have a preference set for them to show user1 for direct messages
|
||||
if result, err := Client.GetAllPreferences(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if data := result.Data.(model.Preferences); len(data) != 2 {
|
||||
} else if data := result.Data.(model.Preferences); len(data) == 0 {
|
||||
t.Fatal("received the wrong number of preferences")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetPreferences(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
user1 := th.BasicUser
|
||||
|
||||
// save 10 preferences
|
||||
var preferences model.Preferences
|
||||
|
|
@ -98,12 +79,7 @@ func TestSetPreferences(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// not able to update as a different user
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
if _, err := Client.SetPreferences(&preferences); err == nil {
|
||||
t.Fatal("shouldn't have been able to update another user's preferences")
|
||||
|
|
@ -111,18 +87,9 @@ func TestSetPreferences(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetPreferenceCategory(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
user1 := th.BasicUser
|
||||
|
||||
category := model.NewId()
|
||||
|
||||
|
|
@ -144,11 +111,8 @@ func TestGetPreferenceCategory(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
Client.Must(Client.SetPreferences(&preferences1))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
if result, err := Client.GetPreferenceCategory(category); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if data := result.Data.(model.Preferences); len(data) != 2 {
|
||||
|
|
@ -157,7 +121,7 @@ func TestGetPreferenceCategory(t *testing.T) {
|
|||
t.Fatal("received incorrect preferences")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
if result, err := Client.GetPreferenceCategory(category); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -167,16 +131,9 @@ func TestGetPreferenceCategory(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetPreference(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
user := th.BasicUser
|
||||
|
||||
preferences := model.Preferences{
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ package api
|
|||
import (
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/braintree/manners"
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
|
|
@ -73,11 +74,10 @@ func StartServer() {
|
|||
}
|
||||
|
||||
go func() {
|
||||
err := manners.ListenAndServe(utils.Cfg.ServiceSettings.ListenAddress, handler)
|
||||
err := manners.ListenAndServe(utils.Cfg.ServiceSettings.ListenAddress, handlers.RecoveryHandler(handlers.PrintRecoveryStack(true))(handler))
|
||||
if err != nil {
|
||||
l4g.Critical(utils.T("api.server.start_server.starting.critical"), err)
|
||||
time.Sleep(time.Second)
|
||||
panic(utils.T("api.server.start_server.starting.panic") + err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package api
|
||||
|
||||
/*
|
||||
func createSubDomain(subDomain string, target string) {
|
||||
|
||||
if utils.Cfg.AWSSettings.Route53AccessKeyId == "" {
|
||||
return
|
||||
}
|
||||
|
||||
creds := aws.Creds(utils.Cfg.AWSSettings.Route53AccessKeyId, utils.Cfg.AWSSettings.Route53SecretAccessKey, "")
|
||||
r53 := route53.New(aws.DefaultConfig.Merge(&aws.Config{Credentials: creds, Region: utils.Cfg.AWSSettings.Route53Region}))
|
||||
|
||||
rr := route53.ResourceRecord{
|
||||
Value: aws.String(target),
|
||||
}
|
||||
|
||||
rrs := make([]*route53.ResourceRecord, 1)
|
||||
rrs[0] = &rr
|
||||
|
||||
change := route53.Change{
|
||||
Action: aws.String("CREATE"),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("%v.%v", subDomain, utils.Cfg.ServiceSettings.Domain)),
|
||||
TTL: aws.Long(300),
|
||||
Type: aws.String("CNAME"),
|
||||
ResourceRecords: rrs,
|
||||
},
|
||||
}
|
||||
|
||||
changes := make([]*route53.Change, 1)
|
||||
changes[0] = &change
|
||||
|
||||
r53req := &route53.ChangeResourceRecordSetsInput{
|
||||
HostedZoneID: aws.String(utils.Cfg.AWSSettings.Route53ZoneId),
|
||||
ChangeBatch: &route53.ChangeBatch{
|
||||
Changes: changes,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := r53.ChangeResourceRecordSets(r53req); err != nil {
|
||||
l4g.Error("erro in createSubDomain domain=%v err=%v", subDomain, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func doesSubDomainExist(subDomain string) bool {
|
||||
|
||||
// if it's configured for testing then skip this step
|
||||
if utils.Cfg.AWSSettings.Route53AccessKeyId == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
creds := aws.Creds(utils.Cfg.AWSSettings.Route53AccessKeyId, utils.Cfg.AWSSettings.Route53SecretAccessKey, "")
|
||||
r53 := route53.New(aws.DefaultConfig.Merge(&aws.Config{Credentials: creds, Region: utils.Cfg.AWSSettings.Route53Region}))
|
||||
|
||||
r53req := &route53.ListResourceRecordSetsInput{
|
||||
HostedZoneID: aws.String(utils.Cfg.AWSSettings.Route53ZoneId),
|
||||
MaxItems: aws.String("1"),
|
||||
StartRecordName: aws.String(fmt.Sprintf("%v.%v.", subDomain, utils.Cfg.ServiceSettings.Domain)),
|
||||
}
|
||||
|
||||
if result, err := r53.ListResourceRecordSets(r53req); err != nil {
|
||||
l4g.Error("error in doesSubDomainExist domain=%v err=%v", subDomain, err)
|
||||
return true
|
||||
} else {
|
||||
|
||||
for _, v := range result.ResourceRecordSets {
|
||||
if v.Name != nil && *v.Name == fmt.Sprintf("%v.%v.", subDomain, utils.Cfg.ServiceSettings.Domain) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
*/
|
||||
|
|
@ -112,7 +112,6 @@ func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map
|
|||
password := model.NewId()
|
||||
|
||||
newUser := model.User{
|
||||
TeamId: teamId,
|
||||
Username: sUser.Username,
|
||||
FirstName: firstName,
|
||||
LastName: lastName,
|
||||
|
|
@ -120,7 +119,7 @@ func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map
|
|||
Password: password,
|
||||
}
|
||||
|
||||
if mUser := ImportUser(&newUser); mUser != nil {
|
||||
if mUser := ImportUser(teamId, &newUser); mUser != nil {
|
||||
addedUsers[sUser.Id] = mUser
|
||||
log.WriteString(utils.T("api.slackimport.slack_add_users.email_pwd", map[string]interface{}{"Email": newUser.Email, "Password": password}))
|
||||
} else {
|
||||
|
|
|
|||
475
api/team.go
475
api/team.go
|
|
@ -6,38 +6,43 @@ package api
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/platform/einterfaces"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
func InitTeam(r *mux.Router) {
|
||||
func InitTeam() {
|
||||
l4g.Debug(utils.T("api.team.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/teams").Subrouter()
|
||||
sr.Handle("/create", ApiAppHandler(createTeam)).Methods("POST")
|
||||
sr.Handle("/create_from_signup", ApiAppHandler(createTeamFromSignup)).Methods("POST")
|
||||
sr.Handle("/create_with_ldap", ApiAppHandler(createTeamWithLdap)).Methods("POST")
|
||||
sr.Handle("/create_with_sso/{service:[A-Za-z]+}", ApiAppHandler(createTeamFromSSO)).Methods("POST")
|
||||
sr.Handle("/signup", ApiAppHandler(signupTeam)).Methods("POST")
|
||||
sr.Handle("/all", ApiAppHandler(getAll)).Methods("GET")
|
||||
sr.Handle("/find_team_by_name", ApiAppHandler(findTeamByName)).Methods("POST")
|
||||
sr.Handle("/invite_members", ApiUserRequired(inviteMembers)).Methods("POST")
|
||||
sr.Handle("/update", ApiUserRequired(updateTeam)).Methods("POST")
|
||||
sr.Handle("/me", ApiUserRequired(getMyTeam)).Methods("GET")
|
||||
sr.Handle("/get_invite_info", ApiAppHandler(getInviteInfo)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/create", ApiAppHandler(createTeam)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/create_from_signup", ApiAppHandler(createTeamFromSignup)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/signup", ApiAppHandler(signupTeam)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/all", ApiAppHandler(getAll)).Methods("GET")
|
||||
BaseRoutes.Teams.Handle("/all_team_listings", ApiUserRequired(GetAllTeamListings)).Methods("GET")
|
||||
BaseRoutes.Teams.Handle("/get_invite_info", ApiAppHandler(getInviteInfo)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/find_team_by_name", ApiAppHandler(findTeamByName)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/members/{id:[A-Za-z0-9]+}", ApiUserRequired(getMembers)).Methods("GET")
|
||||
|
||||
BaseRoutes.NeedTeam.Handle("/me", ApiUserRequired(getMyTeam)).Methods("GET")
|
||||
BaseRoutes.NeedTeam.Handle("/update", ApiUserRequired(updateTeam)).Methods("POST")
|
||||
|
||||
BaseRoutes.NeedTeam.Handle("/invite_members", ApiUserRequired(inviteMembers)).Methods("POST")
|
||||
|
||||
BaseRoutes.NeedTeam.Handle("/add_user_to_team", ApiUserRequired(addUserToTeam)).Methods("POST")
|
||||
|
||||
// These should be moved to the global admain console
|
||||
sr.Handle("/import_team", ApiUserRequired(importTeam)).Methods("POST")
|
||||
sr.Handle("/export_team", ApiUserRequired(exportTeam)).Methods("GET")
|
||||
BaseRoutes.Teams.Handle("/import_team", ApiUserRequired(importTeam)).Methods("POST")
|
||||
BaseRoutes.Teams.Handle("/export_team", ApiUserRequired(exportTeam)).Methods("GET")
|
||||
BaseRoutes.Teams.Handle("/add_user_to_team_from_invite", ApiUserRequired(addUserToTeamFromInvite)).Methods("POST")
|
||||
}
|
||||
|
||||
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -92,67 +97,6 @@ func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
w.Write([]byte(model.MapToJson(m)))
|
||||
}
|
||||
|
||||
func createTeamFromSSO(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
service := params["service"]
|
||||
|
||||
sso := utils.Cfg.GetSSOService(service)
|
||||
if sso != nil && !sso.Enable {
|
||||
c.SetInvalidParam("createTeamFromSSO", "service")
|
||||
return
|
||||
}
|
||||
|
||||
team := model.TeamFromJson(r.Body)
|
||||
|
||||
if team == nil {
|
||||
c.SetInvalidParam("createTeamFromSSO", "team")
|
||||
return
|
||||
}
|
||||
|
||||
if !isTeamCreationAllowed(c, team.Email) {
|
||||
return
|
||||
}
|
||||
|
||||
team.PreSave()
|
||||
|
||||
team.Name = model.CleanTeamName(team.Name)
|
||||
|
||||
if err := team.IsValid(*utils.Cfg.TeamSettings.RestrictTeamNames); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
team.Id = ""
|
||||
|
||||
found := true
|
||||
count := 0
|
||||
for found {
|
||||
if found = FindTeamByName(c, team.Name, "true"); c.Err != nil {
|
||||
return
|
||||
} else if found {
|
||||
team.Name = team.Name + strconv.Itoa(count)
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Team().Save(team); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
rteam := result.Data.(*model.Team)
|
||||
|
||||
if _, err := CreateDefaultChannels(c, rteam.Id); err != nil {
|
||||
c.Err = nil
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]string{"follow_link": c.GetSiteURL() + "/api/v1/oauth/" + service + "/signup?team=" + rteam.Name}
|
||||
w.Write([]byte(model.MapToJson(data)))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
|
||||
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.email_disabled.app_error", nil, "")
|
||||
|
|
@ -186,13 +130,11 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
password := teamSignup.User.Password
|
||||
teamSignup.User.PreSave()
|
||||
teamSignup.User.TeamId = model.NewId()
|
||||
if err := teamSignup.User.IsValid(); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
teamSignup.User.Id = ""
|
||||
teamSignup.User.TeamId = ""
|
||||
teamSignup.User.Password = password
|
||||
|
||||
if !model.ComparePassword(teamSignup.Hash, fmt.Sprintf("%v:%v", teamSignup.Data, utils.Cfg.EmailSettings.InviteSalt)) {
|
||||
|
|
@ -206,10 +148,7 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
found := FindTeamByName(c, teamSignup.Team.Name, "true")
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
found := FindTeamByName(teamSignup.Team.Name)
|
||||
|
||||
if found {
|
||||
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.unavailable.app_error", nil, "d="+teamSignup.Team.Name)
|
||||
|
|
@ -227,15 +166,16 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
teamSignup.User.TeamId = rteam.Id
|
||||
teamSignup.User.EmailVerified = true
|
||||
|
||||
ruser, err := CreateUser(rteam, &teamSignup.User)
|
||||
ruser, err := CreateUser(&teamSignup.User)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
JoinUserToTeam(rteam, ruser)
|
||||
|
||||
InviteMembers(c, rteam, ruser, teamSignup.Invites)
|
||||
|
||||
teamSignup.Team = *rteam
|
||||
|
|
@ -245,85 +185,38 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func createTeamWithLdap(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
ldap := einterfaces.GetLdapInterface()
|
||||
if ldap == nil {
|
||||
c.Err = model.NewLocAppError("createTeamWithLdap", "ent.ldap.do_login.licence_disable.app_error", nil, "")
|
||||
func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
team := model.TeamFromJson(r.Body)
|
||||
|
||||
if team == nil {
|
||||
c.SetInvalidParam("createTeam", "team")
|
||||
return
|
||||
}
|
||||
|
||||
teamSignup := model.TeamSignupFromJson(r.Body)
|
||||
var user *model.User
|
||||
if len(c.Session.UserId) > 0 {
|
||||
uchan := Srv.Store.User().Get(c.Session.UserId)
|
||||
|
||||
if teamSignup == nil {
|
||||
c.SetInvalidParam("createTeam", "teamSignup")
|
||||
return
|
||||
if result := <-uchan; result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
team.Email = user.Email
|
||||
}
|
||||
}
|
||||
|
||||
teamSignup.Team.PreSave()
|
||||
|
||||
if err := teamSignup.Team.IsValid(*utils.Cfg.TeamSettings.RestrictTeamNames); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if !isTeamCreationAllowed(c, teamSignup.Team.Email) {
|
||||
return
|
||||
}
|
||||
|
||||
teamSignup.Team.Id = ""
|
||||
|
||||
found := FindTeamByName(c, teamSignup.Team.Name, "true")
|
||||
rteam := CreateTeam(c, team)
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if found {
|
||||
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.unavailable.app_error", nil, "d="+teamSignup.Team.Name)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := ldap.GetUser(teamSignup.User.Username)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
err = ldap.CheckPassword(teamSignup.User.Username, teamSignup.User.Password)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Team().Save(&teamSignup.Team); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
rteam := result.Data.(*model.Team)
|
||||
|
||||
if _, err := CreateDefaultChannels(c, rteam.Id); err != nil {
|
||||
c.Err = nil
|
||||
return
|
||||
}
|
||||
|
||||
user.TeamId = rteam.Id
|
||||
ruser, err := CreateUser(rteam, user)
|
||||
if user != nil {
|
||||
err := JoinUserToTeam(team, user)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
teamSignup.Team = *rteam
|
||||
teamSignup.User = *ruser
|
||||
|
||||
w.Write([]byte(teamSignup.ToJson()))
|
||||
}
|
||||
}
|
||||
|
||||
func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
team := model.TeamFromJson(r.Body)
|
||||
rteam := CreateTeam(c, team)
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
w.Write([]byte(rteam.ToJson()))
|
||||
|
|
@ -360,6 +253,31 @@ func CreateTeam(c *Context, team *model.Team) *model.Team {
|
|||
}
|
||||
}
|
||||
|
||||
func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError {
|
||||
|
||||
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id}
|
||||
|
||||
channelRole := ""
|
||||
if team.Email == user.Email {
|
||||
tm.Roles = model.ROLE_TEAM_ADMIN
|
||||
channelRole = model.CHANNEL_ROLE_ADMIN
|
||||
}
|
||||
|
||||
if tmr := <-Srv.Store.Team().SaveMember(tm); tmr.Err != nil {
|
||||
return tmr.Err
|
||||
}
|
||||
|
||||
// Soft error if there is an issue joining the default channels
|
||||
if err := JoinDefaultChannels(team.Id, user, channelRole); err != nil {
|
||||
l4g.Error(utils.T("api.user.create_user.joining.error"), user.Id, team.Id, err)
|
||||
}
|
||||
|
||||
RemoveAllSessionsForUserId(user.Id)
|
||||
InvalidateCacheForUser(user.Id)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isTeamCreationAllowed(c *Context, email string) bool {
|
||||
|
||||
email = strings.ToLower(email)
|
||||
|
|
@ -389,6 +307,24 @@ func isTeamCreationAllowed(c *Context, email string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func GetAllTeamListings(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if result := <-Srv.Store.Team().GetAllTeamListing(); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
teams := result.Data.([]*model.Team)
|
||||
m := make(map[string]*model.Team)
|
||||
for _, v := range teams {
|
||||
m[v.Id] = v
|
||||
if !c.IsSystemAdmin() {
|
||||
m[v.Id].Sanitize()
|
||||
}
|
||||
}
|
||||
|
||||
w.Write([]byte(model.TeamMapToJson(m)))
|
||||
}
|
||||
}
|
||||
|
||||
func getAll(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if result := <-Srv.Store.Team().GetAll(); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
|
|
@ -435,42 +371,6 @@ func revokeAllSessions(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func findTeamByName(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
m := model.MapFromJson(r.Body)
|
||||
|
||||
name := strings.ToLower(strings.TrimSpace(m["name"]))
|
||||
all := strings.ToLower(strings.TrimSpace(m["all"]))
|
||||
|
||||
found := FindTeamByName(c, name, all)
|
||||
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if found {
|
||||
w.Write([]byte("true"))
|
||||
} else {
|
||||
w.Write([]byte("false"))
|
||||
}
|
||||
}
|
||||
|
||||
func FindTeamByName(c *Context, name string, all string) bool {
|
||||
|
||||
if name == "" || len(name) > 64 {
|
||||
c.SetInvalidParam("findTeamByName", "domain")
|
||||
return false
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Team().GetByName(name); result.Err != nil {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
invites := model.InvitesFromJson(r.Body)
|
||||
if len(invites.Invites) == 0 {
|
||||
|
|
@ -479,7 +379,7 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
tchan := Srv.Store.Team().Get(c.Session.TeamId)
|
||||
tchan := Srv.Store.Team().Get(c.TeamId)
|
||||
uchan := Srv.Store.User().Get(c.Session.UserId)
|
||||
|
||||
var team *model.Team
|
||||
|
|
@ -498,15 +398,6 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
user = result.Data.(*model.User)
|
||||
}
|
||||
|
||||
var invNum int64 = 0
|
||||
for i, invite := range invites.Invites {
|
||||
if result := <-Srv.Store.User().GetByEmail(c.Session.TeamId, invite["email"]); result.Err == nil || result.Err.Id != store.MISSING_ACCOUNT_ERROR {
|
||||
invNum = int64(i)
|
||||
c.Err = model.NewLocAppError("invite_members", "api.team.invite_members.already.app_error", nil, strconv.FormatInt(invNum, 10))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ia := make([]string, len(invites.Invites))
|
||||
for _, invite := range invites.Invites {
|
||||
ia = append(ia, invite["email"])
|
||||
|
|
@ -517,6 +408,146 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
w.Write([]byte(invites.ToJson()))
|
||||
}
|
||||
|
||||
func addUserToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := model.MapFromJson(r.Body)
|
||||
userId := params["user_id"]
|
||||
|
||||
if len(userId) != 26 {
|
||||
c.SetInvalidParam("addUserToTeam", "user_id")
|
||||
return
|
||||
}
|
||||
|
||||
tchan := Srv.Store.Team().Get(c.TeamId)
|
||||
uchan := Srv.Store.User().Get(userId)
|
||||
|
||||
var team *model.Team
|
||||
if result := <-tchan; result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-uchan; result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
|
||||
if !c.IsTeamAdmin() {
|
||||
c.Err = model.NewLocAppError("addUserToTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
err := JoinUserToTeam(team, user)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
w.Write([]byte(model.MapToJson(params)))
|
||||
}
|
||||
|
||||
func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
params := model.MapFromJson(r.Body)
|
||||
hash := params["hash"]
|
||||
data := params["data"]
|
||||
inviteId := params["invite_id"]
|
||||
|
||||
teamId := ""
|
||||
var team *model.Team
|
||||
|
||||
if len(hash) > 0 {
|
||||
props := model.MapFromJson(strings.NewReader(data))
|
||||
|
||||
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
|
||||
c.Err = model.NewLocAppError("addUserToTeamFromInvite", "api.user.create_user.signup_link_invalid.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
t, err := strconv.ParseInt(props["time"], 10, 64)
|
||||
if err != nil || model.GetMillis()-t > 1000*60*60*48 { // 48 hours
|
||||
c.Err = model.NewLocAppError("addUserToTeamFromInvite", "api.user.create_user.signup_link_expired.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
teamId = props["id"]
|
||||
|
||||
// try to load the team to make sure it exists
|
||||
if result := <-Srv.Store.Team().Get(teamId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
}
|
||||
|
||||
if len(inviteId) > 0 {
|
||||
if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
teamId = team.Id
|
||||
}
|
||||
}
|
||||
|
||||
if len(teamId) == 0 {
|
||||
c.Err = model.NewLocAppError("addUserToTeamFromInvite", "api.user.create_user.signup_link_invalid.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
uchan := Srv.Store.User().Get(c.Session.UserId)
|
||||
|
||||
var user *model.User
|
||||
if result := <-uchan; result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
|
||||
tm := c.Session.GetTeamByTeamId(teamId)
|
||||
|
||||
if tm == nil {
|
||||
err := JoinUserToTeam(team, user)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
team.Sanitize()
|
||||
|
||||
w.Write([]byte(team.ToJson()))
|
||||
}
|
||||
|
||||
func FindTeamByName(name string) bool {
|
||||
if result := <-Srv.Store.Team().GetByName(name); result.Err != nil {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func findTeamByName(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
m := model.MapFromJson(r.Body)
|
||||
name := strings.ToLower(strings.TrimSpace(m["name"]))
|
||||
|
||||
found := FindTeamByName(name)
|
||||
|
||||
if found {
|
||||
w.Write([]byte("true"))
|
||||
} else {
|
||||
w.Write([]byte("false"))
|
||||
}
|
||||
}
|
||||
|
||||
func InviteMembers(c *Context, team *model.Team, user *model.User, invites []string) {
|
||||
for _, invite := range invites {
|
||||
if len(invite) > 0 {
|
||||
|
|
@ -573,7 +604,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
team.Id = c.Session.TeamId
|
||||
team.Id = c.TeamId
|
||||
|
||||
if !c.IsTeamAdmin() {
|
||||
c.Err = model.NewLocAppError("updateTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId)
|
||||
|
|
@ -592,7 +623,6 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
oldTeam.DisplayName = team.DisplayName
|
||||
oldTeam.InviteId = team.InviteId
|
||||
oldTeam.AllowOpenInvite = team.AllowOpenInvite
|
||||
oldTeam.AllowTeamListing = team.AllowTeamListing
|
||||
oldTeam.CompanyName = team.CompanyName
|
||||
oldTeam.AllowedDomains = team.AllowedDomains
|
||||
//oldTeam.Type = team.Type
|
||||
|
|
@ -617,16 +647,11 @@ func PermanentDeleteTeam(c *Context, team *model.Team) *model.AppError {
|
|||
return result.Err
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.User().GetForExport(team.Id); result.Err != nil {
|
||||
if result := <-Srv.Store.Channel().PermanentDeleteByTeam(team.Id); result.Err != nil {
|
||||
return result.Err
|
||||
} else {
|
||||
users := result.Data.([]*model.User)
|
||||
for _, user := range users {
|
||||
PermanentDeleteUser(c, user)
|
||||
}
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Channel().PermanentDeleteByTeam(team.Id); result.Err != nil {
|
||||
if result := <-Srv.Store.Team().RemoveAllMembersByTeam(team.Id); result.Err != nil {
|
||||
return result.Err
|
||||
}
|
||||
|
||||
|
|
@ -642,11 +667,11 @@ func PermanentDeleteTeam(c *Context, team *model.Team) *model.AppError {
|
|||
|
||||
func getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if len(c.Session.TeamId) == 0 {
|
||||
if len(c.TeamId) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Team().Get(c.Session.TeamId); result.Err != nil {
|
||||
if result := <-Srv.Store.Team().Get(c.TeamId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else if HandleEtag(result.Data.(*model.Team).Etag(), w, r) {
|
||||
|
|
@ -659,7 +684,7 @@ func getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.HasPermissionsToTeam(c.Session.TeamId, "import") || !c.IsTeamAdmin() {
|
||||
if !c.HasPermissionsToTeam(c.TeamId, "import") || !c.IsTeamAdmin() {
|
||||
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.admin.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
|
|
@ -714,7 +739,7 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
switch importFrom {
|
||||
case "slack":
|
||||
var err *model.AppError
|
||||
if err, log = SlackImport(fileData, fileSize, c.Session.TeamId); err != nil {
|
||||
if err, log = SlackImport(fileData, fileSize, c.TeamId); err != nil {
|
||||
c.Err = err
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
}
|
||||
|
|
@ -726,7 +751,7 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func exportTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.HasPermissionsToTeam(c.Session.TeamId, "export") || !c.IsTeamAdmin() {
|
||||
if !c.HasPermissionsToTeam(c.TeamId, "export") || !c.IsTeamAdmin() {
|
||||
c.Err = model.NewLocAppError("exportTeam", "api.team.export_team.admin.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
|
|
@ -765,3 +790,23 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
w.Write([]byte(model.MapToJson(result)))
|
||||
}
|
||||
}
|
||||
|
||||
func getMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
id := params["id"]
|
||||
|
||||
if c.Session.GetTeamByTeamId(id) == nil {
|
||||
if !c.HasSystemAdminPermissions("getMembers") {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Team().GetMembers(id); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
members := result.Data.([]*model.TeamMember)
|
||||
w.Write([]byte(model.TeamMembersToJson(members)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
249
api/team_test.go
249
api/team_test.go
|
|
@ -13,7 +13,9 @@ import (
|
|||
)
|
||||
|
||||
func TestSignupTeam(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
_, err := Client.SignupTeam("test@nowhere.com", "name")
|
||||
if err != nil {
|
||||
|
|
@ -22,7 +24,9 @@ func TestSignupTeam(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateFromSignupTeam(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
props := make(map[string]string)
|
||||
props["email"] = strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com"
|
||||
|
|
@ -47,6 +51,8 @@ func TestCreateFromSignupTeam(t *testing.T) {
|
|||
}
|
||||
|
||||
ruser := rts.Data.(*model.TeamSignup).User
|
||||
rteam := rts.Data.(*model.TeamSignup).Team
|
||||
Client.SetTeamId(rteam.Id)
|
||||
|
||||
if result, err := Client.LoginById(ruser.Id, user.Password); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -69,7 +75,9 @@ func TestCreateFromSignupTeam(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateTeam(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
rteam, err := Client.CreateTeam(&team)
|
||||
|
|
@ -77,11 +85,13 @@ func TestCreateTeam(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
user := &model.User{TeamId: rteam.Data.(*model.Team).Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user, rteam.Data.(*model.Team))
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
Client.SetTeamId(rteam.Data.(*model.Team).Id)
|
||||
|
||||
c1 := Client.Must(Client.GetChannels("")).Data.(*model.ChannelList)
|
||||
if len(c1.Channels) != 2 {
|
||||
|
|
@ -108,23 +118,124 @@ func TestCreateTeam(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetAllTeams(t *testing.T) {
|
||||
Setup()
|
||||
func TestAddUserToTeam(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN, AllowTeamListing: true}
|
||||
props := make(map[string]string)
|
||||
props["email"] = strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com"
|
||||
props["name"] = "Test Company name"
|
||||
props["time"] = fmt.Sprintf("%v", model.GetMillis())
|
||||
|
||||
data := model.MapToJson(props)
|
||||
hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
|
||||
|
||||
team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: props["email"], Type: model.TEAM_OPEN}
|
||||
user := model.User{Email: props["email"], Nickname: "Corey Hulen", Password: "hello"}
|
||||
|
||||
ts := model.TeamSignup{Team: team, User: user, Invites: []string{"success+test@simulator.amazonses.com"}, Data: data, Hash: hash}
|
||||
|
||||
rts, err := Client.CreateTeamFromSignup(&ts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if rts.Data.(*model.TeamSignup).Team.DisplayName != team.DisplayName {
|
||||
t.Fatal("full name didn't match")
|
||||
}
|
||||
|
||||
ruser := rts.Data.(*model.TeamSignup).User
|
||||
rteam := rts.Data.(*model.TeamSignup).Team
|
||||
Client.SetTeamId(rteam.Id)
|
||||
|
||||
if result, err := Client.LoginById(ruser.Id, user.Password); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.User).Email != user.Email {
|
||||
t.Fatal("email's didn't match")
|
||||
}
|
||||
}
|
||||
|
||||
user2 := th.CreateUser(th.BasicClient)
|
||||
if result, err := th.BasicClient.AddUserToTeam(user2.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rm := result.Data.(map[string]string)
|
||||
if rm["user_id"] != user2.Id {
|
||||
t.Fatal("email's didn't match")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddUserToTeamFromInvite(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
props := make(map[string]string)
|
||||
props["email"] = strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com"
|
||||
props["name"] = "Test Company name"
|
||||
props["time"] = fmt.Sprintf("%v", model.GetMillis())
|
||||
|
||||
data := model.MapToJson(props)
|
||||
hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
|
||||
|
||||
team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: props["email"], Type: model.TEAM_OPEN}
|
||||
user := model.User{Email: props["email"], Nickname: "Corey Hulen", Password: "hello"}
|
||||
|
||||
ts := model.TeamSignup{Team: team, User: user, Invites: []string{"success+test@simulator.amazonses.com"}, Data: data, Hash: hash}
|
||||
|
||||
rts, err := Client.CreateTeamFromSignup(&ts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if rts.Data.(*model.TeamSignup).Team.DisplayName != team.DisplayName {
|
||||
t.Fatal("full name didn't match")
|
||||
}
|
||||
|
||||
ruser := rts.Data.(*model.TeamSignup).User
|
||||
rteam := rts.Data.(*model.TeamSignup).Team
|
||||
Client.SetTeamId(rteam.Id)
|
||||
|
||||
if result, err := Client.LoginById(ruser.Id, user.Password); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.User).Email != user.Email {
|
||||
t.Fatal("email's didn't match")
|
||||
}
|
||||
}
|
||||
|
||||
user2 := th.CreateUser(th.BasicClient)
|
||||
Client.Must(Client.Logout())
|
||||
Client.Must(Client.LoginByEmail("", user2.Email, user2.Password))
|
||||
|
||||
if result, err := th.BasicClient.AddUserToTeamFromInvite("", "", rteam.InviteId); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rtm := result.Data.(*model.Team)
|
||||
if rtm.Id != rteam.Id {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllTeams(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user, team)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
enableIncomingHooks := *utils.Cfg.TeamSettings.EnableTeamListing
|
||||
defer func() {
|
||||
*utils.Cfg.TeamSettings.EnableTeamListing = enableIncomingHooks
|
||||
}()
|
||||
*utils.Cfg.TeamSettings.EnableTeamListing = true
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if r1, err := Client.GetAllTeams(); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -144,6 +255,56 @@ func TestGetAllTeams(t *testing.T) {
|
|||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if r1, err := Client.GetAllTeams(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
teams := r1.Data.(map[string]*model.Team)
|
||||
if teams[team.Id].Name != team.Name {
|
||||
t.Fatal()
|
||||
}
|
||||
if teams[team.Id].Email != team.Email {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllTeamListings(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN, AllowOpenInvite: true}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user, team)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if r1, err := Client.GetAllTeamListings(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
teams := r1.Data.(map[string]*model.Team)
|
||||
if teams[team.Id].Name != team.Name {
|
||||
t.Fatal()
|
||||
}
|
||||
if teams[team.Id].Email != "" {
|
||||
t.Fatal("Non admin users shoudn't get full listings")
|
||||
}
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if r1, err := Client.GetAllTeams(); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -159,16 +320,20 @@ func TestGetAllTeams(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTeamPermDelete(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user1, team)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
|
@ -198,19 +363,23 @@ func TestTeamPermDelete(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestInviteMembers(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user, team)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
invite := make(map[string]string)
|
||||
invite["email"] = model.NewId() + "success+test@simulator.amazonses.com"
|
||||
invite["email"] = "success+" + model.NewId() + "@simulator.amazonses.com"
|
||||
invite["first_name"] = "Test"
|
||||
invite["last_name"] = "Guy"
|
||||
invites := &model.Invites{Invites: []map[string]string{invite}}
|
||||
|
|
@ -227,20 +396,25 @@ func TestInviteMembers(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateTeamDisplayName(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "success+" + model.NewId() + "@simulator.amazonses.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user := &model.User{Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user, team)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
LinkUserToTeam(user2, team)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
vteam := &model.Team{DisplayName: team.DisplayName, Name: team.Name, Email: team.Email, Type: team.Type}
|
||||
vteam.DisplayName = "NewName"
|
||||
|
|
@ -262,6 +436,9 @@ func TestUpdateTeamDisplayName(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFuzzyTeamCreate(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
for i := 0; i < len(utils.FUZZY_STRINGS_NAMES) || i < len(utils.FUZZY_STRINGS_EMAILS); i++ {
|
||||
testDisplayName := "Name"
|
||||
|
|
@ -284,19 +461,24 @@ func TestFuzzyTeamCreate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetMyTeam(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
th.BasicClient.Logout()
|
||||
Client := th.BasicClient
|
||||
|
||||
team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
rteam, _ := Client.CreateTeam(&team)
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
rteam, _ := Client.CreateTeam(team)
|
||||
team = rteam.Data.(*model.Team)
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user := model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
ruser, _ := Client.CreateUser(&user, "")
|
||||
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
|
||||
|
||||
Client.LoginByEmail(team.Name, user.Email, user.Password)
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if result, err := Client.GetMyTeam(""); err != nil {
|
||||
t.Fatal("Failed to get user")
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.Team).DisplayName != team.DisplayName {
|
||||
t.Fatal("team names did not match")
|
||||
|
|
@ -309,3 +491,14 @@ func TestGetMyTeam(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTeamMembers(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
|
||||
if result, err := th.BasicClient.GetTeamMembers(th.BasicTeam.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
members := result.Data.([]*model.TeamMember)
|
||||
t.Log(members)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1425
api/user.go
1425
api/user.go
File diff suppressed because it is too large
Load diff
577
api/user_test.go
577
api/user_test.go
File diff suppressed because it is too large
Load diff
|
|
@ -7,7 +7,6 @@ import (
|
|||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -21,14 +20,15 @@ const (
|
|||
)
|
||||
|
||||
type WebConn struct {
|
||||
WebSocket *websocket.Conn
|
||||
Send chan *model.Message
|
||||
TeamId string
|
||||
UserId string
|
||||
ChannelAccessCache map[string]bool
|
||||
WebSocket *websocket.Conn
|
||||
Send chan *model.Message
|
||||
SessionId string
|
||||
UserId string
|
||||
hasPermissionsToChannel map[string]bool
|
||||
hasPermissionsToTeam map[string]bool
|
||||
}
|
||||
|
||||
func NewWebConn(ws *websocket.Conn, teamId string, userId string, sessionId string) *WebConn {
|
||||
func NewWebConn(ws *websocket.Conn, userId string, sessionId string) *WebConn {
|
||||
go func() {
|
||||
achan := Srv.Store.User().UpdateUserAndSessionActivity(userId, sessionId, model.GetMillis())
|
||||
pchan := Srv.Store.User().UpdateLastPingAt(userId, model.GetMillis())
|
||||
|
|
@ -42,7 +42,14 @@ func NewWebConn(ws *websocket.Conn, teamId string, userId string, sessionId stri
|
|||
}
|
||||
}()
|
||||
|
||||
return &WebConn{Send: make(chan *model.Message, 64), WebSocket: ws, UserId: userId, TeamId: teamId, ChannelAccessCache: make(map[string]bool)}
|
||||
return &WebConn{
|
||||
Send: make(chan *model.Message, 64),
|
||||
WebSocket: ws,
|
||||
UserId: userId,
|
||||
SessionId: sessionId,
|
||||
hasPermissionsToChannel: make(map[string]bool),
|
||||
hasPermissionsToTeam: make(map[string]bool),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *WebConn) readPump() {
|
||||
|
|
@ -69,7 +76,6 @@ func (c *WebConn) readPump() {
|
|||
if err := c.WebSocket.ReadJSON(&msg); err != nil {
|
||||
return
|
||||
} else {
|
||||
msg.TeamId = c.TeamId
|
||||
msg.UserId = c.UserId
|
||||
PublishAndForget(&msg)
|
||||
}
|
||||
|
|
@ -107,19 +113,53 @@ func (c *WebConn) writePump() {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *WebConn) updateChannelAccessCache(channelId string) bool {
|
||||
allowed := hasPermissionsToChannel(Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.UserId))
|
||||
c.ChannelAccessCache[channelId] = allowed
|
||||
|
||||
return allowed
|
||||
func (c *WebConn) InvalidateCache() {
|
||||
c.hasPermissionsToChannel = make(map[string]bool)
|
||||
c.hasPermissionsToTeam = make(map[string]bool)
|
||||
}
|
||||
|
||||
func hasPermissionsToChannel(sc store.StoreChannel) bool {
|
||||
if cresult := <-sc; cresult.Err != nil {
|
||||
return false
|
||||
} else if cresult.Data.(int64) != 1 {
|
||||
return false
|
||||
func (c *WebConn) HasPermissionsToTeam(teamId string) bool {
|
||||
perm, ok := c.hasPermissionsToTeam[teamId]
|
||||
if !ok {
|
||||
session := GetSession(c.SessionId)
|
||||
if session == nil {
|
||||
perm = false
|
||||
c.hasPermissionsToTeam[teamId] = perm
|
||||
} else {
|
||||
member := session.GetTeamByTeamId(teamId)
|
||||
|
||||
if member != nil {
|
||||
perm = true
|
||||
c.hasPermissionsToTeam[teamId] = perm
|
||||
} else {
|
||||
perm = true
|
||||
c.hasPermissionsToTeam[teamId] = perm
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return perm
|
||||
}
|
||||
|
||||
func (c *WebConn) HasPermissionsToChannel(channelId string) bool {
|
||||
perm, ok := c.hasPermissionsToChannel[channelId]
|
||||
if !ok {
|
||||
if cresult := <-Srv.Store.Channel().CheckPermissionsToNoTeam(channelId, c.UserId); cresult.Err != nil {
|
||||
perm = false
|
||||
c.hasPermissionsToChannel[channelId] = perm
|
||||
} else {
|
||||
count := cresult.Data.(int64)
|
||||
|
||||
if count == 1 {
|
||||
perm = true
|
||||
c.hasPermissionsToChannel[channelId] = perm
|
||||
} else {
|
||||
perm = false
|
||||
c.hasPermissionsToChannel[channelId] = perm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return perm
|
||||
}
|
||||
|
|
|
|||
128
api/web_hub.go
128
api/web_hub.go
|
|
@ -10,19 +10,21 @@ import (
|
|||
)
|
||||
|
||||
type Hub struct {
|
||||
teamHubs map[string]*TeamHub
|
||||
register chan *WebConn
|
||||
unregister chan *WebConn
|
||||
broadcast chan *model.Message
|
||||
stop chan string
|
||||
connections map[*WebConn]bool
|
||||
register chan *WebConn
|
||||
unregister chan *WebConn
|
||||
broadcast chan *model.Message
|
||||
stop chan string
|
||||
invalidateUser chan string
|
||||
}
|
||||
|
||||
var hub = &Hub{
|
||||
register: make(chan *WebConn),
|
||||
unregister: make(chan *WebConn),
|
||||
teamHubs: make(map[string]*TeamHub),
|
||||
broadcast: make(chan *model.Message),
|
||||
stop: make(chan string),
|
||||
register: make(chan *WebConn),
|
||||
unregister: make(chan *WebConn),
|
||||
connections: make(map[*WebConn]bool),
|
||||
broadcast: make(chan *model.Message),
|
||||
stop: make(chan string),
|
||||
invalidateUser: make(chan string),
|
||||
}
|
||||
|
||||
func PublishAndForget(message *model.Message) {
|
||||
|
|
@ -31,16 +33,8 @@ func PublishAndForget(message *model.Message) {
|
|||
}()
|
||||
}
|
||||
|
||||
func UpdateChannelAccessCache(teamId, userId, channelId string) {
|
||||
if nh, ok := hub.teamHubs[teamId]; ok {
|
||||
nh.UpdateChannelAccessCache(userId, channelId)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateChannelAccessCacheAndForget(teamId, userId, channelId string) {
|
||||
go func() {
|
||||
UpdateChannelAccessCache(teamId, userId, channelId)
|
||||
}()
|
||||
func InvalidateCacheForUser(userId string) {
|
||||
hub.invalidateUser <- userId
|
||||
}
|
||||
|
||||
func (h *Hub) Register(webConn *WebConn) {
|
||||
|
|
@ -65,34 +59,92 @@ func (h *Hub) Start() {
|
|||
go func() {
|
||||
for {
|
||||
select {
|
||||
case webCon := <-h.register:
|
||||
h.connections[webCon] = true
|
||||
|
||||
case c := <-h.register:
|
||||
nh := h.teamHubs[c.TeamId]
|
||||
|
||||
if nh == nil {
|
||||
nh = NewTeamHub(c.TeamId)
|
||||
h.teamHubs[c.TeamId] = nh
|
||||
nh.Start()
|
||||
case webCon := <-h.unregister:
|
||||
if _, ok := h.connections[webCon]; ok {
|
||||
delete(h.connections, webCon)
|
||||
close(webCon.Send)
|
||||
}
|
||||
case userId := <-h.invalidateUser:
|
||||
for webCon := range h.connections {
|
||||
if webCon.UserId == userId {
|
||||
webCon.InvalidateCache()
|
||||
}
|
||||
}
|
||||
|
||||
nh.Register(c)
|
||||
|
||||
case c := <-h.unregister:
|
||||
if nh, ok := h.teamHubs[c.TeamId]; ok {
|
||||
nh.Unregister(c)
|
||||
}
|
||||
case msg := <-h.broadcast:
|
||||
nh := h.teamHubs[msg.TeamId]
|
||||
if nh != nil {
|
||||
nh.broadcast <- msg
|
||||
for webCon := range h.connections {
|
||||
if shouldSendEvent(webCon, msg) {
|
||||
select {
|
||||
case webCon.Send <- msg:
|
||||
default:
|
||||
close(webCon.Send)
|
||||
delete(h.connections, webCon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case s := <-h.stop:
|
||||
l4g.Debug(utils.T("api.web_hub.start.stopping.debug"), s)
|
||||
for _, v := range h.teamHubs {
|
||||
v.Stop()
|
||||
|
||||
for webCon := range h.connections {
|
||||
webCon.WebSocket.Close()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func shouldSendEvent(webCon *WebConn, msg *model.Message) bool {
|
||||
|
||||
if webCon.UserId == msg.UserId {
|
||||
// Don't need to tell the user they are typing
|
||||
if msg.Action == model.ACTION_TYPING {
|
||||
return false
|
||||
}
|
||||
|
||||
// We have to make sure the user is in the channel. Otherwise system messages that
|
||||
// post about users in channels they are not in trigger warnings.
|
||||
if len(msg.ChannelId) > 0 {
|
||||
allowed := webCon.HasPermissionsToChannel(msg.ChannelId)
|
||||
|
||||
if !allowed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Don't share a user's view or preference events with other users
|
||||
if msg.Action == model.ACTION_CHANNEL_VIEWED {
|
||||
return false
|
||||
} else if msg.Action == model.ACTION_PREFERENCE_CHANGED {
|
||||
return false
|
||||
} else if msg.Action == model.ACTION_EPHEMERAL_MESSAGE {
|
||||
// For now, ephemeral messages are sent directly to individual users
|
||||
return false
|
||||
}
|
||||
|
||||
// Only report events to users who are in the team for the event
|
||||
if len(msg.TeamId) > 0 {
|
||||
allowed := webCon.HasPermissionsToTeam(msg.TeamId)
|
||||
|
||||
if !allowed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Only report events to users who are in the channel for the event
|
||||
if len(msg.ChannelId) > 0 {
|
||||
allowed := webCon.HasPermissionsToChannel(msg.ChannelId)
|
||||
|
||||
if !allowed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,15 @@ package api
|
|||
|
||||
import (
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func InitWebSocket(r *mux.Router) {
|
||||
func InitWebSocket() {
|
||||
l4g.Debug(utils.T("api.web_socket.init.debug"))
|
||||
r.Handle("/websocket", ApiUserRequiredTrustRequester(connect)).Methods("GET")
|
||||
BaseRoutes.Users.Handle("/websocket", ApiUserRequiredTrustRequester(connect)).Methods("GET")
|
||||
hub.Start()
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +33,7 @@ func connect(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
wc := NewWebConn(ws, c.Session.TeamId, c.Session.UserId, c.Session.Id)
|
||||
wc := NewWebConn(ws, c.Session.UserId, c.Session.Id)
|
||||
hub.Register(wc)
|
||||
go wc.writePump()
|
||||
wc.readPump()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ package api
|
|||
import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
|
@ -14,22 +13,14 @@ import (
|
|||
)
|
||||
|
||||
func TestSocket(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
channel1 := th.BasicChannel
|
||||
channel2 := th.CreateChannel(Client, team)
|
||||
Client.Must(Client.AddChannelMember(channel1.Id, th.BasicUser2.Id))
|
||||
|
||||
url := "ws://localhost" + utils.Cfg.ServiceSettings.ListenAddress + "/api/v1/websocket"
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test Web Scoket 1", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
channel2 := &model.Channel{DisplayName: "Test Web Scoket 2", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
url := "ws://localhost" + utils.Cfg.ServiceSettings.ListenAddress + model.API_URL_SUFFIX + "/users/websocket"
|
||||
|
||||
header1 := http.Header{}
|
||||
header1.Set(model.HEADER_AUTH, "BEARER "+Client.AuthToken)
|
||||
|
|
@ -39,10 +30,7 @@ func TestSocket(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
Client.LoginByEmail(team.Name, user2.Email, "pwd")
|
||||
th.LoginBasic2()
|
||||
|
||||
header2 := http.Header{}
|
||||
header2.Set(model.HEADER_AUTH, "BEARER "+Client.AuthToken)
|
||||
|
|
@ -53,21 +41,11 @@ func TestSocket(t *testing.T) {
|
|||
}
|
||||
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
Client.Must(Client.JoinChannel(channel1.Id))
|
||||
|
||||
// Read the user_added message that gets generated
|
||||
var rmsg model.Message
|
||||
if err := c2.ReadJSON(&rmsg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Read the second user_added message that gets generated
|
||||
if err := c2.ReadJSON(&rmsg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Test sending message without a channelId
|
||||
m := model.NewMessage("", "", "", model.ACTION_TYPING)
|
||||
m := model.NewMessage(team.Id, "", "", model.ACTION_TYPING)
|
||||
m.Add("RootId", model.NewId())
|
||||
m.Add("ParentId", model.NewId())
|
||||
|
||||
|
|
@ -77,6 +55,8 @@ func TestSocket(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Log(rmsg.ToJson())
|
||||
|
||||
if team.Id != rmsg.TeamId {
|
||||
t.Fatal("Ids do not match")
|
||||
}
|
||||
|
|
@ -86,7 +66,7 @@ func TestSocket(t *testing.T) {
|
|||
}
|
||||
|
||||
// Test sending messsage to Channel you have access to
|
||||
m = model.NewMessage("", channel1.Id, "", model.ACTION_TYPING)
|
||||
m = model.NewMessage(team.Id, channel1.Id, "", model.ACTION_TYPING)
|
||||
m.Add("RootId", model.NewId())
|
||||
m.Add("ParentId", model.NewId())
|
||||
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
type TeamHub struct {
|
||||
connections map[*WebConn]bool
|
||||
broadcast chan *model.Message
|
||||
register chan *WebConn
|
||||
unregister chan *WebConn
|
||||
stop chan bool
|
||||
teamId string
|
||||
}
|
||||
|
||||
func NewTeamHub(teamId string) *TeamHub {
|
||||
return &TeamHub{
|
||||
broadcast: make(chan *model.Message),
|
||||
register: make(chan *WebConn),
|
||||
unregister: make(chan *WebConn),
|
||||
connections: make(map[*WebConn]bool),
|
||||
stop: make(chan bool),
|
||||
teamId: teamId,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *TeamHub) Register(webConn *WebConn) {
|
||||
h.register <- webConn
|
||||
}
|
||||
|
||||
func (h *TeamHub) Unregister(webConn *WebConn) {
|
||||
h.unregister <- webConn
|
||||
}
|
||||
|
||||
func (h *TeamHub) Stop() {
|
||||
h.stop <- true
|
||||
}
|
||||
|
||||
func (h *TeamHub) Start() {
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case webCon := <-h.register:
|
||||
h.connections[webCon] = true
|
||||
case webCon := <-h.unregister:
|
||||
if _, ok := h.connections[webCon]; ok {
|
||||
delete(h.connections, webCon)
|
||||
close(webCon.Send)
|
||||
}
|
||||
case msg := <-h.broadcast:
|
||||
for webCon := range h.connections {
|
||||
if ShouldSendEvent(webCon, msg) {
|
||||
select {
|
||||
case webCon.Send <- msg:
|
||||
default:
|
||||
close(webCon.Send)
|
||||
delete(h.connections, webCon)
|
||||
}
|
||||
}
|
||||
}
|
||||
case s := <-h.stop:
|
||||
if s {
|
||||
|
||||
l4g.Debug(utils.T("api.web_team_hun.start.debug"), h.teamId)
|
||||
|
||||
for webCon := range h.connections {
|
||||
webCon.WebSocket.Close()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (h *TeamHub) UpdateChannelAccessCache(userId string, channelId string) {
|
||||
for webCon := range h.connections {
|
||||
if webCon.UserId == userId {
|
||||
webCon.updateChannelAccessCache(channelId)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ShouldSendEvent(webCon *WebConn, msg *model.Message) bool {
|
||||
|
||||
if webCon.UserId == msg.UserId {
|
||||
// Don't need to tell the user they are typing
|
||||
if msg.Action == model.ACTION_TYPING {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
// Don't share a user's view or preference events with other users
|
||||
if msg.Action == model.ACTION_CHANNEL_VIEWED {
|
||||
return false
|
||||
} else if msg.Action == model.ACTION_PREFERENCE_CHANGED {
|
||||
return false
|
||||
} else if msg.Action == model.ACTION_EPHEMERAL_MESSAGE {
|
||||
// For now, ephemeral messages are sent directly to individual users
|
||||
return false
|
||||
}
|
||||
|
||||
// Only report events to a user who is the subject of the event, or is in the channel of the event
|
||||
if len(msg.ChannelId) > 0 {
|
||||
allowed, ok := webCon.ChannelAccessCache[msg.ChannelId]
|
||||
if !ok {
|
||||
allowed = webCon.updateChannelAccessCache(msg.ChannelId)
|
||||
}
|
||||
|
||||
if !allowed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -14,20 +14,19 @@ import (
|
|||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
func InitWebhook(r *mux.Router) {
|
||||
func InitWebhook() {
|
||||
l4g.Debug(utils.T("api.webhook.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/hooks").Subrouter()
|
||||
sr.Handle("/incoming/create", ApiUserRequired(createIncomingHook)).Methods("POST")
|
||||
sr.Handle("/incoming/delete", ApiUserRequired(deleteIncomingHook)).Methods("POST")
|
||||
sr.Handle("/incoming/list", ApiUserRequired(getIncomingHooks)).Methods("GET")
|
||||
BaseRoutes.Hooks.Handle("/incoming/create", ApiUserRequired(createIncomingHook)).Methods("POST")
|
||||
BaseRoutes.Hooks.Handle("/incoming/delete", ApiUserRequired(deleteIncomingHook)).Methods("POST")
|
||||
BaseRoutes.Hooks.Handle("/incoming/list", ApiUserRequired(getIncomingHooks)).Methods("GET")
|
||||
|
||||
sr.Handle("/outgoing/create", ApiUserRequired(createOutgoingHook)).Methods("POST")
|
||||
sr.Handle("/outgoing/regen_token", ApiUserRequired(regenOutgoingHookToken)).Methods("POST")
|
||||
sr.Handle("/outgoing/delete", ApiUserRequired(deleteOutgoingHook)).Methods("POST")
|
||||
sr.Handle("/outgoing/list", ApiUserRequired(getOutgoingHooks)).Methods("GET")
|
||||
BaseRoutes.Hooks.Handle("/outgoing/create", ApiUserRequired(createOutgoingHook)).Methods("POST")
|
||||
BaseRoutes.Hooks.Handle("/outgoing/regen_token", ApiUserRequired(regenOutgoingHookToken)).Methods("POST")
|
||||
BaseRoutes.Hooks.Handle("/outgoing/delete", ApiUserRequired(deleteOutgoingHook)).Methods("POST")
|
||||
BaseRoutes.Hooks.Handle("/outgoing/list", ApiUserRequired(getOutgoingHooks)).Methods("GET")
|
||||
|
||||
sr.Handle("/{id:[A-Za-z0-9]+}", ApiAppHandler(incomingWebhook)).Methods("POST")
|
||||
BaseRoutes.Hooks.Handle("/{id:[A-Za-z0-9]+}", ApiAppHandler(incomingWebhook)).Methods("POST")
|
||||
|
||||
// Old route. Remove eventually.
|
||||
mr := Srv.Router
|
||||
|
|
@ -59,10 +58,10 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
cchan := Srv.Store.Channel().Get(hook.ChannelId)
|
||||
pchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, hook.ChannelId, c.Session.UserId)
|
||||
pchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, hook.ChannelId, c.Session.UserId)
|
||||
|
||||
hook.UserId = c.Session.UserId
|
||||
hook.TeamId = c.Session.TeamId
|
||||
hook.TeamId = c.TeamId
|
||||
|
||||
var channel *model.Channel
|
||||
if result := <-cchan; result.Err != nil {
|
||||
|
|
@ -73,7 +72,7 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
if !c.HasPermissionsToChannel(pchan, "createIncomingHook") {
|
||||
if channel.Type != model.CHANNEL_OPEN || channel.TeamId != c.Session.TeamId {
|
||||
if channel.Type != model.CHANNEL_OPEN || channel.TeamId != c.TeamId {
|
||||
c.LogAudit("fail - bad channel permissions")
|
||||
return
|
||||
}
|
||||
|
|
@ -149,7 +148,7 @@ func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Webhook().GetIncomingByTeam(c.Session.TeamId); result.Err != nil {
|
||||
if result := <-Srv.Store.Webhook().GetIncomingByTeam(c.TeamId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
|
|
@ -183,11 +182,11 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
hook.CreatorId = c.Session.UserId
|
||||
hook.TeamId = c.Session.TeamId
|
||||
hook.TeamId = c.TeamId
|
||||
|
||||
if len(hook.ChannelId) != 0 {
|
||||
cchan := Srv.Store.Channel().Get(hook.ChannelId)
|
||||
pchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, hook.ChannelId, c.Session.UserId)
|
||||
pchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, hook.ChannelId, c.Session.UserId)
|
||||
|
||||
var channel *model.Channel
|
||||
if result := <-cchan; result.Err != nil {
|
||||
|
|
@ -199,11 +198,14 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if channel.Type != model.CHANNEL_OPEN {
|
||||
c.LogAudit("fail - not open channel")
|
||||
c.Err = model.NewLocAppError("createOutgoingHook", "api.webhook.create_outgoing.not_open.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
if !c.HasPermissionsToChannel(pchan, "createOutgoingHook") {
|
||||
if channel.Type != model.CHANNEL_OPEN || channel.TeamId != c.Session.TeamId {
|
||||
if channel.Type != model.CHANNEL_OPEN || channel.TeamId != c.TeamId {
|
||||
c.LogAudit("fail - bad channel permissions")
|
||||
c.Err = model.NewLocAppError("createOutgoingHook", "api.webhook.create_outgoing.permissions.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -237,7 +239,7 @@ func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Webhook().GetOutgoingByTeam(c.Session.TeamId); result.Err != nil {
|
||||
if result := <-Srv.Store.Webhook().GetOutgoingByTeam(c.TeamId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
|
|
@ -292,7 +294,7 @@ func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
|
||||
if !utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
|
||||
c.Err = model.NewLocAppError("regenOutgoingHookToken", "api.webhook.regen_outgoing_token.disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
|
|
@ -323,7 +325,7 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request)
|
|||
} else {
|
||||
hook = result.Data.(*model.OutgoingWebhook)
|
||||
|
||||
if c.Session.TeamId != hook.TeamId && c.Session.UserId != hook.CreatorId && !c.IsTeamAdmin() {
|
||||
if c.TeamId != hook.TeamId && c.Session.UserId != hook.CreatorId && !c.IsTeamAdmin() {
|
||||
c.LogAudit("fail - inappropriate permissions")
|
||||
c.Err = model.NewLocAppError("regenOutgoingHookToken", "api.webhook.regen_outgoing_token.permissions.app_error", nil, "user_id="+c.Session.UserId)
|
||||
return
|
||||
|
|
@ -398,7 +400,7 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
if len(channelName) != 0 {
|
||||
if channelName[0] == '@' {
|
||||
if result := <-Srv.Store.User().GetByUsername(hook.TeamId, channelName[1:]); result.Err != nil {
|
||||
if result := <-Srv.Store.User().GetByUsername(channelName[1:]); result.Err != nil {
|
||||
c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.user.app_error", nil, "err="+result.Err.Message)
|
||||
return
|
||||
} else {
|
||||
|
|
@ -426,7 +428,11 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||
pchan := Srv.Store.Channel().CheckPermissionsTo(hook.TeamId, channel.Id, hook.UserId)
|
||||
|
||||
// create a mock session
|
||||
c.Session = model.Session{UserId: hook.UserId, TeamId: hook.TeamId, IsOAuth: false}
|
||||
c.Session = model.Session{
|
||||
UserId: hook.UserId,
|
||||
TeamMembers: []*model.TeamMember{{TeamId: hook.TeamId, UserId: hook.UserId}},
|
||||
IsOAuth: false,
|
||||
}
|
||||
|
||||
if !c.HasPermissionsToChannel(pchan, "createIncomingHook") && channel.Type != model.CHANNEL_OPEN {
|
||||
c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.permissions.app_error", nil, "")
|
||||
|
|
|
|||
|
|
@ -4,416 +4,599 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCreateIncomingHook(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
user := th.SystemAdminUser
|
||||
team := th.SystemAdminTeam
|
||||
channel1 := th.CreateChannel(Client, team)
|
||||
channel2 := th.CreatePrivateChannel(Client, team)
|
||||
user2 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user2, team)
|
||||
|
||||
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
|
||||
enableOutgoingHooks := utils.Cfg.ServiceSettings.EnableOutgoingWebhooks
|
||||
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
|
||||
|
||||
hook := &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
|
||||
if utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
|
||||
var rhook *model.IncomingWebhook
|
||||
if result, err := Client.CreateIncomingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rhook = result.Data.(*model.IncomingWebhook)
|
||||
}
|
||||
|
||||
if hook.ChannelId != rhook.ChannelId {
|
||||
t.Fatal("channel ids didn't match")
|
||||
}
|
||||
|
||||
if rhook.UserId != user.Id {
|
||||
t.Fatal("user ids didn't match")
|
||||
}
|
||||
|
||||
if rhook.TeamId != team.Id {
|
||||
t.Fatal("team ids didn't match")
|
||||
}
|
||||
|
||||
hook = &model.IncomingWebhook{ChannelId: "junk"}
|
||||
if _, err := Client.CreateIncomingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - bad channel id")
|
||||
}
|
||||
|
||||
hook = &model.IncomingWebhook{ChannelId: channel2.Id, UserId: "123", TeamId: "456"}
|
||||
if result, err := Client.CreateIncomingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.IncomingWebhook).UserId != user.Id {
|
||||
t.Fatal("bad user id wasn't overwritten")
|
||||
}
|
||||
if result.Data.(*model.IncomingWebhook).TeamId != team.Id {
|
||||
t.Fatal("bad team id wasn't overwritten")
|
||||
}
|
||||
}
|
||||
var rhook *model.IncomingWebhook
|
||||
if result, err := Client.CreateIncomingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if _, err := Client.CreateIncomingWebhook(hook); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
rhook = result.Data.(*model.IncomingWebhook)
|
||||
}
|
||||
|
||||
if hook.ChannelId != rhook.ChannelId {
|
||||
t.Fatal("channel ids didn't match")
|
||||
}
|
||||
|
||||
if rhook.UserId != user.Id {
|
||||
t.Fatal("user ids didn't match")
|
||||
}
|
||||
|
||||
if rhook.TeamId != team.Id {
|
||||
t.Fatal("team ids didn't match")
|
||||
}
|
||||
|
||||
hook = &model.IncomingWebhook{ChannelId: "junk"}
|
||||
if _, err := Client.CreateIncomingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - bad channel id")
|
||||
}
|
||||
|
||||
hook = &model.IncomingWebhook{ChannelId: channel2.Id, UserId: "123", TeamId: "456"}
|
||||
if result, err := Client.CreateIncomingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.IncomingWebhook).UserId != user.Id {
|
||||
t.Fatal("bad user id wasn't overwritten")
|
||||
}
|
||||
if result.Data.(*model.IncomingWebhook).TeamId != team.Id {
|
||||
t.Fatal("bad team id wasn't overwritten")
|
||||
}
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user2.Id, user2.Password))
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
hook = &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
|
||||
if _, err := Client.CreateIncomingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - not system/team admin")
|
||||
}
|
||||
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
|
||||
|
||||
if _, err := Client.CreateIncomingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hook = &model.IncomingWebhook{ChannelId: channel2.Id}
|
||||
|
||||
if _, err := Client.CreateIncomingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - channel is private and not a member")
|
||||
}
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = false
|
||||
|
||||
if _, err := Client.CreateIncomingWebhook(hook); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIncomingHooks(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
team := th.SystemAdminTeam
|
||||
channel1 := th.CreateChannel(Client, team)
|
||||
user2 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user2, team)
|
||||
|
||||
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
|
||||
enableOutgoingHooks := utils.Cfg.ServiceSettings.EnableOutgoingWebhooks
|
||||
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
hook1 := &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook1 = Client.Must(Client.CreateIncomingWebhook(hook1)).Data.(*model.IncomingWebhook)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
hook2 := &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook2 = Client.Must(Client.CreateIncomingWebhook(hook2)).Data.(*model.IncomingWebhook)
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
if utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
|
||||
hook1 := &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook1 = Client.Must(Client.CreateIncomingWebhook(hook1)).Data.(*model.IncomingWebhook)
|
||||
|
||||
hook2 := &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook2 = Client.Must(Client.CreateIncomingWebhook(hook2)).Data.(*model.IncomingWebhook)
|
||||
|
||||
if result, err := Client.ListIncomingWebhooks(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
hooks := result.Data.([]*model.IncomingWebhook)
|
||||
|
||||
if len(hooks) != 2 {
|
||||
t.Fatal("incorrect number of hooks")
|
||||
}
|
||||
}
|
||||
if result, err := Client.ListIncomingWebhooks(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if _, err := Client.ListIncomingWebhooks(); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
hooks := result.Data.([]*model.IncomingWebhook)
|
||||
|
||||
if len(hooks) != 2 {
|
||||
t.Fatal("incorrect number of hooks")
|
||||
}
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user2.Id, user2.Password))
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if _, err := Client.ListIncomingWebhooks(); err == nil {
|
||||
t.Fatal("should have errored - not system/team admin")
|
||||
}
|
||||
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
|
||||
|
||||
if _, err := Client.ListIncomingWebhooks(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = false
|
||||
|
||||
if _, err := Client.ListIncomingWebhooks(); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteIncomingHook(t *testing.T) {
|
||||
Setup()
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
team := th.SystemAdminTeam
|
||||
channel1 := th.CreateChannel(Client, team)
|
||||
user2 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user2, team)
|
||||
|
||||
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
|
||||
enableOutgoingHooks := utils.Cfg.ServiceSettings.EnableOutgoingWebhooks
|
||||
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
hook := &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
if _, err := Client.DeleteIncomingWebhook(hook.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
if _, err := Client.DeleteIncomingWebhook("junk"); err == nil {
|
||||
t.Fatal("should have failed - bad id")
|
||||
}
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
if _, err := Client.DeleteIncomingWebhook(""); err == nil {
|
||||
t.Fatal("should have failed - empty id")
|
||||
}
|
||||
|
||||
if utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
|
||||
hook := &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
|
||||
hooks := Client.Must(Client.ListIncomingWebhooks()).Data.([]*model.IncomingWebhook)
|
||||
if len(hooks) != 0 {
|
||||
t.Fatal("delete didn't work properly")
|
||||
}
|
||||
|
||||
data := make(map[string]string)
|
||||
data["id"] = hook.Id
|
||||
hook = &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
|
||||
|
||||
if _, err := Client.DeleteIncomingWebhook(data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user2.Id, user2.Password))
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
hooks := Client.Must(Client.ListIncomingWebhooks()).Data.([]*model.IncomingWebhook)
|
||||
if len(hooks) != 0 {
|
||||
t.Fatal("delete didn't work properly")
|
||||
}
|
||||
} else {
|
||||
data := make(map[string]string)
|
||||
data["id"] = "123"
|
||||
if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
|
||||
t.Fatal("should have failed - not system/team admin")
|
||||
}
|
||||
|
||||
if _, err := Client.DeleteIncomingWebhook(data); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
|
||||
|
||||
if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
|
||||
t.Fatal("should have failed - not creator or team admin")
|
||||
}
|
||||
|
||||
hook = &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
|
||||
|
||||
if _, err := Client.DeleteIncomingWebhook(hook.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = false
|
||||
|
||||
if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOutgoingHook(t *testing.T) {
|
||||
Setup()
|
||||
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
user := th.SystemAdminUser
|
||||
team := th.SystemAdminTeam
|
||||
team2 := th.CreateTeam(Client)
|
||||
channel1 := th.CreateChannel(Client, team)
|
||||
channel2 := th.CreatePrivateChannel(Client, team)
|
||||
user2 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user2, team)
|
||||
user3 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user3, team2)
|
||||
|
||||
enableOutgoingHooks := utils.Cfg.ServiceSettings.EnableOutgoingWebhooks
|
||||
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
|
||||
|
||||
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
|
||||
if utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
|
||||
var rhook *model.OutgoingWebhook
|
||||
if result, err := Client.CreateOutgoingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
rhook = result.Data.(*model.OutgoingWebhook)
|
||||
}
|
||||
|
||||
if hook.ChannelId != rhook.ChannelId {
|
||||
t.Fatal("channel ids didn't match")
|
||||
}
|
||||
|
||||
if rhook.CreatorId != user.Id {
|
||||
t.Fatal("user ids didn't match")
|
||||
}
|
||||
|
||||
if rhook.TeamId != team.Id {
|
||||
t.Fatal("team ids didn't match")
|
||||
}
|
||||
|
||||
hook = &model.OutgoingWebhook{ChannelId: "junk", CallbackURLs: []string{"http://nowhere.com"}}
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - bad channel id")
|
||||
}
|
||||
|
||||
hook = &model.OutgoingWebhook{ChannelId: channel2.Id, CreatorId: "123", TeamId: "456", CallbackURLs: []string{"http://nowhere.com"}}
|
||||
if result, err := Client.CreateOutgoingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.OutgoingWebhook).CreatorId != user.Id {
|
||||
t.Fatal("bad user id wasn't overwritten")
|
||||
}
|
||||
if result.Data.(*model.OutgoingWebhook).TeamId != team.Id {
|
||||
t.Fatal("bad team id wasn't overwritten")
|
||||
}
|
||||
}
|
||||
var rhook *model.OutgoingWebhook
|
||||
if result, err := Client.CreateOutgoingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
rhook = result.Data.(*model.OutgoingWebhook)
|
||||
}
|
||||
|
||||
if hook.ChannelId != rhook.ChannelId {
|
||||
t.Fatal("channel ids didn't match")
|
||||
}
|
||||
|
||||
if rhook.CreatorId != user.Id {
|
||||
t.Fatal("user ids didn't match")
|
||||
}
|
||||
|
||||
if rhook.TeamId != team.Id {
|
||||
t.Fatal("team ids didn't match")
|
||||
}
|
||||
|
||||
hook = &model.OutgoingWebhook{ChannelId: "junk", CallbackURLs: []string{"http://nowhere.com"}}
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - bad channel id")
|
||||
}
|
||||
|
||||
hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CreatorId: "123", TeamId: "456", CallbackURLs: []string{"http://nowhere.com"}}
|
||||
if result, err := Client.CreateOutgoingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.OutgoingWebhook).CreatorId != user.Id {
|
||||
t.Fatal("bad user id wasn't overwritten")
|
||||
}
|
||||
if result.Data.(*model.OutgoingWebhook).TeamId != team.Id {
|
||||
t.Fatal("bad team id wasn't overwritten")
|
||||
}
|
||||
}
|
||||
|
||||
hook = &model.OutgoingWebhook{ChannelId: channel2.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - private channel")
|
||||
}
|
||||
|
||||
hook = &model.OutgoingWebhook{CallbackURLs: []string{"http://nowhere.com"}}
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - blank channel and trigger words")
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user2.Id, user2.Password))
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - not system/team admin")
|
||||
}
|
||||
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
|
||||
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user3.Id, user3.Password))
|
||||
Client.SetTeamId(team2.Id)
|
||||
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
|
||||
t.Fatal("should have failed - wrong team")
|
||||
}
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = false
|
||||
|
||||
if _, err := Client.CreateOutgoingWebhook(hook); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListOutgoingHooks(t *testing.T) {
|
||||
Setup()
|
||||
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
team := th.SystemAdminTeam
|
||||
channel1 := th.CreateChannel(Client, team)
|
||||
user2 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user2, team)
|
||||
|
||||
enableOutgoingHooks := utils.Cfg.ServiceSettings.EnableOutgoingWebhooks
|
||||
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
hook1 := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook1 = Client.Must(Client.CreateOutgoingWebhook(hook1)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
hook2 := &model.OutgoingWebhook{TriggerWords: []string{"trigger"}, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook2 = Client.Must(Client.CreateOutgoingWebhook(hook2)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
if utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
|
||||
hook1 := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook1 = Client.Must(Client.CreateOutgoingWebhook(hook1)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
hook2 := &model.OutgoingWebhook{TriggerWords: []string{"trigger"}, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook2 = Client.Must(Client.CreateOutgoingWebhook(hook2)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
if result, err := Client.ListOutgoingWebhooks(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
hooks := result.Data.([]*model.OutgoingWebhook)
|
||||
|
||||
if len(hooks) != 2 {
|
||||
t.Fatal("incorrect number of hooks")
|
||||
}
|
||||
}
|
||||
if result, err := Client.ListOutgoingWebhooks(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if _, err := Client.ListOutgoingWebhooks(); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
hooks := result.Data.([]*model.OutgoingWebhook)
|
||||
|
||||
if len(hooks) != 2 {
|
||||
t.Fatal("incorrect number of hooks")
|
||||
}
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user2.Id, user2.Password))
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if _, err := Client.ListOutgoingWebhooks(); err == nil {
|
||||
t.Fatal("should have failed - not system/team admin")
|
||||
}
|
||||
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
|
||||
|
||||
if _, err := Client.ListOutgoingWebhooks(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = false
|
||||
|
||||
if _, err := Client.ListOutgoingWebhooks(); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteOutgoingHook(t *testing.T) {
|
||||
Setup()
|
||||
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
team := th.SystemAdminTeam
|
||||
channel1 := th.CreateChannel(Client, team)
|
||||
user2 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user2, team)
|
||||
|
||||
enableOutgoingHooks := utils.Cfg.ServiceSettings.EnableOutgoingWebhooks
|
||||
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
if _, err := Client.DeleteOutgoingWebhook("junk"); err == nil {
|
||||
t.Fatal("should have failed - bad hook id")
|
||||
}
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
if _, err := Client.DeleteOutgoingWebhook(""); err == nil {
|
||||
t.Fatal("should have failed - empty hook id")
|
||||
}
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
if _, err := Client.DeleteOutgoingWebhook(hook.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
|
||||
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
|
||||
hooks := Client.Must(Client.ListOutgoingWebhooks()).Data.([]*model.OutgoingWebhook)
|
||||
if len(hooks) != 0 {
|
||||
t.Fatal("delete didn't work properly")
|
||||
}
|
||||
|
||||
data := make(map[string]string)
|
||||
data["id"] = hook.Id
|
||||
hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
if _, err := Client.DeleteOutgoingWebhook(data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user2.Id, user2.Password))
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
hooks := Client.Must(Client.ListOutgoingWebhooks()).Data.([]*model.OutgoingWebhook)
|
||||
if len(hooks) != 0 {
|
||||
t.Fatal("delete didn't work properly")
|
||||
}
|
||||
} else {
|
||||
data := make(map[string]string)
|
||||
data["id"] = "123"
|
||||
if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
|
||||
t.Fatal("should have failed - not system/team admin")
|
||||
}
|
||||
|
||||
if _, err := Client.DeleteOutgoingWebhook(data); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
|
||||
|
||||
if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
|
||||
t.Fatal("should have failed - not creator or team admin")
|
||||
}
|
||||
|
||||
hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
if _, err := Client.DeleteOutgoingWebhook(hook.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = false
|
||||
|
||||
if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegenOutgoingHookToken(t *testing.T) {
|
||||
Setup()
|
||||
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
team := th.SystemAdminTeam
|
||||
team2 := th.CreateTeam(Client)
|
||||
channel1 := th.CreateChannel(Client, team)
|
||||
user2 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user2, team)
|
||||
user3 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user3, team2)
|
||||
|
||||
enableOutgoingHooks := utils.Cfg.ServiceSettings.EnableOutgoingWebhooks
|
||||
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
|
||||
|
||||
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
if _, err := Client.RegenOutgoingWebhookToken("junk"); err == nil {
|
||||
t.Fatal("should have failed - bad id")
|
||||
}
|
||||
|
||||
if _, err := Client.RegenOutgoingWebhookToken(""); err == nil {
|
||||
t.Fatal("should have failed - empty id")
|
||||
}
|
||||
|
||||
if result, err := Client.RegenOutgoingWebhookToken(hook.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.OutgoingWebhook).Token == hook.Token {
|
||||
t.Fatal("regen didn't work properly")
|
||||
}
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user2.Id, user2.Password))
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err == nil {
|
||||
t.Fatal("should have failed - not system/team admin")
|
||||
}
|
||||
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
|
||||
|
||||
hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
|
||||
|
||||
if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
Client.Must(Client.LoginById(user3.Id, user3.Password))
|
||||
Client.SetTeamId(team2.Id)
|
||||
|
||||
if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err == nil {
|
||||
t.Fatal("should have failed - wrong team")
|
||||
}
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = false
|
||||
|
||||
if _, err := Client.RegenOutgoingWebhookToken(hook.Id); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
}
|
||||
func TestIncomingWebhooks(t *testing.T) {
|
||||
th := Setup().InitSystemAdmin()
|
||||
Client := th.SystemAdminClient
|
||||
team := th.SystemAdminTeam
|
||||
channel1 := th.CreateChannel(Client, team)
|
||||
user2 := th.CreateUser(Client)
|
||||
LinkUserToTeam(user2, team)
|
||||
|
||||
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
hook := &model.IncomingWebhook{ChannelId: channel1.Id}
|
||||
hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
url := "/hooks/" + hook.Id
|
||||
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
Client.LoginByEmail(team.Name, user.Email, "pwd")
|
||||
if _, err := Client.DoPost(url, "{\"text\":\"this is a test\"}", "application/json"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", channel1.Name), "application/json"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
|
||||
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
|
||||
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
|
||||
if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"#%s\"}", channel1.Name), "application/json"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
data := make(map[string]string)
|
||||
data["id"] = hook.Id
|
||||
Client.Must(Client.CreateDirectChannel(user2.Id))
|
||||
|
||||
if result, err := Client.RegenOutgoingWebhookToken(data); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if result.Data.(*model.OutgoingWebhook).Token == hook.Token {
|
||||
t.Fatal("regen didn't work properly")
|
||||
}
|
||||
}
|
||||
if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"@%s\"}", user2.Username), "application/json"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
} else {
|
||||
data := make(map[string]string)
|
||||
data["id"] = "123"
|
||||
if _, err := Client.DoPost(url, "payload={\"text\":\"this is a test\"}", "application/x-www-form-urlencoded"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := Client.RegenOutgoingWebhookToken(data); err == nil {
|
||||
t.Fatal("should have errored - webhooks turned off")
|
||||
}
|
||||
attachmentPayload := `{
|
||||
"text": "this is a test",
|
||||
"attachments": [
|
||||
{
|
||||
"fallback": "Required plain-text summary of the attachment.",
|
||||
|
||||
"color": "#36a64f",
|
||||
|
||||
"pretext": "Optional text that appears above the attachment block",
|
||||
|
||||
"author_name": "Bobby Tables",
|
||||
"author_link": "http://flickr.com/bobby/",
|
||||
"author_icon": "http://flickr.com/icons/bobby.jpg",
|
||||
|
||||
"title": "Slack API Documentation",
|
||||
"title_link": "https://api.slack.com/",
|
||||
|
||||
"text": "Optional text that appears within the attachment",
|
||||
|
||||
"fields": [
|
||||
{
|
||||
"title": "Priority",
|
||||
"value": "High",
|
||||
"short": false
|
||||
}
|
||||
],
|
||||
|
||||
"image_url": "http://my-website.com/path/to/image.jpg",
|
||||
"thumb_url": "http://example.com/path/to/thumb.png"
|
||||
}
|
||||
]
|
||||
}`
|
||||
|
||||
if _, err := Client.DoPost(url, attachmentPayload, "application/json"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := Client.DoPost(url, "{\"text\":\"\"}", "application/json"); err == nil {
|
||||
t.Fatal("should have failed - no text")
|
||||
}
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = false
|
||||
|
||||
if _, err := Client.DoPost(url, "{\"text\":\"this is a test\"}", "application/json"); err == nil {
|
||||
t.Fatal("should have failed - webhooks turned off")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@
|
|||
"MaxUsersPerTeam": 50,
|
||||
"EnableTeamCreation": true,
|
||||
"EnableUserCreation": true,
|
||||
"EnableOpenServer": false,
|
||||
"RestrictCreationToDomains": "",
|
||||
"RestrictTeamNames": true,
|
||||
"EnableTeamListing": false,
|
||||
"EnableCustomBrand": false,
|
||||
"CustomBrandText": ""
|
||||
},
|
||||
|
|
@ -143,6 +143,7 @@
|
|||
"LastNameAttribute": "",
|
||||
"EmailAttribute": "",
|
||||
"UsernameAttribute": "",
|
||||
"NicknameAttribute": "",
|
||||
"IdAttribute": "",
|
||||
"SkipCertificateVerification": false,
|
||||
"QueryTimeout": 60,
|
||||
|
|
@ -154,4 +155,4 @@
|
|||
"Directory": "./data/",
|
||||
"EnableDaily": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,10 +8,10 @@ import (
|
|||
)
|
||||
|
||||
type LdapInterface interface {
|
||||
DoLogin(team *model.Team, id string, password string) (*model.User, *model.AppError)
|
||||
DoLogin(id string, password string) (*model.User, *model.AppError)
|
||||
GetUser(id string) (*model.User, *model.AppError)
|
||||
CheckPassword(id string, password string) *model.AppError
|
||||
SwitchToEmail(userId, ldapId, ldapPassword string) *model.AppError
|
||||
SwitchToLdap(userId, ldapId, ldapPassword string) *model.AppError
|
||||
ValidateFilter(filter string) *model.AppError
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
type MfaInterface interface {
|
||||
GenerateQrCode(team *model.Team, user *model.User) ([]byte, *model.AppError)
|
||||
GenerateQrCode(user *model.User) ([]byte, *model.AppError)
|
||||
Activate(user *model.User, token string) *model.AppError
|
||||
Deactivate(userId string) *model.AppError
|
||||
ValidateToken(secret, token string) (bool, *model.AppError)
|
||||
|
|
|
|||
50
i18n/en.json
50
i18n/en.json
|
|
@ -1313,11 +1313,11 @@
|
|||
},
|
||||
{
|
||||
"id": "api.templates.singin_change_email.body.info",
|
||||
"translation": "You updated your sign-in method for {{.TeamDisplayName}} on {{ .TeamURL }} to {{.Method}}.<br>If this change wasn't initiated by you, please contact your system administrator."
|
||||
"translation": "You updated your sign-in method for on {{ .SiteName }} to {{.Method}}.<br>If this change wasn't initiated by you, please contact your system administrator."
|
||||
},
|
||||
{
|
||||
"id": "api.templates.singin_change_email.subject",
|
||||
"translation": "You updated your sign-in method for {{.TeamDisplayName}} on {{ .SiteName }}"
|
||||
"translation": "You updated your sign-in method on {{ .SiteName }}"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.verify_body.button",
|
||||
|
|
@ -1425,11 +1425,11 @@
|
|||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.already_attached.app_error",
|
||||
"translation": "Team {{.DisplayName}} already has a user with the email address attached to your {{.Service}} account"
|
||||
"translation": "An existing user is already attached to your {{.Service}} account"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.already_used.app_error",
|
||||
"translation": "This {{.Service}} account has already been used to sign up for team {{.DisplayName}}"
|
||||
"translation": "This {{.Service}} account has already been used to sign up"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.create.app_error",
|
||||
|
|
@ -1451,6 +1451,10 @@
|
|||
"id": "api.user.create_profile_image.initial.app_error",
|
||||
"translation": "Could not add user initial to default profile picture"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_user.no_open_server",
|
||||
"translation": "This server does not allow open signups. Please speak with your Administrator to receive an invitation."
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_user.accepted_domain.app_error",
|
||||
"translation": "The email you provided does not belong to an accepted domain. Please contact your administrator or sign up with a different email."
|
||||
|
|
@ -1759,6 +1763,14 @@
|
|||
"id": "api.webhook.create_incoming.disabled.app_errror",
|
||||
"translation": "Incoming webhooks have been disabled by the system admin."
|
||||
},
|
||||
{
|
||||
"id": "api.webhook.create_outgoing.not_open.app_error",
|
||||
"translation": "Outgoing webhooks can only be created for public channels."
|
||||
},
|
||||
{
|
||||
"id": "api.webhook.create_outgoing.permissions.app_error",
|
||||
"translation": "Inappropriate permissions to create outcoming webhook."
|
||||
},
|
||||
{
|
||||
"id": "api.webhook.create_outgoing.disabled.app_error",
|
||||
"translation": "Outgoing webhooks have been disabled by the system admin."
|
||||
|
|
@ -2111,6 +2123,18 @@
|
|||
"id": "model.channel.is_valid.type.app_error",
|
||||
"translation": "Invalid type"
|
||||
},
|
||||
{
|
||||
"id": "model.team_member.is_valid.team_id.app_error",
|
||||
"translation": "Invalid team id"
|
||||
},
|
||||
{
|
||||
"id": "model.team_member.is_valid.user_id.app_error",
|
||||
"translation": "Invalid user id"
|
||||
},
|
||||
{
|
||||
"id": "model.team_member.is_valid.role.app_error",
|
||||
"translation": "Invalid role"
|
||||
},
|
||||
{
|
||||
"id": "model.channel.is_valid.update_at.app_error",
|
||||
"translation": "Update at must be a valid time"
|
||||
|
|
@ -2943,6 +2967,22 @@
|
|||
"id": "store.sql_channel.update_member.app_error",
|
||||
"translation": "We encountered an error updating the channel member"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_team.save_member.exists.app_error",
|
||||
"translation": "A team member with that id already exists"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_team.save_member.save.app_error",
|
||||
"translation": "We couldn't save the team member"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_team.get_members.app_error",
|
||||
"translation": "We couldn't get the team members"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_team.remove_member.app_error",
|
||||
"translation": "We couldn't remove the team member"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_command.analytics_command_count.app_error",
|
||||
"translation": "We couldn't count the commands"
|
||||
|
|
@ -3237,7 +3277,7 @@
|
|||
},
|
||||
{
|
||||
"id": "store.sql_session.remove_all_sessions_for_team.app_error",
|
||||
"translation": "We couldn't remove all the sessions for the team"
|
||||
"translation": "We couldn't remove all the sessions"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_session.save.app_error",
|
||||
|
|
|
|||
20
i18n/es.json
20
i18n/es.json
|
|
@ -1311,14 +1311,6 @@
|
|||
"id": "api.templates.signup_team_subject",
|
||||
"translation": "Configuración del equipo en {{ .SiteName }}"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.singin_change_email.body.info",
|
||||
"translation": "Haz actualizado el método con el que inicias sesión en {{.TeamURL}} para el equipo {{.TeamDisplayName}} por {{.Method}}.<br>Si este cambio no fue realizado por ti, por favor contacta a un administrador del sistema."
|
||||
},
|
||||
{
|
||||
"id": "api.templates.singin_change_email.subject",
|
||||
"translation": "Cambio del método de inicio de sesión para {{.TeamDisplayName}} en {{ .SiteName }}"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.verify_body.button",
|
||||
"translation": "Confirmar Correo"
|
||||
|
|
@ -1423,14 +1415,6 @@
|
|||
"id": "api.user.complete_switch_with_oauth.unavailable.app_error",
|
||||
"translation": "OAuth para {{.Service}} no está disponible en este servidor"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.already_attached.app_error",
|
||||
"translation": "El Equipo {{.DisplayName}} ya tiene un usuario con esta dirección de correo asociada a tu cuenta de {{.Service}}"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.already_used.app_error",
|
||||
"translation": "Esta cuenta de {{.Service}} ya fue utilizada para registrarse en el equipo {{.DisplayName}}"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.create.app_error",
|
||||
"translation": "No se pudo crear el usuario basandose en el objeto de {{.Service}}"
|
||||
|
|
@ -3235,10 +3219,6 @@
|
|||
"id": "store.sql_session.remove.app_error",
|
||||
"translation": "No pudimos remover la sesión"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_session.remove_all_sessions_for_team.app_error",
|
||||
"translation": "No pudimos remover todas las sesiones para el equipo"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_session.save.app_error",
|
||||
"translation": "No pudimos guardar la sesión"
|
||||
|
|
|
|||
16
i18n/fr.json
16
i18n/fr.json
|
|
@ -1235,14 +1235,6 @@
|
|||
"id": "api.templates.signup_team_subject",
|
||||
"translation": "Paramétrage Équipe {{ .SiteName }}"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.singin_change_email.body.info",
|
||||
"translation": "Vous avez mis à jour la méthode de connexion de {{.TeamDisplayName}} sur {{.TeamURL}} pour {{.Method}}.<br>Si cette modification n'a pas été effectuée par vous, veuillez prendre contact avec votre administrateur système."
|
||||
},
|
||||
{
|
||||
"id": "api.templates.singin_change_email.subject",
|
||||
"translation": "Vous avez mis à jour la méthode de connexion de {{.TeamDisplayName}} sur {{ .SiteName }}"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.verify_body.button",
|
||||
"translation": "Vérifier l'adresse électronique"
|
||||
|
|
@ -1339,14 +1331,6 @@
|
|||
"id": "api.user.complete_switch_with_oauth.unavailable.app_error",
|
||||
"translation": "{{.Service}} oauth non disponible sur ce serveur"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.already_attached.app_error",
|
||||
"translation": "L'équipe {{.DisplayName}} dispose déjà d'un utilisateur ayant la même adresse électronique que celle attachée à votre compte {{.Service}}"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.already_used.app_error",
|
||||
"translation": "Ce compte {{.Service}} a déjà été utilisé pour pour se connecter à l'équipe {{.DisplayName}}"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.create.app_error",
|
||||
"translation": "Impossible de créer un utilisateur à partir du user object {{.Service}}"
|
||||
|
|
|
|||
20
i18n/pt.json
20
i18n/pt.json
|
|
@ -1311,14 +1311,6 @@
|
|||
"id": "api.templates.signup_team_subject",
|
||||
"translation": "{{ .SiteName }} Configuração da Equipe"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.singin_change_email.body.info",
|
||||
"translation": "Você atualizou seu método de login para {{.TeamDisplayName}} no {{ .TeamURL }} para {{.Method}}.<br>Se esta mudança não foi iniciada por você, por favor entre em contato com o administrador do sistema."
|
||||
},
|
||||
{
|
||||
"id": "api.templates.singin_change_email.subject",
|
||||
"translation": "Você atualizou seu método de login para {{.TeamDisplayName}} em {{ .SiteName }}"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.verify_body.button",
|
||||
"translation": "Verificar Email"
|
||||
|
|
@ -1423,14 +1415,6 @@
|
|||
"id": "api.user.complete_switch_with_oauth.unavailable.app_error",
|
||||
"translation": "{{.Service}} oauth não disponível neste servidor"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.already_attached.app_error",
|
||||
"translation": "Equipe {{.DisplayName}} já tem um usuário com o endereço de email anexado a sua conta {{.Service}}"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.already_used.app_error",
|
||||
"translation": "Está conta {{.Service}} já foi utilizada para se inscrever na equipe {{.DisplayName}}"
|
||||
},
|
||||
{
|
||||
"id": "api.user.create_oauth_user.create.app_error",
|
||||
"translation": "Não foi possível criar o usuário fora do {{.Service}} do objeto de usuário"
|
||||
|
|
@ -3235,10 +3219,6 @@
|
|||
"id": "store.sql_session.remove.app_error",
|
||||
"translation": "Não foi possível remover a sessão"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_session.remove_all_sessions_for_team.app_error",
|
||||
"translation": "Não foi possível remover todas as sessões para a equipe"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_session.save.app_error",
|
||||
"translation": "Não foi possível salvar a sessão"
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||
team := &model.Team{
|
||||
DisplayName: teamDisplayName[0],
|
||||
Name: utils.RandomName(utils.Range{20, 20}, utils.LOWERCASE),
|
||||
Email: utils.RandomEmail(utils.Range{20, 20}, utils.LOWERCASE),
|
||||
Email: "success+" + model.NewId() + "simulator.amazonses.com",
|
||||
Type: model.TEAM_OPEN,
|
||||
}
|
||||
|
||||
|
|
@ -88,8 +88,7 @@ func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Create user for testing
|
||||
user := &model.User{
|
||||
TeamId: teamID,
|
||||
Email: utils.RandomEmail(utils.Range{20, 20}, utils.LOWERCASE),
|
||||
Email: "success+" + model.NewId() + "simulator.amazonses.com",
|
||||
Nickname: username[0],
|
||||
Password: api.USER_PASSWORD}
|
||||
|
||||
|
|
@ -98,7 +97,10 @@ func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||
c.Err = err
|
||||
return
|
||||
}
|
||||
api.Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id)
|
||||
|
||||
<-api.Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id)
|
||||
<-api.Srv.Store.Team().SaveMember(&model.TeamMember{TeamId: teamID, UserId: result.Data.(*model.User).Id})
|
||||
|
||||
newuser := result.Data.(*model.User)
|
||||
userID = newuser.Id
|
||||
|
||||
|
|
|
|||
430
mattermost.go
430
mattermost.go
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/mattermost/platform/einterfaces"
|
||||
"github.com/mattermost/platform/manualtesting"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"github.com/mattermost/platform/web"
|
||||
|
||||
|
|
@ -36,13 +37,18 @@ import (
|
|||
|
||||
//ENTERPRISE_IMPORTS
|
||||
|
||||
var flagCmdUpdateDb30 bool
|
||||
var flagCmdCreateTeam bool
|
||||
var flagCmdCreateUser bool
|
||||
var flagCmdAssignRole bool
|
||||
var flagCmdVersion bool
|
||||
var flagCmdResetPassword bool
|
||||
var flagCmdResetMfa bool
|
||||
var flagCmdPermanentDeleteUser bool
|
||||
var flagCmdPermanentDeleteTeam bool
|
||||
var flagCmdPermanentDeleteAllUsers bool
|
||||
var flagCmdResetDatabase bool
|
||||
var flagUsername string
|
||||
var flagCmdUploadLicense bool
|
||||
var flagConfigFile string
|
||||
var flagLicenseFile string
|
||||
|
|
@ -69,6 +75,10 @@ func main() {
|
|||
l4g.Info(utils.T("mattermost.working_dir"), pwd)
|
||||
l4g.Info(utils.T("mattermost.config_file"), utils.FindConfigFile(flagConfigFile))
|
||||
|
||||
// Speical case for upgrading the db to 3.0
|
||||
// ADDED for 3.0 REMOVE for 3.4
|
||||
cmdUpdateDb30()
|
||||
|
||||
api.NewServer()
|
||||
api.InitApi()
|
||||
web.InitWeb()
|
||||
|
|
@ -223,19 +233,24 @@ func parseCmds() {
|
|||
}
|
||||
|
||||
flag.StringVar(&flagConfigFile, "config", "config.json", "")
|
||||
flag.StringVar(&flagUsername, "username", "", "")
|
||||
flag.StringVar(&flagLicenseFile, "license", "", "")
|
||||
flag.StringVar(&flagEmail, "email", "", "")
|
||||
flag.StringVar(&flagPassword, "password", "", "")
|
||||
flag.StringVar(&flagTeamName, "team_name", "", "")
|
||||
flag.StringVar(&flagRole, "role", "", "")
|
||||
|
||||
flag.BoolVar(&flagCmdUpdateDb30, "upgrade_db_30", false, "")
|
||||
flag.BoolVar(&flagCmdCreateTeam, "create_team", false, "")
|
||||
flag.BoolVar(&flagCmdCreateUser, "create_user", false, "")
|
||||
flag.BoolVar(&flagCmdAssignRole, "assign_role", false, "")
|
||||
flag.BoolVar(&flagCmdVersion, "version", false, "")
|
||||
flag.BoolVar(&flagCmdResetPassword, "reset_password", false, "")
|
||||
flag.BoolVar(&flagCmdResetMfa, "reset_mfa", false, "")
|
||||
flag.BoolVar(&flagCmdPermanentDeleteUser, "permanent_delete_user", false, "")
|
||||
flag.BoolVar(&flagCmdPermanentDeleteTeam, "permanent_delete_team", false, "")
|
||||
flag.BoolVar(&flagCmdPermanentDeleteAllUsers, "permanent_delete_all_users", false, "")
|
||||
flag.BoolVar(&flagCmdResetDatabase, "reset_database", false, "")
|
||||
flag.BoolVar(&flagCmdUploadLicense, "upload_license", false, "")
|
||||
|
||||
flag.Parse()
|
||||
|
|
@ -244,9 +259,12 @@ func parseCmds() {
|
|||
flagCmdCreateUser ||
|
||||
flagCmdAssignRole ||
|
||||
flagCmdResetPassword ||
|
||||
flagCmdResetMfa ||
|
||||
flagCmdVersion ||
|
||||
flagCmdPermanentDeleteUser ||
|
||||
flagCmdPermanentDeleteTeam ||
|
||||
flagCmdPermanentDeleteAllUsers ||
|
||||
flagCmdResetDatabase ||
|
||||
flagCmdUploadLicense)
|
||||
}
|
||||
|
||||
|
|
@ -256,11 +274,258 @@ func runCmds() {
|
|||
cmdCreateUser()
|
||||
cmdAssignRole()
|
||||
cmdResetPassword()
|
||||
cmdResetMfa()
|
||||
cmdPermDeleteUser()
|
||||
cmdPermDeleteTeam()
|
||||
cmdPermDeleteAllUsers()
|
||||
cmdResetDatabase()
|
||||
cmdUploadLicense()
|
||||
}
|
||||
|
||||
type TeamForUpgrade struct {
|
||||
Id string
|
||||
Name string
|
||||
}
|
||||
|
||||
// ADDED for 3.0 REMOVE for 3.4
|
||||
func cmdUpdateDb30() {
|
||||
if flagCmdUpdateDb30 {
|
||||
api.Srv = &api.Server{}
|
||||
api.Srv.Store = store.NewSqlStoreForUpgrade30()
|
||||
store := api.Srv.Store.(*store.SqlStore)
|
||||
|
||||
l4g.Info("Attempting to run speical upgrade of the database schema to version 3.0 for user model changes")
|
||||
time.Sleep(time.Second)
|
||||
|
||||
if !store.DoesColumnExist("Users", "TeamId") {
|
||||
fmt.Println("**WARNING** the database schema appears to be upgraded to 3.0")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
if !(store.SchemaVersion == "2.2.0" ||
|
||||
store.SchemaVersion == "2.1.0" ||
|
||||
store.SchemaVersion == "2.0.0") {
|
||||
fmt.Println("**WARNING** the database schema needs to be version 2.2.0, 2.1.0 or 2.0.0 to upgrade")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var confirmBackup string
|
||||
fmt.Println("\nPlease see http://www.mattermost.org/upgrade-to-3-0/")
|
||||
fmt.Println("**WARNING** This upgrade process will be irreversible.")
|
||||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Fprintln(os.Stderr, "ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var flagTeamName string
|
||||
var teams []*TeamForUpgrade
|
||||
|
||||
if _, err := store.GetMaster().Select(&teams, "SELECT Id, Name FROM Teams"); err != nil {
|
||||
l4g.Error("Failed to load all teams details=%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
fmt.Println(fmt.Sprintf("We found %v teams.", len(teams)))
|
||||
|
||||
for _, team := range teams {
|
||||
fmt.Println(team.Name)
|
||||
}
|
||||
|
||||
fmt.Print("Please pick a primary team from the list above: ")
|
||||
fmt.Scanln(&flagTeamName)
|
||||
|
||||
var team *TeamForUpgrade
|
||||
for _, t := range teams {
|
||||
if t.Name == flagTeamName {
|
||||
team = t
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if team == nil {
|
||||
l4g.Error("Failed to find primary team details")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
l4g.Info("Starting speical 3.0 database upgrade with performed_backup=YES team_name=%v", team.Name)
|
||||
l4g.Info("Primary team %v will be left unchanged", team.Name)
|
||||
l4g.Info("Upgrading primary team %v", team.Name)
|
||||
|
||||
uniqueEmails := make(map[string]bool)
|
||||
uniqueUsernames := make(map[string]bool)
|
||||
primaryUsers := convertTeamTo30(team, uniqueEmails, uniqueUsernames)
|
||||
|
||||
l4g.Info("Upgraded %v users", len(primaryUsers))
|
||||
|
||||
for _, otherTeam := range teams {
|
||||
if otherTeam.Id != team.Id {
|
||||
l4g.Info("Upgrading team %v", otherTeam.Name)
|
||||
users := convertTeamTo30(otherTeam, uniqueEmails, uniqueUsernames)
|
||||
l4g.Info("Upgraded %v users", len(users))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
l4g.Info("Altering other scheme changes needed 3.0 for user model changes")
|
||||
|
||||
if _, err := store.GetMaster().Exec(`
|
||||
UPDATE Channels
|
||||
SET
|
||||
TeamId = ''
|
||||
WHERE
|
||||
Type = 'D'
|
||||
`,
|
||||
); err != nil {
|
||||
l4g.Error("Failed to update direct channel types details=%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
extraLength := store.GetMaxLengthOfColumnIfExists("Audits", "ExtraInfo")
|
||||
if len(extraLength) > 0 && extraLength != "1024" {
|
||||
store.AlterColumnTypeIfExists("Audits", "ExtraInfo", "VARCHAR(1024)", "VARCHAR(1024)")
|
||||
}
|
||||
|
||||
actionLength := store.GetMaxLengthOfColumnIfExists("Audits", "Action")
|
||||
if len(actionLength) > 0 && actionLength != "512" {
|
||||
store.AlterColumnTypeIfExists("Audits", "Action", "VARCHAR(512)", "VARCHAR(512)")
|
||||
}
|
||||
|
||||
if store.DoesColumnExist("Sessions", "TeamId") {
|
||||
store.RemoveColumnIfExists("Sessions", "TeamId")
|
||||
store.GetMaster().Exec(`TRUNCATE Sessions`)
|
||||
}
|
||||
|
||||
// ADDED for 2.2 REMOVE for 2.6
|
||||
store.CreateColumnIfNotExists("Users", "MfaActive", "tinyint(1)", "boolean", "0")
|
||||
store.CreateColumnIfNotExists("Users", "MfaSecret", "varchar(128)", "character varying(128)", "")
|
||||
|
||||
// ADDED for 2.2 REMOVE for 2.6
|
||||
if store.DoesColumnExist("Users", "TeamId") {
|
||||
store.RemoveIndexIfExists("idx_users_team_id", "Users")
|
||||
store.CreateUniqueIndexIfNotExists("idx_users_email_unique", "Users", "Email")
|
||||
store.CreateUniqueIndexIfNotExists("idx_users_username_unique", "Users", "Username")
|
||||
store.RemoveColumnIfExists("Teams", "AllowTeamListing")
|
||||
store.RemoveColumnIfExists("Users", "TeamId")
|
||||
}
|
||||
|
||||
l4g.Info("Finished running speical upgrade of the database schema to version 3.0 for user model changes")
|
||||
|
||||
if result := <-store.System().Update(&model.System{Name: "Version", Value: model.CurrentVersion}); result.Err != nil {
|
||||
l4g.Error("Failed to update system schema version details=%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
l4g.Info(utils.T("store.sql.upgraded.warn"), model.CurrentVersion)
|
||||
fmt.Println("**SUCCESS** with upgrade")
|
||||
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
|
||||
type UserForUpgrade struct {
|
||||
Id string
|
||||
Username string
|
||||
Email string
|
||||
Roles string
|
||||
TeamId string
|
||||
}
|
||||
|
||||
func convertTeamTo30(team *TeamForUpgrade, uniqueEmails map[string]bool, uniqueUsernames map[string]bool) []*UserForUpgrade {
|
||||
store := api.Srv.Store.(*store.SqlStore)
|
||||
var users []*UserForUpgrade
|
||||
if _, err := store.GetMaster().Select(&users, "SELECT Users.Id, Users.Username, Users.Email, Users.Roles, Users.TeamId FROM Users WHERE Users.TeamId = :TeamId", map[string]interface{}{"TeamId": team.Id}); err != nil {
|
||||
l4g.Error("Failed to load profiles for team details=%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var members []*model.TeamMember
|
||||
if result := <-api.Srv.Store.Team().GetMembers(team.Id); result.Err != nil {
|
||||
l4g.Error("Failed to load team membership details=%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
members = result.Data.([]*model.TeamMember)
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
shouldUpdateUser := false
|
||||
previousRole := user.Roles
|
||||
previousEmail := user.Email
|
||||
previousUsername := user.Username
|
||||
|
||||
member := &model.TeamMember{
|
||||
TeamId: team.Id,
|
||||
UserId: user.Id,
|
||||
}
|
||||
|
||||
if model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) {
|
||||
member.Roles = model.ROLE_TEAM_ADMIN
|
||||
user.Roles = ""
|
||||
shouldUpdateUser = true
|
||||
}
|
||||
|
||||
exists := false
|
||||
for _, member := range members {
|
||||
if member.UserId == user.Id {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !exists {
|
||||
if result := <-api.Srv.Store.Team().SaveMember(member); result.Err != nil {
|
||||
l4g.Error("Failed to save membership for %v details=%v", user.Email, result.Err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if uniqueEmails[user.Email] {
|
||||
shouldUpdateUser = true
|
||||
emailParts := strings.Split(user.Email, "@")
|
||||
if len(emailParts) == 2 {
|
||||
user.Email = emailParts[0] + "+" + team.Name + "@" + emailParts[1]
|
||||
} else {
|
||||
user.Email = user.Email + "." + team.Name
|
||||
}
|
||||
}
|
||||
|
||||
if uniqueUsernames[user.Username] {
|
||||
shouldUpdateUser = true
|
||||
user.Username = user.Username + "." + team.Name
|
||||
}
|
||||
|
||||
if shouldUpdateUser {
|
||||
if _, err := store.GetMaster().Exec(`
|
||||
UPDATE Users
|
||||
SET
|
||||
Email = :Email,
|
||||
Username = :Username,
|
||||
Roles = :Roles
|
||||
WHERE
|
||||
Id = :Id
|
||||
`,
|
||||
map[string]interface{}{
|
||||
"Email": user.Email,
|
||||
"Username": user.Username,
|
||||
"Roles": user.Roles,
|
||||
"Id": user.Id,
|
||||
},
|
||||
); err != nil {
|
||||
l4g.Error("Failed to update user %v details=%v", user.Email, err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
l4g.Info("modified user_id=%v, changed email from=%v to=%v, changed username from=%v to %v changed roles from=%v to=%v", user.Id, previousEmail, user.Email, previousUsername, user.Username, previousRole, user.Roles)
|
||||
}
|
||||
|
||||
uniqueEmails[user.Email] = true
|
||||
uniqueUsernames[user.Username] = true
|
||||
}
|
||||
|
||||
return users
|
||||
}
|
||||
|
||||
func cmdCreateTeam() {
|
||||
if flagCmdCreateTeam {
|
||||
if len(flagTeamName) == 0 {
|
||||
|
|
@ -327,10 +592,9 @@ func cmdCreateUser() {
|
|||
flushLogAndExit(1)
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
user.TeamId = team.Id
|
||||
}
|
||||
|
||||
_, err := api.CreateUser(team, user)
|
||||
ruser, err := api.CreateUser(user)
|
||||
if err != nil {
|
||||
if err.Id != "store.sql_user.save.email_exists.app_error" {
|
||||
l4g.Error("%v", err)
|
||||
|
|
@ -338,6 +602,12 @@ func cmdCreateUser() {
|
|||
}
|
||||
}
|
||||
|
||||
err = api.JoinUserToTeam(team, ruser)
|
||||
if err != nil {
|
||||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
|
@ -368,7 +638,7 @@ func cmdAssignRole() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !model.IsValidRoles(flagRole) {
|
||||
if !model.IsValidUserRoles(flagRole) {
|
||||
fmt.Fprintln(os.Stderr, "flag invalid argument: -role")
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
|
|
@ -376,16 +646,8 @@ func cmdAssignRole() {
|
|||
|
||||
c := getMockContext()
|
||||
|
||||
var team *model.Team
|
||||
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-api.Srv.Store.User().GetByEmail(team.Id, flagEmail); result.Err != nil {
|
||||
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
|
|
@ -426,16 +688,8 @@ func cmdResetPassword() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
var team *model.Team
|
||||
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-api.Srv.Store.User().GetByEmail(team.Id, flagEmail); result.Err != nil {
|
||||
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
|
|
@ -451,14 +705,42 @@ func cmdResetPassword() {
|
|||
}
|
||||
}
|
||||
|
||||
func cmdPermDeleteUser() {
|
||||
if flagCmdPermanentDeleteUser {
|
||||
if len(flagTeamName) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "flag needs an argument: -team_name")
|
||||
func cmdResetMfa() {
|
||||
if flagCmdResetMfa {
|
||||
if len(flagEmail) == 0 && len(flagUsername) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "flag needs an argument: -email OR -username")
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if len(flagEmail) > 0 {
|
||||
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
} else {
|
||||
if result := <-api.Srv.Store.User().GetByUsername(flagUsername); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
}
|
||||
|
||||
if err := api.DeactivateMfa(user.Id); err != nil {
|
||||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
func cmdPermDeleteUser() {
|
||||
if flagCmdPermanentDeleteUser {
|
||||
if len(flagEmail) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "flag needs an argument: -email")
|
||||
flag.Usage()
|
||||
|
|
@ -467,16 +749,8 @@ func cmdPermDeleteUser() {
|
|||
|
||||
c := getMockContext()
|
||||
|
||||
var team *model.Team
|
||||
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-api.Srv.Store.User().GetByEmail(team.Id, flagEmail); result.Err != nil {
|
||||
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
|
|
@ -487,6 +761,7 @@ func cmdPermDeleteUser() {
|
|||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
|
|
@ -494,6 +769,7 @@ func cmdPermDeleteUser() {
|
|||
fmt.Printf("Are you sure you want to delete the user %v? All data will be permanently deleted? (YES/NO): ", user.Email)
|
||||
fmt.Scanln(&confirm)
|
||||
if confirm != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
|
|
@ -501,6 +777,7 @@ func cmdPermDeleteUser() {
|
|||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
fmt.Print("SUCCESS: User deleted.")
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
|
|
@ -528,6 +805,7 @@ func cmdPermDeleteTeam() {
|
|||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
|
|
@ -535,6 +813,7 @@ func cmdPermDeleteTeam() {
|
|||
fmt.Printf("Are you sure you want to delete the team %v? All data will be permanently deleted? (YES/NO): ", team.Name)
|
||||
fmt.Scanln(&confirm)
|
||||
if confirm != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
|
|
@ -542,11 +821,67 @@ func cmdPermDeleteTeam() {
|
|||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
fmt.Print("SUCCESS: Team deleted.")
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cmdPermDeleteAllUsers() {
|
||||
if flagCmdPermanentDeleteAllUsers {
|
||||
c := getMockContext()
|
||||
|
||||
var confirmBackup string
|
||||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var confirm string
|
||||
fmt.Printf("Are you sure you want to delete all the users? All data will be permanently deleted? (YES/NO): ")
|
||||
fmt.Scanln(&confirm)
|
||||
if confirm != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
if err := api.PermanentDeleteAllUsers(c); err != nil {
|
||||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
fmt.Print("SUCCESS: All users deleted.")
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cmdResetDatabase() {
|
||||
if flagCmdResetDatabase {
|
||||
var confirmBackup string
|
||||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var confirm string
|
||||
fmt.Printf("Are you sure you want to delete everything? ALL data will be permanently deleted? (YES/NO): ")
|
||||
fmt.Scanln(&confirm)
|
||||
if confirm != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
api.Srv.Store.DropAllTables()
|
||||
fmt.Print("SUCCESS: Database reset.")
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func cmdUploadLicense() {
|
||||
if flagCmdUploadLicense {
|
||||
if model.BuildEnterpriseReady != "true" {
|
||||
|
|
@ -574,7 +909,7 @@ func cmdUploadLicense() {
|
|||
flushLogAndExit(0)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -604,6 +939,8 @@ USAGE:
|
|||
FLAGS:
|
||||
-config="config.json" Path to the config file
|
||||
|
||||
-username="someuser" Username used in other commands
|
||||
|
||||
-license="ex.mattermost-license" Path to your license file
|
||||
|
||||
-email="user@example.com" Email address used in other commands
|
||||
|
|
@ -644,14 +981,33 @@ COMMANDS:
|
|||
Example:
|
||||
platform -reset_password -team_name="name" -email="user@example.com" -password="newpassword"
|
||||
|
||||
-reset_mfa Turns off multi-factor authentication for a user. It requires the
|
||||
-email or -username flag.
|
||||
Example:
|
||||
platform -reset_mfa -username="someuser"
|
||||
|
||||
-reset_database Completely erases the database causing the loss of all data. This
|
||||
will reset Mattermost to it's initial state. (note this will not
|
||||
erase your configuration.)
|
||||
|
||||
Example:
|
||||
platform -reset_mfa -username="someuser"
|
||||
|
||||
-permanent_delete_user Permanently deletes a user and all related information
|
||||
including posts from the database. It requires the
|
||||
-email flag. You may need to restart the
|
||||
server to invalidate the cache
|
||||
Example:
|
||||
platform -permanent_delete_user -email="user@example.com"
|
||||
|
||||
-permanent_delete_all_users Permanently deletes all users and all related information
|
||||
including posts from the database. It requires the
|
||||
-team_name, and -email flag. You may need to restart the
|
||||
server to invalidate the cache
|
||||
Example:
|
||||
platform -permanent_delete_user -team_name="name" -email="user@example.com"
|
||||
platform -permanent_delete_all_users -team_name="name" -email="user@example.com"
|
||||
|
||||
-permanent_delete_team Permanently deletes a team and all users along with
|
||||
-permanent_delete_team Permanently deletes a team allong with
|
||||
all related information including posts from the database.
|
||||
It requires the -team_name flag. You may need to restart
|
||||
the server to invalidate the cache.
|
||||
|
|
|
|||
308
model/client.go
308
model/client.go
|
|
@ -28,7 +28,10 @@ const (
|
|||
HEADER_AUTH = "Authorization"
|
||||
HEADER_REQUESTED_WITH = "X-Requested-With"
|
||||
HEADER_REQUESTED_WITH_XML = "XMLHttpRequest"
|
||||
API_URL_SUFFIX = "/api/v1"
|
||||
|
||||
API_URL_SUFFIX_V1 = "/api/v1"
|
||||
API_URL_SUFFIX_V3 = "/api/v3"
|
||||
API_URL_SUFFIX = API_URL_SUFFIX_V3
|
||||
)
|
||||
|
||||
type Result struct {
|
||||
|
|
@ -39,16 +42,52 @@ type Result struct {
|
|||
|
||||
type Client struct {
|
||||
Url string // The location of the server like "http://localhost:8065"
|
||||
ApiUrl string // The api location of the server like "http://localhost:8065/api/v1"
|
||||
ApiUrl string // The api location of the server like "http://localhost:8065/api/v3"
|
||||
HttpClient *http.Client // The http client
|
||||
AuthToken string
|
||||
AuthType string
|
||||
TeamId string
|
||||
}
|
||||
|
||||
// NewClient constructs a new client with convienence methods for talking to
|
||||
// the server.
|
||||
func NewClient(url string) *Client {
|
||||
return &Client{url, url + API_URL_SUFFIX, &http.Client{}, "", ""}
|
||||
return &Client{url, url + API_URL_SUFFIX, &http.Client{}, "", "", ""}
|
||||
}
|
||||
|
||||
func (c *Client) SetOAuthToken(token string) {
|
||||
c.AuthToken = token
|
||||
c.AuthType = HEADER_TOKEN
|
||||
}
|
||||
|
||||
func (c *Client) ClearOAuthToken() {
|
||||
c.AuthToken = ""
|
||||
c.AuthType = HEADER_BEARER
|
||||
}
|
||||
|
||||
func (c *Client) SetTeamId(teamId string) {
|
||||
c.TeamId = teamId
|
||||
}
|
||||
|
||||
func (c *Client) GetTeamId() string {
|
||||
if len(c.TeamId) == 0 {
|
||||
println(`You are trying to use a route that requires a team_id,
|
||||
but you have not called SetTeamId() in client.go`)
|
||||
}
|
||||
|
||||
return c.TeamId
|
||||
}
|
||||
|
||||
func (c *Client) ClearTeamId() {
|
||||
c.TeamId = ""
|
||||
}
|
||||
|
||||
func (c *Client) GetTeamRoute() string {
|
||||
return fmt.Sprintf("/teams/%v", c.GetTeamId())
|
||||
}
|
||||
|
||||
func (c *Client) GetChannelRoute(channelId string) string {
|
||||
return fmt.Sprintf("/teams/%v/channels/%v", c.GetTeamId(), channelId)
|
||||
}
|
||||
|
||||
func (c *Client) DoPost(url, data, contentType string) (*http.Response, *AppError) {
|
||||
|
|
@ -162,10 +201,19 @@ func (c *Client) GetAllTeams() (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) FindTeamByName(name string, allServers bool) (*Result, *AppError) {
|
||||
func (c *Client) GetAllTeamListings() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/teams/all_team_listings", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), TeamMapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) FindTeamByName(name string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["name"] = name
|
||||
m["all"] = fmt.Sprintf("%v", allServers)
|
||||
if r, err := c.DoApiPost("/teams/find_team_by_name", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
|
|
@ -179,8 +227,32 @@ func (c *Client) FindTeamByName(name string, allServers bool) (*Result, *AppErro
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) AddUserToTeam(userId string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = userId
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/add_user_to_team", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) AddUserToTeamFromInvite(hash, dataToHash, inviteId string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["hash"] = hash
|
||||
data["data"] = dataToHash
|
||||
data["invite_id"] = inviteId
|
||||
if r, err := c.DoApiPost("/teams/add_user_to_team_from_invite", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), TeamFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) InviteMembers(invites *Invites) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/teams/invite_members", invites.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/invite_members", invites.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -189,7 +261,7 @@ func (c *Client) InviteMembers(invites *Invites) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) UpdateTeam(team *Team) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/teams/update", team.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/update", team.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -206,6 +278,18 @@ func (c *Client) CreateUser(user *User, hash string) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) CreateUserWithInvite(user *User, hash string, data string, inviteId string) (*Result, *AppError) {
|
||||
|
||||
url := "/users/create?d=" + url.QueryEscape(data) + "&h=" + url.QueryEscape(hash) + "&iid=" + url.QueryEscape(inviteId)
|
||||
|
||||
if r, err := c.DoApiPost(url, user.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) CreateUserFromSignup(user *User, data string, hash string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/users/create?d="+url.QueryEscape(data)+"&h="+hash, user.ToJson()); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -216,7 +300,7 @@ func (c *Client) CreateUserFromSignup(user *User, data string, hash string) (*Re
|
|||
}
|
||||
|
||||
func (c *Client) GetUser(id string, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/users/"+id, "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/users/"+id+"/get", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -242,6 +326,24 @@ func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetProfilesForTeam(teamId string, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/users/profiles/"+teamId+"?skip_direct=true", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetDirectProfiles(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/users/direct_profiles", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) LoginById(id string, password string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["id"] = id
|
||||
|
|
@ -274,6 +376,26 @@ func (c *Client) LoginByEmailWithDevice(name string, email string, password stri
|
|||
return c.login(m)
|
||||
}
|
||||
|
||||
func (c *Client) LoginByLdap(userid string, password string, mfatoken string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["id"] = userid
|
||||
m["password"] = password
|
||||
m["token"] = mfatoken
|
||||
if r, err := c.DoApiPost("/users/login_ldap", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
c.AuthToken = r.Header.Get(HEADER_TOKEN)
|
||||
c.AuthType = HEADER_BEARER
|
||||
sessionToken := getCookie(SESSION_COOKIE_TOKEN, r)
|
||||
|
||||
if c.AuthToken != sessionToken.Value {
|
||||
NewLocAppError("/users/login_ldap", "model.client.login.app_error", nil, "")
|
||||
}
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) login(m map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/users/login", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -297,16 +419,16 @@ func (c *Client) Logout() (*Result, *AppError) {
|
|||
} else {
|
||||
c.AuthToken = ""
|
||||
c.AuthType = HEADER_BEARER
|
||||
c.TeamId = ""
|
||||
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) CheckMfa(method, teamName, loginId string) (*Result, *AppError) {
|
||||
func (c *Client) CheckMfa(method, loginId string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["method"] = method
|
||||
m["team_name"] = teamName
|
||||
m["login_id"] = loginId
|
||||
|
||||
if r, err := c.DoApiPost("/users/mfa", MapToJson(m)); err != nil {
|
||||
|
|
@ -339,14 +461,16 @@ func (c *Client) UpdateMfa(activate bool, token string) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) SetOAuthToken(token string) {
|
||||
c.AuthToken = token
|
||||
c.AuthType = HEADER_TOKEN
|
||||
}
|
||||
func (c *Client) AdminResetMfa(userId string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["user_id"] = userId
|
||||
|
||||
func (c *Client) ClearOAuthToken() {
|
||||
c.AuthToken = ""
|
||||
c.AuthType = HEADER_BEARER
|
||||
if r, err := c.DoApiPost("/admin/reset_mfa", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) RevokeSession(sessionAltId string) (*Result, *AppError) {
|
||||
|
|
@ -411,7 +535,7 @@ func (c *Client) Command(channelId string, command string, suggest bool) (*Resul
|
|||
m["command"] = command
|
||||
m["channelId"] = channelId
|
||||
m["suggest"] = strconv.FormatBool(suggest)
|
||||
if r, err := c.DoApiPost("/commands/execute", MapToJson(m)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/execute", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -420,7 +544,7 @@ func (c *Client) Command(channelId string, command string, suggest bool) (*Resul
|
|||
}
|
||||
|
||||
func (c *Client) ListCommands() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/commands/list", "", ""); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/commands/list", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -429,7 +553,7 @@ func (c *Client) ListCommands() (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) ListTeamCommands() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/commands/list_team_commands", "", ""); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/commands/list_team_commands", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -438,7 +562,7 @@ func (c *Client) ListTeamCommands() (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) CreateCommand(cmd *Command) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/commands/create", cmd.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/create", cmd.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -447,7 +571,7 @@ func (c *Client) CreateCommand(cmd *Command) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) RegenCommandToken(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/commands/regen_token", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/regen_token", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -456,7 +580,7 @@ func (c *Client) RegenCommandToken(data map[string]string) (*Result, *AppError)
|
|||
}
|
||||
|
||||
func (c *Client) DeleteCommand(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/commands/delete", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/delete", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -582,7 +706,7 @@ func (c *Client) GetSystemAnalytics(name string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/create", channel.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/create", channel.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -590,8 +714,10 @@ func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) CreateDirectChannel(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/create_direct", MapToJson(data)); err != nil {
|
||||
func (c *Client) CreateDirectChannel(userId string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = userId
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/create_direct", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -600,7 +726,7 @@ func (c *Client) CreateDirectChannel(data map[string]string) (*Result, *AppError
|
|||
}
|
||||
|
||||
func (c *Client) UpdateChannel(channel *Channel) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/update", channel.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update", channel.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -609,7 +735,7 @@ func (c *Client) UpdateChannel(channel *Channel) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) UpdateChannelHeader(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/update_header", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_header", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -618,7 +744,7 @@ func (c *Client) UpdateChannelHeader(data map[string]string) (*Result, *AppError
|
|||
}
|
||||
|
||||
func (c *Client) UpdateChannelPurpose(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/update_purpose", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_purpose", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -627,7 +753,7 @@ func (c *Client) UpdateChannelPurpose(data map[string]string) (*Result, *AppErro
|
|||
}
|
||||
|
||||
func (c *Client) UpdateNotifyProps(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/update_notify_props", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_notify_props", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -636,7 +762,7 @@ func (c *Client) UpdateNotifyProps(data map[string]string) (*Result, *AppError)
|
|||
}
|
||||
|
||||
func (c *Client) GetChannels(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/channels/", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -645,7 +771,7 @@ func (c *Client) GetChannels(etag string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) GetChannel(id, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/channels/"+id+"/", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetChannelRoute(id)+"/", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -654,7 +780,7 @@ func (c *Client) GetChannel(id, etag string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) GetMoreChannels(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/channels/more", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/more", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -663,7 +789,7 @@ func (c *Client) GetMoreChannels(etag string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) GetChannelCounts(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/channels/counts", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/counts", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -672,7 +798,7 @@ func (c *Client) GetChannelCounts(etag string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) JoinChannel(id string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/join", ""); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/join", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -681,7 +807,7 @@ func (c *Client) JoinChannel(id string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) LeaveChannel(id string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/leave", ""); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/leave", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -690,7 +816,7 @@ func (c *Client) LeaveChannel(id string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) DeleteChannel(id string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/delete", ""); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/delete", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -701,7 +827,7 @@ func (c *Client) DeleteChannel(id string) (*Result, *AppError) {
|
|||
func (c *Client) AddChannelMember(id, user_id string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user_id
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/add", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/add", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -712,7 +838,7 @@ func (c *Client) AddChannelMember(id, user_id string) (*Result, *AppError) {
|
|||
func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user_id
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/remove", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/remove", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -721,7 +847,7 @@ func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) UpdateLastViewedAt(channelId string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/"+channelId+"/update_last_viewed_at", ""); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/update_last_viewed_at", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -730,7 +856,7 @@ func (c *Client) UpdateLastViewedAt(channelId string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) GetChannelExtraInfo(id string, memberLimit int, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/channels/"+id+"/extra_info/"+strconv.FormatInt(int64(memberLimit), 10), "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetChannelRoute(id)+"/extra_info/"+strconv.FormatInt(int64(memberLimit), 10), "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -739,7 +865,7 @@ func (c *Client) GetChannelExtraInfo(id string, memberLimit int, etag string) (*
|
|||
}
|
||||
|
||||
func (c *Client) CreatePost(post *Post) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/create", post.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(post.ChannelId)+"/posts/create", post.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -748,7 +874,7 @@ func (c *Client) CreatePost(post *Post) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) UpdatePost(post *Post) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/update", post.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(post.ChannelId)+"/posts/update", post.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -757,7 +883,7 @@ func (c *Client) UpdatePost(post *Post) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) GetPosts(channelId string, offset int, limit int, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/posts/%v/%v", channelId, offset, limit), "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/page/%v/%v", offset, limit), "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -766,7 +892,7 @@ func (c *Client) GetPosts(channelId string, offset int, limit int, etag string)
|
|||
}
|
||||
|
||||
func (c *Client) GetPostsSince(channelId string, time int64) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/posts/%v", channelId, time), "", ""); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/since/%v", time), "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -775,7 +901,7 @@ func (c *Client) GetPostsSince(channelId string, time int64) (*Result, *AppError
|
|||
}
|
||||
|
||||
func (c *Client) GetPostsBefore(channelId string, postid string, offset int, limit int, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/post/%v/before/%v/%v", channelId, postid, offset, limit), "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/before/%v/%v", postid, offset, limit), "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -784,7 +910,7 @@ func (c *Client) GetPostsBefore(channelId string, postid string, offset int, lim
|
|||
}
|
||||
|
||||
func (c *Client) GetPostsAfter(channelId string, postid string, offset int, limit int, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/post/%v/after/%v/%v", channelId, postid, offset, limit), "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf(c.GetChannelRoute(channelId)+"/posts/%v/after/%v/%v", postid, offset, limit), "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -793,7 +919,7 @@ func (c *Client) GetPostsAfter(channelId string, postid string, offset int, limi
|
|||
}
|
||||
|
||||
func (c *Client) GetPost(channelId string, postId string, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/post/%v", channelId, postId), "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/get", postId), "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -802,7 +928,7 @@ func (c *Client) GetPost(channelId string, postId string, etag string) (*Result,
|
|||
}
|
||||
|
||||
func (c *Client) DeletePost(channelId string, postId string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost(fmt.Sprintf("/channels/%v/post/%v/delete", channelId, postId), ""); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/delete", postId), ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -811,7 +937,7 @@ func (c *Client) DeletePost(channelId string, postId string) (*Result, *AppError
|
|||
}
|
||||
|
||||
func (c *Client) SearchPosts(terms string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/posts/search?terms="+url.QueryEscape(terms), "", ""); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/posts/search?terms="+url.QueryEscape(terms), "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -819,8 +945,16 @@ func (c *Client) SearchPosts(terms string) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) UploadFile(url string, data []byte, contentType string) (*Result, *AppError) {
|
||||
rq, _ := http.NewRequest("POST", c.ApiUrl+url, bytes.NewReader(data))
|
||||
func (c *Client) UploadProfileFile(data []byte, contentType string) (*Result, *AppError) {
|
||||
return c.uploadFile(c.ApiUrl+"/users/newimage", data, contentType)
|
||||
}
|
||||
|
||||
func (c *Client) UploadPostAttachment(data []byte, contentType string) (*Result, *AppError) {
|
||||
return c.uploadFile(c.ApiUrl+c.GetTeamRoute()+"/files/upload", data, contentType)
|
||||
}
|
||||
|
||||
func (c *Client) uploadFile(url string, data []byte, contentType string) (*Result, *AppError) {
|
||||
rq, _ := http.NewRequest("POST", url, bytes.NewReader(data))
|
||||
rq.Header.Set("Content-Type", contentType)
|
||||
|
||||
if len(c.AuthToken) > 0 {
|
||||
|
|
@ -842,7 +976,7 @@ func (c *Client) GetFile(url string, isFullUrl bool) (*Result, *AppError) {
|
|||
if isFullUrl {
|
||||
rq, _ = http.NewRequest("GET", url, nil)
|
||||
} else {
|
||||
rq, _ = http.NewRequest("GET", c.ApiUrl+"/files/get"+url, nil)
|
||||
rq, _ = http.NewRequest("GET", c.ApiUrl+c.GetTeamRoute()+"/files/get"+url, nil)
|
||||
}
|
||||
|
||||
if len(c.AuthToken) > 0 {
|
||||
|
|
@ -861,7 +995,7 @@ func (c *Client) GetFile(url string, isFullUrl bool) (*Result, *AppError) {
|
|||
|
||||
func (c *Client) GetFileInfo(url string) (*Result, *AppError) {
|
||||
var rq *http.Request
|
||||
rq, _ = http.NewRequest("GET", c.ApiUrl+"/files/get_info"+url, nil)
|
||||
rq, _ = http.NewRequest("GET", c.ApiUrl+c.GetTeamRoute()+"/files/get_info"+url, nil)
|
||||
|
||||
if len(c.AuthToken) > 0 {
|
||||
rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken)
|
||||
|
|
@ -878,7 +1012,7 @@ func (c *Client) GetFileInfo(url string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) GetPublicLink(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/files/get_public_link", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/files/get_public_link", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -950,7 +1084,9 @@ func (c *Client) UpdateUserPassword(userId, currentPassword, newPassword string)
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) SendPasswordReset(data map[string]string) (*Result, *AppError) {
|
||||
func (c *Client) SendPasswordReset(email string) (*Result, *AppError) {
|
||||
data := map[string]string{}
|
||||
data["email"] = email
|
||||
if r, err := c.DoApiPost("/users/send_password_reset", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
|
|
@ -959,7 +1095,10 @@ func (c *Client) SendPasswordReset(data map[string]string) (*Result, *AppError)
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) ResetPassword(data map[string]string) (*Result, *AppError) {
|
||||
func (c *Client) ResetPassword(code, newPassword string) (*Result, *AppError) {
|
||||
data := map[string]string{}
|
||||
data["code"] = code
|
||||
data["new_password"] = newPassword
|
||||
if r, err := c.DoApiPost("/users/reset_password", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
|
|
@ -968,6 +1107,18 @@ func (c *Client) ResetPassword(data map[string]string) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) AdminResetPassword(userId, newPassword string) (*Result, *AppError) {
|
||||
data := map[string]string{}
|
||||
data["user_id"] = userId
|
||||
data["new_password"] = newPassword
|
||||
if r, err := c.DoApiPost("/admin/reset_password", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetStatuses(data []string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/users/status", ArrayToJson(data)); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -978,7 +1129,7 @@ func (c *Client) GetStatuses(data []string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) GetMyTeam(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/teams/me", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/me", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -986,6 +1137,15 @@ func (c *Client) GetMyTeam(etag string) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetTeamMembers(teamId string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/teams/members/"+teamId, "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), TeamMembersFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) RegisterApp(app *OAuthApp) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/oauth/register", app.ToJson()); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -1014,7 +1174,7 @@ func (c *Client) GetAccessToken(data url.Values) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) CreateIncomingWebhook(hook *IncomingWebhook) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/hooks/incoming/create", hook.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/incoming/create", hook.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -1031,8 +1191,10 @@ func (c *Client) PostToWebhook(id, payload string) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) DeleteIncomingWebhook(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/hooks/incoming/delete", MapToJson(data)); err != nil {
|
||||
func (c *Client) DeleteIncomingWebhook(id string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["id"] = id
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/incoming/delete", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -1041,7 +1203,7 @@ func (c *Client) DeleteIncomingWebhook(data map[string]string) (*Result, *AppErr
|
|||
}
|
||||
|
||||
func (c *Client) ListIncomingWebhooks() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/hooks/incoming/list", "", ""); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/hooks/incoming/list", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -1085,7 +1247,7 @@ func (c *Client) GetPreferenceCategory(category string) (*Result, *AppError) {
|
|||
}
|
||||
|
||||
func (c *Client) CreateOutgoingWebhook(hook *OutgoingWebhook) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/hooks/outgoing/create", hook.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/create", hook.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -1093,8 +1255,10 @@ func (c *Client) CreateOutgoingWebhook(hook *OutgoingWebhook) (*Result, *AppErro
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) DeleteOutgoingWebhook(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/hooks/outgoing/delete", MapToJson(data)); err != nil {
|
||||
func (c *Client) DeleteOutgoingWebhook(id string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["id"] = id
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/delete", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -1103,7 +1267,7 @@ func (c *Client) DeleteOutgoingWebhook(data map[string]string) (*Result, *AppErr
|
|||
}
|
||||
|
||||
func (c *Client) ListOutgoingWebhooks() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/hooks/outgoing/list", "", ""); err != nil {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/hooks/outgoing/list", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -1111,8 +1275,10 @@ func (c *Client) ListOutgoingWebhooks() (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) RegenOutgoingWebhookToken(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/hooks/outgoing/regen_token", MapToJson(data)); err != nil {
|
||||
func (c *Client) RegenOutgoingWebhookToken(id string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["id"] = id
|
||||
if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/regen_token", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
|
@ -1134,11 +1300,11 @@ func (c *Client) GetClientLicenceConfig(etag string) (*Result, *AppError) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetMeLoggedIn() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/users/me_logged_in", "", ""); err != nil {
|
||||
func (c *Client) GetInitialLoad() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/users/initial_load", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
r.Header.Get(HEADER_ETAG_SERVER), InitialLoadFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ func (o *Command) IsValid() *AppError {
|
|||
return NewLocAppError("Command.IsValid", "model.command.is_valid.team_id.app_error", nil, "")
|
||||
}
|
||||
|
||||
if len(o.Trigger) > 128 {
|
||||
if len(o.Trigger) == 0 || len(o.Trigger) > 128 {
|
||||
return NewLocAppError("Command.IsValid", "model.command.is_valid.trigger.app_error", nil, "")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,63 +19,115 @@ func TestCommandJson(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCommandIsValid(t *testing.T) {
|
||||
o := Command{}
|
||||
o := Command{
|
||||
Id: NewId(),
|
||||
Token: NewId(),
|
||||
CreateAt: GetMillis(),
|
||||
UpdateAt: GetMillis(),
|
||||
CreatorId: NewId(),
|
||||
TeamId: NewId(),
|
||||
Trigger: "trigger",
|
||||
URL: "http://example.com",
|
||||
Method: COMMAND_METHOD_GET,
|
||||
DisplayName: "",
|
||||
Description: "",
|
||||
}
|
||||
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.Id = ""
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.Id = NewId()
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.CreateAt = GetMillis()
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.UpdateAt = GetMillis()
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.CreatorId = "123"
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.CreatorId = NewId()
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.Token = "123"
|
||||
o.Token = ""
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.Token = NewId()
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.CreateAt = 0
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.TeamId = "123"
|
||||
o.CreateAt = GetMillis()
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.UpdateAt = 0
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.UpdateAt = GetMillis()
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.CreatorId = ""
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.CreatorId = NewId()
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.TeamId = ""
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.TeamId = NewId()
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.Trigger = ""
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.URL = "nowhere.com/"
|
||||
o.Trigger = strings.Repeat("1", 129)
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.URL = "http://nowhere.com/"
|
||||
o.Trigger = strings.Repeat("1", 128)
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.URL = ""
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.URL = "1234"
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.URL = "https://example.com"
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.Method = "https://example.com"
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
|
@ -85,6 +137,11 @@ func TestCommandIsValid(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.Method = COMMAND_METHOD_POST
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
o.DisplayName = strings.Repeat("1", 65)
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
|
|
|
|||
|
|
@ -155,9 +155,9 @@ type TeamSettings struct {
|
|||
MaxUsersPerTeam int
|
||||
EnableTeamCreation bool
|
||||
EnableUserCreation bool
|
||||
EnableOpenServer *bool
|
||||
RestrictCreationToDomains string
|
||||
RestrictTeamNames *bool
|
||||
EnableTeamListing *bool
|
||||
EnableCustomBrand *bool
|
||||
CustomBrandText *string
|
||||
}
|
||||
|
|
@ -180,6 +180,7 @@ type LdapSettings struct {
|
|||
LastNameAttribute *string
|
||||
EmailAttribute *string
|
||||
UsernameAttribute *string
|
||||
NicknameAttribute *string
|
||||
IdAttribute *string
|
||||
|
||||
// Advanced
|
||||
|
|
@ -297,11 +298,6 @@ func (o *Config) SetDefaults() {
|
|||
*o.TeamSettings.RestrictTeamNames = true
|
||||
}
|
||||
|
||||
if o.TeamSettings.EnableTeamListing == nil {
|
||||
o.TeamSettings.EnableTeamListing = new(bool)
|
||||
*o.TeamSettings.EnableTeamListing = false
|
||||
}
|
||||
|
||||
if o.TeamSettings.EnableCustomBrand == nil {
|
||||
o.TeamSettings.EnableCustomBrand = new(bool)
|
||||
*o.TeamSettings.EnableCustomBrand = false
|
||||
|
|
@ -312,6 +308,11 @@ func (o *Config) SetDefaults() {
|
|||
*o.TeamSettings.CustomBrandText = ""
|
||||
}
|
||||
|
||||
if o.TeamSettings.EnableOpenServer == nil {
|
||||
o.TeamSettings.EnableOpenServer = new(bool)
|
||||
*o.TeamSettings.EnableOpenServer = false
|
||||
}
|
||||
|
||||
if o.EmailSettings.EnableSignInWithEmail == nil {
|
||||
o.EmailSettings.EnableSignInWithEmail = new(bool)
|
||||
|
||||
|
|
@ -476,6 +477,11 @@ func (o *Config) SetDefaults() {
|
|||
o.LdapSettings.SkipCertificateVerification = new(bool)
|
||||
*o.LdapSettings.SkipCertificateVerification = false
|
||||
}
|
||||
|
||||
if o.LdapSettings.NicknameAttribute == nil {
|
||||
o.LdapSettings.NicknameAttribute = new(string)
|
||||
*o.LdapSettings.NicknameAttribute = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Config) IsValid() *AppError {
|
||||
|
|
|
|||
8
model/gitlab.go
Normal file
8
model/gitlab.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
USER_AUTH_SERVICE_GITLAB = "gitlab"
|
||||
)
|
||||
|
|
@ -12,10 +12,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
USER_AUTH_SERVICE_GITLAB = "gitlab"
|
||||
)
|
||||
|
||||
type GitLabProvider struct {
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +25,7 @@ type GitLabUser struct {
|
|||
|
||||
func init() {
|
||||
provider := &GitLabProvider{}
|
||||
einterfaces.RegisterOauthProvider(USER_AUTH_SERVICE_GITLAB, provider)
|
||||
einterfaces.RegisterOauthProvider(model.USER_AUTH_SERVICE_GITLAB, provider)
|
||||
}
|
||||
|
||||
func userFromGitLabUser(glu *GitLabUser) *model.User {
|
||||
|
|
@ -51,7 +47,7 @@ func userFromGitLabUser(glu *GitLabUser) *model.User {
|
|||
}
|
||||
user.Email = glu.Email
|
||||
user.AuthData = strconv.FormatInt(glu.Id, 10)
|
||||
user.AuthService = USER_AUTH_SERVICE_GITLAB
|
||||
user.AuthService = model.USER_AUTH_SERVICE_GITLAB
|
||||
|
||||
return user
|
||||
}
|
||||
|
|
@ -84,7 +80,7 @@ func (glu *GitLabUser) getAuthData() string {
|
|||
}
|
||||
|
||||
func (m *GitLabProvider) GetIdentifier() string {
|
||||
return USER_AUTH_SERVICE_GITLAB
|
||||
return model.USER_AUTH_SERVICE_GITLAB
|
||||
}
|
||||
|
||||
func (m *GitLabProvider) GetUserFromJson(data io.Reader) *model.User {
|
||||
|
|
|
|||
40
model/initial_load.go
Normal file
40
model/initial_load.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2016 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"`
|
||||
DirectProfiles map[string]*User `json:"direct_profiles"`
|
||||
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, err := json.Marshal(me)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func InitialLoadFromJson(data io.Reader) *InitialLoad {
|
||||
decoder := json.NewDecoder(data)
|
||||
var o InitialLoad
|
||||
err := decoder.Decode(&o)
|
||||
if err == nil {
|
||||
return &o
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
20
model/initial_load_test.go
Normal file
20
model/initial_load_test.go
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInitialLoadJson(t *testing.T) {
|
||||
u := &User{Id: NewId()}
|
||||
o := InitialLoad{User: u}
|
||||
json := o.ToJson()
|
||||
ro := InitialLoadFromJson(strings.NewReader(json))
|
||||
|
||||
if o.User.Id != ro.User.Id {
|
||||
t.Fatal("Ids do not match")
|
||||
}
|
||||
}
|
||||
37
model/password_recovery.go
Normal file
37
model/password_recovery.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
const (
|
||||
PASSWORD_RECOVERY_CODE_SIZE = 128
|
||||
PASSWORD_RECOVER_EXPIRY_TIME = 1000 * 60 * 60 // 1 hour
|
||||
)
|
||||
|
||||
type PasswordRecovery struct {
|
||||
UserId string
|
||||
Code string
|
||||
CreateAt int64
|
||||
}
|
||||
|
||||
func (p *PasswordRecovery) IsValid() *AppError {
|
||||
|
||||
if len(p.UserId) != 26 {
|
||||
return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.user_id.app_error", nil, "")
|
||||
}
|
||||
|
||||
if len(p.Code) != PASSWORD_RECOVERY_CODE_SIZE {
|
||||
return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.code.app_error", nil, "")
|
||||
}
|
||||
|
||||
if p.CreateAt == 0 {
|
||||
return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.create_at.app_error", nil, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PasswordRecovery) PreSave() {
|
||||
p.Code = NewRandomString(PASSWORD_RECOVERY_CODE_SIZE)
|
||||
p.CreateAt = GetMillis()
|
||||
}
|
||||
|
|
@ -17,17 +17,17 @@ const (
|
|||
)
|
||||
|
||||
type Session struct {
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
LastActivityAt int64 `json:"last_activity_at"`
|
||||
UserId string `json:"user_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
DeviceId string `json:"device_id"`
|
||||
Roles string `json:"roles"`
|
||||
IsOAuth bool `json:"is_oauth"`
|
||||
Props StringMap `json:"props"`
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
LastActivityAt int64 `json:"last_activity_at"`
|
||||
UserId string `json:"user_id"`
|
||||
DeviceId string `json:"device_id"`
|
||||
Roles string `json:"roles"`
|
||||
IsOAuth bool `json:"is_oauth"`
|
||||
Props StringMap `json:"props"`
|
||||
TeamMembers []*TeamMember `json:"team_members" db:"-"`
|
||||
}
|
||||
|
||||
func (me *Session) ToJson() string {
|
||||
|
|
@ -95,6 +95,16 @@ func (me *Session) AddProp(key string, value string) {
|
|||
me.Props[key] = value
|
||||
}
|
||||
|
||||
func (me *Session) GetTeamByTeamId(teamId string) *TeamMember {
|
||||
for _, team := range me.TeamMembers {
|
||||
if team.TeamId == teamId {
|
||||
return team
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SessionsToJson(o []*Session) string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
|
|
|
|||
|
|
@ -18,19 +18,18 @@ const (
|
|||
)
|
||||
|
||||
type Team struct {
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Type string `json:"type"`
|
||||
CompanyName string `json:"company_name"`
|
||||
AllowedDomains string `json:"allowed_domains"`
|
||||
InviteId string `json:"invite_id"`
|
||||
AllowOpenInvite bool `json:"allow_open_invite"`
|
||||
AllowTeamListing bool `json:"allow_team_listing"`
|
||||
Id string `json:"id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Type string `json:"type"`
|
||||
CompanyName string `json:"company_name"`
|
||||
AllowedDomains string `json:"allowed_domains"`
|
||||
InviteId string `json:"invite_id"`
|
||||
AllowOpenInvite bool `json:"allow_open_invite"`
|
||||
}
|
||||
|
||||
type Invites struct {
|
||||
|
|
|
|||
78
model/team_member.go
Normal file
78
model/team_member.go
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ROLE_TEAM_ADMIN = "admin"
|
||||
)
|
||||
|
||||
type TeamMember struct {
|
||||
TeamId string `json:"team_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Roles string `json:"roles"`
|
||||
}
|
||||
|
||||
func (o *TeamMember) ToJson() string {
|
||||
b, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func TeamMemberFromJson(data io.Reader) *TeamMember {
|
||||
decoder := json.NewDecoder(data)
|
||||
var o TeamMember
|
||||
err := decoder.Decode(&o)
|
||||
if err == nil {
|
||||
return &o
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func TeamMembersToJson(o []*TeamMember) string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func TeamMembersFromJson(data io.Reader) []*TeamMember {
|
||||
decoder := json.NewDecoder(data)
|
||||
var o []*TeamMember
|
||||
err := decoder.Decode(&o)
|
||||
if err == nil {
|
||||
return o
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *TeamMember) IsValid() *AppError {
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
return NewLocAppError("TeamMember.IsValid", "model.team_member.is_valid.team_id.app_error", nil, "")
|
||||
}
|
||||
|
||||
if len(o.UserId) != 26 {
|
||||
return NewLocAppError("TeamMember.IsValid", "model.team_member.is_valid.user_id.app_error", nil, "")
|
||||
}
|
||||
|
||||
for _, role := range strings.Split(o.Roles, " ") {
|
||||
if !(role == "" || role == ROLE_TEAM_ADMIN) {
|
||||
return NewLocAppError("TeamMember.IsValid", "model.team_member.is_valid.role.app_error", nil, "role="+role)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
43
model/team_member_test.go
Normal file
43
model/team_member_test.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTeamMemberJson(t *testing.T) {
|
||||
o := TeamMember{TeamId: NewId(), UserId: NewId()}
|
||||
json := o.ToJson()
|
||||
ro := TeamMemberFromJson(strings.NewReader(json))
|
||||
|
||||
if o.TeamId != ro.TeamId {
|
||||
t.Fatal("Ids do not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTeamMemberIsValid(t *testing.T) {
|
||||
o := TeamMember{}
|
||||
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.TeamId = NewId()
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.UserId = NewId()
|
||||
o.Roles = "blahblah"
|
||||
if err := o.IsValid(); err == nil {
|
||||
t.Fatal("should be invalid")
|
||||
}
|
||||
|
||||
o.Roles = ""
|
||||
if err := o.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
ROLE_TEAM_ADMIN = "admin"
|
||||
ROLE_SYSTEM_ADMIN = "system_admin"
|
||||
USER_AWAY_TIMEOUT = 5 * 60 * 1000 // 5 minutes
|
||||
USER_OFFLINE_TIMEOUT = 1 * 60 * 1000 // 1 minute
|
||||
|
|
@ -28,6 +27,7 @@ const (
|
|||
DEFAULT_LOCALE = "en"
|
||||
USER_AUTH_SERVICE_EMAIL = "email"
|
||||
USER_AUTH_SERVICE_USERNAME = "username"
|
||||
MIN_PASSWORD_LENGTH = 5
|
||||
)
|
||||
|
||||
type User struct {
|
||||
|
|
@ -35,7 +35,6 @@ type User struct {
|
|||
CreateAt int64 `json:"create_at,omitempty"`
|
||||
UpdateAt int64 `json:"update_at,omitempty"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
TeamId string `json:"team_id"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password,omitempty"`
|
||||
AuthData string `json:"auth_data,omitempty"`
|
||||
|
|
@ -76,10 +75,6 @@ func (u *User) IsValid() *AppError {
|
|||
return NewLocAppError("User.IsValid", "model.user.is_valid.update_at.app_error", nil, "user_id="+u.Id)
|
||||
}
|
||||
|
||||
if len(u.TeamId) != 26 {
|
||||
return NewLocAppError("User.IsValid", "model.user.is_valid.team_id.app_error", nil, "")
|
||||
}
|
||||
|
||||
if !IsValidUsername(u.Username) {
|
||||
return NewLocAppError("User.IsValid", "model.user.is_valid.username.app_error", nil, "user_id="+u.Id)
|
||||
}
|
||||
|
|
@ -228,6 +223,7 @@ func (u *User) IsAway() bool {
|
|||
func (u *User) Sanitize(options map[string]bool) {
|
||||
u.Password = ""
|
||||
u.AuthData = ""
|
||||
u.MfaSecret = ""
|
||||
|
||||
if len(options) != 0 && !options["email"] {
|
||||
u.Email = ""
|
||||
|
|
@ -246,6 +242,8 @@ func (u *User) ClearNonProfileFields() {
|
|||
u.Password = ""
|
||||
u.AuthData = ""
|
||||
u.AuthService = ""
|
||||
u.MfaActive = false
|
||||
u.MfaSecret = ""
|
||||
u.EmailVerified = false
|
||||
u.LastPingAt = 0
|
||||
u.AllowMarketing = false
|
||||
|
|
@ -301,7 +299,7 @@ func (u *User) GetDisplayName() string {
|
|||
}
|
||||
}
|
||||
|
||||
func IsValidRoles(userRoles string) bool {
|
||||
func IsValidUserRoles(userRoles string) bool {
|
||||
|
||||
roles := strings.Split(userRoles, " ")
|
||||
|
||||
|
|
@ -319,10 +317,6 @@ func isValidRole(role string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
if role == ROLE_TEAM_ADMIN {
|
||||
return true
|
||||
}
|
||||
|
||||
if role == ROLE_SYSTEM_ADMIN {
|
||||
return true
|
||||
}
|
||||
|
|
@ -351,8 +345,8 @@ func IsInRole(userRoles string, inRole string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (u *User) IsSSOUser() bool {
|
||||
if len(u.AuthData) != 0 && len(u.AuthService) != 0 && u.AuthService != USER_AUTH_SERVICE_LDAP {
|
||||
func (u *User) IsOAuthUser() bool {
|
||||
if u.AuthService == USER_AUTH_SERVICE_GITLAB {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -63,11 +63,6 @@ func TestUserIsValid(t *testing.T) {
|
|||
t.Fatal()
|
||||
}
|
||||
|
||||
user.TeamId = NewId()
|
||||
if err := user.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
user.Username = NewId() + "^hello#"
|
||||
if err := user.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
|
|
@ -195,11 +190,11 @@ func TestCleanUsername(t *testing.T) {
|
|||
|
||||
func TestRoles(t *testing.T) {
|
||||
|
||||
if !IsValidRoles("admin") {
|
||||
if IsValidUserRoles("admin") {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
if IsValidRoles("junk") {
|
||||
if IsValidUserRoles("junk") {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,12 +41,10 @@ func (er *AppError) Error() string {
|
|||
}
|
||||
|
||||
func (er *AppError) Translate(T goi18n.TranslateFunc) {
|
||||
if len(er.Message) == 0 {
|
||||
if er.params == nil {
|
||||
er.Message = T(er.Id)
|
||||
} else {
|
||||
er.Message = T(er.Id, er.params)
|
||||
}
|
||||
if er.params == nil {
|
||||
er.Message = T(er.Id)
|
||||
} else {
|
||||
er.Message = T(er.Id, er.params)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +81,7 @@ func NewLocAppError(where string, id string, params map[string]interface{}, deta
|
|||
ap := &AppError{}
|
||||
ap.Id = id
|
||||
ap.params = params
|
||||
ap.Message = id
|
||||
ap.Where = where
|
||||
ap.DetailedError = details
|
||||
ap.StatusCode = 500
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
// It should be maitained in chronological order with most current
|
||||
// release at the front of the list.
|
||||
var versions = []string{
|
||||
"3.0.0",
|
||||
"2.2.0",
|
||||
"2.1.0",
|
||||
"2.0.0",
|
||||
|
|
|
|||
|
|
@ -28,17 +28,6 @@ func NewSqlAuditStore(sqlStore *SqlStore) AuditStore {
|
|||
}
|
||||
|
||||
func (s SqlAuditStore) UpgradeSchemaIfNeeded() {
|
||||
// ADDED for 2.2 REMOVE for 2.6
|
||||
extraLength := s.GetMaxLengthOfColumnIfExists("Audits", "ExtraInfo")
|
||||
if len(extraLength) > 0 && extraLength != "1024" {
|
||||
s.AlterColumnTypeIfExists("Audits", "ExtraInfo", "VARCHAR(1024)", "VARCHAR(1024)")
|
||||
}
|
||||
|
||||
// ADDED for 2.2 REMOVE for 2.6
|
||||
actionLength := s.GetMaxLengthOfColumnIfExists("Audits", "Action")
|
||||
if len(actionLength) > 0 && actionLength != "512" {
|
||||
s.AlterColumnTypeIfExists("Audits", "Action", "VARCHAR(512)", "VARCHAR(512)")
|
||||
}
|
||||
}
|
||||
|
||||
func (s SqlAuditStore) CreateIndexesIfNotExists() {
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ func (s SqlChannelStore) SaveDirectChannel(directchannel *model.Channel, member1
|
|||
if transaction, err := s.GetMaster().Begin(); err != nil {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.SaveDirectChannel", "store.sql_channel.save_direct_channel.open_transaction.app_error", nil, err.Error())
|
||||
} else {
|
||||
directchannel.TeamId = ""
|
||||
channelResult := s.saveChannelT(transaction, directchannel)
|
||||
|
||||
if channelResult.Err != nil {
|
||||
|
|
@ -330,7 +331,7 @@ func (s SqlChannelStore) GetChannels(teamId string, userId string) StoreChannel
|
|||
result := StoreResult{}
|
||||
|
||||
var data []channelWithMember
|
||||
_, err := s.GetReplica().Select(&data, "SELECT * FROM Channels, ChannelMembers WHERE Id = ChannelId AND TeamId = :TeamId AND UserId = :UserId AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
_, err := s.GetReplica().Select(&data, "SELECT * FROM Channels, ChannelMembers WHERE Id = ChannelId AND UserId = :UserId AND DeleteAt = 0 AND (TeamId = :TeamId OR TeamId = '') ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
|
||||
if err != nil {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.GetChannels", "store.sql_channel.get_channels.get.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error())
|
||||
|
|
@ -411,7 +412,7 @@ func (s SqlChannelStore) GetChannelCounts(teamId string, userId string) StoreCha
|
|||
result := StoreResult{}
|
||||
|
||||
var data []channelIdWithCountAndUpdateAt
|
||||
_, err := s.GetReplica().Select(&data, "SELECT Id, TotalMsgCount, UpdateAt FROM Channels WHERE Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = :UserId) AND TeamId = :TeamId AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
_, err := s.GetReplica().Select(&data, "SELECT Id, TotalMsgCount, UpdateAt FROM Channels WHERE Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = :UserId) AND (TeamId = :TeamId OR TeamId = '') AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
|
||||
if err != nil {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.GetChannelCounts", "store.sql_channel.get_channel_counts.get.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error())
|
||||
|
|
@ -441,7 +442,7 @@ func (s SqlChannelStore) GetByName(teamId string, name string) StoreChannel {
|
|||
|
||||
channel := model.Channel{}
|
||||
|
||||
if err := s.GetReplica().SelectOne(&channel, "SELECT * FROM Channels WHERE TeamId = :TeamId AND Name= :Name AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId, "Name": name}); err != nil {
|
||||
if err := s.GetReplica().SelectOne(&channel, "SELECT * FROM Channels WHERE (TeamId = :TeamId OR TeamId = '') AND Name = :Name AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId, "Name": name}); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.GetByName", MISSING_CHANNEL_ERROR, nil, "teamId="+teamId+", "+"name="+name+", "+err.Error())
|
||||
} else {
|
||||
|
|
@ -719,6 +720,37 @@ func (s SqlChannelStore) PermanentDeleteMembersByUser(userId string) StoreChanne
|
|||
return storeChannel
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) CheckPermissionsToNoTeam(channelId string, userId string) StoreChannel {
|
||||
storeChannel := make(StoreChannel)
|
||||
|
||||
go func() {
|
||||
result := StoreResult{}
|
||||
|
||||
count, err := s.GetReplica().SelectInt(
|
||||
`SELECT
|
||||
COUNT(0)
|
||||
FROM
|
||||
Channels,
|
||||
ChannelMembers
|
||||
WHERE
|
||||
Channels.Id = ChannelMembers.ChannelId
|
||||
AND Channels.DeleteAt = 0
|
||||
AND ChannelMembers.ChannelId = :ChannelId
|
||||
AND ChannelMembers.UserId = :UserId`,
|
||||
map[string]interface{}{"ChannelId": channelId, "UserId": userId})
|
||||
if err != nil {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.CheckPermissionsTo", "store.sql_channel.check_permissions.app_error", nil, "channel_id="+channelId+", user_id="+userId+", "+err.Error())
|
||||
} else {
|
||||
result.Data = count
|
||||
}
|
||||
|
||||
storeChannel <- result
|
||||
close(storeChannel)
|
||||
}()
|
||||
|
||||
return storeChannel
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) CheckPermissionsTo(teamId string, channelId string, userId string) StoreChannel {
|
||||
storeChannel := make(StoreChannel)
|
||||
|
||||
|
|
@ -733,7 +765,7 @@ func (s SqlChannelStore) CheckPermissionsTo(teamId string, channelId string, use
|
|||
ChannelMembers
|
||||
WHERE
|
||||
Channels.Id = ChannelMembers.ChannelId
|
||||
AND Channels.TeamId = :TeamId
|
||||
AND (Channels.TeamId = :TeamId OR Channels.TeamId = '')
|
||||
AND Channels.DeleteAt = 0
|
||||
AND ChannelMembers.ChannelId = :ChannelId
|
||||
AND ChannelMembers.UserId = :UserId`,
|
||||
|
|
@ -765,7 +797,7 @@ func (s SqlChannelStore) CheckPermissionsToByName(teamId string, channelName str
|
|||
ChannelMembers
|
||||
WHERE
|
||||
Channels.Id = ChannelMembers.ChannelId
|
||||
AND Channels.TeamId = :TeamId
|
||||
AND (Channels.TeamId = :TeamId OR Channels.TeamId = '')
|
||||
AND Channels.Name = :Name
|
||||
AND Channels.DeleteAt = 0
|
||||
AND ChannelMembers.UserId = :UserId`,
|
||||
|
|
|
|||
|
|
@ -67,17 +67,17 @@ func TestChannelStoreSaveDirectChannel(t *testing.T) {
|
|||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_DIRECT
|
||||
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1 := &model.User{}
|
||||
u1.Email = model.NewId()
|
||||
u1.Nickname = model.NewId()
|
||||
Must(store.User().Save(&u1))
|
||||
Must(store.User().Save(u1))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
|
||||
|
||||
u2 := model.User{}
|
||||
u2.TeamId = model.NewId()
|
||||
u2 := &model.User{}
|
||||
u2.Email = model.NewId()
|
||||
u2.Nickname = model.NewId()
|
||||
Must(store.User().Save(&u2))
|
||||
Must(store.User().Save(u2))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
|
|
@ -163,17 +163,17 @@ func TestChannelStoreGet(t *testing.T) {
|
|||
t.Fatal("Missing id should have failed")
|
||||
}
|
||||
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1 := &model.User{}
|
||||
u1.Email = model.NewId()
|
||||
u1.Nickname = model.NewId()
|
||||
Must(store.User().Save(&u1))
|
||||
Must(store.User().Save(u1))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
|
||||
|
||||
u2 := model.User{}
|
||||
u2.TeamId = model.NewId()
|
||||
u2.Email = model.NewId()
|
||||
u2.Nickname = model.NewId()
|
||||
Must(store.User().Save(&u2))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
|
||||
|
||||
o2 := model.Channel{}
|
||||
o2.TeamId = model.NewId()
|
||||
|
|
@ -309,16 +309,16 @@ func TestChannelMemberStore(t *testing.T) {
|
|||
t1 := c1t1.ExtraUpdateAt
|
||||
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
u1.Nickname = model.NewId()
|
||||
Must(store.User().Save(&u1))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
|
||||
|
||||
u2 := model.User{}
|
||||
u2.TeamId = model.NewId()
|
||||
u2.Email = model.NewId()
|
||||
u2.Nickname = model.NewId()
|
||||
Must(store.User().Save(&u2))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
|
||||
|
||||
o1 := model.ChannelMember{}
|
||||
o1.ChannelId = c1.Id
|
||||
|
|
@ -405,16 +405,16 @@ func TestChannelDeleteMemberStore(t *testing.T) {
|
|||
t1 := c1t1.ExtraUpdateAt
|
||||
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
u1.Nickname = model.NewId()
|
||||
Must(store.User().Save(&u1))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
|
||||
|
||||
u2 := model.User{}
|
||||
u2.TeamId = model.NewId()
|
||||
u2.Email = model.NewId()
|
||||
u2.Nickname = model.NewId()
|
||||
Must(store.User().Save(&u2))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
|
||||
|
||||
o1 := model.ChannelMember{}
|
||||
o1.ChannelId = c1.Id
|
||||
|
|
@ -469,6 +469,11 @@ func TestChannelStorePermissionsTo(t *testing.T) {
|
|||
t.Fatal("should have permissions")
|
||||
}
|
||||
|
||||
count = (<-store.Channel().CheckPermissionsToNoTeam(o1.Id, m1.UserId)).Data.(int64)
|
||||
if count != 1 {
|
||||
t.Fatal("should have permissions")
|
||||
}
|
||||
|
||||
count = (<-store.Channel().CheckPermissionsTo("junk", o1.Id, m1.UserId)).Data.(int64)
|
||||
if count != 0 {
|
||||
t.Fatal("shouldn't have permissions")
|
||||
|
|
@ -479,11 +484,21 @@ func TestChannelStorePermissionsTo(t *testing.T) {
|
|||
t.Fatal("shouldn't have permissions")
|
||||
}
|
||||
|
||||
count = (<-store.Channel().CheckPermissionsToNoTeam("junk", m1.UserId)).Data.(int64)
|
||||
if count != 0 {
|
||||
t.Fatal("shouldn't have permissions")
|
||||
}
|
||||
|
||||
count = (<-store.Channel().CheckPermissionsTo(o1.TeamId, o1.Id, "junk")).Data.(int64)
|
||||
if count != 0 {
|
||||
t.Fatal("shouldn't have permissions")
|
||||
}
|
||||
|
||||
count = (<-store.Channel().CheckPermissionsToNoTeam(o1.Id, "junk")).Data.(int64)
|
||||
if count != 0 {
|
||||
t.Fatal("shouldn't have permissions")
|
||||
}
|
||||
|
||||
channelId := (<-store.Channel().CheckPermissionsToByName(o1.TeamId, o1.Name, m1.UserId)).Data.(string)
|
||||
if channelId != o1.Id {
|
||||
t.Fatal("should have permissions")
|
||||
|
|
@ -786,12 +801,12 @@ func TestGetMemberCount(t *testing.T) {
|
|||
|
||||
t.Logf("c1.Id = %v", c1.Id)
|
||||
|
||||
u1 := model.User{
|
||||
TeamId: teamId,
|
||||
u1 := &model.User{
|
||||
Email: model.NewId(),
|
||||
DeleteAt: 0,
|
||||
}
|
||||
Must(store.User().Save(&u1))
|
||||
Must(store.User().Save(u1))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
|
||||
|
||||
m1 := model.ChannelMember{
|
||||
ChannelId: c1.Id,
|
||||
|
|
@ -807,11 +822,11 @@ func TestGetMemberCount(t *testing.T) {
|
|||
}
|
||||
|
||||
u2 := model.User{
|
||||
TeamId: teamId,
|
||||
Email: model.NewId(),
|
||||
DeleteAt: 0,
|
||||
}
|
||||
Must(store.User().Save(&u2))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}))
|
||||
|
||||
m2 := model.ChannelMember{
|
||||
ChannelId: c1.Id,
|
||||
|
|
@ -828,11 +843,11 @@ func TestGetMemberCount(t *testing.T) {
|
|||
|
||||
// make sure members of other channels aren't counted
|
||||
u3 := model.User{
|
||||
TeamId: teamId,
|
||||
Email: model.NewId(),
|
||||
DeleteAt: 0,
|
||||
}
|
||||
Must(store.User().Save(&u3))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u3.Id}))
|
||||
|
||||
m3 := model.ChannelMember{
|
||||
ChannelId: c2.Id,
|
||||
|
|
@ -848,12 +863,12 @@ func TestGetMemberCount(t *testing.T) {
|
|||
}
|
||||
|
||||
// make sure inactive users aren't counted
|
||||
u4 := model.User{
|
||||
TeamId: teamId,
|
||||
u4 := &model.User{
|
||||
Email: model.NewId(),
|
||||
DeleteAt: 10000,
|
||||
}
|
||||
Must(store.User().Save(&u4))
|
||||
Must(store.User().Save(u4))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u4.Id}))
|
||||
|
||||
m4 := model.ChannelMember{
|
||||
ChannelId: c1.Id,
|
||||
|
|
@ -892,12 +907,12 @@ func TestUpdateExtrasByUser(t *testing.T) {
|
|||
|
||||
t.Logf("c1.Id = %v", c1.Id)
|
||||
|
||||
u1 := model.User{
|
||||
TeamId: teamId,
|
||||
u1 := &model.User{
|
||||
Email: model.NewId(),
|
||||
DeleteAt: 0,
|
||||
}
|
||||
Must(store.User().Save(&u1))
|
||||
Must(store.User().Save(u1))
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
|
||||
|
||||
m1 := model.ChannelMember{
|
||||
ChannelId: c1.Id,
|
||||
|
|
@ -907,7 +922,7 @@ func TestUpdateExtrasByUser(t *testing.T) {
|
|||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
u1.DeleteAt = model.GetMillis()
|
||||
Must(store.User().Update(&u1, true))
|
||||
Must(store.User().Update(u1, true))
|
||||
|
||||
if result := <-store.Channel().ExtraUpdateByUser(u1.Id, u1.DeleteAt); result.Err != nil {
|
||||
t.Fatal("failed to update extras by user: %v", result.Err)
|
||||
|
|
@ -920,7 +935,7 @@ func TestUpdateExtrasByUser(t *testing.T) {
|
|||
}
|
||||
|
||||
u1.DeleteAt = 0
|
||||
Must(store.User().Update(&u1, true))
|
||||
Must(store.User().Update(u1, true))
|
||||
|
||||
if result := <-store.Channel().ExtraUpdateByUser(u1.Id, u1.DeleteAt); result.Err != nil {
|
||||
t.Fatal("failed to update extras by user: %v", result.Err)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ func TestCommandStoreSave(t *testing.T) {
|
|||
o1.Method = model.COMMAND_METHOD_POST
|
||||
o1.TeamId = model.NewId()
|
||||
o1.URL = "http://nowhere.com/"
|
||||
o1.Trigger = "trigger"
|
||||
|
||||
if err := (<-store.Command().Save(&o1)).Err; err != nil {
|
||||
t.Fatal("couldn't save item", err)
|
||||
|
|
@ -34,6 +35,7 @@ func TestCommandStoreGet(t *testing.T) {
|
|||
o1.Method = model.COMMAND_METHOD_POST
|
||||
o1.TeamId = model.NewId()
|
||||
o1.URL = "http://nowhere.com/"
|
||||
o1.Trigger = "trigger"
|
||||
|
||||
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
|
||||
|
||||
|
|
@ -58,6 +60,7 @@ func TestCommandStoreGetByTeam(t *testing.T) {
|
|||
o1.Method = model.COMMAND_METHOD_POST
|
||||
o1.TeamId = model.NewId()
|
||||
o1.URL = "http://nowhere.com/"
|
||||
o1.Trigger = "trigger"
|
||||
|
||||
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
|
||||
|
||||
|
|
@ -86,6 +89,7 @@ func TestCommandStoreDelete(t *testing.T) {
|
|||
o1.Method = model.COMMAND_METHOD_POST
|
||||
o1.TeamId = model.NewId()
|
||||
o1.URL = "http://nowhere.com/"
|
||||
o1.Trigger = "trigger"
|
||||
|
||||
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
|
||||
|
||||
|
|
@ -115,6 +119,7 @@ func TestCommandStoreDeleteByUser(t *testing.T) {
|
|||
o1.Method = model.COMMAND_METHOD_POST
|
||||
o1.TeamId = model.NewId()
|
||||
o1.URL = "http://nowhere.com/"
|
||||
o1.Trigger = "trigger"
|
||||
|
||||
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
|
||||
|
||||
|
|
@ -144,6 +149,7 @@ func TestCommandStoreUpdate(t *testing.T) {
|
|||
o1.Method = model.COMMAND_METHOD_POST
|
||||
o1.TeamId = model.NewId()
|
||||
o1.URL = "http://nowhere.com/"
|
||||
o1.Trigger = "trigger"
|
||||
|
||||
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
|
||||
|
||||
|
|
@ -162,6 +168,7 @@ func TestCommandCount(t *testing.T) {
|
|||
o1.Method = model.COMMAND_METHOD_POST
|
||||
o1.TeamId = model.NewId()
|
||||
o1.URL = "http://nowhere.com/"
|
||||
o1.Trigger = "trigger"
|
||||
|
||||
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
|
||||
|
||||
|
|
|
|||
|
|
@ -58,16 +58,16 @@ func TestComplianceExport(t *testing.T) {
|
|||
t1 = Must(store.Team().Save(t1)).(*model.Team)
|
||||
|
||||
u1 := &model.User{}
|
||||
u1.TeamId = t1.Id
|
||||
u1.Email = model.NewId()
|
||||
u1.Username = model.NewId()
|
||||
u1 = Must(store.User().Save(u1)).(*model.User)
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u1.Id}))
|
||||
|
||||
u2 := &model.User{}
|
||||
u2.TeamId = t1.Id
|
||||
u2.Email = model.NewId()
|
||||
u2.Username = model.NewId()
|
||||
u2 = Must(store.User().Save(u2)).(*model.User)
|
||||
Must(store.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u2.Id}))
|
||||
|
||||
c1 := &model.Channel{}
|
||||
c1.TeamId = t1.Id
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue