mirror of
https://github.com/MarekWojt/gertdns.git
synced 2025-12-15 12:59:53 +01:00
Password Authentication
This commit is contained in:
84
auth/auth.go
84
auth/auth.go
@@ -1,11 +1,89 @@
|
||||
package auth
|
||||
|
||||
type AuthenticationRequest struct {
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/raja/argon2pw"
|
||||
)
|
||||
|
||||
type PasswordAuthenticationRequest struct {
|
||||
User string
|
||||
Password string
|
||||
Domain string
|
||||
}
|
||||
|
||||
func IsAuthenticated(request AuthenticationRequest) (bool, error) {
|
||||
return true, nil
|
||||
type userRaw struct {
|
||||
Password string
|
||||
Hashed bool
|
||||
Domains []string
|
||||
}
|
||||
|
||||
type user struct {
|
||||
password string
|
||||
domains map[string]string
|
||||
}
|
||||
|
||||
var parsedUsers map[string]user = map[string]user{}
|
||||
|
||||
func (user user) Authenticate(password string) (bool, error) {
|
||||
return argon2pw.CompareHashWithPassword(user.password, password)
|
||||
}
|
||||
|
||||
func (selfUser *userRaw) Tidy() (user, error) {
|
||||
if !selfUser.Hashed {
|
||||
pw, err := argon2pw.GenerateSaltedHash(selfUser.Password)
|
||||
if err != nil {
|
||||
return user{}, err
|
||||
}
|
||||
selfUser.Password = pw
|
||||
selfUser.Hashed = true
|
||||
}
|
||||
|
||||
// Create a map => faster access times
|
||||
parsedDomains := map[string]string{}
|
||||
for _, domain := range selfUser.Domains {
|
||||
parsedDomains[domain] = domain
|
||||
}
|
||||
|
||||
parsedUser := user{
|
||||
password: selfUser.Password,
|
||||
domains: parsedDomains,
|
||||
}
|
||||
|
||||
return parsedUser, nil
|
||||
}
|
||||
|
||||
func IsPasswordAuthenticated(request PasswordAuthenticationRequest) (bool, error) {
|
||||
currentUser, found := parsedUsers[request.User]
|
||||
if !found {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if _, ok := currentUser.domains[request.Domain]; !ok {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return currentUser.Authenticate(request.Password)
|
||||
}
|
||||
|
||||
func Init(authFilePath string) error {
|
||||
users, err := loadAuthFile(authFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for name, user := range users {
|
||||
log.Printf("%s\n", name)
|
||||
log.Printf("%+v\n", user)
|
||||
parsedUser, err := user.Tidy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parsedUsers[name] = parsedUser
|
||||
}
|
||||
|
||||
writeAuthFile(authFilePath, users)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
45
auth/toml.go
Normal file
45
auth/toml.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/gookit/color"
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
)
|
||||
|
||||
func loadAuthFile(authFilePath string) (map[string]*userRaw, error) {
|
||||
bytes, err := ioutil.ReadFile(authFilePath)
|
||||
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
color.Warnln("Creating new authentication file")
|
||||
return writeAuthFile(authFilePath, map[string]*userRaw{})
|
||||
}
|
||||
|
||||
var users map[string]*userRaw
|
||||
err = toml.Unmarshal(bytes, &users)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
color.Errorln("Authentication file " + authFilePath + " could not be read as TOML file")
|
||||
return users, err
|
||||
}
|
||||
color.Infoln("Loaded authentication file " + authFilePath)
|
||||
return users, err
|
||||
}
|
||||
|
||||
func writeAuthFile(authFilePath string, users map[string]*userRaw) (map[string]*userRaw, error) {
|
||||
|
||||
authBytes, err := toml.Marshal(users)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
color.Errorln("Default authentication struct is not TOML conform")
|
||||
return users, err
|
||||
}
|
||||
err = os.WriteFile(authFilePath, authBytes, 0644)
|
||||
if err != nil {
|
||||
color.Errorln(err.Error())
|
||||
color.Warnln("Using default authentication without file")
|
||||
}
|
||||
return users, err
|
||||
}
|
||||
Reference in New Issue
Block a user