From b1f33c872c63e9cfa240a033df88f7c1e33b94f2 Mon Sep 17 00:00:00 2001 From: bouncepaw Date: Sun, 10 Jan 2021 01:49:48 +0500 Subject: [PATCH] Make account system concurrent-safe and refactor it a little --- flag.go | 2 +- go.mod | 1 + go.sum | 11 ++ history/operations.go | 3 +- http_mutators.go | 6 +- hyphae/hypha.go | 55 +--------- markup/paragraph.go | 5 +- storage/storage.go | 65 ++++++++++++ templates/auth.qtpl | 4 +- templates/auth.qtpl.go | 4 +- templates/common.qtpl | 9 +- templates/common.qtpl.go | 139 ++++++++++++------------- templates/http_readers.qtpl | 2 +- templates/http_readers.qtpl.go | 2 +- user/{fs.go => files.go} | 66 +++++++----- user/group.go | 70 ------------- user/net.go | 75 ++++++++++++++ user/user.go | 180 ++++++++++----------------------- user/users.go | 44 ++++++++ 19 files changed, 385 insertions(+), 358 deletions(-) create mode 100644 storage/storage.go rename user/{fs.go => files.go} (55%) delete mode 100644 user/group.go create mode 100644 user/net.go create mode 100644 user/users.go diff --git a/flag.go b/flag.go index 551e0cf..c2cb461 100644 --- a/flag.go +++ b/flag.go @@ -51,7 +51,7 @@ func parseCliArgs() { case "none": case "fixed": user.AuthUsed = true - user.PopulateFixedUserStorage() + user.ReadUsersFromFilesystem() default: log.Fatal("Error: unknown auth method:", util.AuthMethod) } diff --git a/go.mod b/go.mod index c785b3a..2d5ea15 100644 --- a/go.mod +++ b/go.mod @@ -6,5 +6,6 @@ require ( github.com/adrg/xdg v0.2.2 github.com/gorilla/feeds v1.1.1 github.com/hashicorp/go-memdb v1.3.0 + github.com/kr/pretty v0.2.1 // indirect github.com/valyala/quicktemplate v1.6.3 ) diff --git a/go.sum b/go.sum index 9b58270..b20873b 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,7 @@ github.com/adrg/xdg v0.2.2 h1:A7ZHKRz5KGOLJX/bg7IPzStryhvCzAE1wX+KWawPiAo= github.com/adrg/xdg v0.2.2/go.mod h1:7I2hH/IT30IsupOpKZ5ue7/qNi3CoKzD6tL3HwpaRMQ= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gorilla/feeds v1.1.1 h1:HwKXxqzcRNg9to+BbvJog4+f3s/xzvtZXICcQGutYfY= github.com/gorilla/feeds v1.1.1/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBbaightA= @@ -8,14 +9,22 @@ github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrh github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-memdb v1.3.0 h1:xdXq34gBOMEloa9rlGStLxmfX/dyIK8htOv36dQUwHU= github.com/hashicorp/go-memdb v1.3.0/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -29,5 +38,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/history/operations.go b/history/operations.go index fdc64af..49195b6 100644 --- a/history/operations.go +++ b/history/operations.go @@ -121,8 +121,7 @@ func (hop *HistoryOp) WithMsg(userMsg string) *HistoryOp { // WithUser sets a user for the commit. func (hop *HistoryOp) WithUser(u *user.User) *HistoryOp { - u = u.OrAnon() - if u.Group != user.UserAnon { + if u.Group != "anon" { hop.name = u.Name hop.email = u.Name + "@mycorrhiza" } diff --git a/http_mutators.go b/http_mutators.go index f1cd5da..6927e7f 100644 --- a/http_mutators.go +++ b/http_mutators.go @@ -44,7 +44,7 @@ func handlerRenameConfirm(w http.ResponseWriter, rq *http.Request) { newName = CanonicalName(rq.PostFormValue("new-name")) _, newNameIsUsed = HyphaStorage[newName] recursive = rq.PostFormValue("recursive") == "true" - u = user.FromRequest(rq).OrAnon() + u = user.FromRequest(rq) ) switch { case !u.CanProceed("rename-confirm"): @@ -151,7 +151,7 @@ func handlerUploadText(w http.ResponseWriter, rq *http.Request) { var ( hyphaName = HyphaNameFromRq(rq, "upload-text") textData = rq.PostFormValue("text") - u = user.FromRequest(rq).OrAnon() + u = user.FromRequest(rq) ) if ok := user.CanProceed(rq, "upload-text"); !ok { HttpErr(w, http.StatusForbidden, hyphaName, "Not enough rights", "You must be an editor to edit pages.") @@ -174,7 +174,7 @@ func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) { log.Println(rq.URL) var ( hyphaName = HyphaNameFromRq(rq, "upload-binary") - u = user.FromRequest(rq).OrAnon() + u = user.FromRequest(rq) ) if !u.CanProceed("upload-binary") { HttpErr(w, http.StatusForbidden, hyphaName, "Not enough rights", "You must be an editor to upload attachments.") diff --git a/hyphae/hypha.go b/hyphae/hypha.go index e129355..366fd5a 100644 --- a/hyphae/hypha.go +++ b/hyphae/hypha.go @@ -1,7 +1,7 @@ package hyphae import ( - "github.com/hashicorp/go-memdb" + "github.com/bouncepaw/mycorrhiza/storage" ) type Hypha struct { @@ -15,7 +15,7 @@ type Hypha struct { // AddHypha adds a hypha named `name` with such `textPath` and `binaryPath`. Both paths can be empty. Does //not// check for hypha's existence beforehand. Count is handled. func AddHypha(name, textPath, binaryPath string) { - txn := db.Txn(true) + txn := storage.DB.Txn(true) txn.Insert("hyphae", &Hypha{ Name: name, @@ -31,54 +31,3 @@ func AddHypha(name, textPath, binaryPath string) { // DeleteHypha clears both paths and all out-links from the named hypha and marks it as non-existent. It does not actually delete it from the memdb. Count is handled. func DeleteHypha(name string) { } - -// Create the DB schema -var schema = &memdb.DBSchema{ - Tables: map[string]*memdb.TableSchema{ - "hyphae": &memdb.TableSchema{ - Name: "hyphae", - Indexes: map[string]*memdb.IndexSchema{ - "id": &memdb.IndexSchema{ - Name: "id", - Unique: true, - Indexer: &memdb.StringFieldIndex{Field: "Name"}, - }, - "exists": &memdb.IndexSchema{ - Name: "exists", - Unique: false, - Indexer: &memdb.BoolFieldIndex{Field: "Exists"}, - }, - "text-path": &memdb.IndexSchema{ - Name: "text-path", - Unique: true, - Indexer: &memdb.StringFieldIndex{Field: "TextPath"}, - }, - "binary-path": &memdb.IndexSchema{ - Name: "binary-path", - Unique: true, - Indexer: &memdb.StringFieldIndex{Field: "BinaryPath"}, - }, - "out-links": &memdb.IndexSchema{ - Name: "out-links", - Unique: false, - Indexer: &memdb.StringSliceFieldIndex{Field: "OutLinks"}, - }, - "back-links": &memdb.IndexSchema{ - Name: "back-links", - Unique: false, - Indexer: &memdb.StringSliceFieldIndex{Field: "BackLinks"}, - }, - }, - }, - }, -} - -var db *memdb.MemDB - -func init() { - var err error - db, err = memdb.NewMemDB(schema) - if err != nil { - panic(err) - } -} diff --git a/markup/paragraph.go b/markup/paragraph.go index 9148501..bcb1c84 100644 --- a/markup/paragraph.go +++ b/markup/paragraph.go @@ -120,6 +120,9 @@ func ParagraphToHtml(hyphaName, input string) string { startsWith = func(t string) bool { return bytes.HasPrefix(p.Bytes(), []byte(t)) } + noTagsActive = func() bool { + return !(tagState[spanItalic] || tagState[spanBold] || tagState[spanMono] || tagState[spanSuper] || tagState[spanSub] || tagState[spanMark] || tagState[spanLink]) + } ) for p.Len() != 0 { @@ -147,7 +150,7 @@ func ParagraphToHtml(hyphaName, input string) string { p.Next(2) case startsWith("[["): ret.WriteString(getLinkNode(p, hyphaName, true)) - case startsWith("https://"), startsWith("http://"), startsWith("gemini://"), startsWith("gopher://"), startsWith("ftp://"): + case (startsWith("https://") || startsWith("http://") || startsWith("gemini://") || startsWith("gopher://") || startsWith("ftp://")) && noTagsActive(): ret.WriteString(getLinkNode(p, hyphaName, false)) default: ret.WriteString(html.EscapeString(getTextNode(p))) diff --git a/storage/storage.go b/storage/storage.go new file mode 100644 index 0000000..528c109 --- /dev/null +++ b/storage/storage.go @@ -0,0 +1,65 @@ +package storage + +import ( + "github.com/hashicorp/go-memdb" +) + +// Create the DB schema +var schema = &memdb.DBSchema{ + Tables: map[string]*memdb.TableSchema{ + "hyphae": &memdb.TableSchema{ + Name: "hyphae", + Indexes: map[string]*memdb.IndexSchema{ + "id": &memdb.IndexSchema{ + Name: "id", + Unique: true, + Indexer: &memdb.StringFieldIndex{Field: "Name"}, + }, + "exists": &memdb.IndexSchema{ + Name: "exists", + Unique: false, + Indexer: &memdb.BoolFieldIndex{Field: "Exists"}, + }, + "out-links": &memdb.IndexSchema{ + Name: "out-links", + Unique: false, + Indexer: &memdb.StringSliceFieldIndex{Field: "OutLinks"}, + }, + "back-links": &memdb.IndexSchema{ + Name: "back-links", + Unique: false, + Indexer: &memdb.StringSliceFieldIndex{Field: "BackLinks"}, + }, + }, + }, + }, +} + +var DB *memdb.MemDB + +func init() { + var err error + DB, err = memdb.NewMemDB(schema) + if err != nil { + panic(err) + } +} + +func ForEveryRecord(table string, λ func(obj interface{})) error { + txn := DB.Txn(false) + defer txn.Abort() + + it, err := txn.Get(table, "id") + if err != nil { + return err + } + + for obj := it.Next(); obj != nil; obj = it.Next() { + λ(obj) + } + + return nil +} + +func TxnW() *memdb.Txn { return DB.Txn(true) } +func TxnR() *memdb.Txn { return DB.Txn(false) } diff --git a/templates/auth.qtpl b/templates/auth.qtpl index bbb7d25..32ab3d8 100644 --- a/templates/auth.qtpl +++ b/templates/auth.qtpl @@ -6,7 +6,7 @@ {% if user.AuthUsed %}

Login

-

Use the data you were given by the administrator.

+

Use the data you were given by an administrator.

Username @@ -15,7 +15,7 @@ Password
-

By submitting this form you give this wiki a permission to store cookies in your browser. It lets the engine associate your edits with you.

+

By submitting this form you give this wiki a permission to store cookies in your browser. It lets the engine associate your edits with you. You will stay logged in until you log out.

Cancel
diff --git a/templates/auth.qtpl.go b/templates/auth.qtpl.go index 27d13fe..ed88d8d 100644 --- a/templates/auth.qtpl.go +++ b/templates/auth.qtpl.go @@ -33,7 +33,7 @@ func StreamLoginHTML(qw422016 *qt422016.Writer) { qw422016.N().S(`

Login

-

Use the data you were given by the administrator.

+

Use the data you were given by an administrator.

Username @@ -42,7 +42,7 @@ func StreamLoginHTML(qw422016 *qt422016.Writer) { Password
-

By submitting this form you give this wiki a permission to store cookies in your browser. It lets the engine associate your edits with you.

+

By submitting this form you give this wiki a permission to store cookies in your browser. It lets the engine associate your edits with you. You will stay logged in until you log out.

Cancel
diff --git a/templates/common.qtpl b/templates/common.qtpl index 29673cc..a288422 100644 --- a/templates/common.qtpl +++ b/templates/common.qtpl @@ -20,9 +20,10 @@ var navEntries = []navEntry{ %} {% func navHTML(rq *http.Request, hyphaName, navType string, revisionHash ...string) %} -{% code - u := user.FromRequest(rq).OrAnon() +{% code + u := user.FromRequest(rq) %} +