filled in the slippage code and permission checks on posting
This commit is contained in:
+68
-5
@@ -558,6 +558,8 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
||||
// Locate community, conference, and topic.
|
||||
comm := ctxt.CurrentCommunity()
|
||||
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
||||
level := ctxt.GetScratch("levelInConference").(uint16)
|
||||
|
||||
var topic *database.Topic = nil
|
||||
if rawTopic, err := strconv.ParseInt(ctxt.URLParam("topic"), 10, 16); err == nil {
|
||||
topic, err = database.AmGetTopicByNumber(ctxt.Ctx(), conf, int16(rawTopic))
|
||||
@@ -571,6 +573,22 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
||||
if ctxt.FormFieldIsSet("cancel") {
|
||||
return "redirect", urlStem, nil
|
||||
}
|
||||
|
||||
if !conf.TestPermission("Conference.Post", level) {
|
||||
ctxt.SetRC(http.StatusForbidden)
|
||||
return ui.ErrorPage(ctxt, errors.New("you do not have permission to post in this conference"))
|
||||
}
|
||||
|
||||
if topic.Frozen && !conf.TestPermission("Conference.Hide", level) {
|
||||
ctxt.SetRC(http.StatusForbidden)
|
||||
return ui.ErrorPage(ctxt, errors.New("this topic is frozen, and you do not have permission to post to it"))
|
||||
}
|
||||
|
||||
if topic.Archived && !conf.TestPermission("Conference.Hide", level) {
|
||||
ctxt.SetRC(http.StatusForbidden)
|
||||
return ui.ErrorPage(ctxt, errors.New("this topic is archived, and you do not have permission to post to it"))
|
||||
}
|
||||
|
||||
if ctxt.FormFieldIsSet("preview") {
|
||||
// Preview the post.
|
||||
checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "escaper")
|
||||
@@ -595,7 +613,7 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
||||
if err != nil {
|
||||
return ui.ErrorPage(ctxt, err)
|
||||
}
|
||||
checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), conf.TopTopic+1))
|
||||
checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), topic.Number))
|
||||
checker.Append(postdata)
|
||||
checker.Finish()
|
||||
v, _ = checker.Value()
|
||||
@@ -628,8 +646,51 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
||||
}
|
||||
if int32(maxPost) < topic.TopMessage {
|
||||
// Slippage detected! Display the slipped posts and another post box.
|
||||
// TODO
|
||||
return "framed_template", "???", nil
|
||||
// Get the slipped posts.
|
||||
posts, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(maxPost), topic.TopMessage)
|
||||
if err != nil {
|
||||
return ui.ErrorPage(ctxt, err)
|
||||
}
|
||||
|
||||
// start with escaping the post data
|
||||
checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "escaper")
|
||||
if err != nil {
|
||||
return ui.ErrorPage(ctxt, err)
|
||||
}
|
||||
checker.Append(ctxt.FormField("pseud"))
|
||||
checker.Finish()
|
||||
v, _ := checker.Value()
|
||||
ctxt.VarMap().Set("pseud", v)
|
||||
|
||||
// escape the data
|
||||
postdata := ctxt.FormField("pb")
|
||||
checker.Reset()
|
||||
checker.Append(postdata)
|
||||
checker.Finish()
|
||||
v, _ = checker.Value()
|
||||
ctxt.VarMap().Set("pb", v)
|
||||
if ctxt.FormFieldIsSet("attach") {
|
||||
ctxt.VarMap().Set("attachFile", true)
|
||||
}
|
||||
|
||||
plc := database.AmCreatePostLinkContext("", ctxt.GetScratch("currentAlias").(string), topic.Number)
|
||||
topicConferenceRef := plc.AsString()
|
||||
plc.Community = comm.Alias
|
||||
topicPostRef := plc.AsString()
|
||||
|
||||
ctxt.VarMap().Set("post_confRef", topicConferenceRef)
|
||||
ctxt.VarMap().SetFunc("post_getOverrideLine", templateOverrideLine)
|
||||
ctxt.VarMap().SetFunc("post_getOverrideLink", templateOverrideLink)
|
||||
ctxt.VarMap().SetFunc("post_getText", templatePostText)
|
||||
ctxt.VarMap().SetFunc("post_getUserName", templateExtractUserName)
|
||||
ctxt.VarMap().Set("post_stem", fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias").(string), topic.Number))
|
||||
ctxt.VarMap().Set("post_max", topic.TopMessage)
|
||||
ctxt.VarMap().Set("post_topicPermalink", fmt.Sprintf("/go/%s", topicPostRef))
|
||||
ctxt.VarMap().Set("posts", posts)
|
||||
ctxt.VarMap().Set("topicName", topic.Name)
|
||||
ctxt.VarMap().Set("amsterdam_pageTitle", "Slippage or Double-Click Detected")
|
||||
|
||||
return "framed_template", "slippage.jet", nil
|
||||
}
|
||||
// start by checking the title and pseud
|
||||
checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-pseud")
|
||||
@@ -645,14 +706,14 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
||||
if err != nil {
|
||||
return ui.ErrorPage(ctxt, err)
|
||||
}
|
||||
checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), conf.TopTopic+1))
|
||||
checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), topic.Number))
|
||||
checker.Append(ctxt.FormField("pb"))
|
||||
checker.Finish()
|
||||
postText, _ := checker.Value()
|
||||
lines, _ := checker.Lines()
|
||||
|
||||
// Add the post!
|
||||
hdr, err := database.AmNewPost(ctxt.Ctx(), conf, topic, ctxt.CurrentUser(), postPseud, postText, int32(lines))
|
||||
hdr, err := database.AmNewPost(ctxt.Ctx(), conf, topic, ctxt.CurrentUser(), postPseud, postText, int32(lines), ctxt.RemoteIP())
|
||||
if err != nil {
|
||||
return ui.ErrorPage(ctxt, err)
|
||||
}
|
||||
@@ -661,6 +722,8 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
||||
return "redirect", returnURL, nil // no attachment - just redisplay topic list
|
||||
}
|
||||
|
||||
// TODO: whoever's subscribed needs to get a copy of this post in their E-mail
|
||||
|
||||
// go upload the attachment
|
||||
ctxt.VarMap().Set("target", returnURL)
|
||||
ctxt.VarMap().Set("post", hdr.PostId)
|
||||
|
||||
@@ -178,6 +178,15 @@ func (c *Conference) Settings(ctx context.Context, u *User) (*ConferenceSettings
|
||||
return &(dbdata[0]), nil
|
||||
}
|
||||
|
||||
// TouchUpdate updates the "last update" date/time in the conference.
|
||||
func (c *Conference) TouchUpdate(ctx context.Context, tx *sqlx.Tx, lastUpdate time.Time) error {
|
||||
_, err := tx.ExecContext(ctx, "UPDATE confs SET lastupdate = ? WHERE confid = ?", lastUpdate, c.ConfId)
|
||||
if err == nil {
|
||||
c.LastUpdate = &lastUpdate
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// TouchRead updates the "last posted" date/time in the conference for the user.
|
||||
func (c *Conference) TouchRead(ctx context.Context, tx *sqlx.Tx, u *User) (*ConferenceSettings, error) {
|
||||
cs, err := c.Settings(ctx, u)
|
||||
|
||||
+16
-3
@@ -128,12 +128,17 @@ func AmGetPostRange(ctx context.Context, topic *Topic, first, last int32) ([]*Po
|
||||
* pseud - Pseud for the new post.
|
||||
* post - New post text.
|
||||
* postLines - Number of lines in the post text.
|
||||
* ipaddr - IP address of user maing the post.
|
||||
* Returns:
|
||||
* New post header pointer.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func AmNewPost(ctx context.Context, conf *Conference, topic *Topic, user *User, pseud string, post string, postLines int32) (*PostHeader, error) {
|
||||
func AmNewPost(ctx context.Context, conf *Conference, topic *Topic, user *User, pseud string, post string, postLines int32, ipaddr string) (*PostHeader, error) {
|
||||
success := false
|
||||
var ar *AuditRecord = nil
|
||||
defer func() {
|
||||
AmStoreAudit(ar)
|
||||
}()
|
||||
tx := amdb.MustBegin()
|
||||
defer func() {
|
||||
if !success {
|
||||
@@ -141,7 +146,7 @@ func AmNewPost(ctx context.Context, conf *Conference, topic *Topic, user *User,
|
||||
}
|
||||
}()
|
||||
unlock := true
|
||||
tx.ExecContext(ctx, "LOCK TABLES topics WRITE, topicsettings WRITE, posts WRITE, postdata WRITE;")
|
||||
tx.ExecContext(ctx, "LOCK TABLES confs WRITE, topics WRITE, topicsettings WRITE, posts WRITE, postdata WRITE;")
|
||||
defer func() {
|
||||
if unlock {
|
||||
tx.ExecContext(ctx, "UNLOCK TABLES;")
|
||||
@@ -189,7 +194,10 @@ func AmNewPost(ctx context.Context, conf *Conference, topic *Topic, user *User,
|
||||
tx.ExecContext(ctx, "UNLOCK TABLES;")
|
||||
unlock = false
|
||||
|
||||
// update the "last posted" date in the conference settings
|
||||
// update the "last update" date of the conference and the "last posted" date in the conference settings
|
||||
if err = conf.TouchUpdate(ctx, tx, hdr.Posted); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = conf.TouchPost(ctx, tx, user, hdr.Posted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -199,5 +207,10 @@ func AmNewPost(ctx context.Context, conf *Conference, topic *Topic, user *User,
|
||||
return nil, err
|
||||
}
|
||||
success = true
|
||||
|
||||
// create audit record
|
||||
ar = AmNewAudit(AuditConferencePostMessage, user.Uid, ipaddr, fmt.Sprintf("confid=%d", conf.ConfId),
|
||||
fmt.Sprintf("topic=%d", topic.Number), fmt.Sprintf("post=%d", hdr.PostId), fmt.Sprintf("pseud=%s", *hdr.Pseud))
|
||||
|
||||
return hdr, nil
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
{{ m = map("post_cur", p, "post_userName", post_getUserName(p, .), "post_text", post_getText(p, .),
|
||||
"post_overrideLine", post_getOverrideLine(p, .), "post_overrideLink", post_getOverrideLink(p, post_topicPermalink)) }}
|
||||
{{ .SubRender2("singlepost.jet", m) | raw }}
|
||||
{{ if pin == p.Num }}<hr/>{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
@@ -34,8 +33,8 @@
|
||||
|
||||
<!-- Posting Form -->
|
||||
<div class="max-w-3xl">
|
||||
<form method="POST" action="{{ urlStem }}">
|
||||
<input type="hidden" name="xp" value="{{ maxPost }}"/>
|
||||
<form method="POST" action="{{ post_stem }}">
|
||||
<input type="hidden" name="xp" value="{{ post_max }}"/>
|
||||
<div class="bg-gray-50 p-6 rounded-lg space-y-4">
|
||||
<!-- Your Name/Header and Attach File -->
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user