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 }