From c83ea6f356d78a17353a2737f64b3c2fa4ecc878 Mon Sep 17 00:00:00 2001 From: bouncepaw Date: Fri, 13 Nov 2020 23:45:42 +0500 Subject: [PATCH] Start implementing fixed authorization system --- README.md | 9 +++- flag.go | 17 ++++++++ mycocredentials.json | 24 +++++++++++ user/user.go | 99 ++++++++++++++++++++++++++++++++++++++++++++ util/util.go | 11 +++-- 5 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 mycocredentials.json create mode 100644 user/user.go diff --git a/README.md b/README.md index 29f25a9..125672e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ Features planned for this release: * [ ] Authorization * [ ] User groups: `anon`, `editor`, `trusted`, `moderator`, `admin` * [ ] Mycomarkup improvements - * [ ] Strike-through syntax + * [x] Strike-through syntax + * [x] Formatting in headings * [ ] Fix empty line codeblock bug #26 * [ ] `img{}` improvements * [ ] ... @@ -25,12 +26,18 @@ make mycorrhiza [OPTIONS...] WIKI_PATH Options: + -auth-method string + What auth method to use. Variants: "none", "fixed" (default "none") + -fixed-credentials-path string + Used when -auth-method=fixed. Path to file with user credentials. (default "mycocredentials.json") -home string The home page (default "home") -port string Port to serve the wiki at (default "1737") -title string How to call your wiki in the navititle (default "🍄") + -user-tree string + Hypha which is a superhypha of all user pages (default "u") ``` ## Features diff --git a/flag.go b/flag.go index d5d6df4..8a9857a 100644 --- a/flag.go +++ b/flag.go @@ -5,6 +5,7 @@ import ( "log" "path/filepath" + "github.com/bouncepaw/mycorrhiza/user" "github.com/bouncepaw/mycorrhiza/util" ) @@ -12,6 +13,9 @@ func init() { flag.StringVar(&util.ServerPort, "port", "1737", "Port to serve the wiki at") flag.StringVar(&util.HomePage, "home", "home", "The home page") flag.StringVar(&util.SiteTitle, "title", "🍄", "How to call your wiki in the navititle") + flag.StringVar(&util.UserTree, "user-tree", "u", "Hypha which is a superhypha of all user pages") + flag.StringVar(&util.AuthMethod, "auth-method", "none", "What auth method to use. Variants: \"none\", \"fixed\"") + flag.StringVar(&util.FixedCredentialsPath, "fixed-credentials-path", "mycocredentials.json", "Used when -auth-method=fixed. Path to file with user credentials.") } // Do the things related to cli args and die maybe @@ -33,4 +37,17 @@ func parseCliArgs() { if !isCanonicalName(util.HomePage) { log.Fatal("Error: you must use a proper name for the homepage") } + + if !isCanonicalName(util.UserTree) { + log.Fatal("Error: you must use a proper name for user tree") + } + + switch util.AuthMethod { + case "none": + case "fixed": + user.AuthUsed = true + user.PopulateFixedUserStorage() + default: + log.Fatal("Error: unknown auth method:", util.AuthMethod) + } } diff --git a/mycocredentials.json b/mycocredentials.json new file mode 100644 index 0000000..f2ad452 --- /dev/null +++ b/mycocredentials.json @@ -0,0 +1,24 @@ +[ + { + "name": "admin", + "password": "mycorrhiza", + "group": "admin" + }, + { + "name": "weird_fish", + "password": "DeepestOcean", + "group": "moderator" + }, + { + "name": "king_of_limbs", + "password": "ambush", + "group": "trusted" + }, + { + "name": "paranoid_android", + "password": "ok computer", + "group": "editor" + } +] + + diff --git a/user/user.go b/user/user.go new file mode 100644 index 0000000..10fb2cc --- /dev/null +++ b/user/user.go @@ -0,0 +1,99 @@ +package user + +import ( + "encoding/json" + "io/ioutil" + "log" + + "github.com/bouncepaw/mycorrhiza/util" +) + +type FixedUserStorage struct { + Users []*User +} + +var UserStorage = FixedUserStorage{} + +func PopulateFixedUserStorage() { + contents, err := ioutil.ReadFile(util.FixedCredentialsPath) + if err != nil { + log.Fatal(err) + } + err = json.Unmarshal(contents, &UserStorage.Users) + if err != nil { + log.Fatal(err) + } + for _, user := range UserStorage.Users { + user.Group = groupFromString(user.GroupString) + } + log.Println("Found", len(UserStorage.Users), "fixed users") +} + +// AuthUsed shows if a method of authentication is used. You should set it by yourself. +var AuthUsed bool + +// User is a user. +type User struct { + // Name is a username. It must follow hypha naming rules. + Name string `json:"name"` + // Group the user is part of. + Group UserGroup `json:"-"` + GroupString string `json:"group"` + Password string `json:"password"` +} + +func groupFromString(s string) UserGroup { + switch s { + case "admin": + return UserAdmin + case "moderator": + return UserModerator + case "trusted": + return UserTrusted + case "editor": + return UserEditor + default: + log.Fatal("Unknown user group", s) + return UserAnon + } +} + +// UserGroup represents a group that a user is part of. +type UserGroup int + +const ( + // UserAnon is the default user group which all unauthorized visitors have. + UserAnon UserGroup = iota + // UserEditor is a user who can edit and upload stuff. + UserEditor + // UserTrusted is a trusted editor who can also rename stuff. + UserTrusted + // UserModerator is a moderator who can also delete stuff. + UserModerator + // UserAdmin can do everything. + UserAdmin +) + +var minimalRights = map[string]UserGroup{ + "edit": UserEditor, + "upload-binary": UserEditor, + "upload-text": UserEditor, + "rename-ask": UserTrusted, + "rename-confirm": UserTrusted, + "delete-ask": UserModerator, + "delete-confirm": UserModerator, + "reindex": UserAdmin, +} + +func (ug UserGroup) CanAccessRoute(route string) bool { + if !AuthUsed { + return true + } + if minimalRight, ok := minimalRights[route]; ok { + if ug >= minimalRight { + return true + } + return false + } + return true +} diff --git a/util/util.go b/util/util.go index 8458d4f..3da4031 100644 --- a/util/util.go +++ b/util/util.go @@ -6,10 +6,13 @@ import ( ) var ( - ServerPort string - HomePage string - SiteTitle string - WikiDir string + ServerPort string + HomePage string + SiteTitle string + WikiDir string + UserTree string + AuthMethod string + FixedCredentialsPath string ) // ShorterPath is used by handlerList to display shorter path to the files. It simply strips WikiDir.