diff options
author | Brian Picciano <mediocregopher@gmail.com> | 2021-08-18 18:13:18 -0600 |
---|---|---|
committer | Brian Picciano <mediocregopher@gmail.com> | 2021-08-18 18:13:44 -0600 |
commit | a9d8aa2591cd03fe1a9da72bab8d311e4840e8f1 (patch) | |
tree | 98a32eb3a2719f10dc0d55a206851e3793e61388 /srv/chat/user.go | |
parent | bec64827d19d64aae86ca3d2b26de800b427a540 (diff) |
implemented basic userID generation
Diffstat (limited to 'srv/chat/user.go')
-rw-r--r-- | srv/chat/user.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/srv/chat/user.go b/srv/chat/user.go new file mode 100644 index 0000000..1279a45 --- /dev/null +++ b/srv/chat/user.go @@ -0,0 +1,68 @@ +package chat + +import ( + "encoding/hex" + "fmt" + "sync" + + "golang.org/x/crypto/argon2" +) + +// UserID uniquely identifies an individual user who has posted a message in a +// Room. +type UserID struct { + + // Name will be the user's chosen display name. + Name string `json:"name"` + + // Hash will be a hex string generated from a secret only the user knows. + Hash string `json:"id"` +} + +// UserIDCalculator is used to calculate UserIDs. +type UserIDCalculator struct { + + // Secret is used when calculating UserID Hash salts. + Secret []byte + + // TimeCost, MemoryCost, and Threads are used as inputs to the Argon2id + // algorithm which is used to generate the Hash. + TimeCost, MemoryCost uint32 + Threads uint8 + + // HashLen specifies the number of bytes the Hash should be. + HashLen uint32 + + // Lock, if set, forces concurrent Calculate calls to occur sequentially. + Lock *sync.Mutex +} + +// NewUserIDCalculator returns a UserIDCalculator with sane defaults. +func NewUserIDCalculator(secret []byte) UserIDCalculator { + return UserIDCalculator{ + Secret: secret, + TimeCost: 15, + MemoryCost: 128 * 1024, + Threads: 2, + HashLen: 16, + Lock: new(sync.Mutex), + } +} + +// Calculate accepts a name and password and returns the calculated UserID. +func (c UserIDCalculator) Calculate(name, password string) UserID { + + input := fmt.Sprintf("%q:%q", name, password) + + hashB := argon2.IDKey( + []byte(input), + c.Secret, // salt + c.TimeCost, c.MemoryCost, c.Threads, + c.HashLen, + ) + + return UserID{ + Name: name, + Hash: hex.EncodeToString(hashB), + } +} |