1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-30 11:46:16 +00:00
mycorrhiza/user/user.go

109 lines
2.2 KiB
Go
Raw Normal View History

package user
import (
"net/http"
"sync"
2021-06-29 10:34:36 +00:00
"time"
"github.com/bouncepaw/mycorrhiza/cfg"
"golang.org/x/crypto/bcrypt"
)
// User is a user.
type User struct {
// Name is a username. It must follow hypha naming rules.
Name string `json:"name"`
Group string `json:"group"`
Password string `json:"hashed_password"`
RegisteredAt time.Time `json:"registered_on"`
sync.RWMutex
// A note about why HashedPassword is string and not []byte. The reason is
// simple: golang's json marshals []byte as slice of numbers, which is not
// acceptable.
2020-11-14 13:03:06 +00:00
}
// Route — Right (more is more right)
var minimalRights = map[string]int{
2021-01-23 19:00:58 +00:00
"edit": 1,
"upload-binary": 1,
"upload-text": 1,
"rename-ask": 2,
"rename-confirm": 2,
"unattach-ask": 2,
"unattach-confirm": 2,
"update-header-links": 3,
"delete-ask": 3,
"delete-confirm": 3,
"reindex": 4,
"admin": 4,
2021-02-18 14:50:37 +00:00
"admin/shutdown": 4,
2020-11-14 14:46:04 +00:00
}
var groups = []string{
"anon",
"editor",
"trusted",
"moderator",
"admin",
}
// Group — Right
var groupRight = map[string]int{
"anon": 0,
"editor": 1,
"trusted": 2,
"moderator": 3,
"admin": 4,
2020-11-14 13:03:06 +00:00
}
func ValidGroup(group string) bool {
for _, grp := range groups {
if grp == group {
return true
}
}
return false
}
2021-01-24 07:30:14 +00:00
func EmptyUser() *User {
return &User{
Name: "anon",
Group: "anon",
Password: "",
2020-11-14 10:39:18 +00:00
}
}
func (user *User) CanProceed(route string) bool {
if !cfg.UseAuth {
return true
2020-11-14 10:39:18 +00:00
}
2020-11-14 13:03:06 +00:00
user.RLock()
defer user.RUnlock()
2020-11-14 10:39:18 +00:00
right, _ := groupRight[user.Group]
minimalRight, _ := minimalRights[route]
if right >= minimalRight {
return true
2020-11-14 10:39:18 +00:00
}
return false
}
func (user *User) isCorrectPassword(password string) bool {
user.RLock()
defer user.RUnlock()
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
return err == nil
2020-11-14 10:39:18 +00:00
}
// ShowLockMaybe redirects to the lock page if the user is anon and the wiki has been configured to use the lock. It returns true if the user was redirected.
func (user *User) ShowLockMaybe(w http.ResponseWriter, rq *http.Request) bool {
if cfg.Locked && user.Group == "anon" {
http.Redirect(w, rq, "/lock", http.StatusSeeOther)
return true
}
return false
}