From 3ff25d1c3c8749aaab2c1bbdd9b5ec60d1849b80 Mon Sep 17 00:00:00 2001 From: Umputun Date: Mon, 5 Feb 2018 03:27:31 -0600 Subject: [PATCH] add list of blocked users --- README.md | 13 ++++++++----- app/rest/admin.go | 12 ++++++++++++ app/store/bolt.go | 22 ++++++++++++++++++++++ app/store/bolt_test.go | 12 ++++++++++++ app/store/store.go | 1 + remark.rest | 3 +++ 6 files changed, 58 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1359d915..25c673e1 100644 --- a/README.md +++ b/README.md @@ -209,11 +209,14 @@ Sort can be `time` or `score`. Supported sort order with prefix -/+, i.e. `-time ### Admin -- `DELETE /api/v1/admin/comment/{id}?site=site-id&url=post-url` - delete comment by `id`. _auth and admin required_ -- `PUT /api/v1/admin/user/{userid}?site=site-id&block=1` - block or unblock user. _auth and admin required_ -- `GET /api/v1/admin/export?site=side-id&mode=[stream|file]` - export all comments to json stream or gz file. _auth and admin required_ -- `POST /api/v1/admin/import?site=side-id` - import comments from the backup. _auth and admin required_ -- `PUT /api/v1/admin/pin/{id}?site=site-id&url=post-url&pin=1` - pin or unpin comment. _auth and admin required_ +- `DELETE /api/v1/admin/comment/{id}?site=site-id&url=post-url` - delete comment by `id`. +- `PUT /api/v1/admin/user/{userid}?site=site-id&block=1` - block or unblock user. +- `GET api/v1/admin/blocked` - list of blocked user ids. +- `GET /api/v1/admin/export?site=side-id&mode=[stream|file]` - export all comments to json stream or gz file. +- `POST /api/v1/admin/import?site=side-id` - import comments from the backup. +- `PUT /api/v1/admin/pin/{id}?site=site-id&url=post-url&pin=1` - pin or unpin comment. + +_all calls require auth and admin_ ## Technical details diff --git a/app/rest/admin.go b/app/rest/admin.go index 3b3b2119..4af8548a 100644 --- a/app/rest/admin.go +++ b/app/rest/admin.go @@ -33,6 +33,7 @@ func (a *admin) routes() chi.Router { router.Get("/export", a.exportCtrl) router.Post("/import", a.importCtrl) router.Put("/pin/{id}", a.setPinCtrl) + router.Get("/blocked", a.blockedUsersCtrl) return router } @@ -67,6 +68,17 @@ func (a *admin) setBlockCtrl(w http.ResponseWriter, r *http.Request) { render.JSON(w, r, JSON{"user_id": userID, "site_id": siteID, "block": blockStatus}) } +// GET /blocked?site=siteID - list blocked users +func (a *admin) blockedUsersCtrl(w http.ResponseWriter, r *http.Request) { + siteID := r.URL.Query().Get("site") + users, err := a.dataService.Blocked(siteID) + if err != nil { + common.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't get blocked users") + return + } + render.JSON(w, r, users) +} + // PUT /pin/{id}?site=siteID&url=post-url&pin=1 // mark/unmark comment as a special func (a *admin) setPinCtrl(w http.ResponseWriter, r *http.Request) { diff --git a/app/store/bolt.go b/app/store/bolt.go index 24b771c4..3bf971a1 100644 --- a/app/store/bolt.go +++ b/app/store/bolt.go @@ -311,6 +311,28 @@ func (b *BoltDB) IsBlocked(siteID string, userID string) (blocked bool) { return blocked } +// Blocked get lists of blocked users for given site +func (b *BoltDB) Blocked(siteID string) (userIDs []string, err error) { + userIDs = []string{} + bdb, err := b.db(siteID) + if err != nil { + return nil, err + } + + err = bdb.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket([]byte(blocksBucketName)) + if bucket == nil { + return nil + } + return bucket.ForEach(func(k []byte, v []byte) error { + userIDs = append(userIDs, string(k)) + return nil + }) + }) + + return userIDs, err +} + // List returns list of buckets, which is list of all commented posts func (b BoltDB) List(siteID string) (list []PostInfo, err error) { diff --git a/app/store/bolt_test.go b/app/store/bolt_test.go index d08d08d5..aac447a8 100644 --- a/app/store/bolt_test.go +++ b/app/store/bolt_test.go @@ -127,7 +127,19 @@ func TestBoltDB_BlockUser(t *testing.T) { assert.NoError(t, b.SetBlock("radio-t", "user1", false)) assert.False(t, b.IsBlocked("radio-t", "user1"), "user1 unblocked") +} +func TestBoltDB_BlockList(t *testing.T) { + defer os.Remove(testDb) + b := prep(t) + + assert.NoError(t, b.SetBlock("radio-t", "user1", true)) + assert.NoError(t, b.SetBlock("radio-t", "user2", true)) + assert.NoError(t, b.SetBlock("radio-t", "user3", false)) + + ids, err := b.Blocked("radio-t") + assert.NoError(t, err) + assert.Equal(t, []string{"user1", "user2"}, ids) } func TestBoltDB_List(t *testing.T) { diff --git a/app/store/store.go b/app/store/store.go index b3a900d5..96e49dca 100644 --- a/app/store/store.go +++ b/app/store/store.go @@ -30,6 +30,7 @@ type Admin interface { Delete(locator Locator, commentID string) error // delete comment by id SetBlock(siteID string, userID string, status bool) error // block or unblock user IsBlocked(siteID string, userID string) bool // check if user blocked + Blocked(siteID string) (userIDs []string, err error) // get list of blocked users } func sortComments(comments []Comment, sortFld string) []Comment { diff --git a/remark.rest b/remark.rest index 218106ff..d40a45f4 100644 --- a/remark.rest +++ b/remark.rest @@ -62,5 +62,8 @@ PUT {{host}}/api/v1/admin/user/grigorybakunov?site=remark&block=1 ### unblock user PUT {{host}}/api/v1/admin/user/grigorybakunov?site=remark&block=0 +### list blocked user +PUT {{host}}/api/v1/admin/blocked?site=remark + ### delete comment by id DELETE {{host}}/api/v1/admin/comment/3665976683?site=remark&url=https://radio-t.com/p/2017/12/16/podcast-576/