mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-19 12:36:23 -07:00
Add is_secure_tripcode column to posts and update gochan-migration to add it
This commit is contained in:
parent
ffac903eb5
commit
4c0ce122ad
16 changed files with 182 additions and 90 deletions
|
@ -201,24 +201,25 @@ type IPBanAppealAudit struct {
|
|||
|
||||
// table: DBPREFIXposts
|
||||
type Post struct {
|
||||
ID int `json:"no"` // sql: id
|
||||
ThreadID int `json:"-"` // sql: thread_id
|
||||
IsTopPost bool `json:"-"` // sql: is_top_post
|
||||
IP string `json:"-"` // sql: ip
|
||||
CreatedOn time.Time `json:"time"` // sql: created_on
|
||||
Name string `json:"name"` // sql: name
|
||||
Tripcode string `json:"trip"` // sql: tripcode
|
||||
IsRoleSignature bool `json:"-"` // sql: is_role_signature
|
||||
Email string `json:"email"` // sql: email
|
||||
Subject string `json:"sub"` // sql: subject
|
||||
Message template.HTML `json:"-"` // sql: message
|
||||
MessageRaw string `json:"com"` // sql: message_raw
|
||||
Password string `json:"-"` // sql: `password`
|
||||
DeletedAt time.Time `json:"-"` // sql: deleted_at
|
||||
IsDeleted bool `json:"-"` // sql: is_deleted
|
||||
BannedMessage string `json:"-"` // sql: banned_message
|
||||
Flag string `json:"-"` // sql: flag
|
||||
Country string `json:"-"` // sql: country
|
||||
ID int `json:"no"` // sql: id
|
||||
ThreadID int `json:"-"` // sql: thread_id
|
||||
IsTopPost bool `json:"-"` // sql: is_top_post
|
||||
IP string `json:"-"` // sql: ip
|
||||
CreatedOn time.Time `json:"time"` // sql: created_on
|
||||
Name string `json:"name"` // sql: name
|
||||
Tripcode string `json:"trip"` // sql: tripcode
|
||||
IsSecureTripcode bool `json:"-"` // sql: is_secure_tripcode
|
||||
IsRoleSignature bool `json:"-"` // sql: is_role_signature
|
||||
Email string `json:"email"` // sql: email
|
||||
Subject string `json:"sub"` // sql: subject
|
||||
Message template.HTML `json:"-"` // sql: message
|
||||
MessageRaw string `json:"com"` // sql: message_raw
|
||||
Password string `json:"-"` // sql: `password`
|
||||
DeletedAt time.Time `json:"-"` // sql: deleted_at
|
||||
IsDeleted bool `json:"-"` // sql: is_deleted
|
||||
BannedMessage string `json:"-"` // sql: banned_message
|
||||
Flag string `json:"-"` // sql: flag
|
||||
Country string `json:"-"` // sql: country
|
||||
|
||||
// used for convenience to avoid needing to do multiple queries
|
||||
opID int
|
||||
|
|
|
@ -77,44 +77,6 @@ func TestMarshalJSON(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNameParsing(t *testing.T) {
|
||||
testCases := []struct {
|
||||
nameAndTrip string
|
||||
expectedName string
|
||||
expectedTripcode string
|
||||
}{
|
||||
{
|
||||
nameAndTrip: "Name#Trip",
|
||||
expectedName: "Name",
|
||||
expectedTripcode: "piec1MorXg",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "#Trip",
|
||||
expectedName: "",
|
||||
expectedTripcode: "piec1MorXg",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "Name",
|
||||
expectedName: "Name",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "Name#",
|
||||
expectedName: "Name",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "#",
|
||||
expectedName: "",
|
||||
},
|
||||
}
|
||||
for _, tC := range testCases {
|
||||
t.Run(tC.nameAndTrip, func(t *testing.T) {
|
||||
name, trip := ParseName(tC.nameAndTrip)
|
||||
assert.Equal(t, tC.expectedName, name)
|
||||
assert.Equal(t, tC.expectedTripcode, trip)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRealIP(t *testing.T) {
|
||||
const remoteAddr = "192.168.56.1"
|
||||
const testIP = "192.168.56.2"
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aquilax/tripcode"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
x_html "golang.org/x/net/html"
|
||||
)
|
||||
|
@ -147,22 +146,6 @@ func MarshalJSON(data any, indent bool) (string, error) {
|
|||
return string(jsonBytes), err
|
||||
}
|
||||
|
||||
// ParseName takes a name string from a request object and returns the name and tripcode parts
|
||||
func ParseName(name string) (string, string) {
|
||||
var namePart string
|
||||
var tripcodePart string
|
||||
if !strings.Contains(name, "#") {
|
||||
namePart = name
|
||||
} else if strings.Index(name, "#") == 0 {
|
||||
tripcodePart = tripcode.Tripcode(name[1:])
|
||||
} else if strings.Index(name, "#") > 0 {
|
||||
postNameArr := strings.SplitN(name, "#", 2)
|
||||
namePart = postNameArr[0]
|
||||
tripcodePart = tripcode.Tripcode(postNameArr[1])
|
||||
}
|
||||
return namePart, tripcodePart
|
||||
}
|
||||
|
||||
// RandomString returns a randomly generated string of the given length
|
||||
func RandomString(length int) string {
|
||||
var str string
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package posting
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aquilax/tripcode"
|
||||
"github.com/gochan-org/gochan/pkg/building"
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/events"
|
||||
|
@ -170,7 +172,43 @@ func getEmailAndCommand(request *http.Request) (string, string) {
|
|||
return formEmail[:sepIndex], formEmail[sepIndex+1:]
|
||||
}
|
||||
|
||||
func getPostFromRequest(request *http.Request, infoEv, errEv *zerolog.Event) (post *gcsql.Post, err error) {
|
||||
// ParseName takes a name and board string and returns the name and tripcode parts,
|
||||
// using the board's reserved tripcodes if applicable.
|
||||
func ParseName(name string, boardConfig *config.BoardConfig) (string, string) {
|
||||
var namePart string
|
||||
var tripcodePart string
|
||||
var secure bool
|
||||
if strings.Contains(name, "##") {
|
||||
parts := strings.SplitN(name, "##", 2)
|
||||
namePart = parts[0]
|
||||
tripcodePart = parts[1]
|
||||
secure = true
|
||||
} else if strings.Contains(name, "#") {
|
||||
parts := strings.SplitN(name, "#", 2)
|
||||
namePart = parts[0]
|
||||
tripcodePart = parts[1]
|
||||
} else {
|
||||
namePart = name
|
||||
}
|
||||
|
||||
if tripcodePart != "" {
|
||||
reservedTrip, reserved := boardConfig.ReservedTrips[tripcodePart]
|
||||
if secure && reserved {
|
||||
tripcodePart = reservedTrip
|
||||
} else if secure {
|
||||
hash := gcutil.Md5Sum(tripcodePart + config.GetSystemCriticalConfig().RandomSeed)
|
||||
for range 64 {
|
||||
hash = gcutil.Md5Sum(hash + name)
|
||||
}
|
||||
tripcodePart = base64.StdEncoding.EncodeToString([]byte(hash))[:10]
|
||||
} else {
|
||||
tripcodePart = tripcode.Tripcode(tripcodePart)
|
||||
}
|
||||
}
|
||||
return namePart, tripcodePart
|
||||
}
|
||||
|
||||
func getPostFromRequest(request *http.Request, boardConfig *config.BoardConfig, infoEv, errEv *zerolog.Event) (post *gcsql.Post, err error) {
|
||||
post = &gcsql.Post{
|
||||
IP: gcutil.GetRealIP(request),
|
||||
Subject: request.PostFormValue("postsubject"),
|
||||
|
@ -197,7 +235,8 @@ func getPostFromRequest(request *http.Request, infoEv, errEv *zerolog.Event) (po
|
|||
}
|
||||
}
|
||||
}
|
||||
post.Name, post.Tripcode = gcutil.ParseName(request.PostFormValue("postname"))
|
||||
post.Name, post.Tripcode = ParseName(request.PostFormValue("postname"), boardConfig)
|
||||
post.IsSecureTripcode = strings.Contains(post.Tripcode, "##")
|
||||
post.Email, _ = getEmailAndCommand(request)
|
||||
|
||||
password := request.PostFormValue("postpassword")
|
||||
|
@ -300,12 +339,6 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
post, err := getPostFromRequest(request, infoEv, errEv)
|
||||
if err != nil {
|
||||
server.ServeError(writer, err.Error(), wantsJSON, nil)
|
||||
return
|
||||
}
|
||||
|
||||
boardidStr := request.PostFormValue("boardid")
|
||||
boardID, err := strconv.Atoi(boardidStr)
|
||||
if err != nil {
|
||||
|
@ -335,6 +368,12 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
post, err := getPostFromRequest(request, boardConfig, infoEv, errEv)
|
||||
if err != nil {
|
||||
server.ServeError(writer, err.Error(), wantsJSON, nil)
|
||||
return
|
||||
}
|
||||
|
||||
if boardConfig.MaxMessageLength > 0 && len(post.MessageRaw) > boardConfig.MaxMessageLength {
|
||||
warnEv.
|
||||
Int("messageLength", len(post.MessageRaw)).
|
||||
|
|
67
pkg/posting/post_test.go
Normal file
67
pkg/posting/post_test.go
Normal file
|
@ -0,0 +1,67 @@
|
|||
package posting
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type parseNameTestCase struct {
|
||||
nameAndTrip string
|
||||
expectedName string
|
||||
expectedTripcode string
|
||||
}
|
||||
|
||||
func TestParseName(t *testing.T) {
|
||||
config.SetVersion("4.1")
|
||||
boardConfig := config.GetBoardConfig("test")
|
||||
boardConfig.ReservedTrips = map[string]string{
|
||||
"reserved": "TripOut",
|
||||
}
|
||||
config.SetBoardConfig("test", boardConfig)
|
||||
|
||||
config.SetRandomSeed("lol")
|
||||
|
||||
testCases := []parseNameTestCase{
|
||||
{
|
||||
nameAndTrip: "Name#Trip",
|
||||
expectedName: "Name",
|
||||
expectedTripcode: "piec1MorXg",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "#Trip",
|
||||
expectedName: "",
|
||||
expectedTripcode: "piec1MorXg",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "Name",
|
||||
expectedName: "Name",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "Name#",
|
||||
expectedName: "Name",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "#",
|
||||
expectedName: "",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "Name##reserved",
|
||||
expectedName: "Name",
|
||||
expectedTripcode: "TripOut",
|
||||
},
|
||||
{
|
||||
nameAndTrip: "Name##notReserved",
|
||||
expectedName: "Name",
|
||||
expectedTripcode: "MDlhNmNmYj",
|
||||
},
|
||||
}
|
||||
for _, tC := range testCases {
|
||||
t.Run(tC.nameAndTrip, func(t *testing.T) {
|
||||
name, trip := ParseName(tC.nameAndTrip, boardConfig)
|
||||
assert.Equal(t, tC.expectedName, name)
|
||||
assert.Equal(t, tC.expectedTripcode, trip)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue