switch secret generation to use lib

This commit is contained in:
Pascal Fischer 2023-03-08 11:36:03 +01:00
parent 83e7e30218
commit 2b1965c941
2 changed files with 16 additions and 20 deletions

View File

@ -4,10 +4,10 @@ import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"hash/crc32" "hash/crc32"
"math/rand"
"time" "time"
"codeberg.org/ac/base62" "codeberg.org/ac/base62"
b "github.com/hashicorp/go-secure-stdlib/base62"
"github.com/rs/xid" "github.com/rs/xid"
) )
@ -25,8 +25,11 @@ type PersonalAccessToken struct {
// CreateNewPAT will generate a new PersonalAccessToken that can be assigned to a User. // CreateNewPAT will generate a new PersonalAccessToken that can be assigned to a User.
// Additionally, it will return the token in plain text once, to give to the user and only save a hashed version // Additionally, it will return the token in plain text once, to give to the user and only save a hashed version
func CreateNewPAT(description string, expirationInDays int, createdBy string) (*PersonalAccessToken, string) { func CreateNewPAT(description string, expirationInDays int, createdBy string) (*PersonalAccessToken, string, error) {
hashedToken, plainToken := generateNewToken() hashedToken, plainToken, err := generateNewToken()
if err != nil {
return nil, "", err
}
currentTime := time.Now().UTC() currentTime := time.Now().UTC()
return &PersonalAccessToken{ return &PersonalAccessToken{
ID: xid.New().String(), ID: xid.New().String(),
@ -36,26 +39,19 @@ func CreateNewPAT(description string, expirationInDays int, createdBy string) (*
CreatedBy: createdBy, CreatedBy: createdBy,
CreatedAt: currentTime, CreatedAt: currentTime,
LastUsed: currentTime, LastUsed: currentTime,
}, plainToken }, plainToken, nil
} }
func generateNewToken() (string, string) { func generateNewToken() (string, string, error) {
secret := randStringRunes(30) secret, err := b.Random(30)
if err != nil {
return "", "", err
}
checksum := crc32.ChecksumIEEE([]byte(secret)) checksum := crc32.ChecksumIEEE([]byte(secret))
encodedChecksum := base62.Encode(checksum) encodedChecksum := base62.Encode(checksum)
paddedChecksum := fmt.Sprintf("%06s", encodedChecksum) paddedChecksum := fmt.Sprintf("%06s", encodedChecksum)
plainToken := "nbp_" + secret + paddedChecksum plainToken := "nbp_" + secret + paddedChecksum
hashedToken := sha256.Sum256([]byte(plainToken)) hashedToken := sha256.Sum256([]byte(plainToken))
return string(hashedToken[:]), plainToken return string(hashedToken[:]), plainToken, nil
}
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
func randStringRunes(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
} }

View File

@ -11,19 +11,19 @@ import (
) )
func TestPAT_GenerateToken_Hashing(t *testing.T) { func TestPAT_GenerateToken_Hashing(t *testing.T) {
hashedToken, plainToken := generateNewToken() hashedToken, plainToken, _ := generateNewToken()
expectedToken := sha256.Sum256([]byte(plainToken)) expectedToken := sha256.Sum256([]byte(plainToken))
assert.Equal(t, hashedToken, string(expectedToken[:])) assert.Equal(t, hashedToken, string(expectedToken[:]))
} }
func TestPAT_GenerateToken_Prefix(t *testing.T) { func TestPAT_GenerateToken_Prefix(t *testing.T) {
_, plainToken := generateNewToken() _, plainToken, _ := generateNewToken()
fourCharPrefix := plainToken[:4] fourCharPrefix := plainToken[:4]
assert.Equal(t, "nbp_", fourCharPrefix) assert.Equal(t, "nbp_", fourCharPrefix)
} }
func TestPAT_GenerateToken_Checksum(t *testing.T) { func TestPAT_GenerateToken_Checksum(t *testing.T) {
_, plainToken := generateNewToken() _, plainToken, _ := generateNewToken()
tokenWithoutPrefix := strings.Split(plainToken, "_")[1] tokenWithoutPrefix := strings.Split(plainToken, "_")[1]
if len(tokenWithoutPrefix) != 36 { if len(tokenWithoutPrefix) != 36 {
t.Fatal("Token has wrong length") t.Fatal("Token has wrong length")