Files
remark42/app/store/comment.go
T
UmputunandGitHub 6aee34bb1e feature/ts - read-only support (#57)
* extend post info with ts and add info implemenation to engine

* info controller

* remove unused

* docker froendly new test

* tree find to include post info struct

* remove leftovers from codeconv

* test for empty tree request

* add func name to error rest report

* test with disabled proxy

* add read only age and reject updates on old posts

* lint: shaddow err

* make info calls fast. needs migration!

* fix backup restore script

* increase limiter timeout

* add local exporter

* migrate list to new info

* fix rest list tests

* add manual backup script

* default backup path

* fix eait on sec change failing rss tests

* add RO status bucket and rest

* add admin RO controller test
2018-05-28 14:57:36 -05:00

104 lines
2.8 KiB
Go

package store
import (
"html/template"
"regexp"
"time"
"github.com/microcosm-cc/bluemonday"
)
// Comment represents a single comment with optional reference to its parent
type Comment struct {
ID string `json:"id"`
ParentID string `json:"pid"`
Text string `json:"text"`
Orig string `json:"orig,omitempty"`
User User `json:"user"`
Locator Locator `json:"locator"`
Score int `json:"score"`
Votes map[string]bool `json:"votes"`
Timestamp time.Time `json:"time"`
Pin bool `json:"pin,omitempty"`
Edit *Edit `json:"edit,omitempty"` // pointer to have empty default in json response
Deleted bool `json:"delete,omitempty"`
}
// Locator keeps site and url of the post
type Locator struct {
SiteID string `json:"site,omitempty"`
URL string `json:"url"`
}
// Edit indication
type Edit struct {
Timestamp time.Time `json:"time"`
Summary string `json:"summary"`
}
// PostInfo holds summary for given post url
type PostInfo struct {
URL string `json:"url"`
Count int `json:"count"`
ReadOnly bool `json:"read_only,omitempty"`
FirstTS time.Time `json:"first_time,omitempty"`
LastTS time.Time `json:"last_time,omitempty"`
}
// BlockedUser holds id and ts for blocked user
type BlockedUser struct {
ID string `json:"id"`
Name string `json:"name"`
Timestamp time.Time `json:"time"`
}
// DeleteMode defines how much comment info will be erased
type DeleteMode int
// DeleteMode enum
const (
SoftDelete DeleteMode = 0
HardDelete DeleteMode = 1
)
// PrepareUntrusted pre-processes a comment received from untrusted source by clearing all
// autogen fields and reset everything users not supposed to provide
func (c *Comment) PrepareUntrusted() {
c.ID = "" // don't allow user to define ID, force auto-gen
c.Timestamp = time.Time{} // reset time, force auto-gen
c.Votes = make(map[string]bool)
c.Score = 0
c.Edit = nil
c.Pin = false
c.Deleted = false
}
// SetDeleted clears comment info, reset to deleted state. hard flag will clear all user info as well
func (c *Comment) SetDeleted(mode DeleteMode) {
c.Text = ""
c.Orig = ""
c.Score = 0
c.Votes = map[string]bool{}
c.Edit = nil
c.Deleted = true
c.Pin = false
if mode == HardDelete {
c.User.Name = "deleted"
c.User.ID = "deleted"
c.User.Picture = ""
c.User.IP = ""
}
}
// Sanitize clean dangerous html/js from the comment
func (c *Comment) Sanitize() {
p := bluemonday.UGCPolicy()
p.AllowAttrs("class").Matching(regexp.MustCompile("^language-[a-zA-Z0-9]+$")).OnElements("code")
c.Text = p.Sanitize(c.Text)
c.Orig = p.Sanitize(c.Orig)
c.User.ID = template.HTMLEscapeString(c.User.ID)
c.User.Name = template.HTMLEscapeString(c.User.Name)
c.User.Picture = p.Sanitize(c.User.Picture)
}