searcherside/core/services/password_hash.go
Peter Kurfer 9ea9a8f658
Some checks failed
Go build / build (push) Failing after 1m58s
feat: continue basic setup
- setup ent scheme
- add command to create users
- document API
- add helpers to create migrations
- add command to run migrations
- add basic compose file
2024-06-19 21:19:37 +02:00

81 lines
1.8 KiB
Go

package services
import (
"bytes"
"encoding"
"encoding/base64"
"errors"
)
var (
_ encoding.TextMarshaler = (*PasswordHash)(nil)
_ encoding.TextUnmarshaler = (*PasswordHash)(nil)
)
var ErrPasswordHashFormat = errors.New("invalid password hash format")
type hashParams interface {
Algorithm() string
encoding.TextMarshaler
encoding.TextUnmarshaler
}
type PasswordHash struct {
Hash []byte
Salt []byte
Params hashParams
}
func (p *PasswordHash) MarshalText() (text []byte, err error) {
buf := bytes.NewBuffer(make([]byte, 0, 256))
buf.WriteRune('$')
buf.WriteString(p.Params.Algorithm())
buf.WriteRune('$')
params, err := p.Params.MarshalText()
if err != nil {
return nil, err
}
buf.Write(params)
buf.WriteRune('$')
encodedSalt := make([]byte, base64.RawStdEncoding.EncodedLen(len(p.Salt)))
base64.RawStdEncoding.Encode(encodedSalt, p.Salt)
buf.Write(encodedSalt)
buf.WriteRune('$')
encodedCipherText := make([]byte, base64.RawStdEncoding.EncodedLen(len(p.Hash)))
base64.RawStdEncoding.Encode(encodedCipherText, p.Hash)
buf.Write(encodedCipherText)
return buf.Bytes(), nil
}
func (p *PasswordHash) UnmarshalText(text []byte) error {
split := bytes.Split(text, []byte("$"))
if len(split) < 6 {
return ErrPasswordHashFormat
}
p.Params = paramsForAlgorithm(string(split[1]))
if err := p.Params.UnmarshalText(split[len(split)-3]); err != nil {
return err
}
salt := split[len(split)-2]
p.Salt = make([]byte, base64.RawStdEncoding.DecodedLen(len(salt)))
if _, err := base64.RawStdEncoding.Decode(p.Salt, salt); err != nil {
return err
}
hash := split[len(split)-1]
p.Hash = make([]byte, base64.RawStdEncoding.DecodedLen(len(hash)))
if _, err := base64.RawStdEncoding.Decode(p.Hash, hash); err != nil {
return err
}
return nil
}