simplify code, smaller functions
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# remark [](http://drone.umputun.com:9080/umputun/remark)
|
||||
|
||||
Remark ia a comment engine, self-hosted. Lightweight, simple (but functional) and doesn't spy on users.
|
||||
Remark ia a comment engine, self-hosted, lightweight, simple (but functional) and doesn't spy on users.
|
||||
|
||||
- Supports social login via google and github
|
||||
- Moderation allowing admins to remove comments and block users
|
||||
|
||||
@@ -61,7 +61,7 @@ func initProvider(p Params, provider Provider) *Provider {
|
||||
func (p Provider) LoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// make state (random) and store in session
|
||||
state := randToken()
|
||||
state := p.randToken()
|
||||
session, err := p.Get(r, "remark")
|
||||
if err != nil {
|
||||
log.Printf("[DEBUG] can't get session, %s", err)
|
||||
@@ -174,7 +174,7 @@ func (p Provider) LogoutHandler(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("[DEBUG] logout, %+v", session.Values)
|
||||
}
|
||||
|
||||
func randToken() string {
|
||||
func (p Provider) randToken() string {
|
||||
b := make([]byte, 32)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
log.Fatalf("[ERROR] can't get randoms, %s", err)
|
||||
|
||||
@@ -22,8 +22,16 @@ const (
|
||||
Full // real auth
|
||||
)
|
||||
|
||||
var devUser = store.User{
|
||||
ID: "dev",
|
||||
Name: "developer one",
|
||||
Picture: "https://friends.radio-t.com/resources/images/rt_logo_64.png",
|
||||
Profile: "https://radio-t.com/info/",
|
||||
Admin: true,
|
||||
}
|
||||
|
||||
// Auth middleware adds auth from session and populates user info
|
||||
func Auth(sessionStore *sessions.FilesystemStore, admins []string, modes ...Mode) func(http.Handler) http.Handler {
|
||||
func Auth(sessionStore *sessions.FilesystemStore, admins []string, modes []Mode) func(http.Handler) http.Handler {
|
||||
|
||||
inModes := func(mode Mode) bool {
|
||||
for _, m := range modes {
|
||||
@@ -39,13 +47,7 @@ func Auth(sessionStore *sessions.FilesystemStore, admins []string, modes ...Mode
|
||||
|
||||
// for dev mode skip all real auth, make dev admin user
|
||||
if inModes(Developer) {
|
||||
user := store.User{
|
||||
ID: "dev",
|
||||
Name: "developer one",
|
||||
Picture: "https://friends.radio-t.com/resources/images/rt_logo_64.png",
|
||||
Profile: "https://radio-t.com/info/",
|
||||
Admin: true,
|
||||
}
|
||||
user := devUser
|
||||
ctx := r.Context()
|
||||
ctx = context.WithValue(ctx, contextKey("user"), user)
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
+33
-28
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/umputun/remark/app/store"
|
||||
)
|
||||
|
||||
// Tree is formatter as comment tree list of comments
|
||||
// Tree is formatter making tree from list of comments
|
||||
type Tree struct {
|
||||
Nodes []*Node `json:"comments"`
|
||||
}
|
||||
@@ -19,40 +19,22 @@ type Node struct {
|
||||
}
|
||||
|
||||
// MakeTree gets unsorted list of comments and produces Tree
|
||||
func MakeTree(comments []store.Comment, sortType string) (res Tree) {
|
||||
res = Tree{}
|
||||
func MakeTree(comments []store.Comment, sortType string) *Tree {
|
||||
res := Tree{}
|
||||
|
||||
repComments := res.filter(comments, func(c store.Comment) bool { return c.ParentID == "" })
|
||||
repComments := res.filter(comments, "")
|
||||
for _, rc := range repComments {
|
||||
node := Node{Comment: rc}
|
||||
res.Nodes = append(res.Nodes, res.proc(comments, &node, rc.ID))
|
||||
}
|
||||
|
||||
// sort result according to sortType
|
||||
sort.Slice(res.Nodes, func(i, j int) bool {
|
||||
switch sortType {
|
||||
case "+time", "-time", "time":
|
||||
if strings.HasPrefix(sortType, "-") {
|
||||
return res.Nodes[i].Comment.Timestamp.After(res.Nodes[j].Comment.Timestamp)
|
||||
}
|
||||
return res.Nodes[i].Comment.Timestamp.Before(res.Nodes[j].Comment.Timestamp)
|
||||
|
||||
case "+score", "-score", "score":
|
||||
if strings.HasPrefix(sortType, "-") {
|
||||
return res.Nodes[i].Comment.Score > res.Nodes[j].Comment.Score
|
||||
}
|
||||
return res.Nodes[i].Comment.Score < res.Nodes[j].Comment.Score
|
||||
|
||||
default:
|
||||
return res.Nodes[i].Comment.Timestamp.Before(res.Nodes[j].Comment.Timestamp)
|
||||
}
|
||||
})
|
||||
|
||||
return res
|
||||
res.sortNodes(sortType)
|
||||
return &res
|
||||
}
|
||||
|
||||
// proc makes tree for one top-level comment recursively
|
||||
func (t *Tree) proc(comments []store.Comment, node *Node, parentID string) *Node {
|
||||
repComments := t.filter(comments, func(c store.Comment) bool { return c.ParentID == parentID })
|
||||
repComments := t.filter(comments, parentID)
|
||||
for _, rc := range repComments {
|
||||
rnode := &Node{Comment: rc, Replies: []*Node{}}
|
||||
node.Replies = append(node.Replies, rnode)
|
||||
@@ -66,11 +48,34 @@ func (t *Tree) proc(comments []store.Comment, node *Node, parentID string) *Node
|
||||
return node
|
||||
}
|
||||
|
||||
func (t *Tree) filter(comments []store.Comment, fn func(c store.Comment) bool) (f []store.Comment) {
|
||||
// filter returns comments for parentID
|
||||
func (t *Tree) filter(comments []store.Comment, parentID string) (f []store.Comment) {
|
||||
for _, c := range comments {
|
||||
if fn(c) {
|
||||
if c.ParentID == parentID {
|
||||
f = append(f, c)
|
||||
}
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (t *Tree) sortNodes(sortType string) {
|
||||
|
||||
sort.Slice(t.Nodes, func(i, j int) bool {
|
||||
switch sortType {
|
||||
case "+time", "-time", "time":
|
||||
if strings.HasPrefix(sortType, "-") {
|
||||
return t.Nodes[i].Comment.Timestamp.After(t.Nodes[j].Comment.Timestamp)
|
||||
}
|
||||
return t.Nodes[i].Comment.Timestamp.Before(t.Nodes[j].Comment.Timestamp)
|
||||
|
||||
case "+score", "-score", "score":
|
||||
if strings.HasPrefix(sortType, "-") {
|
||||
return t.Nodes[i].Comment.Score > t.Nodes[j].Comment.Score
|
||||
}
|
||||
return t.Nodes[i].Comment.Score < t.Nodes[j].Comment.Score
|
||||
|
||||
default:
|
||||
return t.Nodes[i].Comment.Timestamp.Before(t.Nodes[j].Comment.Timestamp)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func TestStore_MakeTree(t *testing.T) {
|
||||
err := enc.Encode(res)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, expJSON, string(buf.Bytes()))
|
||||
t.Log(string(buf.Bytes()))
|
||||
// t.Log(string(buf.Bytes()))
|
||||
}
|
||||
|
||||
const expJSON = `{
|
||||
|
||||
+6
-2
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/gorilla/context"
|
||||
"github.com/gorilla/sessions"
|
||||
|
||||
"github.com/umputun/remark/app/migrator"
|
||||
@@ -51,9 +52,12 @@ func (s *Server) Run() {
|
||||
router := chi.NewRouter()
|
||||
router.Use(middleware.RealIP, Recoverer)
|
||||
router.Use(middleware.Throttle(1000), middleware.Timeout(60*time.Second))
|
||||
router.Use(auth.Auth(s.SessionStore, s.Admins, applyDevMode(auth.Anonymous)...))
|
||||
router.Use(auth.Auth(s.SessionStore, s.Admins, applyDevMode(auth.Anonymous)))
|
||||
router.Use(Limiter(10), AppInfo("remark", s.Version), Ping, Logger(LogAll))
|
||||
|
||||
// If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler
|
||||
router.Use(context.ClearHandler)
|
||||
|
||||
router.Get("/login/google", s.AuthGoogle.LoginHandler)
|
||||
router.Get("/auth/google", s.AuthGoogle.AuthHandler)
|
||||
router.Get("/logout", s.AuthGithub.LogoutHandler) // can hit any provider
|
||||
@@ -66,7 +70,7 @@ func (s *Server) Run() {
|
||||
rapi.Get("/last/{max}", s.lastCommentsCtrl)
|
||||
rapi.Get("/count", s.countCtrl)
|
||||
|
||||
rapi.With(auth.Auth(s.SessionStore, s.Admins, applyDevMode(auth.Full)...)).Group(func(rauth chi.Router) {
|
||||
rapi.With(auth.Auth(s.SessionStore, s.Admins, applyDevMode(auth.Full))).Group(func(rauth chi.Router) {
|
||||
rauth.Post("/comment", s.createCommentCtrl)
|
||||
rauth.Get("/user", s.userInfoCtrl)
|
||||
rauth.Put("/vote/{id}", s.voteCtrl)
|
||||
|
||||
Reference in New Issue
Block a user