From fbcac585cf626917e2baf1d0065c7b632341ba01 Mon Sep 17 00:00:00 2001 From: Gabriel Arakaki Giovanini Date: Wed, 19 Jul 2023 21:01:23 +0200 Subject: ref: Move auth functions to service --- pkg/service/auth.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 3 deletions(-) (limited to 'pkg/service/auth.go') diff --git a/pkg/service/auth.go b/pkg/service/auth.go index 761c70b..1966e70 100644 --- a/pkg/service/auth.go +++ b/pkg/service/auth.go @@ -1,12 +1,18 @@ package service import ( + "bytes" "context" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/gob" + "errors" + "io" "golang.org/x/crypto/bcrypt" "git.sr.ht/~gabrielgio/img/pkg/database/repository" - "git.sr.ht/~gabrielgio/img/pkg/ext" ) type AuthController struct { @@ -42,11 +48,11 @@ func (c *AuthController) Login(ctx context.Context, username, password []byte) ( return nil, err } - token := &ext.Token{ + token := &Token{ UserID: id, Username: string(username), } - return ext.WriteToken(token, c.key) + return WriteToken(token, c.key) } // InitialRegister register a initial user, it will validate if there is another @@ -75,3 +81,64 @@ func (c *AuthController) InitialRegister(ctx context.Context, username, password return err } + +type Token struct { + UserID uint + Username string +} + +func ReadToken(data []byte, key []byte) (*Token, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + panic(err.Error()) + } + + nonceSize := aesgcm.NonceSize() + if len(data) < nonceSize { + return nil, errors.New("nonce size greater than data's size") + } + + nonce, ciphertext := data[:nonceSize], data[nonceSize:] + plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil) + if err != nil { + return nil, err + } + + r := bytes.NewReader(plaintext) + var token Token + dec := gob.NewDecoder(r) + if err = dec.Decode(&token); err != nil { + return nil, err + } + return &token, nil +} + +func WriteToken(token *Token, key []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + var buffer bytes.Buffer + enc := gob.NewEncoder(&buffer) + if err := enc.Encode(token); err != nil { + return nil, err + } + nonce := make([]byte, aesgcm.NonceSize()) + if _, err = io.ReadFull(rand.Reader, nonce); err != nil { + return nil, err + } + + ciphertext := aesgcm.Seal(nonce, nonce, buffer.Bytes(), nil) + return ciphertext, nil +} -- cgit v1.2.3