mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2025-05-04 07:54:05 +00:00
You can now register, but the new account is not saved on disk
This commit is contained in:
parent
68ab5df3f1
commit
aee2f23b5e
16
http_auth.go
16
http_auth.go
@ -20,9 +20,7 @@ func init() {
|
|||||||
|
|
||||||
func handlerRegister(w http.ResponseWriter, rq *http.Request) {
|
func handlerRegister(w http.ResponseWriter, rq *http.Request) {
|
||||||
log.Println(rq.URL)
|
log.Println(rq.URL)
|
||||||
if util.UseRegistration {
|
if !util.UseRegistration {
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
} else {
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
w.WriteHeader(http.StatusForbidden)
|
||||||
}
|
}
|
||||||
if rq.Method == http.MethodGet {
|
if rq.Method == http.MethodGet {
|
||||||
@ -35,7 +33,17 @@ func handlerRegister(w http.ResponseWriter, rq *http.Request) {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
} else if rq.Method == http.MethodPost {
|
} else if rq.Method == http.MethodPost {
|
||||||
io.WriteString(w, "Not implemented")
|
var (
|
||||||
|
username = rq.PostFormValue("username")
|
||||||
|
password = rq.PostFormValue("password")
|
||||||
|
err = user.Register(username, password)
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
io.WriteString(w, err.Error())
|
||||||
|
} else {
|
||||||
|
user.LoginDataHTTP(w, rq, username, password)
|
||||||
|
http.Redirect(w, rq, "/"+rq.URL.RawQuery, http.StatusSeeOther)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
user/net.go
32
user/net.go
@ -1,11 +1,14 @@
|
|||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bouncepaw/mycorrhiza/util"
|
"github.com/bouncepaw/mycorrhiza/util"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CanProceed returns `true` if the user in `rq` has enough rights to access `route`.
|
// CanProceed returns `true` if the user in `rq` has enough rights to access `route`.
|
||||||
@ -31,6 +34,35 @@ func LogoutFromRequest(w http.ResponseWriter, rq *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register registers the given user. If it fails, a non-nil error is returned.
|
||||||
|
func Register(username, password string) error {
|
||||||
|
username = util.CanonicalName(username)
|
||||||
|
log.Println("Attempt to register user", username)
|
||||||
|
switch {
|
||||||
|
case CountRegistered() >= util.LimitRegistration && util.LimitRegistration > 0:
|
||||||
|
i := strconv.Itoa(util.LimitRegistration)
|
||||||
|
log.Println("Limit reached: " + i)
|
||||||
|
return errors.New("Reached the limit of registered users: " + i)
|
||||||
|
case HasUsername(username):
|
||||||
|
log.Println("Username taken")
|
||||||
|
return errors.New("Username " + username + " is taken already.")
|
||||||
|
case !util.IsPossibleUsername(username):
|
||||||
|
log.Println("Illegal username:", username)
|
||||||
|
}
|
||||||
|
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
u := User{
|
||||||
|
Name: username,
|
||||||
|
Group: "editor",
|
||||||
|
HashedPassword: string(hash),
|
||||||
|
Source: SourceRegistration,
|
||||||
|
}
|
||||||
|
users.Store(username, &u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// LoginDataHTTP logs such user in and returns string representation of an error if there is any.
|
// LoginDataHTTP logs such user in and returns string representation of an error if there is any.
|
||||||
func LoginDataHTTP(w http.ResponseWriter, rq *http.Request, username, password string) string {
|
func LoginDataHTTP(w http.ResponseWriter, rq *http.Request, username, password string) string {
|
||||||
w.Header().Set("Content-Type", "text/html;charset=utf-8")
|
w.Header().Set("Content-Type", "text/html;charset=utf-8")
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UserSource shows where is the user data gotten from.
|
// UserSource shows where is the user data gotten from.
|
||||||
@ -25,6 +26,10 @@ type User struct {
|
|||||||
HashedPassword string `json:"hashed_password"` // for registered
|
HashedPassword string `json:"hashed_password"` // for registered
|
||||||
Source UserSource `json:"-"`
|
Source UserSource `json:"-"`
|
||||||
sync.RWMutex
|
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.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route — Right (more is more right)
|
// Route — Right (more is more right)
|
||||||
|
@ -30,6 +30,17 @@ func ListUsersWithGroup(group string) []string {
|
|||||||
return usersWithTheGroup
|
return usersWithTheGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CountRegistered() int {
|
||||||
|
i := 0
|
||||||
|
users.Range(func(k, v interface{}) bool {
|
||||||
|
if v.(*User).Source == SourceRegistration {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
func Count() int {
|
func Count() int {
|
||||||
i := 0
|
i := 0
|
||||||
users.Range(func(k, v interface{}) bool {
|
users.Range(func(k, v interface{}) bool {
|
||||||
|
@ -82,5 +82,5 @@ func ReadConfigFile(path string) {
|
|||||||
FixedCredentialsPath = cfg.FixedAuthCredentialsPath
|
FixedCredentialsPath = cfg.FixedAuthCredentialsPath
|
||||||
UseRegistration = cfg.UseRegistration
|
UseRegistration = cfg.UseRegistration
|
||||||
RegistrationCredentialsPath = cfg.RegistrationCredentialsPath
|
RegistrationCredentialsPath = cfg.RegistrationCredentialsPath
|
||||||
LimitRegistration = cfg.LimitRegistration
|
LimitRegistration = int(cfg.LimitRegistration)
|
||||||
}
|
}
|
||||||
|
15
util/util.go
15
util/util.go
@ -29,7 +29,7 @@ var (
|
|||||||
FixedCredentialsPath string
|
FixedCredentialsPath string
|
||||||
UseRegistration bool
|
UseRegistration bool
|
||||||
RegistrationCredentialsPath string
|
RegistrationCredentialsPath string
|
||||||
LimitRegistration uint64
|
LimitRegistration int
|
||||||
)
|
)
|
||||||
|
|
||||||
// LettersNumbersOnly keeps letters and numbers only in the given string.
|
// LettersNumbersOnly keeps letters and numbers only in the given string.
|
||||||
@ -94,13 +94,24 @@ func BeautifulName(uglyName string) string {
|
|||||||
|
|
||||||
// CanonicalName makes sure the `name` is canonical. A name is canonical if it is lowercase and all spaces are replaced with underscores.
|
// CanonicalName makes sure the `name` is canonical. A name is canonical if it is lowercase and all spaces are replaced with underscores.
|
||||||
func CanonicalName(name string) string {
|
func CanonicalName(name string) string {
|
||||||
return strings.ToLower(strings.ReplaceAll(name, " ", "_"))
|
return strings.ToLower(
|
||||||
|
strings.ReplaceAll(
|
||||||
|
strings.TrimRight(
|
||||||
|
strings.TrimLeft(name, "_"),
|
||||||
|
"_",
|
||||||
|
), " ", "_"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// HyphaPattern is a pattern which all hyphae must match.
|
// HyphaPattern is a pattern which all hyphae must match.
|
||||||
var HyphaPattern = regexp.MustCompile(`[^?!:#@><*|"\'&%{}]+`)
|
var HyphaPattern = regexp.MustCompile(`[^?!:#@><*|"\'&%{}]+`)
|
||||||
|
|
||||||
|
var UsernamePattern = regexp.MustCompile(`[^?!:#@><*|"\'&%{}/]+`)
|
||||||
|
|
||||||
// IsCanonicalName checks if the `name` is canonical.
|
// IsCanonicalName checks if the `name` is canonical.
|
||||||
func IsCanonicalName(name string) bool {
|
func IsCanonicalName(name string) bool {
|
||||||
return HyphaPattern.MatchString(name)
|
return HyphaPattern.MatchString(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsPossibleUsername(username string) bool {
|
||||||
|
return UsernamePattern.MatchString(strings.TrimSpace(username))
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user