feat: ✨ added more utilities functions
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/o1egl/paseto"
|
||||
)
|
||||
|
||||
type UserPayload struct {
|
||||
Username string `json:"username"`
|
||||
// TODO: Add permissions
|
||||
}
|
||||
|
||||
type Payload struct {
|
||||
UUID uuid.UUID `json:"token_uuid"`
|
||||
User UserPayload `json:"user"`
|
||||
IssuedAt time.Time `json:"issued_at"`
|
||||
ExpiredAt time.Time `json:"expired_at"`
|
||||
}
|
||||
|
||||
type Paseto struct {
|
||||
paseto *paseto.V2
|
||||
publicKey ed25519.PublicKey
|
||||
privateKey ed25519.PrivateKey
|
||||
}
|
||||
|
||||
func New() *Paseto {
|
||||
publicKey, privateKey, _ := ed25519.GenerateKey(nil)
|
||||
return &Paseto{
|
||||
paseto: paseto.NewV2(),
|
||||
publicKey: publicKey,
|
||||
privateKey: privateKey,
|
||||
}
|
||||
}
|
||||
|
||||
func NewPayload(user UserPayload) *Payload {
|
||||
// TODO: add documentation and advert to developers: tokenID != user.UUID
|
||||
tokenID, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return NewPayload(user)
|
||||
}
|
||||
|
||||
payload := &Payload{
|
||||
UUID: tokenID,
|
||||
User: user,
|
||||
IssuedAt: time.Now(),
|
||||
ExpiredAt: time.Now().Add(time.Hour * 24 * 7),
|
||||
}
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
func (m *Paseto) Create(user UserPayload) (string, error) {
|
||||
return m.paseto.Sign(m.privateKey, NewPayload(user), nil)
|
||||
}
|
||||
|
||||
func (m *Paseto) Verify(token string) (*Payload, error) {
|
||||
var payload Payload
|
||||
err := m.paseto.Verify(token, m.publicKey, &payload, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &payload, nil
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zepyrshut/esfaker"
|
||||
)
|
||||
|
||||
func Test_New(t *testing.T) {
|
||||
paseto := New()
|
||||
|
||||
require.NotNil(t, paseto.paseto)
|
||||
require.NotNil(t, paseto.privateKey)
|
||||
require.NotNil(t, paseto.publicKey)
|
||||
}
|
||||
|
||||
func Test_NewPayload(t *testing.T) {
|
||||
user := createRandomUser()
|
||||
payload := NewPayload(user)
|
||||
|
||||
require.True(t, isValidUUID(payload.UUID))
|
||||
require.Equal(t, user, payload.User)
|
||||
}
|
||||
|
||||
func Test_CreateToken(t *testing.T) {
|
||||
token := New()
|
||||
user := createRandomUser()
|
||||
signature, err := token.Create(user)
|
||||
|
||||
require.Nil(t, err)
|
||||
require.NotEmpty(t, signature)
|
||||
}
|
||||
|
||||
func Test_VerifyToken(t *testing.T) {
|
||||
token := New()
|
||||
user := createRandomUser()
|
||||
signature, _ := token.Create(user)
|
||||
payload, err := token.Verify(signature)
|
||||
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, user, payload.User)
|
||||
}
|
||||
|
||||
func Test_VerifyToken_InvalidToken(t *testing.T) {
|
||||
token := New()
|
||||
_, err := token.Verify("invalid-token")
|
||||
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
|
||||
func isValidUUID(u uuid.UUID) bool {
|
||||
_, err := uuid.Parse(u.String())
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func createRandomUser() UserPayload {
|
||||
return UserPayload{
|
||||
Username: esfaker.Chars(5, 10),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user