bunch of comments
This commit is contained in:
@@ -66,6 +66,7 @@ func main() {
|
||||
dataStore := makeBoltStore()
|
||||
|
||||
if p.Active != nil && p.Command.Find("import") == p.Active {
|
||||
// import mode
|
||||
params := migrator.ImportParams{
|
||||
DataStore: dataStore,
|
||||
InputFile: opts.ImportCommand.InputFile,
|
||||
@@ -138,6 +139,7 @@ func makeBoltStore() store.Interface {
|
||||
return result
|
||||
}
|
||||
|
||||
// mkdir -p for all dirs
|
||||
func makeDirs(dirs ...string) error {
|
||||
|
||||
// exists returns whether the given file or directory exists or not
|
||||
|
||||
+8
-3
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/umputun/remark/app/store"
|
||||
)
|
||||
|
||||
// admin provides router for all requests available for admin only
|
||||
// admin provides router for all requests available for admin users only
|
||||
type admin struct {
|
||||
dataService store.Service
|
||||
exporter migrator.Exporter
|
||||
@@ -68,7 +68,8 @@ func (a *admin) setBlockCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, JSON{"user_id": userID, "site_id": siteID, "block": blockStatus})
|
||||
}
|
||||
|
||||
// PUT /pin/{id}?site=siteID&url=post-url&pin=1 - mark/unmark comment as a special
|
||||
// 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) {
|
||||
commentID := chi.URLParam(r, "id")
|
||||
locator := store.Locator{SiteID: r.URL.Query().Get("site"), URL: r.URL.Query().Get("url")}
|
||||
@@ -82,7 +83,8 @@ func (a *admin) setPinCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, JSON{"id": commentID, "loc": locator, "pin": pinStatus})
|
||||
}
|
||||
|
||||
// GET /export?site=site-id?mode=file|stream - exports all comments for siteID as json stream or file
|
||||
// GET /export?site=site-id?mode=file|stream
|
||||
// exports all comments for siteID as json stream or gz file
|
||||
func (a *admin) exportCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
siteID := r.URL.Query().Get("site")
|
||||
var writer io.Writer = w
|
||||
@@ -100,6 +102,7 @@ func (a *admin) exportCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// POST /import?site=site-id
|
||||
// imports comments from post body.
|
||||
func (a *admin) importCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
siteID := r.URL.Query().Get("site")
|
||||
if err := a.importer.Import(r.Body, siteID); err != nil {
|
||||
@@ -112,6 +115,8 @@ func (a *admin) checkBlocked(locator store.Locator, user store.User) bool {
|
||||
return a.dataService.IsBlocked(locator, user.ID)
|
||||
}
|
||||
|
||||
// processes comments and hides text of all comments for blocked users.
|
||||
// resets score and votes too
|
||||
func (a *admin) maskBlockedUsers(comments []store.Comment) (res []store.Comment) {
|
||||
for _, c := range comments {
|
||||
if a.dataService.IsBlocked(c.Locator, c.User.ID) {
|
||||
|
||||
@@ -57,6 +57,7 @@ func (t *Tree) filter(comments []store.Comment, parentID string) (f []store.Comm
|
||||
return f
|
||||
}
|
||||
|
||||
// sort list of nodes, i.e. top-level comments
|
||||
func (t *Tree) sortNodes(sortType string) {
|
||||
|
||||
sort.Slice(t.Nodes, func(i, j int) bool {
|
||||
|
||||
@@ -60,7 +60,7 @@ func Limiter(recSec int, excludeIps ...string) func(http.Handler) http.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
// AppInfo adds custom app-info to header
|
||||
// AppInfo adds custom app-info to the response header
|
||||
func AppInfo(app string, version string) func(http.Handler) http.Handler {
|
||||
f := func(h http.Handler) http.Handler {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -77,7 +77,7 @@ func AppInfo(app string, version string) func(http.Handler) http.Handler {
|
||||
return f
|
||||
}
|
||||
|
||||
// Ping middleware response with pong. Stops chain if ping request detected
|
||||
// Ping middleware response with pong to /ping. Stops chain if ping request detected
|
||||
func Ping(next http.Handler) http.Handler {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -104,10 +104,8 @@ func Recoverer(next http.Handler) http.Handler {
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
}()
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -64,6 +64,7 @@ func (s *Server) Run() {
|
||||
// If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler
|
||||
router.Use(context.ClearHandler)
|
||||
|
||||
// auth routes for all providers
|
||||
router.Route("/auth", func(r chi.Router) {
|
||||
r.Mount("/google", s.AuthGoogle.Routes())
|
||||
r.Mount("/github", s.AuthGithub.Routes())
|
||||
@@ -71,6 +72,7 @@ func (s *Server) Run() {
|
||||
r.Get("/logout", s.AuthGoogle.LogoutHandler) // shortcut, can be any of providers, does the same
|
||||
})
|
||||
|
||||
// api routes
|
||||
router.Route("/api/v1", func(rapi chi.Router) {
|
||||
rapi.Get("/find", s.findCommentsCtrl)
|
||||
rapi.Get("/id/{id}", s.commentByIDCtrl)
|
||||
@@ -78,13 +80,13 @@ func (s *Server) Run() {
|
||||
rapi.Get("/last/{max}", s.lastCommentsCtrl)
|
||||
rapi.Get("/count", s.countCtrl)
|
||||
|
||||
// require auth
|
||||
// protected routes, require auth
|
||||
rapi.With(auth.Auth(s.SessionStore, s.Admins, maybeDevMode(auth.Full))).Group(func(rauth chi.Router) {
|
||||
rauth.Post("/comment", s.createCommentCtrl)
|
||||
rauth.Get("/user", s.userInfoCtrl)
|
||||
rauth.Put("/vote/{id}", s.voteCtrl)
|
||||
|
||||
// require admin
|
||||
// admin routes, admin users only
|
||||
s.mod = admin{dataService: s.DataService, exporter: s.Exporter, respCache: s.respCache}
|
||||
rauth.Mount("/admin", s.mod.routes())
|
||||
})
|
||||
@@ -93,7 +95,6 @@ func (s *Server) Run() {
|
||||
|
||||
router.Get("/robots.txt", func(w http.ResponseWriter, r *http.Request) {
|
||||
render.PlainText(w, r, "User-agent: *\nDisallow: /auth/\nDisallow: /api/\n")
|
||||
|
||||
})
|
||||
s.addFileServer(router, "/web", http.Dir(filepath.Join(".", "web")))
|
||||
|
||||
|
||||
+14
-12
@@ -60,24 +60,25 @@ type Interface interface {
|
||||
|
||||
// Accessor defines all usual access ops avail for regular user
|
||||
type Accessor interface {
|
||||
Create(comment Comment) (commentID string, err error)
|
||||
Get(locator Locator, commentID string) (comment Comment, err error)
|
||||
Put(locator Locator, comment Comment) error
|
||||
Find(request Request) ([]Comment, error)
|
||||
Last(locator Locator, max int) ([]Comment, error)
|
||||
GetByID(locator Locator, commentID string) (Comment, error)
|
||||
GetByUser(locator Locator, userID string) ([]Comment, error)
|
||||
Count(locator Locator) (int, error)
|
||||
List(locator Locator) ([]string, error)
|
||||
Create(comment Comment) (commentID string, err error) // create new comment, avoid dups by ID
|
||||
Get(locator Locator, commentID string) (comment Comment, err error) // get comment by ID
|
||||
Put(locator Locator, comment Comment) error // update comment, mutable parts only
|
||||
Find(request Request) ([]Comment, error) // find comments for request
|
||||
Last(locator Locator, max int) ([]Comment, error) // last comments for given site
|
||||
GetByID(locator Locator, commentID string) (Comment, error) // comment by id
|
||||
GetByUser(locator Locator, userID string) ([]Comment, error) // comment by user
|
||||
Count(locator Locator) (int, error) // number of comments for the post
|
||||
List(locator Locator) ([]string, error) // list of commented posts
|
||||
}
|
||||
|
||||
// Admin defines all store ops avail for admin only
|
||||
type Admin interface {
|
||||
Delete(locator Locator, commentID string) error
|
||||
SetBlock(locator Locator, userID string, status bool) error
|
||||
IsBlocked(locator Locator, userID string) bool
|
||||
Delete(locator Locator, commentID string) error // delete comment by id
|
||||
SetBlock(locator Locator, userID string, status bool) error // block or unblock user
|
||||
IsBlocked(locator Locator, userID string) bool // check if user blocked
|
||||
}
|
||||
|
||||
// makeCommentID generates sha1(random) string
|
||||
func makeCommentID() string {
|
||||
b := make([]byte, 64)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
@@ -90,6 +91,7 @@ func makeCommentID() string {
|
||||
return fmt.Sprintf("%x", s.Sum(nil))
|
||||
}
|
||||
|
||||
// clean dangerous html/js from the comment
|
||||
func sanitizeComment(comment Comment) Comment {
|
||||
p := bluemonday.UGCPolicy()
|
||||
comment.Text = p.Sanitize(comment.Text)
|
||||
|
||||
Reference in New Issue
Block a user