Implement OAuth2 service provider functionality.
Этот коммит содержится в:
@@ -9,17 +9,69 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
ACCESS_TOKEN_GRANT_TYPE = "authorization_code"
|
||||
ACCESS_TOKEN_TYPE = "bearer"
|
||||
ACCESS_TOKEN_GRANT_TYPE = "authorization_code"
|
||||
ACCESS_TOKEN_TYPE = "bearer"
|
||||
REFRESH_TOKEN_GRANT_TYPE = "refresh_token"
|
||||
)
|
||||
|
||||
type AccessData struct {
|
||||
AuthCode string `json:"auth_code"`
|
||||
Token string `json"token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
RedirectUri string `json:"redirect_uri"`
|
||||
}
|
||||
|
||||
type AccessResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
ExpiresIn int32 `json:"expires_in"`
|
||||
Scope string `json:"scope"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
// IsValid validates the AccessData and returns an error if it isn't configured
|
||||
// correctly.
|
||||
func (ad *AccessData) IsValid() *AppError {
|
||||
|
||||
if len(ad.AuthCode) == 0 || len(ad.AuthCode) > 128 {
|
||||
return NewAppError("AccessData.IsValid", "Invalid auth code", "")
|
||||
}
|
||||
|
||||
if len(ad.Token) != 26 {
|
||||
return NewAppError("AccessData.IsValid", "Invalid access token", "")
|
||||
}
|
||||
|
||||
if len(ad.RefreshToken) > 26 {
|
||||
return NewAppError("AccessData.IsValid", "Invalid refresh token", "")
|
||||
}
|
||||
|
||||
if len(ad.RedirectUri) > 256 {
|
||||
return NewAppError("AccessData.IsValid", "Invalid redirect uri", "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ad *AccessData) ToJson() string {
|
||||
b, err := json.Marshal(ad)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func AccessDataFromJson(data io.Reader) *AccessData {
|
||||
decoder := json.NewDecoder(data)
|
||||
var ad AccessData
|
||||
err := decoder.Decode(&ad)
|
||||
if err == nil {
|
||||
return &ad
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (ar *AccessResponse) ToJson() string {
|
||||
b, err := json.Marshal(ar)
|
||||
if err != nil {
|
||||
|
||||
41
model/access_test.go
Обычный файл
41
model/access_test.go
Обычный файл
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAccessJson(t *testing.T) {
|
||||
a1 := AccessData{}
|
||||
a1.AuthCode = NewId()
|
||||
a1.Token = NewId()
|
||||
a1.RefreshToken = NewId()
|
||||
|
||||
json := a1.ToJson()
|
||||
ra1 := AccessDataFromJson(strings.NewReader(json))
|
||||
|
||||
if a1.Token != ra1.Token {
|
||||
t.Fatal("tokens didn't match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccessIsValid(t *testing.T) {
|
||||
ad := AccessData{}
|
||||
|
||||
if err := ad.IsValid(); err == nil {
|
||||
t.Fatal("should have failed")
|
||||
}
|
||||
|
||||
ad.AuthCode = NewId()
|
||||
if err := ad.IsValid(); err == nil {
|
||||
t.Fatal("should have failed")
|
||||
}
|
||||
|
||||
ad.Token = NewId()
|
||||
if err := ad.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
103
model/authorize.go
Обычный файл
103
model/authorize.go
Обычный файл
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
AUTHCODE_EXPIRE_TIME = 60 * 10 // 10 minutes
|
||||
AUTHCODE_RESPONSE_TYPE = "code"
|
||||
)
|
||||
|
||||
type AuthData struct {
|
||||
ClientId string `json:"client_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Code string `json:"code"`
|
||||
ExpiresIn int32 `json:"expires_in"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
RedirectUri string `json:"redirect_uri"`
|
||||
State string `json:"state"`
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
||||
// IsValid validates the AuthData and returns an error if it isn't configured
|
||||
// correctly.
|
||||
func (ad *AuthData) IsValid() *AppError {
|
||||
|
||||
if len(ad.ClientId) != 26 {
|
||||
return NewAppError("AuthData.IsValid", "Invalid client id", "")
|
||||
}
|
||||
|
||||
if len(ad.UserId) != 26 {
|
||||
return NewAppError("AuthData.IsValid", "Invalid user id", "")
|
||||
}
|
||||
|
||||
if len(ad.Code) == 0 || len(ad.Code) > 128 {
|
||||
return NewAppError("AuthData.IsValid", "Invalid authorization code", "client_id="+ad.ClientId)
|
||||
}
|
||||
|
||||
if ad.ExpiresIn == 0 {
|
||||
return NewAppError("AuthData.IsValid", "Expires in must be set", "")
|
||||
}
|
||||
|
||||
if ad.CreateAt <= 0 {
|
||||
return NewAppError("AuthData.IsValid", "Create at must be a valid time", "client_id="+ad.ClientId)
|
||||
}
|
||||
|
||||
if len(ad.RedirectUri) > 256 {
|
||||
return NewAppError("AuthData.IsValid", "Invalid redirect uri", "client_id="+ad.ClientId)
|
||||
}
|
||||
|
||||
if len(ad.State) > 128 {
|
||||
return NewAppError("AuthData.IsValid", "Invalid state", "client_id="+ad.ClientId)
|
||||
}
|
||||
|
||||
if len(ad.Scope) > 128 {
|
||||
return NewAppError("AuthData.IsValid", "Invalid scope", "client_id="+ad.ClientId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ad *AuthData) PreSave() {
|
||||
if ad.ExpiresIn == 0 {
|
||||
ad.ExpiresIn = AUTHCODE_EXPIRE_TIME
|
||||
}
|
||||
|
||||
if ad.CreateAt == 0 {
|
||||
ad.CreateAt = GetMillis()
|
||||
}
|
||||
}
|
||||
|
||||
func (ad *AuthData) ToJson() string {
|
||||
b, err := json.Marshal(ad)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func AuthDataFromJson(data io.Reader) *AuthData {
|
||||
decoder := json.NewDecoder(data)
|
||||
var ad AuthData
|
||||
err := decoder.Decode(&ad)
|
||||
if err == nil {
|
||||
return &ad
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (ad *AuthData) IsExpired() bool {
|
||||
|
||||
if GetMillis() > ad.CreateAt+int64(ad.ExpiresIn*1000) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
66
model/authorize_test.go
Обычный файл
66
model/authorize_test.go
Обычный файл
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAuthJson(t *testing.T) {
|
||||
a1 := AuthData{}
|
||||
a1.ClientId = NewId()
|
||||
a1.UserId = NewId()
|
||||
a1.Code = NewId()
|
||||
|
||||
json := a1.ToJson()
|
||||
ra1 := AuthDataFromJson(strings.NewReader(json))
|
||||
|
||||
if a1.Code != ra1.Code {
|
||||
t.Fatal("codes didn't match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthPreSave(t *testing.T) {
|
||||
a1 := AuthData{}
|
||||
a1.ClientId = NewId()
|
||||
a1.UserId = NewId()
|
||||
a1.Code = NewId()
|
||||
a1.PreSave()
|
||||
a1.IsExpired()
|
||||
}
|
||||
|
||||
func TestAuthIsValid(t *testing.T) {
|
||||
|
||||
ad := AuthData{}
|
||||
|
||||
if err := ad.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
ad.ClientId = NewId()
|
||||
if err := ad.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
ad.UserId = NewId()
|
||||
if err := ad.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
ad.Code = NewId()
|
||||
if err := ad.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
ad.ExpiresIn = 1
|
||||
if err := ad.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
ad.CreateAt = 1
|
||||
if err := ad.IsValid(); err != nil {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
192
model/client.go
192
model/client.go
@@ -23,7 +23,9 @@ const (
|
||||
HEADER_FORWARDED = "X-Forwarded-For"
|
||||
HEADER_FORWARDED_PROTO = "X-Forwarded-Proto"
|
||||
HEADER_TOKEN = "token"
|
||||
HEADER_BEARER = "BEARER"
|
||||
HEADER_AUTH = "Authorization"
|
||||
API_URL_SUFFIX = "/api/v1"
|
||||
)
|
||||
|
||||
type Result struct {
|
||||
@@ -33,22 +35,37 @@ type Result struct {
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
Url string // The location of the server like "http://localhost/api/v1"
|
||||
Url string // The location of the server like "http://localhost:8065"
|
||||
ApiUrl string // The api location of the server like "http://localhost:8065/api/v1"
|
||||
HttpClient *http.Client // The http client
|
||||
AuthToken string
|
||||
AuthType string
|
||||
}
|
||||
|
||||
// NewClient constructs a new client with convienence methods for talking to
|
||||
// the server.
|
||||
func NewClient(url string) *Client {
|
||||
return &Client{url, &http.Client{}, ""}
|
||||
return &Client{url, url + API_URL_SUFFIX, &http.Client{}, "", ""}
|
||||
}
|
||||
|
||||
func (c *Client) DoPost(url string, data string) (*http.Response, *AppError) {
|
||||
func (c *Client) DoPost(url string, data, contentType string) (*http.Response, *AppError) {
|
||||
rq, _ := http.NewRequest("POST", c.Url+url, strings.NewReader(data))
|
||||
rq.Header.Set("Content-Type", contentType)
|
||||
|
||||
if rp, err := c.HttpClient.Do(rq); err != nil {
|
||||
return nil, NewAppError(url, "We encountered an error while connecting to the server", err.Error())
|
||||
} else if rp.StatusCode >= 300 {
|
||||
return nil, AppErrorFromJson(rp.Body)
|
||||
} else {
|
||||
return rp, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) DoApiPost(url string, data string) (*http.Response, *AppError) {
|
||||
rq, _ := http.NewRequest("POST", c.ApiUrl+url, strings.NewReader(data))
|
||||
|
||||
if len(c.AuthToken) > 0 {
|
||||
rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken)
|
||||
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
|
||||
}
|
||||
|
||||
if rp, err := c.HttpClient.Do(rq); err != nil {
|
||||
@@ -60,15 +77,15 @@ func (c *Client) DoPost(url string, data string) (*http.Response, *AppError) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) DoGet(url string, data string, etag string) (*http.Response, *AppError) {
|
||||
rq, _ := http.NewRequest("GET", c.Url+url, strings.NewReader(data))
|
||||
func (c *Client) DoApiGet(url string, data string, etag string) (*http.Response, *AppError) {
|
||||
rq, _ := http.NewRequest("GET", c.ApiUrl+url, strings.NewReader(data))
|
||||
|
||||
if len(etag) > 0 {
|
||||
rq.Header.Set(HEADER_ETAG_CLIENT, etag)
|
||||
}
|
||||
|
||||
if len(c.AuthToken) > 0 {
|
||||
rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken)
|
||||
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
|
||||
}
|
||||
|
||||
if rp, err := c.HttpClient.Do(rq); err != nil {
|
||||
@@ -106,7 +123,7 @@ func (c *Client) SignupTeam(email string, displayName string) (*Result, *AppErro
|
||||
m := make(map[string]string)
|
||||
m["email"] = email
|
||||
m["display_name"] = displayName
|
||||
if r, err := c.DoPost("/teams/signup", MapToJson(m)); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/signup", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -115,7 +132,7 @@ func (c *Client) SignupTeam(email string, displayName string) (*Result, *AppErro
|
||||
}
|
||||
|
||||
func (c *Client) CreateTeamFromSignup(teamSignup *TeamSignup) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/teams/create_from_signup", teamSignup.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/create_from_signup", teamSignup.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -124,7 +141,7 @@ func (c *Client) CreateTeamFromSignup(teamSignup *TeamSignup) (*Result, *AppErro
|
||||
}
|
||||
|
||||
func (c *Client) CreateTeam(team *Team) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/teams/create", team.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/create", team.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -136,7 +153,7 @@ func (c *Client) FindTeamByName(name string, allServers bool) (*Result, *AppErro
|
||||
m := make(map[string]string)
|
||||
m["name"] = name
|
||||
m["all"] = fmt.Sprintf("%v", allServers)
|
||||
if r, err := c.DoPost("/teams/find_team_by_name", MapToJson(m)); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/find_team_by_name", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
val := false
|
||||
@@ -152,7 +169,7 @@ func (c *Client) FindTeamByName(name string, allServers bool) (*Result, *AppErro
|
||||
func (c *Client) FindTeams(email string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["email"] = email
|
||||
if r, err := c.DoPost("/teams/find_teams", MapToJson(m)); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/find_teams", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
|
||||
@@ -164,7 +181,7 @@ func (c *Client) FindTeams(email string) (*Result, *AppError) {
|
||||
func (c *Client) FindTeamsSendEmail(email string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["email"] = email
|
||||
if r, err := c.DoPost("/teams/email_teams", MapToJson(m)); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/email_teams", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -173,7 +190,7 @@ func (c *Client) FindTeamsSendEmail(email string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) InviteMembers(invites *Invites) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/teams/invite_members", invites.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/invite_members", invites.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -182,7 +199,7 @@ func (c *Client) InviteMembers(invites *Invites) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) UpdateTeamDisplayName(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/teams/update_name", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/update_name", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -191,7 +208,7 @@ func (c *Client) UpdateTeamDisplayName(data map[string]string) (*Result, *AppErr
|
||||
}
|
||||
|
||||
func (c *Client) UpdateValetFeature(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/teams/update_valet_feature", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/teams/update_valet_feature", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -200,7 +217,7 @@ func (c *Client) UpdateValetFeature(data map[string]string) (*Result, *AppError)
|
||||
}
|
||||
|
||||
func (c *Client) CreateUser(user *User, hash string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/create", user.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/users/create", user.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -209,7 +226,7 @@ func (c *Client) CreateUser(user *User, hash string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) CreateUserFromSignup(user *User, data string, hash string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/create?d="+data+"&h="+hash, user.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/users/create?d="+data+"&h="+hash, user.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -218,7 +235,7 @@ func (c *Client) CreateUserFromSignup(user *User, data string, hash string) (*Re
|
||||
}
|
||||
|
||||
func (c *Client) GetUser(id string, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/users/"+id, "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/users/"+id, "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -227,7 +244,7 @@ func (c *Client) GetUser(id string, etag string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetMe(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/users/me", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/users/me", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -236,7 +253,7 @@ func (c *Client) GetMe(etag string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/users/profiles", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/users/profiles", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -269,13 +286,14 @@ func (c *Client) LoginByEmailWithDevice(name string, email string, password stri
|
||||
}
|
||||
|
||||
func (c *Client) login(m map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/login", MapToJson(m)); err != nil {
|
||||
if r, err := c.DoApiPost("/users/login", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
c.AuthToken = r.Header.Get(HEADER_TOKEN)
|
||||
sessionId := getCookie(SESSION_TOKEN, r)
|
||||
c.AuthType = HEADER_BEARER
|
||||
sessionToken := getCookie(SESSION_TOKEN, r)
|
||||
|
||||
if c.AuthToken != sessionId.Value {
|
||||
if c.AuthToken != sessionToken.Value {
|
||||
NewAppError("/users/login", "Authentication tokens didn't match", "")
|
||||
}
|
||||
|
||||
@@ -285,21 +303,32 @@ func (c *Client) login(m map[string]string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) Logout() (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/logout", ""); err != nil {
|
||||
if r, err := c.DoApiPost("/users/logout", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
c.AuthToken = ""
|
||||
c.AuthType = HEADER_BEARER
|
||||
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) SetOAuthToken(token string) {
|
||||
c.AuthToken = token
|
||||
c.AuthType = HEADER_TOKEN
|
||||
}
|
||||
|
||||
func (c *Client) ClearOAuthToken() {
|
||||
c.AuthToken = ""
|
||||
c.AuthType = HEADER_BEARER
|
||||
}
|
||||
|
||||
func (c *Client) RevokeSession(sessionAltId string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["id"] = sessionAltId
|
||||
|
||||
if r, err := c.DoPost("/users/revoke_session", MapToJson(m)); err != nil {
|
||||
if r, err := c.DoApiPost("/users/revoke_session", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -308,7 +337,7 @@ func (c *Client) RevokeSession(sessionAltId string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetSessions(id string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/users/"+id+"/sessions", "", ""); err != nil {
|
||||
if r, err := c.DoApiGet("/users/"+id+"/sessions", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -321,7 +350,7 @@ func (c *Client) Command(channelId string, command string, suggest bool) (*Resul
|
||||
m["command"] = command
|
||||
m["channelId"] = channelId
|
||||
m["suggest"] = strconv.FormatBool(suggest)
|
||||
if r, err := c.DoPost("/command", MapToJson(m)); err != nil {
|
||||
if r, err := c.DoApiPost("/command", MapToJson(m)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -330,7 +359,7 @@ func (c *Client) Command(channelId string, command string, suggest bool) (*Resul
|
||||
}
|
||||
|
||||
func (c *Client) GetAudits(id string, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/users/"+id+"/audits", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/users/"+id+"/audits", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -339,7 +368,7 @@ func (c *Client) GetAudits(id string, etag string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetLogs() (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/admin/logs", "", ""); err != nil {
|
||||
if r, err := c.DoApiGet("/admin/logs", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -348,7 +377,7 @@ func (c *Client) GetLogs() (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetClientProperties() (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/admin/client_props", "", ""); err != nil {
|
||||
if r, err := c.DoApiGet("/admin/client_props", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -357,7 +386,7 @@ func (c *Client) GetClientProperties() (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/create", channel.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/create", channel.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -366,7 +395,7 @@ func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) CreateDirectChannel(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/create_direct", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/create_direct", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -375,7 +404,7 @@ func (c *Client) CreateDirectChannel(data map[string]string) (*Result, *AppError
|
||||
}
|
||||
|
||||
func (c *Client) UpdateChannel(channel *Channel) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/update", channel.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/update", channel.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -384,7 +413,7 @@ func (c *Client) UpdateChannel(channel *Channel) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) UpdateChannelDesc(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/update_desc", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/update_desc", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -393,7 +422,7 @@ func (c *Client) UpdateChannelDesc(data map[string]string) (*Result, *AppError)
|
||||
}
|
||||
|
||||
func (c *Client) UpdateNotifyLevel(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/update_notify_level", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/update_notify_level", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -402,7 +431,7 @@ func (c *Client) UpdateNotifyLevel(data map[string]string) (*Result, *AppError)
|
||||
}
|
||||
|
||||
func (c *Client) GetChannels(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/channels/", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/channels/", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -411,7 +440,7 @@ func (c *Client) GetChannels(etag string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetChannel(id, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/channels/"+id+"/", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/channels/"+id+"/", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -420,7 +449,7 @@ func (c *Client) GetChannel(id, etag string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetMoreChannels(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/channels/more", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/channels/more", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -429,7 +458,7 @@ func (c *Client) GetMoreChannels(etag string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetChannelCounts(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/channels/counts", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/channels/counts", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -438,7 +467,7 @@ func (c *Client) GetChannelCounts(etag string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) JoinChannel(id string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/"+id+"/join", ""); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/join", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -447,7 +476,7 @@ func (c *Client) JoinChannel(id string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) LeaveChannel(id string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/"+id+"/leave", ""); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/leave", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -456,7 +485,7 @@ func (c *Client) LeaveChannel(id string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) DeleteChannel(id string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/"+id+"/delete", ""); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/delete", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -467,7 +496,7 @@ func (c *Client) DeleteChannel(id string) (*Result, *AppError) {
|
||||
func (c *Client) AddChannelMember(id, user_id string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user_id
|
||||
if r, err := c.DoPost("/channels/"+id+"/add", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/add", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -478,7 +507,7 @@ func (c *Client) AddChannelMember(id, user_id string) (*Result, *AppError) {
|
||||
func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user_id
|
||||
if r, err := c.DoPost("/channels/"+id+"/remove", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+id+"/remove", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -487,7 +516,7 @@ func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) UpdateLastViewedAt(channelId string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/"+channelId+"/update_last_viewed_at", ""); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+channelId+"/update_last_viewed_at", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -496,7 +525,7 @@ func (c *Client) UpdateLastViewedAt(channelId string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetChannelExtraInfo(id string, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/channels/"+id+"/extra_info", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/channels/"+id+"/extra_info", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -505,7 +534,7 @@ func (c *Client) GetChannelExtraInfo(id string, etag string) (*Result, *AppError
|
||||
}
|
||||
|
||||
func (c *Client) CreatePost(post *Post) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/"+post.ChannelId+"/create", post.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/create", post.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -514,7 +543,7 @@ func (c *Client) CreatePost(post *Post) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) CreateValetPost(post *Post) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/"+post.ChannelId+"/valet_create", post.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/valet_create", post.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -523,7 +552,7 @@ func (c *Client) CreateValetPost(post *Post) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) UpdatePost(post *Post) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/channels/"+post.ChannelId+"/update", post.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/update", post.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -532,7 +561,7 @@ func (c *Client) UpdatePost(post *Post) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetPosts(channelId string, offset int, limit int, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet(fmt.Sprintf("/channels/%v/posts/%v/%v", channelId, offset, limit), "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/posts/%v/%v", channelId, offset, limit), "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -541,7 +570,7 @@ func (c *Client) GetPosts(channelId string, offset int, limit int, etag string)
|
||||
}
|
||||
|
||||
func (c *Client) GetPostsSince(channelId string, time int64) (*Result, *AppError) {
|
||||
if r, err := c.DoGet(fmt.Sprintf("/channels/%v/posts/%v", channelId, time), "", ""); err != nil {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/posts/%v", channelId, time), "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -550,7 +579,7 @@ func (c *Client) GetPostsSince(channelId string, time int64) (*Result, *AppError
|
||||
}
|
||||
|
||||
func (c *Client) GetPost(channelId string, postId string, etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet(fmt.Sprintf("/channels/%v/post/%v", channelId, postId), "", etag); err != nil {
|
||||
if r, err := c.DoApiGet(fmt.Sprintf("/channels/%v/post/%v", channelId, postId), "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -559,7 +588,7 @@ func (c *Client) GetPost(channelId string, postId string, etag string) (*Result,
|
||||
}
|
||||
|
||||
func (c *Client) DeletePost(channelId string, postId string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost(fmt.Sprintf("/channels/%v/post/%v/delete", channelId, postId), ""); err != nil {
|
||||
if r, err := c.DoApiPost(fmt.Sprintf("/channels/%v/post/%v/delete", channelId, postId), ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -568,7 +597,7 @@ func (c *Client) DeletePost(channelId string, postId string) (*Result, *AppError
|
||||
}
|
||||
|
||||
func (c *Client) SearchPosts(terms string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/posts/search?terms="+url.QueryEscape(terms), "", ""); err != nil {
|
||||
if r, err := c.DoApiGet("/posts/search?terms="+url.QueryEscape(terms), "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -577,7 +606,7 @@ func (c *Client) SearchPosts(terms string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) UploadFile(url string, data []byte, contentType string) (*Result, *AppError) {
|
||||
rq, _ := http.NewRequest("POST", c.Url+url, bytes.NewReader(data))
|
||||
rq, _ := http.NewRequest("POST", c.ApiUrl+url, bytes.NewReader(data))
|
||||
rq.Header.Set("Content-Type", contentType)
|
||||
|
||||
if len(c.AuthToken) > 0 {
|
||||
@@ -599,7 +628,7 @@ func (c *Client) GetFile(url string, isFullUrl bool) (*Result, *AppError) {
|
||||
if isFullUrl {
|
||||
rq, _ = http.NewRequest("GET", url, nil)
|
||||
} else {
|
||||
rq, _ = http.NewRequest("GET", c.Url+"/files/get"+url, nil)
|
||||
rq, _ = http.NewRequest("GET", c.ApiUrl+"/files/get"+url, nil)
|
||||
}
|
||||
|
||||
if len(c.AuthToken) > 0 {
|
||||
@@ -618,7 +647,7 @@ func (c *Client) GetFile(url string, isFullUrl bool) (*Result, *AppError) {
|
||||
|
||||
func (c *Client) GetFileInfo(url string) (*Result, *AppError) {
|
||||
var rq *http.Request
|
||||
rq, _ = http.NewRequest("GET", c.Url+"/files/get_info"+url, nil)
|
||||
rq, _ = http.NewRequest("GET", c.ApiUrl+"/files/get_info"+url, nil)
|
||||
|
||||
if len(c.AuthToken) > 0 {
|
||||
rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken)
|
||||
@@ -635,7 +664,7 @@ func (c *Client) GetFileInfo(url string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetPublicLink(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/files/get_public_link", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/files/get_public_link", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -644,7 +673,7 @@ func (c *Client) GetPublicLink(data map[string]string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) UpdateUser(user *User) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/update", user.ToJson()); err != nil {
|
||||
if r, err := c.DoApiPost("/users/update", user.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -653,7 +682,7 @@ func (c *Client) UpdateUser(user *User) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) UpdateUserRoles(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/update_roles", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/users/update_roles", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -665,7 +694,7 @@ func (c *Client) UpdateActive(userId string, active bool) (*Result, *AppError) {
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = userId
|
||||
data["active"] = strconv.FormatBool(active)
|
||||
if r, err := c.DoPost("/users/update_active", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/users/update_active", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -674,7 +703,7 @@ func (c *Client) UpdateActive(userId string, active bool) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) UpdateUserNotify(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/update_notify", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/users/update_notify", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -688,7 +717,7 @@ func (c *Client) UpdateUserPassword(userId, currentPassword, newPassword string)
|
||||
data["new_password"] = newPassword
|
||||
data["user_id"] = userId
|
||||
|
||||
if r, err := c.DoPost("/users/newpassword", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/users/newpassword", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -697,7 +726,7 @@ func (c *Client) UpdateUserPassword(userId, currentPassword, newPassword string)
|
||||
}
|
||||
|
||||
func (c *Client) SendPasswordReset(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/send_password_reset", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/users/send_password_reset", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -706,7 +735,7 @@ func (c *Client) SendPasswordReset(data map[string]string) (*Result, *AppError)
|
||||
}
|
||||
|
||||
func (c *Client) ResetPassword(data map[string]string) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/users/reset_password", MapToJson(data)); err != nil {
|
||||
if r, err := c.DoApiPost("/users/reset_password", MapToJson(data)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -715,7 +744,7 @@ func (c *Client) ResetPassword(data map[string]string) (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetStatuses() (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/users/status", "", ""); err != nil {
|
||||
if r, err := c.DoApiGet("/users/status", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -724,7 +753,7 @@ func (c *Client) GetStatuses() (*Result, *AppError) {
|
||||
}
|
||||
|
||||
func (c *Client) GetMyTeam(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoGet("/teams/me", "", etag); err != nil {
|
||||
if r, err := c.DoApiGet("/teams/me", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
@@ -732,6 +761,33 @@ func (c *Client) GetMyTeam(etag string) (*Result, *AppError) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) RegisterApp(app *OAuthApp) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost("/oauth/register", app.ToJson()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), OAuthAppFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) AllowOAuth(rspType, clientId, redirect, scope, state string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/oauth/allow?response_type="+rspType+"&client_id="+clientId+"&redirect_uri="+url.QueryEscape(redirect)+"&scope="+scope+"&state="+url.QueryEscape(state), "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetAccessToken(data url.Values) (*Result, *AppError) {
|
||||
if r, err := c.DoPost("/oauth/access_token", data.Encode(), "application/x-www-form-urlencoded"); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), AccessResponseFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) MockSession(sessionToken string) {
|
||||
c.AuthToken = sessionToken
|
||||
}
|
||||
|
||||
151
model/oauth.go
Обычный файл
151
model/oauth.go
Обычный файл
@@ -0,0 +1,151 @@
|
||||
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type OAuthApp struct {
|
||||
Id string `json:"id"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
CreateAt int64 `json:"update_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
CallbackUrls StringArray `json:"callback_urls"`
|
||||
Homepage string `json:"homepage"`
|
||||
}
|
||||
|
||||
// IsValid validates the app and returns an error if it isn't configured
|
||||
// correctly.
|
||||
func (a *OAuthApp) IsValid() *AppError {
|
||||
|
||||
if len(a.Id) != 26 {
|
||||
return NewAppError("OAuthApp.IsValid", "Invalid app id", "")
|
||||
}
|
||||
|
||||
if a.CreateAt == 0 {
|
||||
return NewAppError("OAuthApp.IsValid", "Create at must be a valid time", "app_id="+a.Id)
|
||||
}
|
||||
|
||||
if a.UpdateAt == 0 {
|
||||
return NewAppError("OAuthApp.IsValid", "Update at must be a valid time", "app_id="+a.Id)
|
||||
}
|
||||
|
||||
if len(a.CreatorId) != 26 {
|
||||
return NewAppError("OAuthApp.IsValid", "Invalid creator id", "app_id="+a.Id)
|
||||
}
|
||||
|
||||
if len(a.ClientSecret) == 0 || len(a.ClientSecret) > 128 {
|
||||
return NewAppError("OAuthApp.IsValid", "Invalid client secret", "app_id="+a.Id)
|
||||
}
|
||||
|
||||
if len(a.Name) == 0 || len(a.Name) > 64 {
|
||||
return NewAppError("OAuthApp.IsValid", "Invalid name", "app_id="+a.Id)
|
||||
}
|
||||
|
||||
if len(a.CallbackUrls) == 0 || len(fmt.Sprintf("%s", a.CallbackUrls)) > 1024 {
|
||||
return NewAppError("OAuthApp.IsValid", "Invalid callback urls", "app_id="+a.Id)
|
||||
}
|
||||
|
||||
if len(a.Homepage) == 0 || len(a.Homepage) > 256 {
|
||||
return NewAppError("OAuthApp.IsValid", "Invalid homepage", "app_id="+a.Id)
|
||||
}
|
||||
|
||||
if len(a.Description) > 512 {
|
||||
return NewAppError("OAuthApp.IsValid", "Invalid description", "app_id="+a.Id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PreSave will set the Id and ClientSecret if missing. It will also fill
|
||||
// in the CreateAt, UpdateAt times. It should be run before saving the app to the db.
|
||||
func (a *OAuthApp) PreSave() {
|
||||
if a.Id == "" {
|
||||
a.Id = NewId()
|
||||
}
|
||||
|
||||
if a.ClientSecret == "" {
|
||||
a.ClientSecret = NewId()
|
||||
}
|
||||
|
||||
a.CreateAt = GetMillis()
|
||||
a.UpdateAt = a.CreateAt
|
||||
|
||||
if len(a.ClientSecret) > 0 {
|
||||
a.ClientSecret = HashPassword(a.ClientSecret)
|
||||
}
|
||||
}
|
||||
|
||||
// PreUpdate should be run before updating the app in the db.
|
||||
func (a *OAuthApp) PreUpdate() {
|
||||
a.UpdateAt = GetMillis()
|
||||
}
|
||||
|
||||
// ToJson convert a User to a json string
|
||||
func (a *OAuthApp) ToJson() string {
|
||||
b, err := json.Marshal(a)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a valid strong etag so the browser can cache the results
|
||||
func (a *OAuthApp) Etag() string {
|
||||
return Etag(a.Id, a.UpdateAt)
|
||||
}
|
||||
|
||||
// Remove any private data from the app object
|
||||
func (a *OAuthApp) Sanitize() {
|
||||
a.ClientSecret = ""
|
||||
}
|
||||
|
||||
func (a *OAuthApp) IsValidRedirectURL(url string) bool {
|
||||
for _, u := range a.CallbackUrls {
|
||||
if u == url {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// OAuthAppFromJson will decode the input and return a User
|
||||
func OAuthAppFromJson(data io.Reader) *OAuthApp {
|
||||
decoder := json.NewDecoder(data)
|
||||
var app OAuthApp
|
||||
err := decoder.Decode(&app)
|
||||
if err == nil {
|
||||
return &app
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func OAuthAppMapToJson(a map[string]*OAuthApp) string {
|
||||
b, err := json.Marshal(a)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func OAuthAppMapFromJson(data io.Reader) map[string]*OAuthApp {
|
||||
decoder := json.NewDecoder(data)
|
||||
var apps map[string]*OAuthApp
|
||||
err := decoder.Decode(&apps)
|
||||
if err == nil {
|
||||
return apps
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
95
model/oauth_test.go
Обычный файл
95
model/oauth_test.go
Обычный файл
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOAuthAppJson(t *testing.T) {
|
||||
a1 := OAuthApp{}
|
||||
a1.Id = NewId()
|
||||
a1.Name = "TestOAuthApp" + NewId()
|
||||
a1.CallbackUrls = []string{"https://nowhere.com"}
|
||||
a1.Homepage = "https://nowhere.com"
|
||||
a1.ClientSecret = NewId()
|
||||
|
||||
json := a1.ToJson()
|
||||
ra1 := OAuthAppFromJson(strings.NewReader(json))
|
||||
|
||||
if a1.Id != ra1.Id {
|
||||
t.Fatal("ids did not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOAuthAppPreSave(t *testing.T) {
|
||||
a1 := OAuthApp{}
|
||||
a1.Id = NewId()
|
||||
a1.Name = "TestOAuthApp" + NewId()
|
||||
a1.CallbackUrls = []string{"https://nowhere.com"}
|
||||
a1.Homepage = "https://nowhere.com"
|
||||
a1.ClientSecret = NewId()
|
||||
a1.PreSave()
|
||||
a1.Etag()
|
||||
a1.Sanitize()
|
||||
}
|
||||
|
||||
func TestOAuthAppPreUpdate(t *testing.T) {
|
||||
a1 := OAuthApp{}
|
||||
a1.Id = NewId()
|
||||
a1.Name = "TestOAuthApp" + NewId()
|
||||
a1.CallbackUrls = []string{"https://nowhere.com"}
|
||||
a1.Homepage = "https://nowhere.com"
|
||||
a1.ClientSecret = NewId()
|
||||
a1.PreUpdate()
|
||||
}
|
||||
|
||||
func TestOAuthAppIsValid(t *testing.T) {
|
||||
app := OAuthApp{}
|
||||
|
||||
if err := app.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
app.Id = NewId()
|
||||
if err := app.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
app.CreateAt = 1
|
||||
if err := app.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
app.UpdateAt = 1
|
||||
if err := app.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
app.CreatorId = NewId()
|
||||
if err := app.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
app.ClientSecret = NewId()
|
||||
if err := app.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
app.Name = "TestOAuthApp"
|
||||
if err := app.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
app.CallbackUrls = []string{"https://nowhere.com"}
|
||||
if err := app.IsValid(); err == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
app.Homepage = "https://nowhere.com"
|
||||
if err := app.IsValid(); err != nil {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ const (
|
||||
SESSION_TIME_WEB_IN_SECS = 60 * 60 * 24 * SESSION_TIME_WEB_IN_DAYS
|
||||
SESSION_TIME_MOBILE_IN_DAYS = 30
|
||||
SESSION_TIME_MOBILE_IN_SECS = 60 * 60 * 24 * SESSION_TIME_MOBILE_IN_DAYS
|
||||
SESSION_TIME_OAUTH_IN_DAYS = 365
|
||||
SESSION_TIME_OAUTH_IN_SECS = 60 * 60 * 24 * SESSION_TIME_OAUTH_IN_DAYS
|
||||
SESSION_CACHE_IN_SECS = 60 * 10
|
||||
SESSION_CACHE_SIZE = 10000
|
||||
SESSION_PROP_PLATFORM = "platform"
|
||||
@@ -23,7 +25,7 @@ const (
|
||||
|
||||
type Session struct {
|
||||
Id string `json:"id"`
|
||||
AltId string `json:"alt_id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
LastActivityAt int64 `json:"last_activity_at"`
|
||||
@@ -31,6 +33,7 @@ type Session struct {
|
||||
TeamId string `json:"team_id"`
|
||||
DeviceId string `json:"device_id"`
|
||||
Roles string `json:"roles"`
|
||||
IsOAuth bool `json:"is_oauth"`
|
||||
Props StringMap `json:"props"`
|
||||
}
|
||||
|
||||
@@ -59,7 +62,7 @@ func (me *Session) PreSave() {
|
||||
me.Id = NewId()
|
||||
}
|
||||
|
||||
me.AltId = NewId()
|
||||
me.Token = NewId()
|
||||
|
||||
me.CreateAt = GetMillis()
|
||||
me.LastActivityAt = me.CreateAt
|
||||
@@ -70,7 +73,7 @@ func (me *Session) PreSave() {
|
||||
}
|
||||
|
||||
func (me *Session) Sanitize() {
|
||||
me.Id = ""
|
||||
me.Token = ""
|
||||
}
|
||||
|
||||
func (me *Session) IsExpired() bool {
|
||||
|
||||
@@ -32,6 +32,7 @@ type AppError struct {
|
||||
RequestId string `json:"request_id"` // The RequestId that's also set in the header
|
||||
StatusCode int `json:"status_code"` // The http status code
|
||||
Where string `json:"-"` // The function where it happened in the form of Struct.Func
|
||||
IsOAuth bool `json:"is_oauth"` // Whether the error is OAuth specific
|
||||
}
|
||||
|
||||
func (er *AppError) Error() string {
|
||||
@@ -65,6 +66,7 @@ func NewAppError(where string, message string, details string) *AppError {
|
||||
ap.Where = where
|
||||
ap.DetailedError = details
|
||||
ap.StatusCode = 500
|
||||
ap.IsOAuth = false
|
||||
return ap
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user