summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Minko <vitaly.minko@gmail.com>2019-06-05 13:26:09 +0300
committerVitaly Minko <vitaly.minko@gmail.com>2019-06-05 13:26:09 +0300
commitd9dcba96af25bfa8cc8b43652335a2677c4b78ec (patch)
tree270b7d96ca65e378cf20ba806cd05ade3d5028db
parentba92d3e6cc48f562cc957984081201ccf2047174 (diff)
Fixed several minor bugs.
-rw-r--r--cmd/dscuss-web/controller/board_handlers.go16
-rw-r--r--cmd/dscuss-web/controller/login_handlers.go13
-rw-r--r--cmd/dscuss-web/controller/reply_handlers.go24
-rw-r--r--cmd/dscuss-web/controller/thread_handlers.go7
-rw-r--r--cmd/dscuss-web/main.go5
-rw-r--r--cmd/dscuss-web/view/reply.go4
-rw-r--r--cmd/dscuss-web/view/thread.go2
-rw-r--r--entity/entity.go4
-rw-r--r--entity/message.go13
-rw-r--r--entity/user.go5
10 files changed, 52 insertions, 41 deletions
diff --git a/cmd/dscuss-web/controller/board_handlers.go b/cmd/dscuss-web/controller/board_handlers.go
index 6fdb436..a02a5f7 100644
--- a/cmd/dscuss-web/controller/board_handlers.go
+++ b/cmd/dscuss-web/controller/board_handlers.go
@@ -28,15 +28,9 @@ import (
)
func boardHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle, s *Session) {
- type Thread struct {
- ID string
- Topic string
- Subject string
- Text string
- DateWritten string
- AuthorName string
- AuthorID string
- AuthorShortID string
+ if len(r.URL.Query()) > 1 {
+ BadRequestHandler(w, r, "Wrong number of query parameters")
+ return
}
var validURI = regexp.MustCompile("^/board(topic=[a-z,]*)?$")
m := validURI.FindStringSubmatch(r.URL.Path)
@@ -66,9 +60,9 @@ func boardHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle,
log.Fatal("Can't list board: " + err.Error() + ".")
}
- var threads []Thread
+ var threads []RootMessage
for _, msg := range messages {
- threads = append(threads, Thread{})
+ threads = append(threads, RootMessage{})
t := &threads[len(threads)-1]
t.ID = msg.ID().String()
t.Topic = msg.Topic.String()
diff --git a/cmd/dscuss-web/controller/login_handlers.go b/cmd/dscuss-web/controller/login_handlers.go
index bd1c907..6d4d079 100644
--- a/cmd/dscuss-web/controller/login_handlers.go
+++ b/cmd/dscuss-web/controller/login_handlers.go
@@ -20,21 +20,18 @@ import (
"html/template"
"net/http"
"net/url"
- "regexp"
"vminko.org/dscuss"
"vminko.org/dscuss/cmd/dscuss-web/view"
+ "vminko.org/dscuss/entity"
)
const (
- maxUsernameLength = 64
- maxPasswordLength = 64
+ MaxPasswordLen = 64
)
func loginHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle, s *Session) {
- var validURI = regexp.MustCompile("^/login(\\?next=[a-zA-Z0-9\\/+=]+)?$")
- m := validURI.FindStringSubmatch(r.URL.Path)
- if m == nil {
- NotFoundHandler(w, r)
+ if len(r.URL.Query()) > 1 {
+ BadRequestHandler(w, r, "Wrong number of query parameters")
return
}
var err error
@@ -54,7 +51,7 @@ func loginHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle,
if r.Method == "POST" {
user := r.PostFormValue("username")
pass := r.PostFormValue("password")
- if len(user) > maxUsernameLength || len(pass) > maxPasswordLength {
+ if len(user) > entity.MaxUsernameLen || len(pass) > MaxPasswordLen {
msg = "Specified username or password is too long."
} else if err = s.Authenticate(l, user, pass); err != nil {
msg = err.Error()
diff --git a/cmd/dscuss-web/controller/reply_handlers.go b/cmd/dscuss-web/controller/reply_handlers.go
index ceb6744..27add9e 100644
--- a/cmd/dscuss-web/controller/reply_handlers.go
+++ b/cmd/dscuss-web/controller/reply_handlers.go
@@ -17,9 +17,9 @@ this program. If not, see <http://www.gnu.org/licenses/>.
package controller
import (
+ "fmt"
"net/http"
"net/url"
- "regexp"
"vminko.org/dscuss"
"vminko.org/dscuss/cmd/dscuss-web/view"
"vminko.org/dscuss/entity"
@@ -27,15 +27,9 @@ import (
"vminko.org/dscuss/log"
)
-const (
- maxSubjectLength = 128
- maxTextLength = 1024
-)
-
func replyHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle, s *Session) {
- var validURI = regexp.MustCompile("^/reply(\\?id=[a-zA-Z0-9\\/+=]+)?$")
- if validURI.FindStringSubmatch(r.URL.Path) == nil {
- NotFoundHandler(w, r)
+ if len(r.URL.Query()) != 1 {
+ BadRequestHandler(w, r, "Wrong number of query parameters")
return
}
if !s.IsAuthenticated {
@@ -54,7 +48,7 @@ func replyHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle,
var pid entity.ID
err := pid.ParseString(pidStr)
if err != nil {
- BadRequestHandler(w, r, pidStr+" is not a valid entity ID.")
+ BadRequestHandler(w, r, "'"+pidStr+"' is not a valid entity ID.")
return
}
@@ -82,8 +76,12 @@ func replyHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle,
if r.Method == "POST" {
rpl.Subject = r.PostFormValue("subject")
rpl.Text = r.PostFormValue("text")
- if len(rpl.Subject) > maxSubjectLength || len(rpl.Text) > maxTextLength {
- msg = "Specified subject or text is too long."
+ if (rpl.Subject == "") || (len(rpl.Subject) > entity.MaxSubjectLen) {
+ msg = "Specified subject is unacceptable: empty or too long."
+ goto render
+ }
+ if (rpl.Text == "") || (len(rpl.Text) > entity.MaxTextLen) {
+ msg = "Specified message text is unacceptable: empty or too long."
goto render
}
rplMsg, err := l.NewReply(rpl.Subject, rpl.Text, &pid)
@@ -96,6 +94,8 @@ func replyHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle,
msg = "Error posting new reply: " + err.Error() + "."
goto render
}
+ http.Redirect(w, r, "/thread?id="+url.QueryEscape(rm.ID), http.StatusSeeOther)
+ return
}
render:
view.Render(w, "reply.html", map[string]interface{}{
diff --git a/cmd/dscuss-web/controller/thread_handlers.go b/cmd/dscuss-web/controller/thread_handlers.go
index dbcf023..02dcb55 100644
--- a/cmd/dscuss-web/controller/thread_handlers.go
+++ b/cmd/dscuss-web/controller/thread_handlers.go
@@ -18,7 +18,6 @@ package controller
import (
"net/http"
- "regexp"
"vminko.org/dscuss"
"vminko.org/dscuss/cmd/dscuss-web/view"
"vminko.org/dscuss/entity"
@@ -47,10 +46,8 @@ func (tc *ThreadComposer) Handle(n *thread.Node) bool {
}
func threadHandler(w http.ResponseWriter, r *http.Request, l *dscuss.LoginHandle, s *Session) {
- var validURI = regexp.MustCompile("^/thread(id=[a-zA-Z0-9\\/+=]{32})?$")
- m := validURI.FindStringSubmatch(r.URL.Path)
- if m == nil {
- NotFoundHandler(w, r)
+ if len(r.URL.Query()) != 1 {
+ BadRequestHandler(w, r, "Wrong number of query parameters")
return
}
idStr := r.URL.Query().Get("id")
diff --git a/cmd/dscuss-web/main.go b/cmd/dscuss-web/main.go
index ef06eb7..617540a 100644
--- a/cmd/dscuss-web/main.go
+++ b/cmd/dscuss-web/main.go
@@ -103,6 +103,11 @@ func main() {
fmt.Println("You have to specify a custom password.")
return
}
+ if len(*argPassword) > controller.MaxPasswordLen {
+ fmt.Print("The specified password is too long. ")
+ fmt.Printf("Max password length = %d.\n", controller.MaxPasswordLen)
+ return
+ }
controller.SetPassword(*argPassword)
fmt.Println("Starting Dscuss...")
diff --git a/cmd/dscuss-web/view/reply.go b/cmd/dscuss-web/view/reply.go
index 22450c1..6eb1335 100644
--- a/cmd/dscuss-web/view/reply.go
+++ b/cmd/dscuss-web/view/reply.go
@@ -20,7 +20,7 @@ package view
const replyHTML = `
{{ define "content" }}
-<h2>Reply to <a href="/topic?id={{ .Thread.ID }}">{{ .Thread.Subject }}</a></h2>
+<h2 id="title">Reply to <a href="/thread?id={{ .Thread.ID }}">{{ .Thread.Subject }}</a></h2>
<span class="topic">in <a href="/board?topic={{ .Thread.Topic }}">{{ .Thread.Topic }}</a></span>
{{ if .ShowParentSubject }}
<b>{{ .Parent.Subject }}</b>
@@ -37,7 +37,7 @@ const replyHTML = `
Subject: <input type="text" name="subject" value="{{ .Reply.Subject }}" placeholder="Re: {{.Parent.Subject}}">
<textarea name="text" rows="12">{{ .Reply.Text }}</textarea>
{{ if .Message }}
- <span class="alert">{{ .Message }}</span>
+ <span class="alert">{{ .Message }}</span><br>
{{ end }}
<input type="submit" name="action" class="no-double-post" value="Submit reply">
</form>
diff --git a/cmd/dscuss-web/view/thread.go b/cmd/dscuss-web/view/thread.go
index d241e2e..2c82a75 100644
--- a/cmd/dscuss-web/view/thread.go
+++ b/cmd/dscuss-web/view/thread.go
@@ -52,7 +52,7 @@ const threadHTML = `
{{ if $.Common.IsWritingPermitted }}
| <a href="/ban?id={{ .AuthorID }}">ban</a>
| <a href="/rmmsg?id={{ .ID }}">delete</a>
- | <a href="/reply?id={{ $.ID }}">reply</a>
+ | <a href="/reply?id={{ .ID }}">reply</a>
{{ end }}
</div>
</div>
diff --git a/entity/entity.go b/entity/entity.go
index ad297d9..29188e0 100644
--- a/entity/entity.go
+++ b/entity/entity.go
@@ -77,6 +77,10 @@ func (i *ID) String() string {
}
func (i *ID) ParseString(s string) error {
+ if len(s) != len(i.String()) {
+ log.Warningf("Failed to parse ID string - wrong length (%d)", len(s))
+ return errors.Parsing
+ }
res, err := base64.StdEncoding.DecodeString(s)
copy(i[:], res[:])
return err
diff --git a/entity/message.go b/entity/message.go
index 2358896..c2ad468 100644
--- a/entity/message.go
+++ b/entity/message.go
@@ -55,6 +55,11 @@ type StoredMessage struct {
Stored time.Time
}
+const (
+ MaxSubjectLen = 128
+ MaxTextLen = 1024
+)
+
// EmergeMessage creates a new message. It should be called when owner wants to
// post a new message. Signature will be created using the provided signer.
func EmergeMessage(
@@ -128,6 +133,14 @@ func (um *UnsignedMessage) isValid() bool {
log.Debugf("Message %s has invalid ID", um)
return false
}
+ if len(um.Subject) > MaxSubjectLen {
+ log.Debugf("Message %s has too long subject (%d)", um, len(um.Subject))
+ return false
+ }
+ if len(um.Text) > MaxTextLen {
+ log.Debugf("Message %s has too long text (%d)", um, len(um.Text))
+ return false
+ }
if um.Subject == "" || um.Text == "" {
log.Debugf("Message %s has empty subject or text", um)
return false
diff --git a/entity/user.go b/entity/user.go
index 888f648..6a28e95 100644
--- a/entity/user.go
+++ b/entity/user.go
@@ -60,12 +60,13 @@ type UserHistory struct {
}
const (
- nicknameRegex string = "^[a-zA-Z0-9_]+$"
+ MaxUsernameLen = 64
+ nicknameRegex string = "^[a-zA-Z0-9_]+$"
)
func IsNicknameValid(nickname string) bool {
var nickRe = regexp.MustCompile(nicknameRegex)
- return nickRe.MatchString(nickname)
+ return (len(nickname) <= MaxUsernameLen) && nickRe.MatchString(nickname)
}
// EmergeUser creates a new user entity. It should only be called when