draincloud-core/internal/app/auth.go

64 lines
1.4 KiB
Go

package app
import (
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"log/slog"
"net/http"
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
"github.com/gin-gonic/gin"
)
const (
csrfTokenCookie = "__Csrf_token"
sessionTokenCookie = "__Session_token"
)
var (
ErrorUnauthorized = errors.New("unauthorized")
)
func (d *DrainCloud) authorize(ctx *gin.Context) (*models.Session, error) {
session, err := d.getSession(ctx)
if err != nil && !errors.Is(err, http.ErrNoCookie) {
return nil, ErrorUnauthorized
}
if session == nil {
return nil, ErrorUnauthorized
}
if err := validateSession(ctx, session); err != nil {
// TODO add audit log entry
return nil, ErrorUnauthorized
}
logger.Debug(ctx, "[authorize] user authorized", slog.String("session_id", session.ID.String()))
return session, nil
}
func validateLoginAndPassword(login, password string) error {
if len(login) < 4 {
return fmt.Errorf("login must be longer than 8 chars")
}
if len(password) < 6 {
return fmt.Errorf("password must be longer than 8 chars")
}
return nil
}
func generateSessionToken(length int) (string, error) {
bytes := make([]byte, length)
if _, err := rand.Read(bytes); err != nil {
return "", fmt.Errorf("failed to generate token: %w", err)
}
return base64.URLEncoding.EncodeToString(bytes), nil
}