Files
warewulf/internal/pkg/config/authentication.go
Jonathon Anderson 4005afac4c Add a new OpenAPI v3 REST API to warewulfd at /api
Co-authored-by: jason yang <jasonyangshadow@gmail.com>

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
2025-04-03 07:12:03 -06:00

73 lines
1.5 KiB
Go

package config
import (
"fmt"
"os"
"github.com/pkg/errors"
"golang.org/x/crypto/bcrypt"
"gopkg.in/yaml.v3"
"github.com/warewulf/warewulf/internal/pkg/wwlog"
)
type User struct {
Name string `json:"name" yaml:"name"`
PasswordHash string `json:"password hash" yaml:"password hash"`
}
type Authentication struct {
Users []User `json:"users" yaml:"users"`
userMap map[string]User `json:"-" yaml:"-"`
}
func NewAuthentication() *Authentication {
auth := new(Authentication)
auth.userMap = make(map[string]User)
return auth
}
func (auth *Authentication) ParseFromRaw(data []byte) error {
err := yaml.Unmarshal(data, auth)
if err != nil {
return err
}
if len(auth.Users) == 0 {
return fmt.Errorf("no record users")
}
for _, user := range auth.Users {
if _, ok := auth.userMap[user.Name]; ok {
return fmt.Errorf("duplicated user names")
}
auth.userMap[user.Name] = user
}
return nil
}
func (auth *Authentication) Read(confFileName string) error {
if data, err := os.ReadFile(confFileName); err != nil {
return err
} else {
if err := auth.ParseFromRaw(data); err != nil {
return err
}
}
return nil
}
var (
UnauthorizedError = errors.New("Unauthorized")
)
func (auth *Authentication) Authenticate(name, pass string) (*User, error) {
if user, ok := auth.userMap[name]; !ok {
return nil, UnauthorizedError
} else {
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(pass)); err != nil {
wwlog.Warn("%v\n", err)
return nil, UnauthorizedError
}
return &user, nil
}
}