Didn't have the chance to migrate //all// templates just yet. We'll get there.
* Implement yet another template system
* Move orphans to the new system and fix a bug in it
* Link orphans in the admin panel
* Move the backlink handlers to the web package
* Move auth routing to web
* Move /user-list to the new system
* Move change password and translate it
* Move stuff
* Move admin-related stuff to the web
* Move a lot of files into internal dir
Outside of it are web and stuff that needs further refactoring
* Fix static not loading and de-qtpl tree
* Move tree to internal
* Keep the globe on the same line #230
* Revert "Keep the globe on the same line #230"
This reverts commit ae78e5e459.
* Migrate templates from hypview: delete, edit, start empty and existing WIP
The delete media view was removed, I didn't even know it still existed as a GET. A rudiment.
* Make views multi-file and break compilation
* Megarefactoring of hypha views
* Auth-related stuffs
* Fix some of those weird imports
* Migrate cat views
* Fix cat js
* Lower standards
* Internalize trauma
126 lines
2.6 KiB
Go
126 lines
2.6 KiB
Go
package user
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
)
|
|
|
|
var users sync.Map
|
|
var tokens sync.Map
|
|
|
|
// YieldUsers creates a channel which iterates existing users.
|
|
func YieldUsers() chan *User {
|
|
ch := make(chan *User)
|
|
go func(ch chan *User) {
|
|
users.Range(func(_, v any) bool {
|
|
ch <- v.(*User)
|
|
return true
|
|
})
|
|
close(ch)
|
|
}(ch)
|
|
return ch
|
|
}
|
|
|
|
// ListUsersWithGroup returns a slice with users of desired group.
|
|
func ListUsersWithGroup(group string) []string {
|
|
var filtered []string
|
|
for u := range YieldUsers() {
|
|
if u.Group == group {
|
|
filtered = append(filtered, u.Name)
|
|
}
|
|
}
|
|
return filtered
|
|
}
|
|
|
|
// Count returns total users count
|
|
func Count() (i uint64) {
|
|
users.Range(func(k, v interface{}) bool {
|
|
i++
|
|
return true
|
|
})
|
|
return i
|
|
}
|
|
|
|
func HasAnyAdmins() bool {
|
|
for u := range YieldUsers() {
|
|
if u.Group == "admin" {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HasUsername checks whether the desired user exists
|
|
func HasUsername(username string) bool {
|
|
_, has := users.Load(username)
|
|
return has
|
|
}
|
|
|
|
// CredentialsOK checks whether a correct user-password pair is provided
|
|
func CredentialsOK(username, password string) bool {
|
|
return ByName(username).isCorrectPassword(password)
|
|
}
|
|
|
|
// ByToken finds a user by provided session token
|
|
func ByToken(token string) *User {
|
|
// TODO: Needs more session data -- chekoopa
|
|
if usernameUntyped, ok := tokens.Load(token); ok {
|
|
username := usernameUntyped.(string)
|
|
return ByName(username)
|
|
}
|
|
return EmptyUser()
|
|
}
|
|
|
|
// ByName finds a user by one's username
|
|
func ByName(username string) *User {
|
|
if userUntyped, ok := users.Load(username); ok {
|
|
user := userUntyped.(*User)
|
|
return user
|
|
}
|
|
return EmptyUser()
|
|
}
|
|
|
|
// DeleteUser removes a user by one's name and saves user database.
|
|
func DeleteUser(name string) error {
|
|
user, loaded := users.LoadAndDelete(name)
|
|
if loaded {
|
|
u := user.(*User)
|
|
u.Name = "anon"
|
|
u.Group = "anon"
|
|
u.Password = ""
|
|
return SaveUserDatabase()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func commenceSession(username, token string) {
|
|
tokens.Store(token, username)
|
|
dumpTokens()
|
|
}
|
|
|
|
func terminateSession(token string) {
|
|
tokens.Delete(token)
|
|
dumpTokens()
|
|
}
|
|
|
|
func UsersInGroups() (admins []string, moderators []string, editors []string, readers []string) {
|
|
for u := range YieldUsers() {
|
|
switch u.Group {
|
|
// What if we place the users into sorted slices?
|
|
case "admin":
|
|
admins = append(admins, u.Name)
|
|
case "moderator":
|
|
moderators = append(moderators, u.Name)
|
|
case "editor", "trusted":
|
|
editors = append(editors, u.Name)
|
|
case "reader":
|
|
readers = append(readers, u.Name)
|
|
}
|
|
}
|
|
sort.Strings(admins)
|
|
sort.Strings(moderators)
|
|
sort.Strings(editors)
|
|
sort.Strings(readers)
|
|
return
|
|
}
|