add remote implementation of admin store
This commit is contained in:
@@ -2,14 +2,12 @@ package cmd
|
||||
|
||||
import (
|
||||
"path"
|
||||
"time"
|
||||
|
||||
bolt "github.com/coreos/bbolt"
|
||||
log "github.com/go-pkgz/lgr"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-pkgz/auth/avatar"
|
||||
"github.com/go-pkgz/mongo"
|
||||
)
|
||||
|
||||
// AvatarCommand set of flags and command for avatar migration
|
||||
@@ -18,7 +16,7 @@ import (
|
||||
type AvatarCommand struct {
|
||||
AvatarSrc AvatarGroup `group:"src" namespace:"src"`
|
||||
AvatarDst AvatarGroup `group:"dst" namespace:"dst"`
|
||||
Mongo MongoGroup `group:"mongo" namespace:"mongo" env-namespace:"MONGO"`
|
||||
// Mongo MongoGroup `group:"mongo" namespace:"mongo" env-namespace:"MONGO"`
|
||||
|
||||
migrator AvatarMigrator
|
||||
CommonOpts
|
||||
@@ -78,13 +76,6 @@ func (ac *AvatarCommand) makeAvatarStore(gr AvatarGroup) (avatar.Store, error) {
|
||||
return nil, err
|
||||
}
|
||||
return avatar.NewLocalFS(gr.FS.Path), nil
|
||||
case "mongo":
|
||||
mgServer, err := ac.makeMongo()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create mongo server")
|
||||
}
|
||||
conn := mongo.NewConnection(mgServer, ac.Mongo.DB, "")
|
||||
return avatar.NewGridFS(conn), nil
|
||||
case "bolt":
|
||||
if err := makeDirs(path.Dir(gr.Bolt.File)); err != nil {
|
||||
return nil, err
|
||||
@@ -93,10 +84,3 @@ func (ac *AvatarCommand) makeAvatarStore(gr AvatarGroup) (avatar.Store, error) {
|
||||
}
|
||||
return nil, errors.Errorf("unsupported avatar store type %s", gr.Type)
|
||||
}
|
||||
|
||||
func (ac *AvatarCommand) makeMongo() (result *mongo.Server, err error) {
|
||||
if ac.Mongo.URL == "" {
|
||||
return nil, errors.New("no mongo URL provided")
|
||||
}
|
||||
return mongo.NewServerWithURL(ac.Mongo.URL, 10*time.Second)
|
||||
}
|
||||
|
||||
+19
-30
@@ -22,7 +22,6 @@ import (
|
||||
"github.com/go-pkgz/auth/avatar"
|
||||
"github.com/go-pkgz/auth/provider"
|
||||
"github.com/go-pkgz/auth/token"
|
||||
"github.com/go-pkgz/mongo"
|
||||
"github.com/go-pkgz/rest/cache"
|
||||
|
||||
"github.com/umputun/remark/backend/app/migrator"
|
||||
@@ -41,7 +40,6 @@ type ServerCommand struct {
|
||||
Store StoreGroup `group:"store" namespace:"store" env-namespace:"STORE"`
|
||||
Avatar AvatarGroup `group:"avatar" namespace:"avatar" env-namespace:"AVATAR"`
|
||||
Cache CacheGroup `group:"cache" namespace:"cache" env-namespace:"CACHE"`
|
||||
Mongo MongoGroup `group:"mongo" namespace:"mongo" env-namespace:"MONGO"`
|
||||
Admin AdminGroup `group:"admin" namespace:"admin" env-namespace:"ADMIN"`
|
||||
Notify NotifyGroup `group:"notify" namespace:"notify" env-namespace:"NOTIFY"`
|
||||
Image ImageGroup `group:"image" namespace:"image" env-namespace:"IMAGE"`
|
||||
@@ -89,11 +87,15 @@ type AuthGroup struct {
|
||||
|
||||
// StoreGroup defines options group for store params
|
||||
type StoreGroup struct {
|
||||
Type string `long:"type" env:"TYPE" description:"type of storage" choice:"bolt" choice:"mongo" default:"bolt"`
|
||||
Type string `long:"type" env:"TYPE" description:"type of storage" choice:"bolt" choice:"remote" default:"bolt"`
|
||||
Bolt struct {
|
||||
Path string `long:"path" env:"PATH" default:"./var" description:"parent dir for bolt files"`
|
||||
Timeout time.Duration `long:"timeout" env:"TIMEOUT" default:"30s" description:"bolt timeout"`
|
||||
} `group:"bolt" namespace:"bolt" env-namespace:"BOLT"`
|
||||
Remote struct {
|
||||
API string `long:"api" env:"API" description:"remote extension api url"`
|
||||
TimeOut time.Duration `long:"timeout" env:"TIMEOUT" description:"http timeout"`
|
||||
} `group:"remote" namespace:"remote" env-namespace:"REMOTE"`
|
||||
}
|
||||
|
||||
// ImageGroup defines options group for store pictures
|
||||
@@ -134,12 +136,6 @@ type CacheGroup struct {
|
||||
} `group:"max" namespace:"max" env-namespace:"MAX"`
|
||||
}
|
||||
|
||||
// MongoGroup holds all mongo params, used by store, avatar and cache
|
||||
type MongoGroup struct {
|
||||
URL string `long:"url" env:"URL" description:"mongo url"`
|
||||
DB string `long:"db" env:"DB" default:"remark42" description:"mongo database"`
|
||||
}
|
||||
|
||||
// AdminGroup defines options group for admin params
|
||||
type AdminGroup struct {
|
||||
Type string `long:"type" env:"TYPE" description:"type of admin store" choice:"shared" choice:"mongo" default:"shared"`
|
||||
@@ -436,13 +432,13 @@ func (s *ServerCommand) makeAvatarStore() (avatar.Store, error) {
|
||||
return nil, err
|
||||
}
|
||||
return avatar.NewLocalFS(s.Avatar.FS.Path), nil
|
||||
case "mongo":
|
||||
mgServer, err := s.makeMongo()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create mongo server")
|
||||
}
|
||||
conn := mongo.NewConnection(mgServer, s.Mongo.DB, "")
|
||||
return avatar.NewGridFS(conn), nil
|
||||
// case "mongo":
|
||||
// mgServer, err := s.makeMongo()
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrap(err, "failed to create mongo server")
|
||||
// }
|
||||
// conn := mongo.NewConnection(mgServer, s.Mongo.DB, "")
|
||||
// return avatar.NewGridFS(conn), nil
|
||||
case "bolt":
|
||||
if err := makeDirs(path.Dir(s.Avatar.Bolt.File)); err != nil {
|
||||
return nil, err
|
||||
@@ -485,13 +481,13 @@ func (s *ServerCommand) makeAdminStore() (admin.Store, error) {
|
||||
}
|
||||
}
|
||||
return admin.NewStaticStore(s.SharedSecret, s.Admin.Shared.Admins, s.Admin.Shared.Email), nil
|
||||
case "mongo":
|
||||
mgServer, e := s.makeMongo()
|
||||
if e != nil {
|
||||
return nil, errors.Wrap(e, "failed to create mongo server")
|
||||
}
|
||||
conn := mongo.NewConnection(mgServer, s.Mongo.DB, "admin")
|
||||
return admin.NewMongoStore(conn, s.SharedSecret), nil
|
||||
// case "mongo":
|
||||
// mgServer, e := s.makeMongo()
|
||||
// if e != nil {
|
||||
// return nil, errors.Wrap(e, "failed to create mongo server")
|
||||
// }
|
||||
// conn := mongo.NewConnection(mgServer, s.Mongo.DB, "admin")
|
||||
// return admin.NewMongoStore(conn, s.SharedSecret), nil
|
||||
default:
|
||||
return nil, errors.Errorf("unsupported admin store type %s", s.Admin.Type)
|
||||
}
|
||||
@@ -517,13 +513,6 @@ func (s *ServerCommand) makeCache() (cache.LoadingCache, error) {
|
||||
return nil, errors.Errorf("unsupported cache type %s", s.Cache.Type)
|
||||
}
|
||||
|
||||
func (s *ServerCommand) makeMongo() (result *mongo.Server, err error) {
|
||||
if s.Mongo.URL == "" {
|
||||
return nil, errors.New("no mongo URL provided")
|
||||
}
|
||||
return mongo.NewServerWithURL(s.Mongo.URL, 10*time.Second)
|
||||
}
|
||||
|
||||
func (s *ServerCommand) addAuthProviders(authenticator *auth.Service) {
|
||||
|
||||
providers := 0
|
||||
|
||||
@@ -55,7 +55,9 @@ func TestServerApp(t *testing.T) {
|
||||
body, _ = ioutil.ReadAll(resp.Body)
|
||||
t.Log(string(body))
|
||||
|
||||
assert.Equal(t, "admin@demo.remark42.com", app.dataService.AdminStore.Email(""), "default admin email")
|
||||
email, err := app.dataService.AdminStore.Email("")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "admin@demo.remark42.com", email, "default admin email")
|
||||
|
||||
app.Wait()
|
||||
}
|
||||
|
||||
@@ -377,6 +377,9 @@ func (s *Rest) updateLimiter() float64 {
|
||||
func (s *Rest) configCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
siteID := r.URL.Query().Get("site")
|
||||
|
||||
admins, _ := s.DataService.AdminStore.Admins(siteID)
|
||||
emails, _ := s.DataService.AdminStore.Email(siteID)
|
||||
|
||||
cnf := struct {
|
||||
Version string `json:"version"`
|
||||
EditDuration int `json:"edit_duration"`
|
||||
@@ -393,8 +396,8 @@ func (s *Rest) configCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
Version: s.Version,
|
||||
EditDuration: int(s.DataService.EditDuration.Seconds()),
|
||||
MaxCommentSize: s.DataService.MaxCommentSize,
|
||||
Admins: s.DataService.AdminStore.Admins(siteID),
|
||||
AdminEmail: s.DataService.AdminStore.Email(siteID),
|
||||
Admins: admins,
|
||||
AdminEmail: emails,
|
||||
LowScore: s.ScoreThresholds.Low,
|
||||
CriticalScore: s.ScoreThresholds.Critical,
|
||||
PositiveScore: s.DataService.PositiveScore,
|
||||
|
||||
@@ -10,25 +10,17 @@ import (
|
||||
// Store defines interface returning admins info for given site
|
||||
type Store interface {
|
||||
Key() (key string, err error)
|
||||
Admins(siteID string) (ids []string)
|
||||
Email(siteID string) (email string)
|
||||
Admins(siteID string) (ids []string, err error)
|
||||
Email(siteID string) (email string, err error)
|
||||
}
|
||||
|
||||
// StaticStore implements keys.Store with a single, predefined key
|
||||
// StaticStore implements keys.Store with a single set of admins and email for all sites
|
||||
type StaticStore struct {
|
||||
admins []string
|
||||
email string
|
||||
key string
|
||||
}
|
||||
|
||||
// Key returns static key for all sites, allows empty site
|
||||
func (s *StaticStore) Key() (key string, err error) {
|
||||
if s.key == "" {
|
||||
return "", errors.New("empty key for static key store")
|
||||
}
|
||||
return s.key, nil
|
||||
}
|
||||
|
||||
// NewStaticStore makes StaticStore instance with given key
|
||||
func NewStaticStore(key string, admins []string, email string) *StaticStore {
|
||||
log.Printf("[DEBUG] admin users %+v, email %s", admins, email)
|
||||
@@ -40,12 +32,20 @@ func NewStaticKeyStore(key string) *StaticStore {
|
||||
return &StaticStore{key: key, admins: []string{}, email: ""}
|
||||
}
|
||||
|
||||
// Key returns static key, same for all sites
|
||||
func (s *StaticStore) Key() (key string, err error) {
|
||||
if s.key == "" {
|
||||
return "", errors.New("empty key for static key store")
|
||||
}
|
||||
return s.key, nil
|
||||
}
|
||||
|
||||
// Admins returns static list of admin's ids, the same for all sites
|
||||
func (s *StaticStore) Admins(string) (ids []string) {
|
||||
return s.admins
|
||||
func (s *StaticStore) Admins(string) (ids []string, err error) {
|
||||
return s.admins, nil
|
||||
}
|
||||
|
||||
// Email gets static email address
|
||||
func (s *StaticStore) Email(string) (email string) {
|
||||
return s.email
|
||||
func (s *StaticStore) Email(string) (email string, err error) {
|
||||
return s.email, nil
|
||||
}
|
||||
|
||||
@@ -3,10 +3,7 @@ package admin
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/globalsign/mgo"
|
||||
"github.com/go-pkgz/mongo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStaticStore_Get(t *testing.T) {
|
||||
@@ -16,48 +13,11 @@ func TestStaticStore_Get(t *testing.T) {
|
||||
assert.NoError(t, err, "valid store")
|
||||
assert.Equal(t, "key123", k, "valid site")
|
||||
|
||||
a := ks.Admins("any")
|
||||
a, err := ks.Admins("any")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{"123", "xyz"}, a)
|
||||
|
||||
email := ks.Email("blah")
|
||||
email, err := ks.Email("blah")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "aa@example.com", email)
|
||||
}
|
||||
|
||||
func TestMongoStore_Get(t *testing.T) {
|
||||
conn, err := mongo.MakeTestConnection(t)
|
||||
require.NoError(t, err)
|
||||
var ms Store = NewMongoStore(conn, "secret")
|
||||
|
||||
recs := []mongoRec{
|
||||
{"site1", []string{"i11", "i12"}, "e1"},
|
||||
{"site2", []string{"i21", "i22"}, "e2"},
|
||||
}
|
||||
err = conn.WithCollection(func(coll *mgo.Collection) error {
|
||||
if e1 := coll.Insert(recs[0]); e1 != nil {
|
||||
return e1
|
||||
}
|
||||
return coll.Insert(recs[1])
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
admins := ms.Admins("site1")
|
||||
assert.Equal(t, []string{"i11", "i12"}, admins)
|
||||
email := ms.Email("site1")
|
||||
assert.Equal(t, "e1", email)
|
||||
key, err := ms.Key()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "secret", key)
|
||||
|
||||
admins = ms.Admins("site2")
|
||||
assert.Equal(t, []string{"i21", "i22"}, admins)
|
||||
email = ms.Email("site2")
|
||||
assert.Equal(t, "e2", email)
|
||||
key, err = ms.Key()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "secret", key)
|
||||
|
||||
admins = ms.Admins("no-site-in-db")
|
||||
assert.Equal(t, []string{}, admins)
|
||||
email = ms.Email("no-site-in-db")
|
||||
assert.Equal(t, "", email)
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/globalsign/mgo"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
log "github.com/go-pkgz/lgr"
|
||||
|
||||
"github.com/go-pkgz/mongo"
|
||||
)
|
||||
|
||||
// MongoStore implements admin.Store with mongo backend
|
||||
type MongoStore struct {
|
||||
connection *mongo.Connection
|
||||
key string
|
||||
}
|
||||
|
||||
type mongoRec struct {
|
||||
SiteID string `bson:"site"`
|
||||
IDs []string `bson:"admin_ids"`
|
||||
Email string `bson:"admin_email"`
|
||||
}
|
||||
|
||||
// NewMongoStore makes admin Store for mongo's connection
|
||||
func NewMongoStore(conn *mongo.Connection, key string) *MongoStore {
|
||||
log.Printf("[DEBUG] make mongo admin store with %+v", conn)
|
||||
return &MongoStore{connection: conn, key: key}
|
||||
}
|
||||
|
||||
// Key executes find by siteID and returns substructure with secret key
|
||||
func (m *MongoStore) Key() (key string, err error) {
|
||||
return m.key, nil
|
||||
}
|
||||
|
||||
// Admins executes find by siteID and returns admins ids
|
||||
func (m *MongoStore) Admins(siteID string) (ids []string) {
|
||||
resp := mongoRec{}
|
||||
err := m.connection.WithCollection(func(coll *mgo.Collection) error {
|
||||
return coll.Find(bson.M{"site": siteID}).One(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
return resp.IDs
|
||||
}
|
||||
|
||||
// Email executes find by siteID and returns admin's email
|
||||
func (m *MongoStore) Email(siteID string) (email string) {
|
||||
resp := mongoRec{}
|
||||
err := m.connection.WithCollection(func(coll *mgo.Collection) error {
|
||||
return coll.Find(bson.M{"site": siteID}).One(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return resp.Email
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2019 Umputun. All rights reserved.
|
||||
* Use of this source code is governed by a MIT-style
|
||||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package admin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/umputun/remark/backend/app/store/remote"
|
||||
)
|
||||
|
||||
// Remote implements remote engine and delegates all Calls to remote http server
|
||||
type Remote struct {
|
||||
remote.Client
|
||||
}
|
||||
|
||||
// Key returns the key, same for all sites
|
||||
func (r *Remote) Key() (key string, err error) {
|
||||
resp, err := r.Call("admin.key")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(*resp.Result, &key)
|
||||
return key, err
|
||||
}
|
||||
|
||||
// Admins returns list of admin's ids for given site
|
||||
func (r *Remote) Admins(siteID string) (ids []string, err error) {
|
||||
resp, err := r.Call("admin.admins", siteID)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(*resp.Result, &ids); err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// Email gets email address for given site
|
||||
func (r *Remote) Email(siteID string) (email string, err error) {
|
||||
resp, err := r.Call("admin.email", siteID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(*resp.Result, &email); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return email, nil
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2019 Umputun. All rights reserved.
|
||||
* Use of this source code is governed by a MIT-style
|
||||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package admin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/umputun/remark/backend/app/store/remote"
|
||||
)
|
||||
|
||||
func TestRemote_Key(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"admin.key","params":null,"id":1}`,
|
||||
`{"result":"12345","id":1}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
|
||||
var a Store = &c
|
||||
_ = a
|
||||
|
||||
res, err := c.Key()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "12345", res)
|
||||
t.Logf("%v %T", res, res)
|
||||
}
|
||||
|
||||
func TestRemote_Admins(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"admin.admins","params":["site-1"],"id":1}`,
|
||||
`{"result":["id1","id2"],"id":1}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
|
||||
var a Store = &c
|
||||
_ = a
|
||||
|
||||
res, err := c.Admins("site-1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{"id1", "id2"}, res)
|
||||
t.Logf("%v %T", res, res)
|
||||
}
|
||||
|
||||
func TestRemote_Email(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"admin.email","params":["site-1"],"id":1}`,
|
||||
`{"result":"bbb@example.com","id":1}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
|
||||
var a Store = &c
|
||||
_ = a
|
||||
|
||||
res, err := c.Email("site-1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "bbb@example.com", res)
|
||||
t.Logf("%v %T", res, res)
|
||||
}
|
||||
func testServer(t *testing.T, req, resp string) *httptest.Server {
|
||||
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, req, string(body))
|
||||
t.Logf("req: %s", string(body))
|
||||
fmt.Fprintf(w, resp)
|
||||
}))
|
||||
}
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
bolt "github.com/coreos/bbolt"
|
||||
log "github.com/go-pkgz/lgr"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/umputun/remark/backend/app/store/remote"
|
||||
)
|
||||
|
||||
func TestClient_Create(t *testing.T) {
|
||||
func TestRemote_Create(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.create","params":{"id":"123","pid":"","text":"msg","user":{"name":"","id":"","picture":"","admin":false},"locator":{"site":"site","url":"http://example.com/url"},"score":0,"vote":0,"time":"0001-01-01T00:00:00Z"},"id":1}`,
|
||||
`{"result":"12345","id":1}`)
|
||||
defer ts.Close()
|
||||
@@ -32,7 +32,7 @@ func TestClient_Create(t *testing.T) {
|
||||
t.Logf("%v %T", res, res)
|
||||
}
|
||||
|
||||
func TestClient_Get(t *testing.T) {
|
||||
func TestRemote_Get(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.get","params":{"locator":{"url":"http://example.com/url"},"comment_id":"site"},"id":1}`, `{"result":{"id":"123","pid":"","text":"msg","delete":true}}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -44,7 +44,7 @@ func TestClient_Get(t *testing.T) {
|
||||
t.Logf("%v %T", res, res)
|
||||
}
|
||||
|
||||
func TestClient_GetWithErrorResult(t *testing.T) {
|
||||
func TestRemote_GetWithErrorResult(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.get","params":{"locator":{"url":"http://example.com/url"},"comment_id":"site"},"id":1}`, `{"error":"failed"}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -54,7 +54,7 @@ func TestClient_GetWithErrorResult(t *testing.T) {
|
||||
assert.EqualError(t, err, "failed")
|
||||
}
|
||||
|
||||
func TestClient_GetWithErrorDecode(t *testing.T) {
|
||||
func TestRemote_GetWithErrorDecode(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.get","params":{"locator":{"url":"http://example.com/url"},"comment_id":"site"},"id":1}`, ``)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -64,7 +64,7 @@ func TestClient_GetWithErrorDecode(t *testing.T) {
|
||||
assert.EqualError(t, err, "failed to decode response for store.get: EOF")
|
||||
}
|
||||
|
||||
func TestClient_GetWithErrorRemote(t *testing.T) {
|
||||
func TestRemote_GetWithErrorRemote(t *testing.T) {
|
||||
c := Remote{Client: remote.Client{API: "http://127.0.0.2", Client: http.Client{Timeout: 10 * time.Millisecond}}}
|
||||
|
||||
req := GetRequest{Locator: store.Locator{URL: "http://example.com/url"}, CommentID: "site"}
|
||||
@@ -73,7 +73,7 @@ func TestClient_GetWithErrorRemote(t *testing.T) {
|
||||
assert.True(t, strings.Contains(err.Error(), "remote call failed for store.get:"), err.Error())
|
||||
}
|
||||
|
||||
func TestClient_FailedStatus(t *testing.T) {
|
||||
func TestRemote_FailedStatus(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
@@ -88,7 +88,7 @@ func TestClient_FailedStatus(t *testing.T) {
|
||||
assert.EqualError(t, err, "bad status 400 for store.get")
|
||||
}
|
||||
|
||||
func TestClient_Update(t *testing.T) {
|
||||
func TestRemote_Update(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.update","params":{"id":"123","pid":"","text":"msg","user":{"name":"","id":"","picture":"","admin":false},"locator":{"site":"site123","url":"http://example.com/url"},"score":0,"vote":0,"time":"0001-01-01T00:00:00Z"},"id":1}`, `{}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -99,7 +99,7 @@ func TestClient_Update(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestClient_Find(t *testing.T) {
|
||||
func TestRemote_Find(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.find","params":{"locator":{"url":"http://example.com/url"},"sort":"-time","since":"0001-01-01T00:00:00Z","limit":10},"id":1}`, `{"result":[{"text":"1"},{"text":"2"}]}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -109,7 +109,7 @@ func TestClient_Find(t *testing.T) {
|
||||
assert.Equal(t, []store.Comment{{Text: "1"}, {Text: "2"}}, res)
|
||||
}
|
||||
|
||||
func TestClient_Info(t *testing.T) {
|
||||
func TestRemote_Info(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.info","params":{"locator":{"url":"http://example.com/url"},"limit":10,"skip":5,"ro_age":10},"id":1}`, `{"result":[{"url":"u1","count":22},{"url":"u2","count":33}]}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -120,7 +120,7 @@ func TestClient_Info(t *testing.T) {
|
||||
assert.Equal(t, []store.PostInfo{{URL: "u1", Count: 22}, {URL: "u2", Count: 33}}, res)
|
||||
}
|
||||
|
||||
func TestClient_Flag(t *testing.T) {
|
||||
func TestRemote_Flag(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.flag","params":{"flag":"verified","locator":{"url":"http://example.com/url"}},"id":1}`, `{"result":false}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -130,7 +130,7 @@ func TestClient_Flag(t *testing.T) {
|
||||
assert.Equal(t, false, res)
|
||||
}
|
||||
|
||||
func TestClient_ListFlag(t *testing.T) {
|
||||
func TestRemote_ListFlag(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.list_flags","params":{"flag":"blocked","locator":{"site":"site_id","url":""}},"id":1}`, `{"result":[{"ID":"id1"},{"ID":"id2"}]}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -139,7 +139,7 @@ func TestClient_ListFlag(t *testing.T) {
|
||||
assert.Equal(t, []interface{}{map[string]interface{}{"ID": "id1"}, map[string]interface{}{"ID": "id2"}}, res)
|
||||
}
|
||||
|
||||
func TestClient_Count(t *testing.T) {
|
||||
func TestRemote_Count(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.count","params":{"locator":{"url":"http://example.com/url"},"since":"0001-01-01T00:00:00Z"},"id":1}`, `{"result":11}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
@@ -149,7 +149,7 @@ func TestClient_Count(t *testing.T) {
|
||||
assert.Equal(t, 11, res)
|
||||
}
|
||||
|
||||
func TestClient_Delete(t *testing.T) {
|
||||
func TestRemote_Delete(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.delete","params":{"locator":{"url":"http://example.com/url"},"del_mode":0},"id":1}`,
|
||||
`{}`)
|
||||
defer ts.Close()
|
||||
@@ -159,7 +159,7 @@ func TestClient_Delete(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestClient_Close(t *testing.T) {
|
||||
func TestRemote_Close(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.close","params":null,"id":1}`, `{}`)
|
||||
defer ts.Close()
|
||||
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
|
||||
|
||||
@@ -462,7 +462,11 @@ func (s *DataStore) ValidateComment(c *store.Comment) error {
|
||||
|
||||
// IsAdmin checks if usesID in the list of admins
|
||||
func (s *DataStore) IsAdmin(siteID string, userID string) bool {
|
||||
for _, a := range s.AdminStore.Admins(siteID) {
|
||||
admins, err := s.AdminStore.Admins(siteID)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, a := range admins {
|
||||
if a == userID {
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user