Merge pull request #131 from mattermost/mm-1391
Fixes mm-1391 adding travis CI
Этот коммит содержится в:
33
.travis.yml
Обычный файл
33
.travis.yml
Обычный файл
@@ -0,0 +1,33 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.4.2
|
||||
|
||||
before_install:
|
||||
- gem install compass
|
||||
- "sudo apt-get update -qq"
|
||||
|
||||
- "sudo apt-get remove mysql-common mysql-server-5.5 mysql-server-core-5.5 mysql-client-5.5 mysql-client-core-5.5"
|
||||
- "sudo apt-get autoremove"
|
||||
- "sudo apt-get install libaio1"
|
||||
- "wget -O mysql-5.6.17.deb http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.17-debian6.0-x86_64.deb"
|
||||
- "sudo dpkg -i mysql-5.6.17.deb"
|
||||
- "sudo cp /opt/mysql/server-5.6/support-files/mysql.server /etc/init.d/mysql.server"
|
||||
- "sudo ln -s /opt/mysql/server-5.6/bin/* /usr/bin/"
|
||||
# some config values were changed since 5.5
|
||||
- "sudo sed -i'' 's/table_cache/table_open_cache/' /etc/mysql/my.cnf"
|
||||
- "sudo sed -i'' 's/log_slow_queries/slow_query_log/' /etc/mysql/my.cnf"
|
||||
- "sudo sed -i'' 's/basedir[^=]\\+=.*$/basedir = \\/opt\\/mysql\\/server-5.6/' /etc/mysql/my.cnf"
|
||||
- "sudo /etc/init.d/mysql.server start"
|
||||
|
||||
before_script:
|
||||
- mysql -e "CREATE DATABASE IF NOT EXISTS mattermost_test ;" -uroot
|
||||
- mysql -e "CREATE USER 'mmuser'@'%' IDENTIFIED BY 'mostest' ;" -uroot
|
||||
- mysql -e "GRANT ALL ON mattermost_test.* TO 'mmuser'@'%' ;" -uroot
|
||||
|
||||
services:
|
||||
- redis-server
|
||||
|
||||
addons:
|
||||
hosts:
|
||||
- 127.0.0.1 dockerhost
|
||||
13
Godeps/Godeps.json
сгенерированный
13
Godeps/Godeps.json
сгенерированный
@@ -88,11 +88,6 @@
|
||||
"ImportPath": "github.com/gorilla/websocket",
|
||||
"Rev": "6fd0f867fef40c540fa05c59f86396de10a632a6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/huandu/facebook",
|
||||
"Comment": "v1.5.2",
|
||||
"Rev": "7c46d89211b9a3f01087f47f6a399b815801ade4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mssola/user_agent",
|
||||
"Comment": "v0.4.1-2-g35c7f18",
|
||||
@@ -122,6 +117,10 @@
|
||||
"ImportPath": "golang.org/x/crypto/blowfish",
|
||||
"Rev": "74f810a0152f4c50a16195f6b9ff44afc35594e8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/image/bmp",
|
||||
"Rev": "eb11b45157c1b71f30b3cec66306f1cd779a689e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/bufio.v1",
|
||||
"Comment": "v1",
|
||||
@@ -136,10 +135,6 @@
|
||||
"ImportPath": "gopkg.in/redis.v2",
|
||||
"Comment": "v2.3.2",
|
||||
"Rev": "e6179049628164864e6e84e973cfb56335748dea"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/image/bmp",
|
||||
"Rev": "eb11b45157c1b71f30b3cec66306f1cd779a689e"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
47
Godeps/_workspace/src/github.com/huandu/facebook/CHANGELOG.md
сгенерированный
поставляемый
47
Godeps/_workspace/src/github.com/huandu/facebook/CHANGELOG.md
сгенерированный
поставляемый
@@ -1,47 +0,0 @@
|
||||
# Change Log #
|
||||
|
||||
## v1.5.2 ##
|
||||
|
||||
* `[FIX]` [#32](https://github.com/huandu/facebook/pull/32) BatchApi/Batch returns facebook error when access token is not valid.
|
||||
|
||||
## v1.5.1 ##
|
||||
|
||||
* `[FIX]` [#31](https://github.com/huandu/facebook/pull/31) When `/oauth/access_token` returns a query string instead of json, this package can correctly handle it.
|
||||
|
||||
## v1.5.0 ##
|
||||
|
||||
* `[NEW]` [#28](https://github.com/huandu/facebook/pull/28) Support debug mode introduced by facebook graph API v2.3.
|
||||
* `[FIX]` Removed all test cases depending on facebook graph API v1.0.
|
||||
|
||||
## v1.4.1 ##
|
||||
|
||||
* `[NEW]` [#27](https://github.com/huandu/facebook/pull/27) Timestamp value in Graph API response can be decoded as a `time.Time` value now. Thanks, [@Lazyshot](https://github.com/Lazyshot).
|
||||
|
||||
## v1.4.0 ##
|
||||
|
||||
* `[FIX]` [#23](https://github.com/huandu/facebook/issues/24) Algorithm change: Camel case string to underscore string supports abbreviation
|
||||
|
||||
Fix for [#23](https://github.com/huandu/facebook/issues/24) could be a breaking change. Camel case string `HTTPServer` will be converted to `http_server` instead of `h_t_t_p_server`. See issue description for detail.
|
||||
|
||||
## v1.3.0 ##
|
||||
|
||||
* `[NEW]` [#22](https://github.com/huandu/facebook/issues/22) Add a new helper struct `BatchResult` to hold batch request responses.
|
||||
|
||||
## v1.2.0 ##
|
||||
|
||||
* `[NEW]` [#20](https://github.com/huandu/facebook/issues/20) Add Decode functionality for paging results. Thanks, [@cbroglie](https://github.com/cbroglie).
|
||||
* `[FIX]` [#21](https://github.com/huandu/facebook/issues/21) `Session#Inspect` cannot return error if access token is invalid.
|
||||
|
||||
Fix for [#21](https://github.com/huandu/facebook/issues/21) will result a possible breaking change in `Session#Inspect`. It was return whole result returned by facebook inspect api. Now it only return its "data" sub-tree. As facebook puts everything including error message in "data" sub-tree, I believe it's reasonable to make this change.
|
||||
|
||||
## v1.1.0 ##
|
||||
|
||||
* `[FIX]` [#19](https://github.com/huandu/facebook/issues/19) Any valid int64 number larger than 2^53 or smaller than -2^53 can be correctly decoded without precision lost.
|
||||
|
||||
Fix for [#19](https://github.com/huandu/facebook/issues/19) will result a possible breaking change in `Result#Get` and `Result#GetField`. If a JSON field is a number, these two functions will return json.Number instead of float64.
|
||||
|
||||
The fix also introduces a side effect in `Result#Decode` and `Result#DecodeField`. A number field (`int*` and `float*`) can be decoded to a string. It was not allowed in previous version.
|
||||
|
||||
## v1.0.0 ##
|
||||
|
||||
Initial tag. Library is stable enough for all features mentioned in README.md.
|
||||
7
Godeps/_workspace/src/github.com/huandu/facebook/CONTRIBUTING.md
сгенерированный
поставляемый
7
Godeps/_workspace/src/github.com/huandu/facebook/CONTRIBUTING.md
сгенерированный
поставляемый
@@ -1,7 +0,0 @@
|
||||
Thanks for contributing this project!
|
||||
|
||||
Please don't forget to use `gofmt` to make your code look good.
|
||||
|
||||
Here is the command I use. Please always use the same parameters.
|
||||
|
||||
go fmt
|
||||
19
Godeps/_workspace/src/github.com/huandu/facebook/LICENSE
сгенерированный
поставляемый
19
Godeps/_workspace/src/github.com/huandu/facebook/LICENSE
сгенерированный
поставляемый
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2012 - 2015 Huan Du
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
347
Godeps/_workspace/src/github.com/huandu/facebook/README.md
сгенерированный
поставляемый
347
Godeps/_workspace/src/github.com/huandu/facebook/README.md
сгенерированный
поставляемый
@@ -1,347 +0,0 @@
|
||||
# A Facebook Graph API SDK In Golang #
|
||||
|
||||
[](https://travis-ci.org/huandu/facebook)
|
||||
|
||||
This is a Go package fully supports Facebook Graph API with file upload, batch request, FQL and multi-FQL. It can be used in Google App Engine.
|
||||
|
||||
API documents can be found on [godoc](http://godoc.org/github.com/huandu/facebook).
|
||||
|
||||
Feel free to create an issue or send me a pull request if you have any "how-to" question or bug or suggestion when using this package. I'll try my best to reply it.
|
||||
|
||||
## Get It ##
|
||||
|
||||
Use `go get -u github.com/huandu/facebook` to get or update it.
|
||||
|
||||
## Usage ##
|
||||
|
||||
### Quick start ###
|
||||
|
||||
Here is a sample to read my Facebook username by uid.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
fb "github.com/huandu/facebook"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res, _ := fb.Get("/538744468", fb.Params{
|
||||
"fields": "username",
|
||||
"access_token": "a-valid-access-token",
|
||||
})
|
||||
fmt.Println("here is my facebook username:", res["username"])
|
||||
}
|
||||
```
|
||||
|
||||
Type of `res` is `fb.Result` (a.k.a. `map[string]interface{}`).
|
||||
This type has several useful methods to decode `res` to any Go type safely.
|
||||
|
||||
```go
|
||||
// Decode "username" to a Go string.
|
||||
var username string
|
||||
res.DecodeField("username", &username)
|
||||
fmt.Println("alternative way to get username:", username)
|
||||
|
||||
// It's also possible to decode the whole result into a predefined struct.
|
||||
type User struct {
|
||||
Username string
|
||||
}
|
||||
|
||||
var user User
|
||||
res.Decode(&user)
|
||||
fmt.Println("print username in struct:", user.Username)
|
||||
```
|
||||
|
||||
### Read a graph `user` object with a valid access token ###
|
||||
|
||||
```go
|
||||
res, err := fb.Get("/me/feed", fb.Params{
|
||||
"access_token": "a-valid-access-token",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// err can be an facebook API error.
|
||||
// if so, the Error struct contains error details.
|
||||
if e, ok := err.(*Error); ok {
|
||||
fmt.Logf("facebook error. [message:%v] [type:%v] [code:%v] [subcode:%v]",
|
||||
e.Message, e.Type, e.Code, e.ErrorSubcode)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// read my last feed.
|
||||
fmt.Println("my latest feed story is:", res.Get("data.0.story"))
|
||||
```
|
||||
|
||||
### Read a graph `search` for page and decode slice of maps
|
||||
|
||||
```go
|
||||
res, _ := fb.Get("/search", fb.Params{
|
||||
"access_token": "a-valid-access-token",
|
||||
"type": "page",
|
||||
"q": "nightlife,singapore",
|
||||
})
|
||||
|
||||
var items []fb.Result
|
||||
|
||||
err := res.DecodeField("data", &items)
|
||||
|
||||
if err != nil {
|
||||
fmt.Logf("An error has happened %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
fmt.Println(item["id"])
|
||||
}
|
||||
```
|
||||
|
||||
### Use `App` and `Session` ###
|
||||
|
||||
It's recommended to use `App` and `Session` in a production app. They provide more controls over all API calls. They can also make code clear and concise.
|
||||
|
||||
```go
|
||||
// create a global App var to hold app id and secret.
|
||||
var globalApp = fb.New("your-app-id", "your-app-secret")
|
||||
|
||||
// facebook asks for a valid redirect uri when parsing signed request.
|
||||
// it's a new enforced policy starting in late 2013.
|
||||
globalApp.RedirectUri = "http://your.site/canvas/url/"
|
||||
|
||||
// here comes a client with a facebook signed request string in query string.
|
||||
// creates a new session with signed request.
|
||||
session, _ := globalApp.SessionFromSignedRequest(signedRequest)
|
||||
|
||||
// if there is another way to get decoded access token,
|
||||
// creates a session directly with the token.
|
||||
session := globalApp.Session(token)
|
||||
|
||||
// validate access token. err is nil if token is valid.
|
||||
err := session.Validate()
|
||||
|
||||
// use session to send api request with access token.
|
||||
res, _ := session.Get("/me/feed", nil)
|
||||
```
|
||||
|
||||
### Use `paging` field in response. ###
|
||||
|
||||
Some Graph API responses use a special JSON structure to provide paging information. Use `Result.Paging()` to walk through all data in such results.
|
||||
|
||||
```go
|
||||
res, _ := session.Get("/me/home", nil)
|
||||
|
||||
// create a paging structure.
|
||||
paging, _ := res.Paging(session)
|
||||
|
||||
// get current results.
|
||||
results := paging.Data()
|
||||
|
||||
// get next page.
|
||||
noMore, err := paging.Next()
|
||||
results = paging.Data()
|
||||
```
|
||||
|
||||
### Read graph api response and decode result into a struct ###
|
||||
|
||||
As facebook Graph API always uses lower case words as keys in API response.
|
||||
This package can convert go's camel-case-style struct field name to facebook's underscore-style API key name.
|
||||
|
||||
For instance, to decode following JSON response...
|
||||
|
||||
```json
|
||||
{
|
||||
"foo_bar": "player"
|
||||
}
|
||||
```
|
||||
|
||||
One can use following struct.
|
||||
|
||||
```go
|
||||
type Data struct {
|
||||
FooBar string // "FooBar" maps to "foo_bar" in JSON automatically in this case.
|
||||
}
|
||||
```
|
||||
|
||||
Decoding behavior can be changed per field through field tag -- just like what `encoding/json` does.
|
||||
|
||||
Following is a sample shows all possible field tags.
|
||||
|
||||
```go
|
||||
// define a facebook feed object.
|
||||
type FacebookFeed struct {
|
||||
Id string `facebook:",required"` // this field must exist in response.
|
||||
// mind the "," before "required".
|
||||
Story string
|
||||
FeedFrom *FacebookFeedFrom `facebook:"from"` // use customized field name "from"
|
||||
CreatedTime string `facebook:"created_time,required"` // both customized field name and "required" flag.
|
||||
}
|
||||
|
||||
type FacebookFeedFrom struct {
|
||||
Name, Id string
|
||||
}
|
||||
|
||||
// create a feed object direct from graph api result.
|
||||
var feed FacebookFeed
|
||||
res, _ := session.Get("/me/feed", nil)
|
||||
res.DecodeField("data.0", &feed) // read latest feed
|
||||
```
|
||||
|
||||
### Send a batch request ###
|
||||
|
||||
```go
|
||||
params1 := Params{
|
||||
"method": fb.GET,
|
||||
"relative_url": "me",
|
||||
}
|
||||
params2 := Params{
|
||||
"method": fb.GET,
|
||||
"relative_url": uint64(100002828925788),
|
||||
}
|
||||
results, err := fb.BatchApi(your_access_token, params1, params2)
|
||||
|
||||
if err != nil {
|
||||
// check error...
|
||||
return
|
||||
}
|
||||
|
||||
// batchResult1 and batchResult2 are response for params1 and params2.
|
||||
batchResult1, _ := results[0].Batch()
|
||||
batchResult2, _ := results[1].Batch()
|
||||
|
||||
// Use parsed result.
|
||||
var id string
|
||||
res := batchResult1.Result
|
||||
res.DecodeField("id", &id)
|
||||
|
||||
// Use response header.
|
||||
contentType := batchResult1.Header.Get("Content-Type")
|
||||
```
|
||||
|
||||
### Send FQL query ###
|
||||
|
||||
```go
|
||||
results, _ := fb.FQL("SELECT username FROM page WHERE page_id = 20531316728")
|
||||
fmt.Println(results[0]["username"]) // print "facebook"
|
||||
|
||||
// most FQL query requires access token. create session to hold access token.
|
||||
session := &fb.Session{}
|
||||
session.SetAccessToken("A-VALID-ACCESS-TOKEN")
|
||||
results, _ := session.FQL("SELECT username FROM page WHERE page_id = 20531316728")
|
||||
fmt.Println(results[0]["username"]) // print "facebook"
|
||||
```
|
||||
|
||||
### Make multi-FQL ###
|
||||
|
||||
```go
|
||||
res, _ := fb.MultiFQL(Params{
|
||||
"query1": "SELECT username FROM page WHERE page_id = 20531316728",
|
||||
"query2": "SELECT uid FROM user WHERE uid = 538744468",
|
||||
})
|
||||
var query1, query2 []Result
|
||||
|
||||
// get response for query1 and query2.
|
||||
res.DecodeField("query1", &query1)
|
||||
res.DecodeField("query2", &query2)
|
||||
|
||||
// most FQL query requires access token. create session to hold access token.
|
||||
session := &fb.Session{}
|
||||
session.SetAccessToken("A-VALID-ACCESS-TOKEN")
|
||||
res, _ := session.MultiFQL(Params{
|
||||
"query1": "...",
|
||||
"query2": "...",
|
||||
})
|
||||
|
||||
// same as the sample without access token...
|
||||
```
|
||||
|
||||
### Use it in Google App Engine ###
|
||||
|
||||
Google App Engine provide `appengine/urlfetch` package as standard http client package. Default client in `net/http` doesn't work. One must explicitly set http client in `Session` to make it work.
|
||||
|
||||
```go
|
||||
import (
|
||||
"appengine"
|
||||
"appengine/urlfetch"
|
||||
)
|
||||
|
||||
// suppose it's the appengine context initialized somewhere.
|
||||
var context appengine.Context
|
||||
|
||||
// default Session object uses http.DefaultClient which is not allowed to use
|
||||
// in appengine. one has to create a Session and assign it a special client.
|
||||
seesion := globalApp.Session("a-access-token")
|
||||
session.HttpClient = urlfetch.Client(context)
|
||||
|
||||
// now, session uses appengine http client now.
|
||||
res, err := session.Get("/me", nil)
|
||||
```
|
||||
|
||||
### Select Graph API version ###
|
||||
|
||||
See [Platform Versioning](https://developers.facebook.com/docs/apps/versions) to understand facebook versioning strategy.
|
||||
|
||||
```go
|
||||
// this package uses default version which is controlled by facebook app setting.
|
||||
// change following global variable to specific a global default version.
|
||||
fb.Version = "v2.0"
|
||||
|
||||
// starting with graph api v2.0, it's not allowed to get user information without access token.
|
||||
fb.Api("huan.du", GET, nil)
|
||||
|
||||
// it's possible to specify version per session.
|
||||
session := &fb.Session{}
|
||||
session.Version = "v2.0" // overwrite global default.
|
||||
```
|
||||
|
||||
### Enable `appsecret_proof` ###
|
||||
|
||||
Facebook can verify Graph API Calls with `appsecret_proof`. It's a feature to make Graph API call more secure. See [Securing Graph API Requests](https://developers.facebook.com/docs/graph-api/securing-requests) to know more about it.
|
||||
|
||||
```go
|
||||
globalApp := fb.New("your-app-id", "your-app-secret")
|
||||
|
||||
// enable "appsecret_proof" for all sessions created by this app.
|
||||
globalApp.EnableAppsecretProof = true
|
||||
|
||||
// all calls in this session are secured.
|
||||
session := globalApp.Session("a-valid-access-token")
|
||||
session.Get("/me", nil)
|
||||
|
||||
// it's also possible to enable/disable this feature per session.
|
||||
session.EnableAppsecretProof(false)
|
||||
```
|
||||
|
||||
### Debugging API Requests ###
|
||||
|
||||
Facebook introduces a way to debug graph API calls. See [Debugging API Requests](https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#debugging) for details.
|
||||
|
||||
This package provides both package level and per session debug flag. Set `Debug` to a `DEBUG_*` constant to change debug mode globally; or use `Session#SetDebug` to change debug mode for one session.
|
||||
|
||||
When debug mode is turned on, use `Result#DebugInfo` to get `DebugInfo` struct from result.
|
||||
|
||||
```go
|
||||
fb.Debug = fb.DEBUG_ALL
|
||||
|
||||
res, _ := fb.Get("/me", fb.Params{"access_token": "xxx"})
|
||||
debugInfo := res.DebugInfo()
|
||||
|
||||
fmt.Println("http headers:", debugInfo.Header)
|
||||
fmt.Println("facebook api version:", debugInfo.FacebookApiVersion)
|
||||
```
|
||||
|
||||
## Change Log ##
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
## Out of Scope ##
|
||||
|
||||
1. No OAuth integration. This package only provides APIs to parse/verify access token and code generated in OAuth 2.0 authentication process.
|
||||
2. No old RESTful API support. Such APIs are deprecated for years. Forget about them.
|
||||
|
||||
## License ##
|
||||
|
||||
This package is licensed under MIT license. See LICENSE for details.
|
||||
180
Godeps/_workspace/src/github.com/huandu/facebook/api.go
сгенерированный
поставляемый
180
Godeps/_workspace/src/github.com/huandu/facebook/api.go
сгенерированный
поставляемый
@@ -1,180 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
// This is a Go library fully supports Facebook Graph API (both 1.0 and 2.x) with
|
||||
// file upload, batch request, FQL and multi-FQL. It can be used in Google App Engine.
|
||||
//
|
||||
// Library design is highly influenced by facebook official PHP/JS SDK.
|
||||
// If you have experience with PHP/JS SDK, you may feel quite familiar with it.
|
||||
//
|
||||
// Go to project home page to see samples. Link: https://github.com/huandu/facebook
|
||||
//
|
||||
// This library doesn't implement any deprecated old RESTful API. And it won't.
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var (
|
||||
// Default facebook api version.
|
||||
// It can be any valid version string (e.g. "v2.3") or empty.
|
||||
//
|
||||
// See https://developers.facebook.com/docs/apps/versions for details.
|
||||
Version string
|
||||
|
||||
// Set app level debug mode.
|
||||
// After setting DebugMode, all newly created session will use the mode
|
||||
// to communicate with graph API.
|
||||
//
|
||||
// See https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#debugging
|
||||
Debug DebugMode
|
||||
)
|
||||
|
||||
// Makes a facebook graph api call with default session.
|
||||
//
|
||||
// Method can be GET, POST, DELETE or PUT.
|
||||
//
|
||||
// Params represents query strings in this call.
|
||||
// Keys and values in params will be encoded for URL automatically. So there is
|
||||
// no need to encode keys or values in params manually. Params can be nil.
|
||||
//
|
||||
// If you want to get
|
||||
// https://graph.facebook.com/huandu?fields=name,username
|
||||
// Api should be called as following
|
||||
// Api("/huandu", GET, Params{"fields": "name,username"})
|
||||
// or in a simplified way
|
||||
// Get("/huandu", Params{"fields": "name,username"})
|
||||
//
|
||||
// Api is a wrapper of Session.Api(). It's designed for graph api that doesn't require
|
||||
// app id, app secret and access token. It can be called in multiple goroutines.
|
||||
//
|
||||
// If app id, app secret or access token is required in graph api, caller should
|
||||
// create a new facebook session through App instance instead.
|
||||
func Api(path string, method Method, params Params) (Result, error) {
|
||||
return defaultSession.Api(path, method, params)
|
||||
}
|
||||
|
||||
// Get is a short hand of Api(path, GET, params).
|
||||
func Get(path string, params Params) (Result, error) {
|
||||
return Api(path, GET, params)
|
||||
}
|
||||
|
||||
// Post is a short hand of Api(path, POST, params).
|
||||
func Post(path string, params Params) (Result, error) {
|
||||
return Api(path, POST, params)
|
||||
}
|
||||
|
||||
// Delete is a short hand of Api(path, DELETE, params).
|
||||
func Delete(path string, params Params) (Result, error) {
|
||||
return Api(path, DELETE, params)
|
||||
}
|
||||
|
||||
// Put is a short hand of Api(path, PUT, params).
|
||||
func Put(path string, params Params) (Result, error) {
|
||||
return Api(path, PUT, params)
|
||||
}
|
||||
|
||||
// Makes a batch facebook graph api call with default session.
|
||||
//
|
||||
// BatchApi supports most kinds of batch calls defines in facebook batch api document,
|
||||
// except uploading binary data. Use Batch to do so.
|
||||
//
|
||||
// Note: API response is stored in "body" field of a Result.
|
||||
// results, _ := BatchApi(accessToken, Params{...}, Params{...})
|
||||
//
|
||||
// // Use first batch api response.
|
||||
// var res1 *BatchResult
|
||||
// var err error
|
||||
// res1, err = results[0].Batch()
|
||||
//
|
||||
// if err != nil {
|
||||
// // this is not a valid batch api response.
|
||||
// }
|
||||
//
|
||||
// // Use BatchResult#Result to get response body content as Result.
|
||||
// res := res1.Result
|
||||
//
|
||||
// Facebook document: https://developers.facebook.com/docs/graph-api/making-multiple-requests
|
||||
func BatchApi(accessToken string, params ...Params) ([]Result, error) {
|
||||
return Batch(Params{"access_token": accessToken}, params...)
|
||||
}
|
||||
|
||||
// Makes a batch facebook graph api call with default session.
|
||||
// Batch is designed for more advanced usage including uploading binary files.
|
||||
//
|
||||
// An uploading files sample
|
||||
// // equivalent to following curl command (borrowed from facebook docs)
|
||||
// // curl \
|
||||
// // -F 'access_token=…' \
|
||||
// // -F 'batch=[{"method":"POST","relative_url":"me/photos","body":"message=My cat photo","attached_files":"file1"},{"method":"POST","relative_url":"me/photos","body":"message=My dog photo","attached_files":"file2"},]' \
|
||||
// // -F 'file1=@cat.gif' \
|
||||
// // -F 'file2=@dog.jpg' \
|
||||
// // https://graph.facebook.com
|
||||
// Batch(Params{
|
||||
// "access_token": "the-access-token",
|
||||
// "file1": File("cat.gif"),
|
||||
// "file2": File("dog.jpg"),
|
||||
// }, Params{
|
||||
// "method": "POST",
|
||||
// "relative_url": "me/photos",
|
||||
// "body": "message=My cat photo",
|
||||
// "attached_files": "file1",
|
||||
// }, Params{
|
||||
// "method": "POST",
|
||||
// "relative_url": "me/photos",
|
||||
// "body": "message=My dog photo",
|
||||
// "attached_files": "file2",
|
||||
// })
|
||||
//
|
||||
// Facebook document: https://developers.facebook.com/docs/graph-api/making-multiple-requests
|
||||
func Batch(batchParams Params, params ...Params) ([]Result, error) {
|
||||
return defaultSession.Batch(batchParams, params...)
|
||||
}
|
||||
|
||||
// Makes a FQL query with default session.
|
||||
// Returns a slice of Result. If there is no query result, the result is nil.
|
||||
//
|
||||
// FQL can only make query without "access_token". For query requiring "access_token", create
|
||||
// Session and call its FQL method.
|
||||
//
|
||||
// Facebook document: https://developers.facebook.com/docs/technical-guides/fql#query
|
||||
func FQL(query string) ([]Result, error) {
|
||||
return defaultSession.FQL(query)
|
||||
}
|
||||
|
||||
// Makes a multi FQL query with default session.
|
||||
// Returns a parsed Result. The key is the multi query key, and the value is the query result.
|
||||
//
|
||||
// MultiFQL can only make query without "access_token". For query requiring "access_token", create
|
||||
// Session and call its MultiFQL method.
|
||||
//
|
||||
// See Session.MultiFQL document for samples.
|
||||
//
|
||||
// Facebook document: https://developers.facebook.com/docs/technical-guides/fql#multi
|
||||
func MultiFQL(queries Params) (Result, error) {
|
||||
return defaultSession.MultiFQL(queries)
|
||||
}
|
||||
|
||||
// Makes an arbitrary HTTP request with default session.
|
||||
// It expects server responses a facebook Graph API response.
|
||||
// request, _ := http.NewRequest("https://graph.facebook.com/538744468", "GET", nil)
|
||||
// res, err := Request(request)
|
||||
// fmt.Println(res["gender"]) // get "male"
|
||||
func Request(request *http.Request) (Result, error) {
|
||||
return defaultSession.Request(request)
|
||||
}
|
||||
|
||||
// DefaultHttpClient returns the http client for default session.
|
||||
func DefaultHttpClient() HttpClient {
|
||||
return defaultSession.HttpClient
|
||||
}
|
||||
|
||||
// SetHttpClient updates the http client of default session.
|
||||
func SetHttpClient(client HttpClient) {
|
||||
defaultSession.HttpClient = client
|
||||
}
|
||||
255
Godeps/_workspace/src/github.com/huandu/facebook/app.go
сгенерированный
поставляемый
255
Godeps/_workspace/src/github.com/huandu/facebook/app.go
сгенерированный
поставляемый
@@ -1,255 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Creates a new App and sets app id and secret.
|
||||
func New(appId, appSecret string) *App {
|
||||
return &App{
|
||||
AppId: appId,
|
||||
AppSecret: appSecret,
|
||||
}
|
||||
}
|
||||
|
||||
// Gets application access token, useful for gathering public information about users and applications.
|
||||
func (app *App) AppAccessToken() string {
|
||||
return app.AppId + "|" + app.AppSecret
|
||||
}
|
||||
|
||||
// Parses signed request.
|
||||
func (app *App) ParseSignedRequest(signedRequest string) (res Result, err error) {
|
||||
strs := strings.SplitN(signedRequest, ".", 2)
|
||||
|
||||
if len(strs) != 2 {
|
||||
err = fmt.Errorf("invalid signed request format.")
|
||||
return
|
||||
}
|
||||
|
||||
sig, e1 := decodeBase64URLEncodingString(strs[0])
|
||||
|
||||
if e1 != nil {
|
||||
err = fmt.Errorf("cannot decode signed request sig. error is %v.", e1)
|
||||
return
|
||||
}
|
||||
|
||||
payload, e2 := decodeBase64URLEncodingString(strs[1])
|
||||
|
||||
if e2 != nil {
|
||||
err = fmt.Errorf("cannot decode signed request payload. error is %v.", e2)
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(payload, &res)
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("signed request payload is not a valid json string. error is %v.", err)
|
||||
return
|
||||
}
|
||||
|
||||
var hashMethod string
|
||||
err = res.DecodeField("algorithm", &hashMethod)
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("signed request payload doesn't contains a valid 'algorithm' field.")
|
||||
return
|
||||
}
|
||||
|
||||
hashMethod = strings.ToUpper(hashMethod)
|
||||
|
||||
if hashMethod != "HMAC-SHA256" {
|
||||
err = fmt.Errorf("signed request payload uses an unknown HMAC method. expect 'HMAC-SHA256'. actual '%v'.", hashMethod)
|
||||
return
|
||||
}
|
||||
|
||||
hash := hmac.New(sha256.New, []byte(app.AppSecret))
|
||||
hash.Write([]byte(strs[1])) // note: here uses the payload base64 string, not decoded bytes
|
||||
expectedSig := hash.Sum(nil)
|
||||
|
||||
if bytes.Compare(sig, expectedSig) != 0 {
|
||||
err = fmt.Errorf("bad signed request signiture.")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ParseCode redeems code for a valid access token.
|
||||
// It's a shorthand call to ParseCodeInfo(code, "").
|
||||
//
|
||||
// In facebook PHP SDK, there is a CSRF state to avoid attack.
|
||||
// That state is not checked in this library.
|
||||
// Caller is responsible to store and check state if possible.
|
||||
func (app *App) ParseCode(code string) (token string, err error) {
|
||||
token, _, _, err = app.ParseCodeInfo(code, "")
|
||||
return
|
||||
}
|
||||
|
||||
// ParseCodeInfo redeems code for access token and returns extra information.
|
||||
// The machineId is optional.
|
||||
//
|
||||
// See https://developers.facebook.com/docs/facebook-login/access-tokens#extending
|
||||
func (app *App) ParseCodeInfo(code, machineId string) (token string, expires int, newMachineId string, err error) {
|
||||
if code == "" {
|
||||
err = fmt.Errorf("code is empty")
|
||||
return
|
||||
}
|
||||
|
||||
var res Result
|
||||
res, err = defaultSession.sendOauthRequest("/oauth/access_token", Params{
|
||||
"client_id": app.AppId,
|
||||
"redirect_uri": app.RedirectUri,
|
||||
"code": code,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot parse facebook response. error is %v.", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = res.DecodeField("access_token", &token)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = res.DecodeField("expires_in", &expires)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := res["machine_id"]; ok {
|
||||
err = res.DecodeField("machine_id", &newMachineId)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Exchange a short lived access token to a long lived access token.
|
||||
// Return new access token and its expires time.
|
||||
func (app *App) ExchangeToken(accessToken string) (token string, expires int, err error) {
|
||||
if accessToken == "" {
|
||||
err = fmt.Errorf("short lived accessToken is empty")
|
||||
return
|
||||
}
|
||||
|
||||
var res Result
|
||||
res, err = defaultSession.sendOauthRequest("/oauth/access_token", Params{
|
||||
"grant_type": "fb_exchange_token",
|
||||
"client_id": app.AppId,
|
||||
"client_secret": app.AppSecret,
|
||||
"fb_exchange_token": accessToken,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot parse facebook response. error is %v.", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = res.DecodeField("access_token", &token)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = res.DecodeField("expires_in", &expires)
|
||||
return
|
||||
}
|
||||
|
||||
// Get code from a long lived access token.
|
||||
// Return the code retrieved from facebook.
|
||||
func (app *App) GetCode(accessToken string) (code string, err error) {
|
||||
if accessToken == "" {
|
||||
err = fmt.Errorf("long lived accessToken is empty")
|
||||
return
|
||||
}
|
||||
|
||||
var res Result
|
||||
res, err = defaultSession.sendOauthRequest("/oauth/client_code", Params{
|
||||
"client_id": app.AppId,
|
||||
"client_secret": app.AppSecret,
|
||||
"redirect_uri": app.RedirectUri,
|
||||
"access_token": accessToken,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot get code from facebook. error is %v.", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = res.DecodeField("code", &code)
|
||||
return
|
||||
}
|
||||
|
||||
// Creates a session based on current App setting.
|
||||
func (app *App) Session(accessToken string) *Session {
|
||||
return &Session{
|
||||
accessToken: accessToken,
|
||||
app: app,
|
||||
enableAppsecretProof: app.EnableAppsecretProof,
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a session from a signed request.
|
||||
// If signed request contains a code, it will automatically use this code
|
||||
// to exchange a valid access token.
|
||||
func (app *App) SessionFromSignedRequest(signedRequest string) (session *Session, err error) {
|
||||
var res Result
|
||||
|
||||
res, err = app.ParseSignedRequest(signedRequest)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var id, token string
|
||||
|
||||
res.DecodeField("user_id", &id) // it's ok without user id.
|
||||
err = res.DecodeField("oauth_token", &token)
|
||||
|
||||
if err == nil {
|
||||
session = &Session{
|
||||
accessToken: token,
|
||||
app: app,
|
||||
id: id,
|
||||
enableAppsecretProof: app.EnableAppsecretProof,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// cannot get "oauth_token"? try to get "code".
|
||||
err = res.DecodeField("code", &token)
|
||||
|
||||
if err != nil {
|
||||
// no code? no way to continue.
|
||||
err = fmt.Errorf("cannot find 'oauth_token' and 'code'. no way to continue.")
|
||||
return
|
||||
}
|
||||
|
||||
token, err = app.ParseCode(token)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
session = &Session{
|
||||
accessToken: token,
|
||||
app: app,
|
||||
id: id,
|
||||
enableAppsecretProof: app.EnableAppsecretProof,
|
||||
}
|
||||
return
|
||||
}
|
||||
52
Godeps/_workspace/src/github.com/huandu/facebook/batch_result.go
сгенерированный
поставляемый
52
Godeps/_workspace/src/github.com/huandu/facebook/batch_result.go
сгенерированный
поставляемый
@@ -1,52 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type batchResultHeader struct {
|
||||
Name string `facebook=",required"`
|
||||
Value string `facebook=",required"`
|
||||
}
|
||||
|
||||
type batchResultData struct {
|
||||
Code int `facebook=",required"`
|
||||
Headers []batchResultHeader `facebook=",required"`
|
||||
Body string `facebook=",required"`
|
||||
}
|
||||
|
||||
func newBatchResult(res Result) (*BatchResult, error) {
|
||||
var data batchResultData
|
||||
err := res.Decode(&data)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &BatchResult{
|
||||
StatusCode: data.Code,
|
||||
Header: http.Header{},
|
||||
Body: data.Body,
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(result.Body), &result.Result)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// add headers to result.
|
||||
for _, header := range data.Headers {
|
||||
result.Header.Add(header.Name, header.Value)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
74
Godeps/_workspace/src/github.com/huandu/facebook/const.go
сгенерированный
поставляемый
74
Godeps/_workspace/src/github.com/huandu/facebook/const.go
сгенерированный
поставляемый
@@ -1,74 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Facebook graph api methods.
|
||||
const (
|
||||
GET Method = "GET"
|
||||
POST Method = "POST"
|
||||
DELETE Method = "DELETE"
|
||||
PUT Method = "PUT"
|
||||
)
|
||||
|
||||
const (
|
||||
ERROR_CODE_UNKNOWN = -1 // unknown facebook graph api error code.
|
||||
|
||||
_MIME_FORM_URLENCODED = "application/x-www-form-urlencoded"
|
||||
)
|
||||
|
||||
// Graph API debug mode values.
|
||||
const (
|
||||
DEBUG_OFF DebugMode = "" // turn off debug.
|
||||
|
||||
DEBUG_ALL DebugMode = "all"
|
||||
DEBUG_INFO DebugMode = "info"
|
||||
DEBUG_WARNING DebugMode = "warning"
|
||||
)
|
||||
|
||||
const (
|
||||
debugInfoKey = "__debug__"
|
||||
debugProtoKey = "__proto__"
|
||||
debugHeaderKey = "__header__"
|
||||
|
||||
facebookApiVersionHeader = "facebook-api-version"
|
||||
facebookDebugHeader = "x-fb-debug"
|
||||
facebookRevHeader = "x-fb-rev"
|
||||
)
|
||||
|
||||
var (
|
||||
// Maps aliases to Facebook domains.
|
||||
// Copied from Facebook PHP SDK.
|
||||
domainMap = map[string]string{
|
||||
"api": "https://api.facebook.com/",
|
||||
"api_video": "https://api-video.facebook.com/",
|
||||
"api_read": "https://api-read.facebook.com/",
|
||||
"graph": "https://graph.facebook.com/",
|
||||
"graph_video": "https://graph-video.facebook.com/",
|
||||
"www": "https://www.facebook.com/",
|
||||
}
|
||||
|
||||
// checks whether it's a video post.
|
||||
regexpIsVideoPost = regexp.MustCompile(`/^(\/)(.+)(\/)(videos)$/`)
|
||||
|
||||
// default facebook session.
|
||||
defaultSession = &Session{}
|
||||
|
||||
typeOfPointerToBinaryData = reflect.TypeOf(&binaryData{})
|
||||
typeOfPointerToBinaryFile = reflect.TypeOf(&binaryFile{})
|
||||
typeOfJSONNumber = reflect.TypeOf(json.Number(""))
|
||||
typeOfTime = reflect.TypeOf(time.Time{})
|
||||
|
||||
facebookSuccessJsonBytes = []byte("true")
|
||||
)
|
||||
1469
Godeps/_workspace/src/github.com/huandu/facebook/facebook_test.go
сгенерированный
поставляемый
1469
Godeps/_workspace/src/github.com/huandu/facebook/facebook_test.go
сгенерированный
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
131
Godeps/_workspace/src/github.com/huandu/facebook/misc.go
сгенерированный
поставляемый
131
Godeps/_workspace/src/github.com/huandu/facebook/misc.go
сгенерированный
поставляемый
@@ -1,131 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func camelCaseToUnderScore(str string) string {
|
||||
if len(str) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
var prev, r0, r1 rune
|
||||
var size int
|
||||
|
||||
r0 = '_'
|
||||
|
||||
for len(str) > 0 {
|
||||
prev = r0
|
||||
r0, size = utf8.DecodeRuneInString(str)
|
||||
str = str[size:]
|
||||
|
||||
switch {
|
||||
case r0 == utf8.RuneError:
|
||||
buf.WriteByte(byte(str[0]))
|
||||
|
||||
case unicode.IsUpper(r0):
|
||||
if prev != '_' {
|
||||
buf.WriteRune('_')
|
||||
}
|
||||
|
||||
buf.WriteRune(unicode.ToLower(r0))
|
||||
|
||||
if len(str) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
r0, size = utf8.DecodeRuneInString(str)
|
||||
str = str[size:]
|
||||
|
||||
if !unicode.IsUpper(r0) {
|
||||
buf.WriteRune(r0)
|
||||
break
|
||||
}
|
||||
|
||||
// find next non-upper-case character and insert `_` properly.
|
||||
// it's designed to convert `HTTPServer` to `http_server`.
|
||||
// if there are more than 2 adjacent upper case characters in a word,
|
||||
// treat them as an abbreviation plus a normal word.
|
||||
for len(str) > 0 {
|
||||
r1 = r0
|
||||
r0, size = utf8.DecodeRuneInString(str)
|
||||
str = str[size:]
|
||||
|
||||
if r0 == utf8.RuneError {
|
||||
buf.WriteRune(unicode.ToLower(r1))
|
||||
buf.WriteByte(byte(str[0]))
|
||||
break
|
||||
}
|
||||
|
||||
if !unicode.IsUpper(r0) {
|
||||
if r0 == '_' || r0 == ' ' || r0 == '-' {
|
||||
r0 = '_'
|
||||
|
||||
buf.WriteRune(unicode.ToLower(r1))
|
||||
} else {
|
||||
buf.WriteRune('_')
|
||||
buf.WriteRune(unicode.ToLower(r1))
|
||||
buf.WriteRune(r0)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
buf.WriteRune(unicode.ToLower(r1))
|
||||
}
|
||||
|
||||
if len(str) == 0 || r0 == '_' {
|
||||
buf.WriteRune(unicode.ToLower(r0))
|
||||
break
|
||||
}
|
||||
|
||||
default:
|
||||
if r0 == ' ' || r0 == '-' {
|
||||
r0 = '_'
|
||||
}
|
||||
|
||||
buf.WriteRune(r0)
|
||||
}
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Returns error string.
|
||||
func (e *Error) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// Creates a new binary data holder.
|
||||
func Data(filename string, source io.Reader) *binaryData {
|
||||
return &binaryData{
|
||||
Filename: filename,
|
||||
Source: source,
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a binary file holder.
|
||||
func File(filename, path string) *binaryFile {
|
||||
return &binaryFile{
|
||||
Filename: filename,
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a binary file holder and specific a different path for reading.
|
||||
func FileAlias(filename, path string) *binaryFile {
|
||||
return &binaryFile{
|
||||
Filename: filename,
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
146
Godeps/_workspace/src/github.com/huandu/facebook/paging_result.go
сгенерированный
поставляемый
146
Godeps/_workspace/src/github.com/huandu/facebook/paging_result.go
сгенерированный
поставляемый
@@ -1,146 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type pagingData struct {
|
||||
Data []Result `facebook:",required"`
|
||||
Paging *pagingNavigator
|
||||
}
|
||||
|
||||
type pagingNavigator struct {
|
||||
Previous string
|
||||
Next string
|
||||
}
|
||||
|
||||
func newPagingResult(session *Session, res Result) (*PagingResult, error) {
|
||||
// quick check whether Result is a paging response.
|
||||
if _, ok := res["data"]; !ok {
|
||||
return nil, fmt.Errorf("current Result is not a paging response.")
|
||||
}
|
||||
|
||||
pr := &PagingResult{
|
||||
session: session,
|
||||
}
|
||||
paging := &pr.paging
|
||||
err := res.Decode(paging)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if paging.Paging != nil {
|
||||
pr.previous = paging.Paging.Previous
|
||||
pr.next = paging.Paging.Next
|
||||
}
|
||||
|
||||
return pr, nil
|
||||
}
|
||||
|
||||
// Get current data.
|
||||
func (pr *PagingResult) Data() []Result {
|
||||
return pr.paging.Data
|
||||
}
|
||||
|
||||
// Decodes the current full result to a struct. See Result#Decode.
|
||||
func (pr *PagingResult) Decode(v interface{}) (err error) {
|
||||
res := Result{
|
||||
"data": pr.Data(),
|
||||
}
|
||||
return res.Decode(v)
|
||||
}
|
||||
|
||||
// Read previous page.
|
||||
func (pr *PagingResult) Previous() (noMore bool, err error) {
|
||||
if !pr.HasPrevious() {
|
||||
noMore = true
|
||||
return
|
||||
}
|
||||
|
||||
return pr.navigate(&pr.previous)
|
||||
}
|
||||
|
||||
// Read next page.
|
||||
func (pr *PagingResult) Next() (noMore bool, err error) {
|
||||
if !pr.HasNext() {
|
||||
noMore = true
|
||||
return
|
||||
}
|
||||
|
||||
return pr.navigate(&pr.next)
|
||||
}
|
||||
|
||||
// Check whether there is previous page.
|
||||
func (pr *PagingResult) HasPrevious() bool {
|
||||
return pr.previous != ""
|
||||
}
|
||||
|
||||
// Check whether there is next page.
|
||||
func (pr *PagingResult) HasNext() bool {
|
||||
return pr.next != ""
|
||||
}
|
||||
|
||||
func (pr *PagingResult) navigate(url *string) (noMore bool, err error) {
|
||||
var pagingUrl string
|
||||
|
||||
// add session information in paging url.
|
||||
params := Params{}
|
||||
pr.session.prepareParams(params)
|
||||
|
||||
if len(params) == 0 {
|
||||
pagingUrl = *url
|
||||
} else {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString(*url)
|
||||
buf.WriteRune('&')
|
||||
params.Encode(buf)
|
||||
|
||||
pagingUrl = buf.String()
|
||||
}
|
||||
|
||||
var request *http.Request
|
||||
var res Result
|
||||
|
||||
request, err = http.NewRequest("GET", pagingUrl, nil)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
res, err = pr.session.Request(request)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if pr.paging.Paging != nil {
|
||||
pr.paging.Paging.Next = ""
|
||||
pr.paging.Paging.Previous = ""
|
||||
}
|
||||
paging := &pr.paging
|
||||
err = res.Decode(paging)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if paging.Paging == nil || len(paging.Data) == 0 {
|
||||
*url = ""
|
||||
noMore = true
|
||||
} else {
|
||||
pr.previous = paging.Paging.Previous
|
||||
pr.next = paging.Paging.Next
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
227
Godeps/_workspace/src/github.com/huandu/facebook/params.go
сгенерированный
поставляемый
227
Godeps/_workspace/src/github.com/huandu/facebook/params.go
сгенерированный
поставляемый
@@ -1,227 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Makes a new Params instance by given data.
|
||||
// Data must be a struct or a map with string keys.
|
||||
// MakeParams will change all struct field name to lower case name with underscore.
|
||||
// e.g. "FooBar" will be changed to "foo_bar".
|
||||
//
|
||||
// Returns nil if data cannot be used to make a Params instance.
|
||||
func MakeParams(data interface{}) (params Params) {
|
||||
if p, ok := data.(Params); ok {
|
||||
return p
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if _, ok := r.(runtime.Error); ok {
|
||||
panic(r)
|
||||
}
|
||||
|
||||
params = nil
|
||||
}
|
||||
}()
|
||||
|
||||
params = makeParams(reflect.ValueOf(data))
|
||||
return
|
||||
}
|
||||
|
||||
func makeParams(value reflect.Value) (params Params) {
|
||||
for value.Kind() == reflect.Ptr || value.Kind() == reflect.Interface {
|
||||
value = value.Elem()
|
||||
}
|
||||
|
||||
// only map with string keys can be converted to Params
|
||||
if value.Kind() == reflect.Map && value.Type().Key().Kind() == reflect.String {
|
||||
params = Params{}
|
||||
|
||||
for _, key := range value.MapKeys() {
|
||||
params[key.String()] = value.MapIndex(key).Interface()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if value.Kind() != reflect.Struct {
|
||||
return
|
||||
}
|
||||
|
||||
params = Params{}
|
||||
num := value.NumField()
|
||||
|
||||
for i := 0; i < num; i++ {
|
||||
name := camelCaseToUnderScore(value.Type().Field(i).Name)
|
||||
field := value.Field(i)
|
||||
|
||||
for field.Kind() == reflect.Ptr {
|
||||
field = field.Elem()
|
||||
}
|
||||
|
||||
switch field.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.UnsafePointer, reflect.Invalid:
|
||||
// these types won't be marshalled in json.
|
||||
params = nil
|
||||
return
|
||||
|
||||
default:
|
||||
params[name] = field.Interface()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Encodes params to query string.
|
||||
// If map value is not a string, Encode uses json.Marshal() to convert value to string.
|
||||
//
|
||||
// Encode will panic if Params contains values that cannot be marshalled to json string.
|
||||
func (params Params) Encode(writer io.Writer) (mime string, err error) {
|
||||
if params == nil || len(params) == 0 {
|
||||
mime = _MIME_FORM_URLENCODED
|
||||
return
|
||||
}
|
||||
|
||||
// check whether params contains any binary data.
|
||||
hasBinary := false
|
||||
|
||||
for _, v := range params {
|
||||
typ := reflect.TypeOf(v)
|
||||
|
||||
if typ == typeOfPointerToBinaryData || typ == typeOfPointerToBinaryFile {
|
||||
hasBinary = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if hasBinary {
|
||||
return params.encodeMultipartForm(writer)
|
||||
}
|
||||
|
||||
return params.encodeFormUrlEncoded(writer)
|
||||
}
|
||||
|
||||
func (params Params) encodeFormUrlEncoded(writer io.Writer) (mime string, err error) {
|
||||
var jsonStr []byte
|
||||
written := false
|
||||
|
||||
for k, v := range params {
|
||||
if written {
|
||||
io.WriteString(writer, "&")
|
||||
}
|
||||
|
||||
io.WriteString(writer, url.QueryEscape(k))
|
||||
io.WriteString(writer, "=")
|
||||
|
||||
if reflect.TypeOf(v).Kind() == reflect.String {
|
||||
io.WriteString(writer, url.QueryEscape(reflect.ValueOf(v).String()))
|
||||
} else {
|
||||
jsonStr, err = json.Marshal(v)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
io.WriteString(writer, url.QueryEscape(string(jsonStr)))
|
||||
}
|
||||
|
||||
written = true
|
||||
}
|
||||
|
||||
mime = _MIME_FORM_URLENCODED
|
||||
return
|
||||
}
|
||||
|
||||
func (params Params) encodeMultipartForm(writer io.Writer) (mime string, err error) {
|
||||
w := multipart.NewWriter(writer)
|
||||
defer func() {
|
||||
w.Close()
|
||||
mime = w.FormDataContentType()
|
||||
}()
|
||||
|
||||
for k, v := range params {
|
||||
switch value := v.(type) {
|
||||
case *binaryData:
|
||||
var dst io.Writer
|
||||
dst, err = w.CreateFormFile(k, value.Filename)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = io.Copy(dst, value.Source)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
case *binaryFile:
|
||||
var dst io.Writer
|
||||
var file *os.File
|
||||
var path string
|
||||
|
||||
dst, err = w.CreateFormFile(k, value.Filename)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if value.Path == "" {
|
||||
path = value.Filename
|
||||
} else {
|
||||
path = value.Path
|
||||
}
|
||||
|
||||
file, err = os.Open(path)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = io.Copy(dst, file)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
var dst io.Writer
|
||||
var jsonStr []byte
|
||||
|
||||
dst, err = w.CreateFormField(k)
|
||||
|
||||
if reflect.TypeOf(v).Kind() == reflect.String {
|
||||
io.WriteString(dst, reflect.ValueOf(v).String())
|
||||
} else {
|
||||
jsonStr, err = json.Marshal(v)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = dst.Write(jsonStr)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
1097
Godeps/_workspace/src/github.com/huandu/facebook/result.go
сгенерированный
поставляемый
1097
Godeps/_workspace/src/github.com/huandu/facebook/result.go
сгенерированный
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
667
Godeps/_workspace/src/github.com/huandu/facebook/session.go
сгенерированный
поставляемый
667
Godeps/_workspace/src/github.com/huandu/facebook/session.go
сгенерированный
поставляемый
@@ -1,667 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Makes a facebook graph api call.
|
||||
//
|
||||
// If session access token is set, "access_token" in params will be set to the token value.
|
||||
//
|
||||
// Returns facebook graph api call result.
|
||||
// If facebook returns error in response, returns error details in res and set err.
|
||||
func (session *Session) Api(path string, method Method, params Params) (Result, error) {
|
||||
return session.graph(path, method, params)
|
||||
}
|
||||
|
||||
// Get is a short hand of Api(path, GET, params).
|
||||
func (session *Session) Get(path string, params Params) (Result, error) {
|
||||
return session.Api(path, GET, params)
|
||||
}
|
||||
|
||||
// Post is a short hand of Api(path, POST, params).
|
||||
func (session *Session) Post(path string, params Params) (Result, error) {
|
||||
return session.Api(path, POST, params)
|
||||
}
|
||||
|
||||
// Delete is a short hand of Api(path, DELETE, params).
|
||||
func (session *Session) Delete(path string, params Params) (Result, error) {
|
||||
return session.Api(path, DELETE, params)
|
||||
}
|
||||
|
||||
// Put is a short hand of Api(path, PUT, params).
|
||||
func (session *Session) Put(path string, params Params) (Result, error) {
|
||||
return session.Api(path, PUT, params)
|
||||
}
|
||||
|
||||
// Makes a batch call. Each params represent a single facebook graph api call.
|
||||
//
|
||||
// BatchApi supports most kinds of batch calls defines in facebook batch api document,
|
||||
// except uploading binary data. Use Batch to upload binary data.
|
||||
//
|
||||
// If session access token is set, the token will be used in batch api call.
|
||||
//
|
||||
// Returns an array of batch call result on success.
|
||||
//
|
||||
// Facebook document: https://developers.facebook.com/docs/graph-api/making-multiple-requests
|
||||
func (session *Session) BatchApi(params ...Params) ([]Result, error) {
|
||||
return session.Batch(nil, params...)
|
||||
}
|
||||
|
||||
// Makes a batch facebook graph api call.
|
||||
// Batch is designed for more advanced usage including uploading binary files.
|
||||
//
|
||||
// If session access token is set, "access_token" in batchParams will be set to the token value.
|
||||
//
|
||||
// Facebook document: https://developers.facebook.com/docs/graph-api/making-multiple-requests
|
||||
func (session *Session) Batch(batchParams Params, params ...Params) ([]Result, error) {
|
||||
return session.graphBatch(batchParams, params...)
|
||||
}
|
||||
|
||||
// Makes a FQL query.
|
||||
// Returns a slice of Result. If there is no query result, the result is nil.
|
||||
//
|
||||
// Facebook document: https://developers.facebook.com/docs/technical-guides/fql#query
|
||||
func (session *Session) FQL(query string) ([]Result, error) {
|
||||
res, err := session.graphFQL(Params{
|
||||
"q": query,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// query result is stored in "data" field.
|
||||
var data []Result
|
||||
err = res.DecodeField("data", &data)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Makes a multi FQL query.
|
||||
// Returns a parsed Result. The key is the multi query key, and the value is the query result.
|
||||
//
|
||||
// Here is a multi-query sample.
|
||||
//
|
||||
// res, _ := session.MultiFQL(Params{
|
||||
// "query1": "SELECT name FROM user WHERE uid = me()",
|
||||
// "query2": "SELECT uid1, uid2 FROM friend WHERE uid1 = me()",
|
||||
// })
|
||||
//
|
||||
// // Get query results from response.
|
||||
// var query1, query2 []Result
|
||||
// res.DecodeField("query1", &query1)
|
||||
// res.DecodeField("query2", &query2)
|
||||
//
|
||||
// Facebook document: https://developers.facebook.com/docs/technical-guides/fql#multi
|
||||
func (session *Session) MultiFQL(queries Params) (Result, error) {
|
||||
res, err := session.graphFQL(Params{
|
||||
"q": queries,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// query result is stored in "data" field.
|
||||
var data []Result
|
||||
err = res.DecodeField("data", &data)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if data == nil {
|
||||
return nil, fmt.Errorf("multi-fql result is not found.")
|
||||
}
|
||||
|
||||
// Multi-fql data structure is:
|
||||
// {
|
||||
// "data": [
|
||||
// {
|
||||
// "name": "query1",
|
||||
// "fql_result_set": [
|
||||
// {...}, {...}, ...
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// "name": "query2",
|
||||
// "fql_result_set": [
|
||||
// {...}, {...}, ...
|
||||
// ]
|
||||
// },
|
||||
// ...
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// Parse the structure to following go map.
|
||||
// {
|
||||
// "query1": [
|
||||
// // Come from field "fql_result_set".
|
||||
// {...}, {...}, ...
|
||||
// ],
|
||||
// "query2": [
|
||||
// {...}, {...}, ...
|
||||
// ],
|
||||
// ...
|
||||
// }
|
||||
var name string
|
||||
var apiResponse interface{}
|
||||
var ok bool
|
||||
result := Result{}
|
||||
|
||||
for k, v := range data {
|
||||
err = v.DecodeField("name", &name)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("missing required field 'name' in multi-query data.%v. %v", k, err)
|
||||
}
|
||||
|
||||
apiResponse, ok = v["fql_result_set"]
|
||||
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("missing required field 'fql_result_set' in multi-query data.%v.", k)
|
||||
}
|
||||
|
||||
result[name] = apiResponse
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Makes an arbitrary HTTP request.
|
||||
// It expects server responses a facebook Graph API response.
|
||||
// request, _ := http.NewRequest("https://graph.facebook.com/538744468", "GET", nil)
|
||||
// res, err := session.Request(request)
|
||||
// fmt.Println(res["gender"]) // get "male"
|
||||
func (session *Session) Request(request *http.Request) (res Result, err error) {
|
||||
var response *http.Response
|
||||
var data []byte
|
||||
|
||||
response, data, err = session.sendRequest(request)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
res, err = MakeResult(data)
|
||||
session.addDebugInfo(res, response)
|
||||
|
||||
if res != nil {
|
||||
err = res.Err()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Gets current user id from access token.
|
||||
//
|
||||
// Returns error if access token is not set or invalid.
|
||||
//
|
||||
// It's a standard way to validate a facebook access token.
|
||||
func (session *Session) User() (id string, err error) {
|
||||
if session.id != "" {
|
||||
id = session.id
|
||||
return
|
||||
}
|
||||
|
||||
if session.accessToken == "" {
|
||||
err = fmt.Errorf("access token is not set.")
|
||||
return
|
||||
}
|
||||
|
||||
var result Result
|
||||
result, err = session.Api("/me", GET, Params{"fields": "id"})
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = result.DecodeField("id", &id)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Validates Session access token.
|
||||
// Returns nil if access token is valid.
|
||||
func (session *Session) Validate() (err error) {
|
||||
if session.accessToken == "" {
|
||||
err = fmt.Errorf("access token is not set.")
|
||||
return
|
||||
}
|
||||
|
||||
var result Result
|
||||
result, err = session.Api("/me", GET, Params{"fields": "id"})
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if f := result.Get("id"); f == nil {
|
||||
err = fmt.Errorf("invalid access token.")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Inspect Session access token.
|
||||
// Returns JSON array containing data about the inspected token.
|
||||
// See https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2#checktoken
|
||||
func (session *Session) Inspect() (result Result, err error) {
|
||||
if session.accessToken == "" {
|
||||
err = fmt.Errorf("access token is not set.")
|
||||
return
|
||||
}
|
||||
|
||||
if session.app == nil {
|
||||
err = fmt.Errorf("cannot inspect access token without binding an app.")
|
||||
return
|
||||
}
|
||||
|
||||
appAccessToken := session.app.AppAccessToken()
|
||||
|
||||
if appAccessToken == "" {
|
||||
err = fmt.Errorf("app access token is not set.")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = session.Api("/debug_token", GET, Params{
|
||||
"input_token": session.accessToken,
|
||||
"access_token": appAccessToken,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// facebook stores everything, including error, inside result["data"].
|
||||
// make sure that result["data"] exists and doesn't contain error.
|
||||
if _, ok := result["data"]; !ok {
|
||||
err = fmt.Errorf("facebook inspect api returns unexpected result.")
|
||||
return
|
||||
}
|
||||
|
||||
var data Result
|
||||
result.DecodeField("data", &data)
|
||||
result = data
|
||||
err = result.Err()
|
||||
return
|
||||
}
|
||||
|
||||
// Gets current access token.
|
||||
func (session *Session) AccessToken() string {
|
||||
return session.accessToken
|
||||
}
|
||||
|
||||
// Sets a new access token.
|
||||
func (session *Session) SetAccessToken(token string) {
|
||||
if token != session.accessToken {
|
||||
session.id = ""
|
||||
session.accessToken = token
|
||||
session.appsecretProof = ""
|
||||
}
|
||||
}
|
||||
|
||||
// Check appsecret proof is enabled or not.
|
||||
func (session *Session) AppsecretProof() string {
|
||||
if !session.enableAppsecretProof {
|
||||
return ""
|
||||
}
|
||||
|
||||
if session.accessToken == "" || session.app == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if session.appsecretProof == "" {
|
||||
hash := hmac.New(sha256.New, []byte(session.app.AppSecret))
|
||||
hash.Write([]byte(session.accessToken))
|
||||
session.appsecretProof = hex.EncodeToString(hash.Sum(nil))
|
||||
}
|
||||
|
||||
return session.appsecretProof
|
||||
}
|
||||
|
||||
// Enable or disable appsecret proof status.
|
||||
// Returns error if there is no App associasted with this Session.
|
||||
func (session *Session) EnableAppsecretProof(enabled bool) error {
|
||||
if session.app == nil {
|
||||
return fmt.Errorf("cannot change appsecret proof status without an associated App.")
|
||||
}
|
||||
|
||||
if session.enableAppsecretProof != enabled {
|
||||
session.enableAppsecretProof = enabled
|
||||
|
||||
// reset pre-calculated proof here to give caller a way to do so in some rare case,
|
||||
// e.g. associated app's secret is changed.
|
||||
session.appsecretProof = ""
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets associated App.
|
||||
func (session *Session) App() *App {
|
||||
return session.app
|
||||
}
|
||||
|
||||
// Debug returns current debug mode.
|
||||
func (session *Session) Debug() DebugMode {
|
||||
if session.debug != DEBUG_OFF {
|
||||
return session.debug
|
||||
}
|
||||
|
||||
return Debug
|
||||
}
|
||||
|
||||
// SetDebug updates per session debug mode and returns old mode.
|
||||
// If per session debug mode is DEBUG_OFF, session will use global
|
||||
// Debug mode.
|
||||
func (session *Session) SetDebug(debug DebugMode) DebugMode {
|
||||
old := session.debug
|
||||
session.debug = debug
|
||||
return old
|
||||
}
|
||||
|
||||
func (session *Session) graph(path string, method Method, params Params) (res Result, err error) {
|
||||
var graphUrl string
|
||||
|
||||
if params == nil {
|
||||
params = Params{}
|
||||
}
|
||||
|
||||
// always format as json.
|
||||
params["format"] = "json"
|
||||
|
||||
// overwrite method as we always use post
|
||||
params["method"] = method
|
||||
|
||||
// get graph api url.
|
||||
if session.isVideoPost(path, method) {
|
||||
graphUrl = session.getUrl("graph_video", path, nil)
|
||||
} else {
|
||||
graphUrl = session.getUrl("graph", path, nil)
|
||||
}
|
||||
|
||||
var response *http.Response
|
||||
response, err = session.sendPostRequest(graphUrl, params, &res)
|
||||
session.addDebugInfo(res, response)
|
||||
|
||||
if res != nil {
|
||||
err = res.Err()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (session *Session) graphBatch(batchParams Params, params ...Params) ([]Result, error) {
|
||||
if batchParams == nil {
|
||||
batchParams = Params{}
|
||||
}
|
||||
|
||||
batchParams["batch"] = params
|
||||
|
||||
var res []Result
|
||||
graphUrl := session.getUrl("graph", "", nil)
|
||||
_, err := session.sendPostRequest(graphUrl, batchParams, &res)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (session *Session) graphFQL(params Params) (res Result, err error) {
|
||||
if params == nil {
|
||||
params = Params{}
|
||||
}
|
||||
|
||||
session.prepareParams(params)
|
||||
|
||||
// encode url.
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString(domainMap["graph"])
|
||||
buf.WriteString("fql?")
|
||||
_, err = params.Encode(buf)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot encode params. %v", err)
|
||||
}
|
||||
|
||||
// it seems facebook disallow POST to /fql. always use GET for FQL.
|
||||
var response *http.Response
|
||||
response, err = session.sendGetRequest(buf.String(), &res)
|
||||
session.addDebugInfo(res, response)
|
||||
|
||||
if res != nil {
|
||||
err = res.Err()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (session *Session) prepareParams(params Params) {
|
||||
if _, ok := params["access_token"]; !ok && session.accessToken != "" {
|
||||
params["access_token"] = session.accessToken
|
||||
}
|
||||
|
||||
if session.enableAppsecretProof && session.accessToken != "" && session.app != nil {
|
||||
params["appsecret_proof"] = session.AppsecretProof()
|
||||
}
|
||||
|
||||
debug := session.Debug()
|
||||
|
||||
if debug != DEBUG_OFF {
|
||||
params["debug"] = debug
|
||||
}
|
||||
}
|
||||
|
||||
func (session *Session) sendGetRequest(uri string, res interface{}) (*http.Response, error) {
|
||||
request, err := http.NewRequest("GET", uri, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, data, err := session.sendRequest(request)
|
||||
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
err = makeResult(data, res)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func (session *Session) sendPostRequest(uri string, params Params, res interface{}) (*http.Response, error) {
|
||||
session.prepareParams(params)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
mime, err := params.Encode(buf)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot encode POST params. %v", err)
|
||||
}
|
||||
|
||||
var request *http.Request
|
||||
|
||||
request, err = http.NewRequest("POST", uri, buf)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request.Header.Set("Content-Type", mime)
|
||||
response, data, err := session.sendRequest(request)
|
||||
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
err = makeResult(data, res)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func (session *Session) sendOauthRequest(uri string, params Params) (Result, error) {
|
||||
urlStr := session.getUrl("graph", uri, nil)
|
||||
buf := &bytes.Buffer{}
|
||||
mime, err := params.Encode(buf)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot encode POST params. %v", err)
|
||||
}
|
||||
|
||||
var request *http.Request
|
||||
|
||||
request, err = http.NewRequest("POST", urlStr, buf)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request.Header.Set("Content-Type", mime)
|
||||
_, data, err := session.sendRequest(request)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
return nil, fmt.Errorf("empty response from facebook")
|
||||
}
|
||||
|
||||
// facebook may return a query string.
|
||||
if 'a' <= data[0] && data[0] <= 'z' {
|
||||
query, err := url.ParseQuery(string(data))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// convert a query to Result.
|
||||
res := Result{}
|
||||
|
||||
for k := range query {
|
||||
res[k] = query.Get(k)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
res, err := MakeResult(data)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (session *Session) sendRequest(request *http.Request) (response *http.Response, data []byte, err error) {
|
||||
if session.HttpClient == nil {
|
||||
response, err = http.DefaultClient.Do(request)
|
||||
} else {
|
||||
response, err = session.HttpClient.Do(request)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot reach facebook server. %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
_, err = io.Copy(buf, response.Body)
|
||||
response.Body.Close()
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot read facebook response. %v", err)
|
||||
}
|
||||
|
||||
data = buf.Bytes()
|
||||
return
|
||||
}
|
||||
|
||||
func (session *Session) isVideoPost(path string, method Method) bool {
|
||||
return method == POST && regexpIsVideoPost.MatchString(path)
|
||||
}
|
||||
|
||||
func (session *Session) getUrl(name, path string, params Params) string {
|
||||
offset := 0
|
||||
|
||||
if path != "" && path[0] == '/' {
|
||||
offset = 1
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString(domainMap[name])
|
||||
|
||||
// facebook versioning.
|
||||
if session.Version == "" {
|
||||
if Version != "" {
|
||||
buf.WriteString(Version)
|
||||
buf.WriteRune('/')
|
||||
}
|
||||
} else {
|
||||
buf.WriteString(session.Version)
|
||||
buf.WriteRune('/')
|
||||
}
|
||||
|
||||
buf.WriteString(string(path[offset:]))
|
||||
|
||||
if params != nil {
|
||||
buf.WriteRune('?')
|
||||
params.Encode(buf)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (session *Session) addDebugInfo(res Result, response *http.Response) Result {
|
||||
if session.Debug() == DEBUG_OFF || res == nil || response == nil {
|
||||
return res
|
||||
}
|
||||
|
||||
debugInfo := make(map[string]interface{})
|
||||
|
||||
// save debug information in result directly.
|
||||
res.DecodeField("__debug__", &debugInfo)
|
||||
debugInfo[debugProtoKey] = response.Proto
|
||||
debugInfo[debugHeaderKey] = response.Header
|
||||
|
||||
res["__debug__"] = debugInfo
|
||||
return res
|
||||
}
|
||||
|
||||
func decodeBase64URLEncodingString(data string) ([]byte, error) {
|
||||
buf := bytes.NewBufferString(data)
|
||||
|
||||
// go's URLEncoding implementation requires base64 padding.
|
||||
if m := len(data) % 4; m != 0 {
|
||||
buf.WriteString(strings.Repeat("=", 4-m))
|
||||
}
|
||||
|
||||
reader := base64.NewDecoder(base64.URLEncoding, buf)
|
||||
output := &bytes.Buffer{}
|
||||
_, err := io.Copy(output, reader)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return output.Bytes(), nil
|
||||
}
|
||||
127
Godeps/_workspace/src/github.com/huandu/facebook/type.go
сгенерированный
поставляемый
127
Godeps/_workspace/src/github.com/huandu/facebook/type.go
сгенерированный
поставляемый
@@ -1,127 +0,0 @@
|
||||
// A facebook graph api client in go.
|
||||
// https://github.com/huandu/facebook/
|
||||
//
|
||||
// Copyright 2012 - 2015, Huan Du
|
||||
// Licensed under the MIT license
|
||||
// https://github.com/huandu/facebook/blob/master/LICENSE
|
||||
|
||||
package facebook
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Holds facebook application information.
|
||||
type App struct {
|
||||
// Facebook app id
|
||||
AppId string
|
||||
|
||||
// Facebook app secret
|
||||
AppSecret string
|
||||
|
||||
// Facebook app redirect URI in the app's configuration.
|
||||
RedirectUri string
|
||||
|
||||
// Enable appsecret proof in every API call to facebook.
|
||||
// Facebook document: https://developers.facebook.com/docs/graph-api/securing-requests
|
||||
EnableAppsecretProof bool
|
||||
}
|
||||
|
||||
// An interface to send http request.
|
||||
// This interface is designed to be compatible with type `*http.Client`.
|
||||
type HttpClient interface {
|
||||
Do(req *http.Request) (resp *http.Response, err error)
|
||||
Get(url string) (resp *http.Response, err error)
|
||||
Post(url string, bodyType string, body io.Reader) (resp *http.Response, err error)
|
||||
}
|
||||
|
||||
// Holds a facebook session with an access token.
|
||||
// Session should be created by App.Session or App.SessionFromSignedRequest.
|
||||
type Session struct {
|
||||
HttpClient HttpClient
|
||||
Version string // facebook versioning.
|
||||
|
||||
accessToken string // facebook access token. can be empty.
|
||||
app *App
|
||||
id string
|
||||
|
||||
enableAppsecretProof bool // add "appsecret_proof" parameter in every facebook API call.
|
||||
appsecretProof string // pre-calculated "appsecret_proof" value.
|
||||
|
||||
debug DebugMode // using facebook debugging api in every request.
|
||||
}
|
||||
|
||||
// API HTTP method.
|
||||
// Can be GET, POST or DELETE.
|
||||
type Method string
|
||||
|
||||
// Graph API debug mode.
|
||||
// See https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#graphapidebugmode
|
||||
type DebugMode string
|
||||
|
||||
// API params.
|
||||
//
|
||||
// For general uses, just use Params as a ordinary map.
|
||||
//
|
||||
// For advanced uses, use MakeParams to create Params from any struct.
|
||||
type Params map[string]interface{}
|
||||
|
||||
// Facebook API call result.
|
||||
type Result map[string]interface{}
|
||||
|
||||
// Represents facebook API call result with paging information.
|
||||
type PagingResult struct {
|
||||
session *Session
|
||||
paging pagingData
|
||||
previous string
|
||||
next string
|
||||
}
|
||||
|
||||
// Represents facebook batch API call result.
|
||||
// See https://developers.facebook.com/docs/graph-api/making-multiple-requests/#multiple_methods.
|
||||
type BatchResult struct {
|
||||
StatusCode int // HTTP status code.
|
||||
Header http.Header // HTTP response headers.
|
||||
Body string // Raw HTTP response body string.
|
||||
Result Result // Facebook api result parsed from body.
|
||||
}
|
||||
|
||||
// Facebook API error.
|
||||
type Error struct {
|
||||
Message string
|
||||
Type string
|
||||
Code int
|
||||
ErrorSubcode int // subcode for authentication related errors.
|
||||
}
|
||||
|
||||
// Binary data.
|
||||
type binaryData struct {
|
||||
Filename string // filename used in multipart form writer.
|
||||
Source io.Reader // file data source.
|
||||
}
|
||||
|
||||
// Binary file.
|
||||
type binaryFile struct {
|
||||
Filename string // filename used in multipart form writer.
|
||||
Path string // path to file. must be readable.
|
||||
}
|
||||
|
||||
// DebugInfo is the debug information returned by facebook when debug mode is enabled.
|
||||
type DebugInfo struct {
|
||||
Messages []DebugMessage // debug messages. it can be nil if there is no message.
|
||||
Header http.Header // all HTTP headers for this response.
|
||||
Proto string // HTTP protocol name for this response.
|
||||
|
||||
// Facebook debug HTTP headers.
|
||||
FacebookApiVersion string // the actual graph API version provided by facebook-api-version HTTP header.
|
||||
FacebookDebug string // the X-FB-Debug HTTP header.
|
||||
FacebookRev string // the x-fb-rev HTTP header.
|
||||
}
|
||||
|
||||
// DebugMessage is one debug message in "__debug__" of graph API response.
|
||||
type DebugMessage struct {
|
||||
Type string
|
||||
Message string
|
||||
Link string
|
||||
}
|
||||
199
Godeps/_workspace/src/golang.org/x/image/bmp/reader.go
сгенерированный
поставляемый
Обычный файл
199
Godeps/_workspace/src/golang.org/x/image/bmp/reader.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,199 @@
|
||||
// Copyright 2011 The Go 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 bmp implements a BMP image decoder and encoder.
|
||||
//
|
||||
// The BMP specification is at http://www.digicamsoft.com/bmp/bmp.html.
|
||||
package bmp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"image"
|
||||
"image/color"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ErrUnsupported means that the input BMP image uses a valid but unsupported
|
||||
// feature.
|
||||
var ErrUnsupported = errors.New("bmp: unsupported BMP image")
|
||||
|
||||
func readUint16(b []byte) uint16 {
|
||||
return uint16(b[0]) | uint16(b[1])<<8
|
||||
}
|
||||
|
||||
func readUint32(b []byte) uint32 {
|
||||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||
}
|
||||
|
||||
// decodePaletted reads an 8 bit-per-pixel BMP image from r.
|
||||
// If topDown is false, the image rows will be read bottom-up.
|
||||
func decodePaletted(r io.Reader, c image.Config, topDown bool) (image.Image, error) {
|
||||
paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(color.Palette))
|
||||
if c.Width == 0 || c.Height == 0 {
|
||||
return paletted, nil
|
||||
}
|
||||
var tmp [4]byte
|
||||
y0, y1, yDelta := c.Height-1, -1, -1
|
||||
if topDown {
|
||||
y0, y1, yDelta = 0, c.Height, +1
|
||||
}
|
||||
for y := y0; y != y1; y += yDelta {
|
||||
p := paletted.Pix[y*paletted.Stride : y*paletted.Stride+c.Width]
|
||||
if _, err := io.ReadFull(r, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Each row is 4-byte aligned.
|
||||
if c.Width%4 != 0 {
|
||||
_, err := io.ReadFull(r, tmp[:4-c.Width%4])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return paletted, nil
|
||||
}
|
||||
|
||||
// decodeRGB reads a 24 bit-per-pixel BMP image from r.
|
||||
// If topDown is false, the image rows will be read bottom-up.
|
||||
func decodeRGB(r io.Reader, c image.Config, topDown bool) (image.Image, error) {
|
||||
rgba := image.NewRGBA(image.Rect(0, 0, c.Width, c.Height))
|
||||
if c.Width == 0 || c.Height == 0 {
|
||||
return rgba, nil
|
||||
}
|
||||
// There are 3 bytes per pixel, and each row is 4-byte aligned.
|
||||
b := make([]byte, (3*c.Width+3)&^3)
|
||||
y0, y1, yDelta := c.Height-1, -1, -1
|
||||
if topDown {
|
||||
y0, y1, yDelta = 0, c.Height, +1
|
||||
}
|
||||
for y := y0; y != y1; y += yDelta {
|
||||
if _, err := io.ReadFull(r, b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4]
|
||||
for i, j := 0, 0; i < len(p); i, j = i+4, j+3 {
|
||||
// BMP images are stored in BGR order rather than RGB order.
|
||||
p[i+0] = b[j+2]
|
||||
p[i+1] = b[j+1]
|
||||
p[i+2] = b[j+0]
|
||||
p[i+3] = 0xFF
|
||||
}
|
||||
}
|
||||
return rgba, nil
|
||||
}
|
||||
|
||||
// decodeNRGBA reads a 32 bit-per-pixel BMP image from r.
|
||||
// If topDown is false, the image rows will be read bottom-up.
|
||||
func decodeNRGBA(r io.Reader, c image.Config, topDown bool) (image.Image, error) {
|
||||
rgba := image.NewNRGBA(image.Rect(0, 0, c.Width, c.Height))
|
||||
if c.Width == 0 || c.Height == 0 {
|
||||
return rgba, nil
|
||||
}
|
||||
y0, y1, yDelta := c.Height-1, -1, -1
|
||||
if topDown {
|
||||
y0, y1, yDelta = 0, c.Height, +1
|
||||
}
|
||||
for y := y0; y != y1; y += yDelta {
|
||||
p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4]
|
||||
if _, err := io.ReadFull(r, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(p); i += 4 {
|
||||
// BMP images are stored in BGRA order rather than RGBA order.
|
||||
p[i+0], p[i+2] = p[i+2], p[i+0]
|
||||
}
|
||||
}
|
||||
return rgba, nil
|
||||
}
|
||||
|
||||
// Decode reads a BMP image from r and returns it as an image.Image.
|
||||
// Limitation: The file must be 8, 24 or 32 bits per pixel.
|
||||
func Decode(r io.Reader) (image.Image, error) {
|
||||
c, bpp, topDown, err := decodeConfig(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch bpp {
|
||||
case 8:
|
||||
return decodePaletted(r, c, topDown)
|
||||
case 24:
|
||||
return decodeRGB(r, c, topDown)
|
||||
case 32:
|
||||
return decodeNRGBA(r, c, topDown)
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// DecodeConfig returns the color model and dimensions of a BMP image without
|
||||
// decoding the entire image.
|
||||
// Limitation: The file must be 8, 24 or 32 bits per pixel.
|
||||
func DecodeConfig(r io.Reader) (image.Config, error) {
|
||||
config, _, _, err := decodeConfig(r)
|
||||
return config, err
|
||||
}
|
||||
|
||||
func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown bool, err error) {
|
||||
// We only support those BMP images that are a BITMAPFILEHEADER
|
||||
// immediately followed by a BITMAPINFOHEADER.
|
||||
const (
|
||||
fileHeaderLen = 14
|
||||
infoHeaderLen = 40
|
||||
)
|
||||
var b [1024]byte
|
||||
if _, err := io.ReadFull(r, b[:fileHeaderLen+infoHeaderLen]); err != nil {
|
||||
return image.Config{}, 0, false, err
|
||||
}
|
||||
if string(b[:2]) != "BM" {
|
||||
return image.Config{}, 0, false, errors.New("bmp: invalid format")
|
||||
}
|
||||
offset := readUint32(b[10:14])
|
||||
if readUint32(b[14:18]) != infoHeaderLen {
|
||||
return image.Config{}, 0, false, ErrUnsupported
|
||||
}
|
||||
width := int(int32(readUint32(b[18:22])))
|
||||
height := int(int32(readUint32(b[22:26])))
|
||||
if height < 0 {
|
||||
height, topDown = -height, true
|
||||
}
|
||||
if width < 0 || height < 0 {
|
||||
return image.Config{}, 0, false, ErrUnsupported
|
||||
}
|
||||
// We only support 1 plane, 8 or 24 bits per pixel and no compression.
|
||||
planes, bpp, compression := readUint16(b[26:28]), readUint16(b[28:30]), readUint32(b[30:34])
|
||||
if planes != 1 || compression != 0 {
|
||||
return image.Config{}, 0, false, ErrUnsupported
|
||||
}
|
||||
switch bpp {
|
||||
case 8:
|
||||
if offset != fileHeaderLen+infoHeaderLen+256*4 {
|
||||
return image.Config{}, 0, false, ErrUnsupported
|
||||
}
|
||||
_, err = io.ReadFull(r, b[:256*4])
|
||||
if err != nil {
|
||||
return image.Config{}, 0, false, err
|
||||
}
|
||||
pcm := make(color.Palette, 256)
|
||||
for i := range pcm {
|
||||
// BMP images are stored in BGR order rather than RGB order.
|
||||
// Every 4th byte is padding.
|
||||
pcm[i] = color.RGBA{b[4*i+2], b[4*i+1], b[4*i+0], 0xFF}
|
||||
}
|
||||
return image.Config{ColorModel: pcm, Width: width, Height: height}, 8, topDown, nil
|
||||
case 24:
|
||||
if offset != fileHeaderLen+infoHeaderLen {
|
||||
return image.Config{}, 0, false, ErrUnsupported
|
||||
}
|
||||
return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 24, topDown, nil
|
||||
case 32:
|
||||
if offset != fileHeaderLen+infoHeaderLen {
|
||||
return image.Config{}, 0, false, ErrUnsupported
|
||||
}
|
||||
return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 32, topDown, nil
|
||||
}
|
||||
return image.Config{}, 0, false, ErrUnsupported
|
||||
}
|
||||
|
||||
func init() {
|
||||
image.RegisterFormat("bmp", "BM????\x00\x00\x00\x00", Decode, DecodeConfig)
|
||||
}
|
||||
75
Godeps/_workspace/src/golang.org/x/image/bmp/reader_test.go
сгенерированный
поставляемый
Обычный файл
75
Godeps/_workspace/src/golang.org/x/image/bmp/reader_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,75 @@
|
||||
// Copyright 2012 The Go 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 bmp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
_ "image/png"
|
||||
)
|
||||
|
||||
const testdataDir = "../testdata/"
|
||||
|
||||
func compare(t *testing.T, img0, img1 image.Image) error {
|
||||
b := img1.Bounds()
|
||||
if !b.Eq(img0.Bounds()) {
|
||||
return fmt.Errorf("wrong image size: want %s, got %s", img0.Bounds(), b)
|
||||
}
|
||||
for y := b.Min.Y; y < b.Max.Y; y++ {
|
||||
for x := b.Min.X; x < b.Max.X; x++ {
|
||||
c0 := img0.At(x, y)
|
||||
c1 := img1.At(x, y)
|
||||
r0, g0, b0, a0 := c0.RGBA()
|
||||
r1, g1, b1, a1 := c1.RGBA()
|
||||
if r0 != r1 || g0 != g1 || b0 != b1 || a0 != a1 {
|
||||
return fmt.Errorf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, c0, c1)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestDecode tests that decoding a PNG image and a BMP image result in the
|
||||
// same pixel data.
|
||||
func TestDecode(t *testing.T) {
|
||||
testCases := []string{
|
||||
"video-001",
|
||||
"yellow_rose-small",
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
f0, err := os.Open(testdataDir + tc + ".png")
|
||||
if err != nil {
|
||||
t.Errorf("%s: Open PNG: %v", tc, err)
|
||||
continue
|
||||
}
|
||||
defer f0.Close()
|
||||
img0, _, err := image.Decode(f0)
|
||||
if err != nil {
|
||||
t.Errorf("%s: Decode PNG: %v", tc, err)
|
||||
continue
|
||||
}
|
||||
|
||||
f1, err := os.Open(testdataDir + tc + ".bmp")
|
||||
if err != nil {
|
||||
t.Errorf("%s: Open BMP: %v", tc, err)
|
||||
continue
|
||||
}
|
||||
defer f1.Close()
|
||||
img1, _, err := image.Decode(f1)
|
||||
if err != nil {
|
||||
t.Errorf("%s: Decode BMP: %v", tc, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := compare(t, img0, img1); err != nil {
|
||||
t.Errorf("%s: %v", tc, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
166
Godeps/_workspace/src/golang.org/x/image/bmp/writer.go
сгенерированный
поставляемый
Обычный файл
166
Godeps/_workspace/src/golang.org/x/image/bmp/writer.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,166 @@
|
||||
// Copyright 2013 The Go 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 bmp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"image"
|
||||
"io"
|
||||
)
|
||||
|
||||
type header struct {
|
||||
sigBM [2]byte
|
||||
fileSize uint32
|
||||
resverved [2]uint16
|
||||
pixOffset uint32
|
||||
dibHeaderSize uint32
|
||||
width uint32
|
||||
height uint32
|
||||
colorPlane uint16
|
||||
bpp uint16
|
||||
compression uint32
|
||||
imageSize uint32
|
||||
xPixelsPerMeter uint32
|
||||
yPixelsPerMeter uint32
|
||||
colorUse uint32
|
||||
colorImportant uint32
|
||||
}
|
||||
|
||||
func encodePaletted(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
|
||||
var padding []byte
|
||||
if dx < step {
|
||||
padding = make([]byte, step-dx)
|
||||
}
|
||||
for y := dy - 1; y >= 0; y-- {
|
||||
min := y*stride + 0
|
||||
max := y*stride + dx
|
||||
if _, err := w.Write(pix[min:max]); err != nil {
|
||||
return err
|
||||
}
|
||||
if padding != nil {
|
||||
if _, err := w.Write(padding); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
|
||||
buf := make([]byte, step)
|
||||
for y := dy - 1; y >= 0; y-- {
|
||||
min := y*stride + 0
|
||||
max := y*stride + dx*4
|
||||
off := 0
|
||||
for i := min; i < max; i += 4 {
|
||||
buf[off+2] = pix[i+0]
|
||||
buf[off+1] = pix[i+1]
|
||||
buf[off+0] = pix[i+2]
|
||||
off += 3
|
||||
}
|
||||
if _, err := w.Write(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func encode(w io.Writer, m image.Image, step int) error {
|
||||
b := m.Bounds()
|
||||
buf := make([]byte, step)
|
||||
for y := b.Max.Y - 1; y >= b.Min.Y; y-- {
|
||||
off := 0
|
||||
for x := b.Min.X; x < b.Max.X; x++ {
|
||||
r, g, b, _ := m.At(x, y).RGBA()
|
||||
buf[off+2] = byte(r >> 8)
|
||||
buf[off+1] = byte(g >> 8)
|
||||
buf[off+0] = byte(b >> 8)
|
||||
off += 3
|
||||
}
|
||||
if _, err := w.Write(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encode writes the image m to w in BMP format.
|
||||
func Encode(w io.Writer, m image.Image) error {
|
||||
d := m.Bounds().Size()
|
||||
if d.X < 0 || d.Y < 0 {
|
||||
return errors.New("bmp: negative bounds")
|
||||
}
|
||||
h := &header{
|
||||
sigBM: [2]byte{'B', 'M'},
|
||||
fileSize: 14 + 40,
|
||||
pixOffset: 14 + 40,
|
||||
dibHeaderSize: 40,
|
||||
width: uint32(d.X),
|
||||
height: uint32(d.Y),
|
||||
colorPlane: 1,
|
||||
}
|
||||
|
||||
var step int
|
||||
var palette []byte
|
||||
switch m := m.(type) {
|
||||
case *image.Gray:
|
||||
step = (d.X + 3) &^ 3
|
||||
palette = make([]byte, 1024)
|
||||
for i := 0; i < 256; i++ {
|
||||
palette[i*4+0] = uint8(i)
|
||||
palette[i*4+1] = uint8(i)
|
||||
palette[i*4+2] = uint8(i)
|
||||
palette[i*4+3] = 0xFF
|
||||
}
|
||||
h.imageSize = uint32(d.Y * step)
|
||||
h.fileSize += uint32(len(palette)) + h.imageSize
|
||||
h.pixOffset += uint32(len(palette))
|
||||
h.bpp = 8
|
||||
|
||||
case *image.Paletted:
|
||||
step = (d.X + 3) &^ 3
|
||||
palette = make([]byte, 1024)
|
||||
for i := 0; i < len(m.Palette) && i < 256; i++ {
|
||||
r, g, b, _ := m.Palette[i].RGBA()
|
||||
palette[i*4+0] = uint8(b >> 8)
|
||||
palette[i*4+1] = uint8(g >> 8)
|
||||
palette[i*4+2] = uint8(r >> 8)
|
||||
palette[i*4+3] = 0xFF
|
||||
}
|
||||
h.imageSize = uint32(d.Y * step)
|
||||
h.fileSize += uint32(len(palette)) + h.imageSize
|
||||
h.pixOffset += uint32(len(palette))
|
||||
h.bpp = 8
|
||||
default:
|
||||
step = (3*d.X + 3) &^ 3
|
||||
h.imageSize = uint32(d.Y * step)
|
||||
h.fileSize += h.imageSize
|
||||
h.bpp = 24
|
||||
}
|
||||
|
||||
if err := binary.Write(w, binary.LittleEndian, h); err != nil {
|
||||
return err
|
||||
}
|
||||
if palette != nil {
|
||||
if err := binary.Write(w, binary.LittleEndian, palette); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if d.X == 0 || d.Y == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch m := m.(type) {
|
||||
case *image.Gray:
|
||||
return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step)
|
||||
case *image.Paletted:
|
||||
return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step)
|
||||
case *image.RGBA:
|
||||
return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step)
|
||||
}
|
||||
return encode(w, m, step)
|
||||
}
|
||||
91
Godeps/_workspace/src/golang.org/x/image/bmp/writer_test.go
сгенерированный
поставляемый
Обычный файл
91
Godeps/_workspace/src/golang.org/x/image/bmp/writer_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,91 @@
|
||||
// Copyright 2013 The Go 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 bmp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func openImage(filename string) (image.Image, error) {
|
||||
f, err := os.Open(testdataDir + filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return Decode(f)
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
img0, err := openImage("video-001.bmp")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
err = Encode(buf, img0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
img1, err := Decode(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
compare(t, img0, img1)
|
||||
}
|
||||
|
||||
// TestZeroWidthVeryLargeHeight tests that encoding and decoding a degenerate
|
||||
// image with zero width but over one billion pixels in height is faster than
|
||||
// naively calling an io.Reader or io.Writer method once per row.
|
||||
func TestZeroWidthVeryLargeHeight(t *testing.T) {
|
||||
c := make(chan error, 1)
|
||||
go func() {
|
||||
b := image.Rect(0, 0, 0, 0x3fffffff)
|
||||
var buf bytes.Buffer
|
||||
if err := Encode(&buf, image.NewRGBA(b)); err != nil {
|
||||
c <- err
|
||||
return
|
||||
}
|
||||
m, err := Decode(&buf)
|
||||
if err != nil {
|
||||
c <- err
|
||||
return
|
||||
}
|
||||
if got := m.Bounds(); got != b {
|
||||
c <- fmt.Errorf("bounds: got %v, want %v", got, b)
|
||||
return
|
||||
}
|
||||
c <- nil
|
||||
}()
|
||||
select {
|
||||
case err := <-c:
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatalf("timed out")
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkEncode benchmarks the encoding of an image.
|
||||
func BenchmarkEncode(b *testing.B) {
|
||||
img, err := openImage("video-001.bmp")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
s := img.Bounds().Size()
|
||||
b.SetBytes(int64(s.X * s.Y * 4))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Encode(ioutil.Discard, img)
|
||||
}
|
||||
}
|
||||
22
Makefile
22
Makefile
@@ -1,4 +1,4 @@
|
||||
.PHONY: all test clean build install run stop cover dist dist-battlehouse cleandb
|
||||
.PHONY: all test clean build install run stop cover dist cleandb travis
|
||||
|
||||
GOPATH ?= $(GOPATH:)
|
||||
GOFLAGS ?= $(GOFLAGS:)
|
||||
@@ -15,7 +15,25 @@ DIST_RESULTS=$(DIST_ROOT)/results
|
||||
BENCH=.
|
||||
TESTS=.
|
||||
|
||||
all: build
|
||||
all: travis
|
||||
|
||||
travis:
|
||||
@echo building for travis
|
||||
|
||||
rm -Rf $(DIST_ROOT)
|
||||
@go clean $(GOFLAGS) -i ./...
|
||||
|
||||
@cd web/react/ && npm install
|
||||
|
||||
@go build $(GOFLAGS) ./...
|
||||
|
||||
@mkdir -p logs
|
||||
|
||||
@go test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./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
|
||||
|
||||
build:
|
||||
@go build $(GOFLAGS) ./...
|
||||
|
||||
@@ -5,6 +5,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
@@ -27,7 +28,7 @@ func SetupBenchmark() (*model.Team, *model.User, *model.Channel) {
|
||||
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "benchmark@test.com", FullName: "Mr. Benchmarker", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
Client.LoginByEmail(team.Domain, 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)
|
||||
|
||||
@@ -5,6 +5,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
@@ -45,7 +46,7 @@ func CreateBasicUser(client *model.Client) *model.AppError {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -72,7 +73,7 @@ func (cfg *AutoUserCreator) createRandomUser() (*model.User, bool) {
|
||||
return nil, false
|
||||
}
|
||||
// We need to cheat to verify the user's email
|
||||
Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id))
|
||||
return result.Data.(*model.User), true
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"testing"
|
||||
)
|
||||
@@ -139,7 +140,7 @@ func BenchmarkJoinChannel(b *testing.B) {
|
||||
// Secondary test user to join channels created by primary test user
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "random@test.com", FullName: "That Guy", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
// Benchmark Start
|
||||
|
||||
@@ -5,8 +5,10 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCreateChannel(t *testing.T) {
|
||||
@@ -20,7 +22,7 @@ func TestCreateChannel(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -88,11 +90,11 @@ func TestCreateDirectChannel(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -143,15 +145,15 @@ func TestUpdateChannel(t *testing.T) {
|
||||
|
||||
userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, FullName: "Corey Hulen", Password: "pwd"}
|
||||
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userTeamAdmin.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
|
||||
|
||||
userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userChannelAdmin.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
|
||||
|
||||
userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userStd.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
|
||||
userStd.Roles = ""
|
||||
|
||||
Client.LoginByEmail(team.Domain, userChannelAdmin.Email, "pwd")
|
||||
@@ -214,7 +216,7 @@ func TestUpdateChannelDesc(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -257,7 +259,7 @@ func TestUpdateChannelDesc(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
|
||||
@@ -276,7 +278,7 @@ func TestGetChannel(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -318,7 +320,7 @@ func TestGetMoreChannel(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -330,7 +332,7 @@ func TestGetMoreChannel(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
|
||||
@@ -362,7 +364,7 @@ func TestJoinChannel(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -374,7 +376,7 @@ func TestJoinChannel(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
|
||||
@@ -406,7 +408,7 @@ func TestLeaveChannel(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -418,7 +420,7 @@ func TestLeaveChannel(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
|
||||
@@ -455,11 +457,11 @@ func TestDeleteChannel(t *testing.T) {
|
||||
|
||||
userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, FullName: "Corey Hulen", Password: "pwd"}
|
||||
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userTeamAdmin.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
|
||||
|
||||
userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userChannelAdmin.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, userChannelAdmin.Email, "pwd")
|
||||
|
||||
@@ -491,7 +493,7 @@ func TestDeleteChannel(t *testing.T) {
|
||||
|
||||
userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userStd.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, userStd.Email, "pwd")
|
||||
|
||||
@@ -525,7 +527,7 @@ func TestGetChannelExtraInfo(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -546,7 +548,7 @@ func TestAddChannelMember(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -555,7 +557,7 @@ func TestAddChannelMember(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
if _, err := Client.AddChannelMember(channel1.Id, user2.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -604,11 +606,11 @@ func TestRemoveChannelMember(t *testing.T) {
|
||||
|
||||
userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, FullName: "Corey Hulen", Password: "pwd"}
|
||||
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userTeamAdmin.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
|
||||
|
||||
userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userChannelAdmin.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, userChannelAdmin.Email, "pwd")
|
||||
|
||||
@@ -624,7 +626,7 @@ func TestRemoveChannelMember(t *testing.T) {
|
||||
|
||||
userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(userStd.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
|
||||
|
||||
Client.Must(Client.AddChannelMember(channel1.Id, userStd.Id))
|
||||
|
||||
@@ -674,7 +676,7 @@ func TestUpdateNotifyLevel(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -687,6 +689,7 @@ func TestUpdateNotifyLevel(t *testing.T) {
|
||||
data["notify_level"] = model.CHANNEL_NOTIFY_MENTION
|
||||
|
||||
timeBeforeUpdate := model.GetMillis()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if _, err := Client.UpdateNotifyLevel(data); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -755,7 +758,7 @@ func TestFuzzyChannel(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -16,7 +17,7 @@ func TestSuggestRootCommands(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -59,7 +60,7 @@ func TestLogoutCommands(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -77,7 +78,7 @@ func TestJoinCommands(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -91,7 +92,7 @@ func TestJoinCommands(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user2.Id
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/goamz/goamz/aws"
|
||||
"github.com/goamz/goamz/s3"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
@@ -28,7 +29,7 @@ func TestUploadFile(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -115,7 +116,7 @@ func TestGetFile(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -177,7 +178,7 @@ func TestGetFile(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
newProps := make(map[string]string)
|
||||
newProps["filename"] = filenames[0]
|
||||
@@ -262,11 +263,11 @@ func TestGetPublicLink(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"net/http"
|
||||
"testing"
|
||||
@@ -22,11 +23,11 @@ func TestCreatePost(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -104,7 +105,7 @@ func TestCreatePost(t *testing.T) {
|
||||
|
||||
user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user3.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
Client.LoginByEmail(team2.Domain, user3.Email, "pwd")
|
||||
|
||||
@@ -133,11 +134,11 @@ func TestCreateValetPost(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -189,7 +190,7 @@ func TestCreateValetPost(t *testing.T) {
|
||||
|
||||
user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user3.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
Client.LoginByEmail(team2.Domain, user3.Email, "pwd")
|
||||
|
||||
@@ -225,11 +226,11 @@ func TestUpdatePost(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -293,7 +294,7 @@ func TestGetPosts(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -358,7 +359,7 @@ func TestSearchPosts(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -404,7 +405,7 @@ func TestSearchHashtagPosts(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -435,7 +436,7 @@ func TestGetPostsCache(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -484,7 +485,7 @@ func TestDeletePosts(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -532,7 +533,7 @@ func TestEmailMention(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: "corey@test.com", FullName: "Bob Bobby", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
@@ -554,7 +555,7 @@ func TestFuzzyPosts(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ package api
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -78,7 +79,7 @@ func TestCreateTeam(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: rteam.Data.(*model.Team).Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -115,7 +116,7 @@ func TestFindTeamByEmail(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
if r1, err := Client.FindTeams(user.Email); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -143,7 +144,7 @@ func TestFindTeamByDomain(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
if r1, err := Client.FindTeamByDomain(team.Domain, false); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -183,7 +184,7 @@ func TestFindTeamByEmailSend(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
if _, err := Client.FindTeamsSendEmail(user.Email); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -207,7 +208,7 @@ func TestInviteMembers(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -236,11 +237,11 @@ func TestUpdateTeamName(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
|
||||
@@ -311,7 +312,7 @@ func TestGetMyTeam(t *testing.T) {
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
ruser, _ := Client.CreateUser(&user, "")
|
||||
Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, user.Password)
|
||||
|
||||
@@ -338,18 +339,18 @@ func TestUpdateValetFeature(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
team2 := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
|
||||
|
||||
user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user3.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/goamz/goamz/aws"
|
||||
"github.com/goamz/goamz/s3"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"image"
|
||||
"image/color"
|
||||
@@ -99,7 +100,7 @@ func TestLogin(t *testing.T) {
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
ruser, _ := Client.CreateUser(&user, "")
|
||||
Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
|
||||
|
||||
if result, err := Client.LoginById(ruser.Data.(*model.User).Id, user.Password); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -168,7 +169,7 @@ func TestSessions(t *testing.T) {
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(ruser.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
|
||||
|
||||
deviceId := model.NewId()
|
||||
Client.LoginByEmailWithDevice(team.Domain, user.Email, user.Password, deviceId)
|
||||
@@ -225,11 +226,11 @@ func TestGetUser(t *testing.T) {
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
ruser, _ := Client.CreateUser(&user, "")
|
||||
Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
|
||||
|
||||
user2 := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
ruser2, _ := Client.CreateUser(&user2, "")
|
||||
Srv.Store.User().VerifyEmail(ruser2.Data.(*model.User).Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser2.Data.(*model.User).Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, user.Password)
|
||||
|
||||
@@ -296,11 +297,13 @@ func TestGetAudits(t *testing.T) {
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
ruser, _ := Client.CreateUser(&user, "")
|
||||
Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, user.Password)
|
||||
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if result, err := Client.GetAudits(ruser.Data.(*model.User).Id, ""); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -347,7 +350,7 @@ func TestUserCreateImage(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
@@ -363,7 +366,7 @@ func TestUserUploadProfileImage(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
if utils.IsS3Configured() {
|
||||
|
||||
@@ -462,7 +465,7 @@ func TestUserUpdate(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd", LastActivityAt: time1, LastPingAt: time1, Roles: ""}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
if _, err := Client.UpdateUser(user); err == nil {
|
||||
t.Fatal("Should have errored")
|
||||
@@ -470,8 +473,12 @@ func TestUserUpdate(t *testing.T) {
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, "pwd")
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
time2 := model.GetMillis()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
user.FullName = "Jim Jimmy"
|
||||
user.TeamId = "12345678901234567890123456"
|
||||
user.LastActivityAt = time2
|
||||
@@ -488,10 +495,10 @@ func TestUserUpdate(t *testing.T) {
|
||||
if result.Data.(*model.User).TeamId != team.Id {
|
||||
t.Fatal("TeamId should not have updated")
|
||||
}
|
||||
if result.Data.(*model.User).LastActivityAt != time1 {
|
||||
if result.Data.(*model.User).LastActivityAt == time2 {
|
||||
t.Fatal("LastActivityAt should not have updated")
|
||||
}
|
||||
if result.Data.(*model.User).LastPingAt != time1 {
|
||||
if result.Data.(*model.User).LastPingAt == time2 {
|
||||
t.Fatal("LastPingAt should not have updated")
|
||||
}
|
||||
if result.Data.(*model.User).Roles != "" {
|
||||
@@ -514,7 +521,7 @@ func TestUserUpdate(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
|
||||
@@ -533,7 +540,7 @@ func TestUserUpdatePassword(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
if _, err := Client.UpdateUserPassword(user.Id, "pwd", "newpwd"); err == nil {
|
||||
t.Fatal("Should have errored")
|
||||
@@ -592,11 +599,11 @@ func TestUserUpdateRoles(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user.Id
|
||||
@@ -617,7 +624,7 @@ func TestUserUpdateRoles(t *testing.T) {
|
||||
|
||||
user3 := &model.User{TeamId: team2.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user3.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
Client.LoginByEmail(team2.Domain, user3.Email, "pwd")
|
||||
|
||||
@@ -661,11 +668,11 @@ func TestUserUpdateActive(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
|
||||
if _, err := Client.UpdateActive(user.Id, false); err == nil {
|
||||
t.Fatal("Should have errored, not logged in")
|
||||
@@ -682,7 +689,7 @@ func TestUserUpdateActive(t *testing.T) {
|
||||
|
||||
user3 := &model.User{TeamId: team2.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user3.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
|
||||
|
||||
Client.LoginByEmail(team2.Domain, user3.Email, "pwd")
|
||||
|
||||
@@ -725,7 +732,7 @@ func TestSendPasswordReset(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
data := make(map[string]string)
|
||||
data["email"] = user.Email
|
||||
@@ -765,7 +772,7 @@ func TestResetPassword(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
data := make(map[string]string)
|
||||
data["new_password"] = "newpwd"
|
||||
@@ -849,7 +856,7 @@ func TestUserUpdateNotify(t *testing.T) {
|
||||
|
||||
user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd", Roles: ""}
|
||||
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user.Id))
|
||||
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user.Id
|
||||
@@ -943,7 +950,7 @@ func TestStatuses(t *testing.T) {
|
||||
|
||||
user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(ruser.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
|
||||
|
||||
Client.LoginByEmail(team.Domain, user.Email, user.Password)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ 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"
|
||||
@@ -21,7 +22,7 @@ func TestSocket(t *testing.T) {
|
||||
|
||||
user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user1.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
|
||||
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "Test Web Scoket 1", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
@@ -40,7 +41,7 @@ func TestSocket(t *testing.T) {
|
||||
|
||||
user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user2.Id)
|
||||
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
|
||||
header2 := http.Header{}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"LogSettings": {
|
||||
"ConsoleEnable": true,
|
||||
"ConsoleLevel": "INFO",
|
||||
"ConsoleLevel": "DEBUG",
|
||||
"FileEnable": true,
|
||||
"FileLevel": "INFO",
|
||||
"FileFormat": "",
|
||||
|
||||
@@ -6,17 +6,24 @@ package store
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSqlAuditStore(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
audit := &model.Audit{UserId: model.NewId(), IpAddress: "ipaddress", Action: "Action"}
|
||||
<-store.Audit().Save(audit)
|
||||
<-store.Audit().Save(audit)
|
||||
<-store.Audit().Save(audit)
|
||||
Must(store.Audit().Save(audit))
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
Must(store.Audit().Save(audit))
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
Must(store.Audit().Save(audit))
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
audit.ExtraInfo = "extra"
|
||||
<-store.Audit().Save(audit)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
Must(store.Audit().Save(audit))
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
c := store.Audit().Get(audit.UserId, 100)
|
||||
result := <-c
|
||||
|
||||
@@ -6,6 +6,7 @@ package store
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestChannelStoreSave(t *testing.T) {
|
||||
@@ -55,7 +56,12 @@ func TestChannelStoreUpdate(t *testing.T) {
|
||||
o1.DisplayName = "Name"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o1)
|
||||
|
||||
if err := (<-store.Channel().Save(&o1)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if err := (<-store.Channel().Update(&o1)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -80,7 +86,7 @@ func TestChannelStoreGet(t *testing.T) {
|
||||
o1.DisplayName = "Name"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
if r1 := <-store.Channel().Get(o1.Id); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
@@ -103,40 +109,40 @@ func TestChannelStoreDelete(t *testing.T) {
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
o2 := model.Channel{}
|
||||
o2.TeamId = o1.TeamId
|
||||
o2.DisplayName = "Channel2"
|
||||
o2.Name = "a" + model.NewId() + "b"
|
||||
o2.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o2)
|
||||
Must(store.Channel().Save(&o2))
|
||||
|
||||
o3 := model.Channel{}
|
||||
o3.TeamId = o1.TeamId
|
||||
o3.DisplayName = "Channel3"
|
||||
o3.Name = "a" + model.NewId() + "b"
|
||||
o3.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o3)
|
||||
Must(store.Channel().Save(&o3))
|
||||
|
||||
o4 := model.Channel{}
|
||||
o4.TeamId = o1.TeamId
|
||||
o4.DisplayName = "Channel4"
|
||||
o4.Name = "a" + model.NewId() + "b"
|
||||
o4.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o4)
|
||||
Must(store.Channel().Save(&o4))
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
m1.UserId = model.NewId()
|
||||
m1.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m1)
|
||||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
m2 := model.ChannelMember{}
|
||||
m2.ChannelId = o2.Id
|
||||
m2.UserId = m1.UserId
|
||||
m2.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m2)
|
||||
Must(store.Channel().SaveMember(&m2))
|
||||
|
||||
if r := <-store.Channel().Delete(o1.Id, model.GetMillis()); r.Err != nil {
|
||||
t.Fatal(r.Err)
|
||||
@@ -173,7 +179,7 @@ func TestChannelStoreGetByName(t *testing.T) {
|
||||
o1.DisplayName = "Name"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
if r1 := <-store.Channel().GetByName(o1.TeamId, o1.Name); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
@@ -195,32 +201,32 @@ func TestChannelMemberStore(t *testing.T) {
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
u1.FullName = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
u2 := model.User{}
|
||||
u2.TeamId = model.NewId()
|
||||
u2.Email = model.NewId()
|
||||
u2.FullName = model.NewId()
|
||||
<-store.User().Save(&u2)
|
||||
Must(store.User().Save(&u2))
|
||||
|
||||
o1 := model.ChannelMember{}
|
||||
o1.ChannelId = model.NewId()
|
||||
o1.UserId = u1.Id
|
||||
o1.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&o1)
|
||||
Must(store.Channel().SaveMember(&o1))
|
||||
|
||||
o2 := model.ChannelMember{}
|
||||
o2.ChannelId = o1.ChannelId
|
||||
o2.UserId = u2.Id
|
||||
o2.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&o2)
|
||||
Must(store.Channel().SaveMember(&o2))
|
||||
|
||||
members := (<-store.Channel().GetMembers(o1.ChannelId)).Data.([]model.ChannelMember)
|
||||
if len(members) != 2 {
|
||||
t.Fatal("should have saved 2 members")
|
||||
}
|
||||
|
||||
<-store.Channel().RemoveMember(o2.ChannelId, o2.UserId)
|
||||
Must(store.Channel().RemoveMember(o2.ChannelId, o2.UserId))
|
||||
|
||||
members = (<-store.Channel().GetMembers(o1.ChannelId)).Data.([]model.ChannelMember)
|
||||
if len(members) != 1 {
|
||||
@@ -250,13 +256,13 @@ func TestChannelStorePermissionsTo(t *testing.T) {
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
m1.UserId = model.NewId()
|
||||
m1.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m1)
|
||||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
count := (<-store.Channel().CheckPermissionsTo(o1.TeamId, o1.Id, m1.UserId)).Data.(int64)
|
||||
if count != 1 {
|
||||
@@ -297,7 +303,7 @@ func TestChannelStoreOpenChannelPermissionsTo(t *testing.T) {
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
count := (<-store.Channel().CheckOpenChannelPermissions(o1.TeamId, o1.Id)).Data.(int64)
|
||||
if count != 1 {
|
||||
@@ -323,32 +329,32 @@ func TestChannelStoreGetChannels(t *testing.T) {
|
||||
o2.DisplayName = "Channel2"
|
||||
o2.Name = "a" + model.NewId() + "b"
|
||||
o2.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o2)
|
||||
Must(store.Channel().Save(&o2))
|
||||
|
||||
o1 := model.Channel{}
|
||||
o1.TeamId = model.NewId()
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
m1.UserId = model.NewId()
|
||||
m1.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m1)
|
||||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
m2 := model.ChannelMember{}
|
||||
m2.ChannelId = o1.Id
|
||||
m2.UserId = model.NewId()
|
||||
m2.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m2)
|
||||
Must(store.Channel().SaveMember(&m2))
|
||||
|
||||
m3 := model.ChannelMember{}
|
||||
m3.ChannelId = o2.Id
|
||||
m3.UserId = model.NewId()
|
||||
m3.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m3)
|
||||
Must(store.Channel().SaveMember(&m3))
|
||||
|
||||
cresult := <-store.Channel().GetChannels(o1.TeamId, m1.UserId)
|
||||
list := cresult.Data.(*model.ChannelList)
|
||||
@@ -366,53 +372,53 @@ func TestChannelStoreGetMoreChannels(t *testing.T) {
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
o2 := model.Channel{}
|
||||
o2.TeamId = model.NewId()
|
||||
o2.DisplayName = "Channel2"
|
||||
o2.Name = "a" + model.NewId() + "b"
|
||||
o2.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o2)
|
||||
Must(store.Channel().Save(&o2))
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
m1.UserId = model.NewId()
|
||||
m1.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m1)
|
||||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
m2 := model.ChannelMember{}
|
||||
m2.ChannelId = o1.Id
|
||||
m2.UserId = model.NewId()
|
||||
m2.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m2)
|
||||
Must(store.Channel().SaveMember(&m2))
|
||||
|
||||
m3 := model.ChannelMember{}
|
||||
m3.ChannelId = o2.Id
|
||||
m3.UserId = model.NewId()
|
||||
m3.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m3)
|
||||
Must(store.Channel().SaveMember(&m3))
|
||||
|
||||
o3 := model.Channel{}
|
||||
o3.TeamId = o1.TeamId
|
||||
o3.DisplayName = "ChannelA"
|
||||
o3.Name = "a" + model.NewId() + "b"
|
||||
o3.Type = model.CHANNEL_OPEN
|
||||
<-store.Channel().Save(&o3)
|
||||
Must(store.Channel().Save(&o3))
|
||||
|
||||
o4 := model.Channel{}
|
||||
o4.TeamId = o1.TeamId
|
||||
o4.DisplayName = "ChannelB"
|
||||
o4.Name = "a" + model.NewId() + "b"
|
||||
o4.Type = model.CHANNEL_PRIVATE
|
||||
<-store.Channel().Save(&o4)
|
||||
Must(store.Channel().Save(&o4))
|
||||
|
||||
o5 := model.Channel{}
|
||||
o5.TeamId = o1.TeamId
|
||||
o5.DisplayName = "ChannelC"
|
||||
o5.Name = "a" + model.NewId() + "b"
|
||||
o5.Type = model.CHANNEL_PRIVATE
|
||||
<-store.Channel().Save(&o5)
|
||||
Must(store.Channel().Save(&o5))
|
||||
|
||||
cresult := <-store.Channel().GetMoreChannels(o1.TeamId, m1.UserId)
|
||||
list := cresult.Data.(*model.ChannelList)
|
||||
@@ -435,13 +441,13 @@ func TestChannelStoreUpdateLastViewedAt(t *testing.T) {
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
o1.TotalMsgCount = 25
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
m1.UserId = model.NewId()
|
||||
m1.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m1)
|
||||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
err := (<-store.Channel().UpdateLastViewedAt(m1.ChannelId, m1.UserId)).Err
|
||||
if err != nil {
|
||||
@@ -463,13 +469,13 @@ func TestChannelStoreIncrementMentionCount(t *testing.T) {
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
o1.TotalMsgCount = 25
|
||||
<-store.Channel().Save(&o1)
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
m1.UserId = model.NewId()
|
||||
m1.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m1)
|
||||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
err := (<-store.Channel().IncrementMentionCount(m1.ChannelId, m1.UserId)).Err
|
||||
if err != nil {
|
||||
|
||||
@@ -280,7 +280,7 @@ func TestPostStoreGetWithChildren(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
<-store.Post().Delete(o3.Id, model.GetMillis())
|
||||
Must(store.Post().Delete(o3.Id, model.GetMillis()))
|
||||
|
||||
if r2 := <-store.Post().Get(o1.Id); r2.Err != nil {
|
||||
t.Fatal(r2.Err)
|
||||
@@ -291,7 +291,7 @@ func TestPostStoreGetWithChildren(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
<-store.Post().Delete(o2.Id, model.GetMillis())
|
||||
Must(store.Post().Delete(o2.Id, model.GetMillis()))
|
||||
|
||||
if r3 := <-store.Post().Get(o1.Id); r3.Err != nil {
|
||||
t.Fatal(r3.Err)
|
||||
@@ -399,7 +399,7 @@ func TestPostStoreSearch(t *testing.T) {
|
||||
m1.ChannelId = c1.Id
|
||||
m1.UserId = userId
|
||||
m1.NotifyLevel = model.CHANNEL_NOTIFY_ALL
|
||||
<-store.Channel().SaveMember(&m1)
|
||||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
c2 := &model.Channel{}
|
||||
c2.TeamId = teamId
|
||||
|
||||
@@ -26,18 +26,18 @@ func TestSessionGet(t *testing.T) {
|
||||
s1 := model.Session{}
|
||||
s1.UserId = model.NewId()
|
||||
s1.TeamId = model.NewId()
|
||||
<-store.Session().Save(&s1)
|
||||
Must(store.Session().Save(&s1))
|
||||
|
||||
s2 := model.Session{}
|
||||
s2.UserId = s1.UserId
|
||||
s2.TeamId = s1.TeamId
|
||||
<-store.Session().Save(&s2)
|
||||
Must(store.Session().Save(&s2))
|
||||
|
||||
s3 := model.Session{}
|
||||
s3.UserId = s1.UserId
|
||||
s3.TeamId = s1.TeamId
|
||||
s3.ExpiresAt = 1
|
||||
<-store.Session().Save(&s3)
|
||||
Must(store.Session().Save(&s3))
|
||||
|
||||
if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil {
|
||||
t.Fatal(rs1.Err)
|
||||
@@ -63,7 +63,7 @@ func TestSessionRemove(t *testing.T) {
|
||||
s1 := model.Session{}
|
||||
s1.UserId = model.NewId()
|
||||
s1.TeamId = model.NewId()
|
||||
<-store.Session().Save(&s1)
|
||||
Must(store.Session().Save(&s1))
|
||||
|
||||
if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil {
|
||||
t.Fatal(rs1.Err)
|
||||
@@ -73,7 +73,7 @@ func TestSessionRemove(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
<-store.Session().Remove(s1.Id)
|
||||
Must(store.Session().Remove(s1.Id))
|
||||
|
||||
if rs2 := (<-store.Session().Get(s1.Id)); rs2.Err == nil {
|
||||
t.Fatal("should have been removed")
|
||||
@@ -86,7 +86,7 @@ func TestSessionRemoveAlt(t *testing.T) {
|
||||
s1 := model.Session{}
|
||||
s1.UserId = model.NewId()
|
||||
s1.TeamId = model.NewId()
|
||||
<-store.Session().Save(&s1)
|
||||
Must(store.Session().Save(&s1))
|
||||
|
||||
if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil {
|
||||
t.Fatal(rs1.Err)
|
||||
@@ -96,7 +96,7 @@ func TestSessionRemoveAlt(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
<-store.Session().Remove(s1.AltId)
|
||||
Must(store.Session().Remove(s1.AltId))
|
||||
|
||||
if rs2 := (<-store.Session().Get(s1.Id)); rs2.Err == nil {
|
||||
t.Fatal("should have been removed")
|
||||
@@ -117,7 +117,7 @@ func TestSessionStoreUpdateLastActivityAt(t *testing.T) {
|
||||
s1 := model.Session{}
|
||||
s1.UserId = model.NewId()
|
||||
s1.TeamId = model.NewId()
|
||||
<-store.Session().Save(&s1)
|
||||
Must(store.Session().Save(&s1))
|
||||
|
||||
if err := (<-store.Session().UpdateLastActivityAt(s1.Id, 1234567890)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
crand "crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
crand "crypto/rand"
|
||||
dbsql "database/sql"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
@@ -362,21 +362,21 @@ func decrypt(key []byte, cryptoText string) (string, error) {
|
||||
|
||||
ciphertext, err := base64.URLEncoding.DecodeString(cryptoText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", err
|
||||
}
|
||||
|
||||
skey := sha512.Sum512(key)
|
||||
ekey, akey := skey[:32], skey[32:]
|
||||
macfn := hmac.New(sha256.New, akey)
|
||||
if len(ciphertext) < aes.BlockSize+macfn.Size() {
|
||||
return "", errors.New("short ciphertext")
|
||||
return "", errors.New("short ciphertext")
|
||||
}
|
||||
|
||||
macfn.Write(ciphertext[aes.BlockSize+macfn.Size():])
|
||||
expectedMac := macfn.Sum(nil)
|
||||
mac := ciphertext[aes.BlockSize:aes.BlockSize+macfn.Size()]
|
||||
mac := ciphertext[aes.BlockSize : aes.BlockSize+macfn.Size()]
|
||||
if hmac.Equal(expectedMac, mac) != true {
|
||||
return "", errors.New("Incorrect MAC for the given ciphertext")
|
||||
return "", errors.New("Incorrect MAC for the given ciphertext")
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(ekey)
|
||||
|
||||
@@ -6,6 +6,7 @@ package store
|
||||
import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTeamStoreSave(t *testing.T) {
|
||||
@@ -39,7 +40,11 @@ func TestTeamStoreUpdate(t *testing.T) {
|
||||
o1.Domain = "a" + model.NewId() + "b"
|
||||
o1.Email = model.NewId() + "@nowhere.com"
|
||||
o1.Type = model.TEAM_OPEN
|
||||
<-store.Team().Save(&o1)
|
||||
if err := (<-store.Team().Save(&o1)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if err := (<-store.Team().Update(&o1)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -86,7 +91,7 @@ func TestTeamStoreGet(t *testing.T) {
|
||||
o1.Domain = "a" + model.NewId() + "b"
|
||||
o1.Email = model.NewId() + "@nowhere.com"
|
||||
o1.Type = model.TEAM_OPEN
|
||||
<-store.Team().Save(&o1)
|
||||
Must(store.Team().Save(&o1))
|
||||
|
||||
if r1 := <-store.Team().Get(o1.Id); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
@@ -135,12 +140,12 @@ func TestTeamStoreGetForEmail(t *testing.T) {
|
||||
o1.Domain = "a" + model.NewId() + "b"
|
||||
o1.Email = model.NewId() + "@nowhere.com"
|
||||
o1.Type = model.TEAM_OPEN
|
||||
<-store.Team().Save(&o1)
|
||||
Must(store.Team().Save(&o1))
|
||||
|
||||
u1 := model.User{}
|
||||
u1.TeamId = o1.Id
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
if r1 := <-store.Team().GetTeamsForEmail(u1.Email); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
|
||||
@@ -137,7 +137,7 @@ func (us SqlUserStore) Update(user *model.User, allowRoleActiveUpdate bool) Stor
|
||||
if count, err := us.GetMaster().Update(user); err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.Update", "We encounted an error updating the account", "user_id="+user.Id+", "+err.Error())
|
||||
} else if count != 1 {
|
||||
result.Err = model.NewAppError("SqlUserStore.Update", "We couldn't update the account", "user_id="+user.Id)
|
||||
result.Err = model.NewAppError("SqlUserStore.Update", "We couldn't update the account", fmt.Sprintf("user_id=%v, count=%v", user.Id, count))
|
||||
} else {
|
||||
result.Data = [2]*model.User{user, oldUser}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ func TestUserStoreUpdate(t *testing.T) {
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
if err := (<-store.User().Update(&u1, false)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -87,7 +87,7 @@ func TestUserStoreUpdateLastPingAt(t *testing.T) {
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
if err := (<-store.User().UpdateLastPingAt(u1.Id, 1234567890)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -109,7 +109,7 @@ func TestUserStoreUpdateLastActivityAt(t *testing.T) {
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
if err := (<-store.User().UpdateLastActivityAt(u1.Id, 1234567890)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -131,12 +131,12 @@ func TestUserStoreUpdateUserAndSessionActivity(t *testing.T) {
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
s1 := model.Session{}
|
||||
s1.UserId = u1.Id
|
||||
s1.TeamId = u1.TeamId
|
||||
<-store.Session().Save(&s1)
|
||||
Must(store.Session().Save(&s1))
|
||||
|
||||
if err := (<-store.User().UpdateUserAndSessionActivity(u1.Id, s1.Id, 1234567890)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -166,7 +166,7 @@ func TestUserStoreGet(t *testing.T) {
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
if r1 := <-store.User().Get(u1.Id); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
@@ -187,12 +187,12 @@ func TestUserStoreGetProfiles(t *testing.T) {
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
u2 := model.User{}
|
||||
u2.TeamId = u1.TeamId
|
||||
u2.Email = model.NewId()
|
||||
<-store.User().Save(&u2)
|
||||
Must(store.User().Save(&u2))
|
||||
|
||||
if r1 := <-store.User().GetProfiles(u1.TeamId); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
@@ -222,7 +222,7 @@ func TestUserStoreGetByEmail(t *testing.T) {
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
if err := (<-store.User().GetByEmail(u1.TeamId, u1.Email)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -240,7 +240,7 @@ func TestUserStoreGetByUsername(t *testing.T) {
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
u1.Username = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
if err := (<-store.User().GetByUsername(u1.TeamId, u1.Username)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -257,7 +257,7 @@ func TestUserStoreUpdatePassword(t *testing.T) {
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
<-store.User().Save(&u1)
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
hashedPassword := model.HashPassword("newpwd")
|
||||
|
||||
|
||||
@@ -14,6 +14,15 @@ type StoreResult struct {
|
||||
|
||||
type StoreChannel chan StoreResult
|
||||
|
||||
func Must(sc StoreChannel) interface{} {
|
||||
r := <-sc
|
||||
if r.Err != nil {
|
||||
panic(r.Err)
|
||||
}
|
||||
|
||||
return r.Data
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
Team() TeamStore
|
||||
Channel() ChannelStore
|
||||
|
||||
Ссылка в новой задаче
Block a user