package service import ( "encoding/json" "fmt" "log" "os" "path" "github.com/spf13/viper" "golang.org/x/crypto/bcrypt" ) type UnauthorizedError string func (uae UnauthorizedError) Error() string { return "Invalid user or password" } type UserConfig struct { DB *viper.Viper UserName string PassWord string Router UserConfigRouter Others []UserConfigOther } type UserConfigRouter struct { DNS string NFT UserConfigNFT } type UserConfigOther struct { DNS string V6IID string RegisterV4 bool NFT UserConfigNFT } type UserConfigNFT struct { Table string Set4 string Set6 string } func LoadConfigForUser(username string, password string) (*UserConfig, error) { configFile := fmt.Sprintf("%s/%s.yml", C.Users.ConfigDir, username) configFile = path.Clean(configFile) log.Printf("Trying to load config file %s for user %s", configFile, username) if _, err := os.Stat(configFile); err != nil { log.Printf("cannot stat the file %s: %v", configFile, err) return nil, UnauthorizedError("cannot stat") } v := viper.New() v.SetConfigFile(configFile) err := v.ReadInConfig() if err != nil { return nil, fmt.Errorf("failed to parse config file %s: %v", configFile, err) } result := &UserConfig{DB: v} err = result.PasswordCheck(password) if err != nil { return nil, UnauthorizedError("pwcheck failed") } err = result.DB.Unmarshal(result) if err != nil { return nil, fmt.Errorf("failed to unmarshal config file %s: %v", configFile, err) } return result, nil } func HashPassword(pw []byte) (string, error) { hash, err := bcrypt.GenerateFromPassword(pw, bcrypt.DefaultCost) if err != nil { return "", fmt.Errorf("failed to create password hash: %v", err) } return string(hash), nil } func (ur *UserConfig) PasswordCheck(pwToCheck string) error { hashedPassword := []byte(ur.DB.GetString("password")) bytePwToCheck := []byte(pwToCheck) err := bcrypt.CompareHashAndPassword(hashedPassword, bytePwToCheck) return err } func (uc *UserConfig) PrettyPrint() string { s, err := json.MarshalIndent(uc, "", " ") if err != nil { log.Fatalf("Failed to pretty print UpdateConfig via JSON: %v", err) } return string(s) }