tmp
This commit is contained in:
parent
24f225f68b
commit
b9d8aa6525
12
.mockery.yaml
Normal file
12
.mockery.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
filename: "mock_{{.InterfaceName}}.go"
|
||||
dir: "mocks/{{.PackagePath}}"
|
||||
outpkg: "{{.PackageName}}"
|
||||
with-expecter: true
|
||||
packages:
|
||||
git.optclblast.xyz/draincloud/draincloud-core/internal/storage:
|
||||
interfaces:
|
||||
Database:
|
||||
AuthAuditLogStorage:
|
||||
AuthStorage:
|
||||
BlobStorage:
|
||||
MetaStorage:
|
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Package",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}/cmd/main.go"
|
||||
|
||||
}
|
||||
]
|
||||
}
|
13
cmd/main.go
13
cmd/main.go
@ -2,20 +2,29 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/app"
|
||||
cleanupsessions "git.optclblast.xyz/draincloud/draincloud-core/internal/cron/cleanup_sessions"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/plugin"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/postgres"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
||||
defer cancel()
|
||||
|
||||
plugin.MustNewPluginLoader(ctx, 8081, plugin.NewPluginStore()).
|
||||
Run(ctx)
|
||||
|
||||
pg := postgres.New(ctx, "postgres://draincloud:draincloud@localhost:5432/draincloud?sslmode=disable")
|
||||
|
||||
app.New(pg).
|
||||
cleanupSessionsCron := cleanupsessions.New(pg)
|
||||
cleanupSessionsCron.Run(ctx)
|
||||
|
||||
go app.New(pg).
|
||||
Run(ctx)
|
||||
|
||||
<-ctx.Done()
|
||||
}
|
||||
|
4
go.mod
4
go.mod
@ -3,12 +3,14 @@ module git.optclblast.xyz/draincloud/draincloud-core
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
github.com/fatih/color v1.17.0
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/jackc/pgx/v5 v5.7.1
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/spf13/viper v1.19.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/crypto v0.28.0
|
||||
)
|
||||
|
||||
@ -36,6 +38,7 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
@ -43,6 +46,7 @@ require (
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
|
1
go.sum
1
go.sum
@ -105,6 +105,7 @@ github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
|
@ -2,31 +2,31 @@ package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/domain"
|
||||
filesengine "git.optclblast.xyz/draincloud/draincloud-core/internal/files_engine"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type DrainCloud struct {
|
||||
mux *gin.Engine
|
||||
datadase storage.Database
|
||||
database storage.Database
|
||||
filesEngine *filesengine.FilesEngine
|
||||
}
|
||||
|
||||
func New(
|
||||
datadase storage.Database,
|
||||
database storage.Database,
|
||||
filesEngine *filesengine.FilesEngine,
|
||||
) *DrainCloud {
|
||||
mux := gin.Default()
|
||||
|
||||
d := &DrainCloud{
|
||||
datadase: datadase,
|
||||
database: database,
|
||||
filesEngine: filesEngine,
|
||||
}
|
||||
|
||||
// Built-in auth component of DrainCloud-Core
|
||||
@ -34,7 +34,17 @@ func New(
|
||||
{
|
||||
authGroup.POST("/register", d.Register)
|
||||
authGroup.POST("/login", d.Login)
|
||||
authGroup.POST("/logout", d.Logout)
|
||||
}
|
||||
|
||||
filesGroup := mux.Group("/files")
|
||||
{
|
||||
filesGroup.POST("/upload", func(ctx *gin.Context) {
|
||||
err := d.uploadFile(ctx)
|
||||
if err != nil {
|
||||
logger.Error(ctx.Request.Context(), "", logger.Err(err))
|
||||
ctx.String(400, err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
d.mux = mux
|
||||
@ -46,95 +56,22 @@ func (d *DrainCloud) Run(ctx context.Context) error {
|
||||
return d.mux.Run()
|
||||
}
|
||||
|
||||
func (d *DrainCloud) Register(ctx *gin.Context) {
|
||||
logger.Debug(ctx, "[register] new request")
|
||||
|
||||
req := new(domain.RegisterRequest)
|
||||
err := ctx.BindJSON(req)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[register] failed to bind request", logger.Err(err))
|
||||
ctx.JSON(http.StatusBadRequest, map[string]string{
|
||||
"error": "bad request",
|
||||
func writeError(ctx *gin.Context, err error) {
|
||||
switch {
|
||||
case errors.Is(err, ErrorAccessDenied):
|
||||
ctx.JSON(http.StatusInternalServerError, domain.ErrorJson{
|
||||
Code: http.StatusForbidden,
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
_, err = d.register(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[register] failed to register user", logger.Err(err))
|
||||
ctx.JSON(http.StatusBadRequest, map[string]string{
|
||||
"error": err.Error(),
|
||||
case errors.Is(err, ErrorSessionExpired):
|
||||
ctx.JSON(http.StatusInternalServerError, domain.ErrorJson{
|
||||
Code: http.StatusForbidden,
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, map[string]bool{
|
||||
"ok": true,
|
||||
default:
|
||||
ctx.JSON(http.StatusInternalServerError, domain.ErrorJson{
|
||||
Code: http.StatusInternalServerError,
|
||||
Message: "Internal Error",
|
||||
})
|
||||
}
|
||||
|
||||
type registerResult struct {
|
||||
// cookies []http.Cookie
|
||||
}
|
||||
|
||||
func (d *DrainCloud) register(ctx *gin.Context, req *domain.RegisterRequest) (*registerResult, error) {
|
||||
if err := validateLoginAndPassword(req.Login, req.Password); err != nil {
|
||||
return nil, fmt.Errorf("invalid creds: %w", err)
|
||||
}
|
||||
|
||||
passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 10)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[register] failed to generate password", logger.Err(err))
|
||||
return nil, fmt.Errorf("failed to generate password: %w", err)
|
||||
}
|
||||
|
||||
_, err = d.datadase.AddUser(ctx, req.Login, req.Login, passwordHash)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to add new user: %w", err)
|
||||
}
|
||||
|
||||
sessionToken, err := generateSessionToken(100)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate a session token: %w", err)
|
||||
}
|
||||
|
||||
ctx.SetCookie("__Session_token", sessionToken, int((time.Hour * 24).Seconds()), "_path", "_domain", true, true)
|
||||
|
||||
csrfToken, err := generateSessionToken(100)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate a csrf token: %w", err)
|
||||
}
|
||||
|
||||
ctx.SetCookie("__Csrf_token", csrfToken, int((time.Hour * 24).Seconds()), "_path", "_domain", true, false)
|
||||
|
||||
// TODO save session into database
|
||||
|
||||
return ®isterResult{}, 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
|
||||
}
|
||||
|
||||
func (d *DrainCloud) Login(ctx *gin.Context) {
|
||||
|
||||
}
|
||||
func (d *DrainCloud) Logout(ctx *gin.Context) {
|
||||
|
||||
}
|
||||
|
63
internal/app/auth.go
Normal file
63
internal/app/auth.go
Normal file
@ -0,0 +1,63 @@
|
||||
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.Int64("session_id", session.ID))
|
||||
|
||||
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
|
||||
}
|
156
internal/app/login.go
Normal file
156
internal/app/login.go
Normal file
@ -0,0 +1,156 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/domain"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrorAccessDenied = errors.New("access denied")
|
||||
ErrorSessionExpired = errors.New("session expired")
|
||||
)
|
||||
|
||||
func (d *DrainCloud) Login(ctx *gin.Context) {
|
||||
logger.Debug(ctx, "[Login] new request")
|
||||
|
||||
req := new(domain.LoginRequest)
|
||||
err := ctx.BindJSON(req)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[Login] failed to bind request", logger.Err(err))
|
||||
ctx.JSON(http.StatusBadRequest, map[string]string{
|
||||
"error": "bad request",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := d.login(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[Login] failed to login user", logger.Err(err))
|
||||
ctx.JSON(http.StatusInternalServerError, map[string]string{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, resp)
|
||||
}
|
||||
|
||||
func (d *DrainCloud) login(ctx *gin.Context, req *domain.LoginRequest) (*domain.LoginResponse, error) {
|
||||
session, err := d.getSession(ctx)
|
||||
if err != nil && !errors.Is(err, http.ErrNoCookie) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if session != nil {
|
||||
if err := validateSession(ctx, session); err != nil {
|
||||
// TODO add audit log entry
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logger.Debug(ctx, "[login] user is already logged in", slog.Int64("session_id", session.ID))
|
||||
return &domain.LoginResponse{
|
||||
Ok: true,
|
||||
}, nil
|
||||
}
|
||||
logger.Debug(ctx, "[login] session not found. trying to authorize")
|
||||
|
||||
passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 10)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[login] failed to generate password hash", logger.Err(err))
|
||||
return nil, fmt.Errorf("failed to generate password hash: %w", err)
|
||||
}
|
||||
|
||||
user, err := d.database.GetUserByLogin(ctx, req.Login)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch user by login: %w", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(passwordHash, user.PasswordHash) {
|
||||
logger.Warn(ctx, "[login] failed to login user. passwords hashes not equal")
|
||||
return nil, ErrorAccessDenied
|
||||
}
|
||||
|
||||
sessionCreatedAt := time.Now()
|
||||
sessionExpiredAt := sessionCreatedAt.Add(time.Hour * 24 * 7)
|
||||
|
||||
sessionToken, err := generateSessionToken(100)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate a session token: %w", err)
|
||||
}
|
||||
ctx.SetCookie(sessionTokenCookie, sessionToken, int(sessionExpiredAt.Sub(sessionCreatedAt).Seconds()), "_path", "_domain", true, true)
|
||||
|
||||
csrfToken, err := generateSessionToken(100)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate a csrf token: %w", err)
|
||||
}
|
||||
ctx.SetCookie(csrfTokenCookie, csrfToken, int(sessionExpiredAt.Sub(sessionCreatedAt).Seconds()), "_path", "_domain", true, false)
|
||||
|
||||
if _, err = d.database.AddSession(ctx, &models.Session{
|
||||
SessionToken: sessionToken,
|
||||
CsrfToken: csrfToken,
|
||||
UserID: user.ID,
|
||||
CreatedAt: sessionCreatedAt,
|
||||
ExpiredAt: sessionExpiredAt,
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed to save session: %w", err)
|
||||
}
|
||||
|
||||
// TODO add audit log entry
|
||||
|
||||
return &domain.LoginResponse{
|
||||
Ok: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DrainCloud) getSession(ctx *gin.Context) (*models.Session, error) {
|
||||
token, err := ctx.Cookie(sessionTokenCookie)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch session cookie from request: %w", err)
|
||||
}
|
||||
csrfToken, err := ctx.Cookie(csrfTokenCookie)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch csrf cookie from request: %w", err)
|
||||
}
|
||||
|
||||
if len(csrfToken) == 0 || len(token) == 0 {
|
||||
return nil, fmt.Errorf("session token or csrf token is empty")
|
||||
}
|
||||
|
||||
session, err := d.database.GetSession(ctx, token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch session from repo: %w", err)
|
||||
}
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func validateSession(ctx *gin.Context, session *models.Session) error {
|
||||
if session == nil {
|
||||
return ErrorAccessDenied
|
||||
}
|
||||
|
||||
csrfToken, err := ctx.Cookie(csrfTokenCookie)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch csrf cookie from request: %w", err)
|
||||
}
|
||||
|
||||
if session.CsrfToken != csrfToken {
|
||||
return ErrorAccessDenied
|
||||
}
|
||||
|
||||
if session.ExpiredAt.Before(time.Now()) {
|
||||
return ErrorSessionExpired
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
28
internal/app/middleware.go
Normal file
28
internal/app/middleware.go
Normal file
@ -0,0 +1,28 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/reqcontext"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type authorizer interface {
|
||||
authorize(ctx *gin.Context) (*models.Session, error)
|
||||
}
|
||||
|
||||
func WithAuth(handler gin.HandlerFunc, auth authorizer) gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
sess, err := auth.authorize(ctx)
|
||||
if err != nil {
|
||||
writeError(ctx, err)
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
authCtx := reqcontext.WithSession(ctx.Request.Context(), sess)
|
||||
authCtx = reqcontext.WithUserID(authCtx, sess.UserID)
|
||||
ctx.Request = ctx.Request.WithContext(authCtx)
|
||||
|
||||
handler(ctx)
|
||||
}
|
||||
}
|
93
internal/app/register.go
Normal file
93
internal/app/register.go
Normal file
@ -0,0 +1,93 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/domain"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func (d *DrainCloud) Register(ctx *gin.Context) {
|
||||
logger.Debug(ctx, "[register] new request")
|
||||
|
||||
// TODO check if registration is enabled
|
||||
|
||||
req := new(domain.RegisterRequest)
|
||||
err := ctx.BindJSON(req)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[register] failed to bind request", logger.Err(err))
|
||||
ctx.JSON(http.StatusBadRequest, map[string]string{
|
||||
"error": "bad request",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := d.register(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[register] failed to register user", logger.Err(err))
|
||||
ctx.JSON(http.StatusInternalServerError, map[string]string{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, resp)
|
||||
}
|
||||
|
||||
func (d *DrainCloud) register(ctx *gin.Context, req *domain.RegisterRequest) (*domain.RegisterResponse, error) {
|
||||
if err := validateLoginAndPassword(req.Login, req.Password); err != nil {
|
||||
return nil, fmt.Errorf("invalid creds: %w", err)
|
||||
}
|
||||
|
||||
passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 10)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "[register] failed to generate password hash", logger.Err(err))
|
||||
return nil, fmt.Errorf("failed to generate password hash: %w", err)
|
||||
}
|
||||
|
||||
user := &models.User{
|
||||
Username: req.Login,
|
||||
Login: req.Login,
|
||||
PasswordHash: passwordHash,
|
||||
}
|
||||
|
||||
userID, err := d.database.AddUser(ctx, user.Login, user.Username, user.PasswordHash)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to add new user: %w", err)
|
||||
}
|
||||
user.ID = userID
|
||||
|
||||
sessionCreatedAt := time.Now()
|
||||
sessionExpiredAt := sessionCreatedAt.Add(time.Hour * 24 * 7)
|
||||
|
||||
sessionToken, err := generateSessionToken(100)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate a session token: %w", err)
|
||||
}
|
||||
ctx.SetCookie(sessionTokenCookie, sessionToken, int(sessionExpiredAt.Sub(sessionCreatedAt).Seconds()), "_path", "_domain", true, true)
|
||||
|
||||
csrfToken, err := generateSessionToken(100)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate a csrf token: %w", err)
|
||||
}
|
||||
ctx.SetCookie(csrfTokenCookie, csrfToken, int(sessionExpiredAt.Sub(sessionCreatedAt).Seconds()), "_path", "_domain", true, false)
|
||||
|
||||
if _, err = d.database.AddSession(ctx, &models.Session{
|
||||
SessionToken: sessionToken,
|
||||
CsrfToken: csrfToken,
|
||||
UserID: user.ID,
|
||||
CreatedAt: sessionCreatedAt,
|
||||
ExpiredAt: sessionExpiredAt,
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed to save session: %w", err)
|
||||
}
|
||||
|
||||
return &domain.RegisterResponse{
|
||||
Ok: true,
|
||||
}, nil
|
||||
}
|
52
internal/app/upload_file.go
Normal file
52
internal/app/upload_file.go
Normal file
@ -0,0 +1,52 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log/slog"
|
||||
|
||||
filesengine "git.optclblast.xyz/draincloud/draincloud-core/internal/files_engine"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
maxFileSize = 10 << 30
|
||||
)
|
||||
|
||||
func (d *DrainCloud) UploadFile(ctx *gin.Context) {
|
||||
if err := ctx.Request.ParseMultipartForm(maxFileSize); err != nil {
|
||||
logger.Error(ctx, "uploadFile handler error", logger.Err(err))
|
||||
writeError(ctx, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := d.uploadFile(ctx); err != nil {
|
||||
logger.Error(ctx, "uploadFile handle", logger.Err(err))
|
||||
writeError(ctx, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DrainCloud) uploadFile(ctx *gin.Context) error {
|
||||
title := ctx.PostForm("file")
|
||||
logger.Info(ctx, "uploadFile", slog.Any("postForm data", spew.Sdump(title)))
|
||||
|
||||
file, header, err := ctx.Request.FormFile("file")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info(ctx, "uploadFile", slog.Any("header", spew.Sdump(header)))
|
||||
|
||||
data, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.filesEngine.SaveFile(ctx, filesengine.File{
|
||||
Name: header.Filename,
|
||||
// UserID: ,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
46
internal/cron/cleanup_sessions/cleanup_session.go
Normal file
46
internal/cron/cleanup_sessions/cleanup_session.go
Normal file
@ -0,0 +1,46 @@
|
||||
package cleanupsessions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
|
||||
)
|
||||
|
||||
// TODO set with config
|
||||
const cronInterval = time.Minute * 10
|
||||
|
||||
type ExpiredSessionsRemover interface {
|
||||
RemoveExpiredSessions(ctx context.Context) error
|
||||
}
|
||||
|
||||
type CleanupSessionCron struct {
|
||||
db ExpiredSessionsRemover
|
||||
}
|
||||
|
||||
func New(db ExpiredSessionsRemover) *CleanupSessionCron {
|
||||
return &CleanupSessionCron{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CleanupSessionCron) Run(ctx context.Context) {
|
||||
logger.Info(ctx, "[CleanupSessionCron] running cron")
|
||||
go func() {
|
||||
t := time.NewTicker(cronInterval)
|
||||
defer t.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
logger.Warn(ctx, "[CleanupSessionCron] context cancelled")
|
||||
return
|
||||
case <-t.C:
|
||||
logger.Notice(ctx, "[CleanupSessionCron] cleanup started")
|
||||
t.Reset(cronInterval)
|
||||
if err := c.db.RemoveExpiredSessions(ctx); err != nil {
|
||||
logger.Error(ctx, "[CleanupSessionCron] failed to remove expired sessions", logger.Err(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
7
internal/cron/cron.go
Normal file
7
internal/cron/cron.go
Normal file
@ -0,0 +1,7 @@
|
||||
package cron
|
||||
|
||||
import "context"
|
||||
|
||||
type Cron interface {
|
||||
Run(ctx context.Context)
|
||||
}
|
1
internal/domain/files.go
Normal file
1
internal/domain/files.go
Normal file
@ -0,0 +1 @@
|
||||
package domain
|
@ -15,5 +15,15 @@ type LoginRequest struct {
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type LogoutRequest struct {
|
||||
}
|
||||
|
||||
type ErrorJson struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
39
internal/files_engine/engine.go
Normal file
39
internal/files_engine/engine.go
Normal file
@ -0,0 +1,39 @@
|
||||
package filesengine
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage"
|
||||
)
|
||||
|
||||
type FilesEngine struct {
|
||||
blobStorage storage.BlobStorage
|
||||
metaStorage storage.MetaStorage
|
||||
}
|
||||
|
||||
func NewFilesEngine(
|
||||
blobStorage storage.BlobStorage,
|
||||
metaStorage storage.MetaStorage,
|
||||
) *FilesEngine {
|
||||
return &FilesEngine{
|
||||
blobStorage: blobStorage,
|
||||
metaStorage: metaStorage,
|
||||
}
|
||||
}
|
||||
|
||||
type File struct {
|
||||
Name string
|
||||
UserID int64
|
||||
Ext string
|
||||
Type string
|
||||
Size int64
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func (e *FilesEngine) SaveFile(
|
||||
ctx context.Context,
|
||||
file File,
|
||||
) (int64, error) {
|
||||
|
||||
return -1, nil
|
||||
}
|
@ -7,7 +7,11 @@ import (
|
||||
)
|
||||
|
||||
//nolint:gochecknoglobals // ...
|
||||
var globalLogger *slog.Logger = newLogger(LevelInfo, os.Stdout)
|
||||
var globalLogger *slog.Logger = newLogger(LevelDebug, os.Stdout)
|
||||
|
||||
func SetLevel(l slog.Level) {
|
||||
globalLogger = newLogger(l, os.Stdout)
|
||||
}
|
||||
|
||||
const (
|
||||
LevelEmergency = slog.Level(10000)
|
||||
@ -73,5 +77,5 @@ func Info(ctx context.Context, message string, attrs ...any) {
|
||||
func Debug(ctx context.Context, message string, attrs ...any) {
|
||||
l := loggerFromCtx(ctx)
|
||||
|
||||
l.Log(ctx, LevelCritial, message, attrs...)
|
||||
l.DebugContext(ctx, message, attrs...)
|
||||
}
|
||||
|
37
internal/reqcontext/auth.go
Normal file
37
internal/reqcontext/auth.go
Normal file
@ -0,0 +1,37 @@
|
||||
package reqcontext
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
|
||||
)
|
||||
|
||||
type CtxKey string
|
||||
|
||||
const (
|
||||
UserIDCtxKey CtxKey = "_ctx_user_id"
|
||||
SessionCtxKey CtxKey = "_ctx_session"
|
||||
)
|
||||
|
||||
func WithUserID(parent context.Context, userID int64) context.Context {
|
||||
return context.WithValue(parent, UserIDCtxKey, userID)
|
||||
}
|
||||
|
||||
func GetUserID(ctx context.Context) (int64, error) {
|
||||
if id, ok := ctx.Value(UserIDCtxKey).(int64); ok {
|
||||
return id, nil
|
||||
}
|
||||
return -1, fmt.Errorf("userID not passed with context")
|
||||
}
|
||||
|
||||
func WithSession(parent context.Context, session *models.Session) context.Context {
|
||||
return context.WithValue(parent, SessionCtxKey, session)
|
||||
}
|
||||
|
||||
func GetSession(ctx context.Context) (*models.Session, error) {
|
||||
if ses, ok := ctx.Value(UserIDCtxKey).(*models.Session); ok {
|
||||
return ses, nil
|
||||
}
|
||||
return nil, fmt.Errorf("session not passed with context")
|
||||
}
|
19
internal/storage/audit/storage.go
Normal file
19
internal/storage/audit/storage.go
Normal file
@ -0,0 +1,19 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/audit"
|
||||
)
|
||||
|
||||
type Repository struct {
|
||||
db *pgx.Conn
|
||||
}
|
||||
|
||||
func (r *Repository) AddEntry(ctx context.Context, entry audit.AuditLogEntry) error {
|
||||
logger.Warn(ctx, "[Repository][AddEntry] not implemented yet!")
|
||||
return nil
|
||||
}
|
86
internal/storage/filestorage/fs/storage.go
Normal file
86
internal/storage/filestorage/fs/storage.go
Normal file
@ -0,0 +1,86 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
|
||||
)
|
||||
|
||||
type Storage struct {
|
||||
lm *sync.Map
|
||||
dir string
|
||||
}
|
||||
|
||||
func NewFSStorage(dir string) *Storage {
|
||||
return &Storage{
|
||||
lm: &sync.Map{},
|
||||
dir: dir,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Storage) GetFile(ctx context.Context, id int64) (*os.File, error) {
|
||||
tx := lockFile(s.lm, id)
|
||||
defer unlockFile(s.lm, id, tx)
|
||||
|
||||
file, err := os.Open(getFilePath(s.dir, id))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open file: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err = file.Close(); err != nil {
|
||||
logger.Error(ctx, "[getFile] close error", logger.Err(err))
|
||||
}
|
||||
}()
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
||||
func (s *Storage) SaveBlob(ctx context.Context, id int64, data []byte) error {
|
||||
tx := lockFile(s.lm, id)
|
||||
defer unlockFile(s.lm, id, tx)
|
||||
|
||||
file, err := os.Open(getFilePath(s.dir, id))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open file: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err = file.Close(); err != nil {
|
||||
logger.Error(ctx, "[saveFile] close error", logger.Err(err))
|
||||
}
|
||||
}()
|
||||
|
||||
if _, err = file.Write(data); err != nil {
|
||||
return fmt.Errorf("failed to write data to file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Storage) DeleteFile(ctx context.Context, id int64) error {
|
||||
tx := lockFile(s.lm, id)
|
||||
defer unlockFile(s.lm, id, tx)
|
||||
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getFilePath(dir string, id int64) string {
|
||||
return fmt.Sprintf("%s/%v", dir, id)
|
||||
}
|
||||
|
||||
func lockFile(lm *sync.Map, id int64) sync.Locker {
|
||||
_m := &sync.Mutex{}
|
||||
many, _ := lm.LoadOrStore(id, _m)
|
||||
_m, _ = many.(*sync.Mutex)
|
||||
_m.Lock()
|
||||
return _m
|
||||
}
|
||||
|
||||
func unlockFile(lm *sync.Map, id int64, tx sync.Locker) {
|
||||
tx.Unlock()
|
||||
lm.Delete(id)
|
||||
}
|
@ -2,8 +2,10 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
|
||||
auditmodels "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/audit"
|
||||
)
|
||||
|
||||
type Database interface {
|
||||
@ -11,7 +13,25 @@ type Database interface {
|
||||
}
|
||||
|
||||
type AuthStorage interface {
|
||||
AddUser(ctx context.Context, login string, username string, passwordHash []byte) (uint64, error)
|
||||
AddUser(ctx context.Context, login string, username string, passwordHash []byte) (int64, error)
|
||||
GetUserByLogin(ctx context.Context, login string) (*models.User, error)
|
||||
GetUserByID(ctx context.Context, id uint64) (*models.User, error)
|
||||
|
||||
AddSession(ctx context.Context, ses *models.Session) (int64, error)
|
||||
GetSession(ctx context.Context, sessionToken string) (*models.Session, error)
|
||||
RemoveSession(ctx context.Context, id int64) error
|
||||
}
|
||||
|
||||
type AuthAuditLogStorage interface {
|
||||
AddEntry(ctx context.Context, entry auditmodels.AuditLogEntry) error
|
||||
}
|
||||
|
||||
type MetaStorage interface {
|
||||
SaveMetadata(ctx context.Context, fileType string, size int64, ext string) (int64, error)
|
||||
}
|
||||
|
||||
type BlobStorage interface {
|
||||
GetFile(ctx context.Context, id int64) (*os.File, error)
|
||||
SaveBlob(ctx context.Context, id int64, data []byte) error
|
||||
DeleteFile(ctx context.Context, id int64) error
|
||||
}
|
||||
|
49
internal/storage/models/audit/audit_log.go
Normal file
49
internal/storage/models/audit/audit_log.go
Normal file
@ -0,0 +1,49 @@
|
||||
package audit
|
||||
|
||||
import "time"
|
||||
|
||||
type EventType int
|
||||
|
||||
const (
|
||||
EventUnspecified EventType = iota
|
||||
EventSuccessfullLogin
|
||||
EventFailedLogin
|
||||
EventSuccessfullRegister
|
||||
EventFailedRegister
|
||||
EventSuccessfullAuth
|
||||
EventFailedAuth
|
||||
EventUserUpdated
|
||||
)
|
||||
|
||||
type Severity int
|
||||
|
||||
const (
|
||||
SeverityAlert = 0
|
||||
SeverityWarning = 10
|
||||
SeverityInfo = 100
|
||||
SeverityNotice = 200
|
||||
)
|
||||
|
||||
type Actor struct {
|
||||
ActorSysName string
|
||||
RemoteIP string
|
||||
ID int64
|
||||
}
|
||||
|
||||
const (
|
||||
ActorDrainCloudCore = "_actor_draincloud_core"
|
||||
ActorUser = "user"
|
||||
)
|
||||
|
||||
type AuditLogEntry struct {
|
||||
EventType EventType
|
||||
// Who caused changes
|
||||
Actor Actor
|
||||
Severity Severity
|
||||
SessionID int64
|
||||
CreatedAt time.Time
|
||||
// What changed
|
||||
Object string
|
||||
// How it was changed
|
||||
Action string
|
||||
}
|
@ -3,16 +3,16 @@ package models
|
||||
import "time"
|
||||
|
||||
type Session struct {
|
||||
ID string
|
||||
ID int64
|
||||
SessionToken string
|
||||
CsrfToken string
|
||||
User *User
|
||||
UserID int64
|
||||
CreatedAt time.Time
|
||||
ExpiredAt time.Time
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID uint64
|
||||
ID int64
|
||||
Username string
|
||||
Login string
|
||||
PasswordHash []byte
|
||||
|
@ -2,7 +2,9 @@ package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"git.optclblast.xyz/draincloud/draincloud-core/internal/closer"
|
||||
@ -37,7 +39,7 @@ type dbtx interface {
|
||||
Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)
|
||||
}
|
||||
|
||||
func (d *Database) AddUser(ctx context.Context, login string, username string, passwordHash []byte) (uint64, error) {
|
||||
func (d *Database) AddUser(ctx context.Context, login string, username string, passwordHash []byte) (int64, error) {
|
||||
return addUser(ctx, d.db, login, username, passwordHash)
|
||||
}
|
||||
|
||||
@ -49,18 +51,59 @@ func (d *Database) GetUserByLogin(ctx context.Context, login string) (*models.Us
|
||||
return getUserByLogin(ctx, d.db, login)
|
||||
}
|
||||
|
||||
func (d *Database) AddSession(ctx context.Context, ses *models.Session) (uint64, error) {
|
||||
func (d *Database) AddSession(ctx context.Context, ses *models.Session) (int64, error) {
|
||||
return addSession(ctx, d.db, ses)
|
||||
}
|
||||
|
||||
func addUser(ctx context.Context, conn dbtx, login string, username string, passwordHash []byte) (uint64, error) {
|
||||
func (d *Database) GetSession(ctx context.Context, sessionToken string) (*models.Session, error) {
|
||||
const stmt = `SELECT
|
||||
s.id, s.session_token, s.csrf_token, s.user_id, s.created_at, s.expired_at
|
||||
FROM sessions as s
|
||||
WHERE s.session_token = $1;`
|
||||
|
||||
row := d.db.QueryRow(ctx, stmt, sessionToken)
|
||||
|
||||
var (
|
||||
id int64
|
||||
sesToken, csrfToken string
|
||||
userID int64
|
||||
createdAt sql.NullTime
|
||||
expiredAt sql.NullTime
|
||||
)
|
||||
|
||||
if err := row.Scan(&id, &sesToken, &csrfToken, &userID, &createdAt, &expiredAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.Session{
|
||||
ID: id,
|
||||
SessionToken: sesToken,
|
||||
CsrfToken: csrfToken,
|
||||
UserID: userID,
|
||||
CreatedAt: createdAt.Time,
|
||||
ExpiredAt: expiredAt.Time,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Database) RemoveSession(ctx context.Context, id int64) error {
|
||||
const stmt = `DELETE FROM sessions WHERE id = $1;`
|
||||
_, err := d.db.Exec(ctx, stmt, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) RemoveExpiredSessions(ctx context.Context) error {
|
||||
const stmt = `DELETE FROM sessions WHERE expired_at < $1;`
|
||||
res, err := d.db.Exec(ctx, stmt, time.Now())
|
||||
logger.Notice(ctx, "[Database][RemoveExpiredSessions] sessions cleanup", slog.Int64("removed", res.RowsAffected()))
|
||||
return err
|
||||
}
|
||||
|
||||
func addUser(ctx context.Context, conn dbtx, login string, username string, passwordHash []byte) (int64, error) {
|
||||
const stmt = `INSERT INTO users (login,username,password)
|
||||
VALUES ($1,$2,$3) RETURNING id`
|
||||
|
||||
row := conn.QueryRow(ctx, stmt, login, username, passwordHash)
|
||||
|
||||
var id uint64
|
||||
|
||||
var id int64
|
||||
if err := row.Scan(&id); err != nil {
|
||||
return 0, fmt.Errorf("failed to insert user data into users table: %w", err)
|
||||
}
|
||||
@ -71,7 +114,6 @@ func addUser(ctx context.Context, conn dbtx, login string, username string, pass
|
||||
func getUserByID(ctx context.Context, conn dbtx, id uint64) (*models.User, error) {
|
||||
const stmt = `SELECT * FROM users WHERE id = $1 LIMIT 1`
|
||||
u := new(models.User)
|
||||
|
||||
row := conn.QueryRow(ctx, stmt, id)
|
||||
if err := row.Scan(&u.ID, &u.Login, &u.Username, &u.PasswordHash, &u.CreatedAt, &u.UpdatedAt); err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch user by id: %w", err)
|
||||
@ -83,7 +125,6 @@ func getUserByID(ctx context.Context, conn dbtx, id uint64) (*models.User, error
|
||||
func getUserByLogin(ctx context.Context, conn dbtx, login string) (*models.User, error) {
|
||||
const stmt = `SELECT * FROM users WHERE login = $1 LIMIT 1`
|
||||
u := new(models.User)
|
||||
|
||||
row := conn.QueryRow(ctx, stmt, login)
|
||||
if err := row.Scan(&u.ID, &u.Login, &u.Username, &u.PasswordHash, &u.CreatedAt, &u.UpdatedAt); err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch user by login: %w", err)
|
||||
@ -92,11 +133,11 @@ func getUserByLogin(ctx context.Context, conn dbtx, login string) (*models.User,
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func addSession(ctx context.Context, conn dbtx, session *models.Session) (uint64, error) {
|
||||
func addSession(ctx context.Context, conn dbtx, session *models.Session) (int64, error) {
|
||||
const stmt = `INSERT INTO sessions (session_token, csrf_token, user_id,
|
||||
created_at, expired_at) VALUES ($1, $2, $3, $4, $5) RETURNING id;`
|
||||
var id uint64
|
||||
row := conn.QueryRow(ctx, stmt, session.SessionToken, session.CsrfToken, session.User.ID, session.CreatedAt, session.ExpiredAt)
|
||||
var id int64
|
||||
row := conn.QueryRow(ctx, stmt, session.SessionToken, session.CsrfToken, session.UserID, session.CreatedAt, session.ExpiredAt)
|
||||
if err := row.Scan(&id); err != nil {
|
||||
return 0, fmt.Errorf("failed to insert new session: %w", err)
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
// Code generated by mockery v2.48.0. DO NOT EDIT.
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
audit "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/audit"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockAuthAuditLogStorage is an autogenerated mock type for the AuthAuditLogStorage type
|
||||
type MockAuthAuditLogStorage struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockAuthAuditLogStorage_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockAuthAuditLogStorage) EXPECT() *MockAuthAuditLogStorage_Expecter {
|
||||
return &MockAuthAuditLogStorage_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// AddEntry provides a mock function with given fields: ctx, entry
|
||||
func (_m *MockAuthAuditLogStorage) AddEntry(ctx context.Context, entry audit.AuditLogEntry) error {
|
||||
ret := _m.Called(ctx, entry)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddEntry")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, audit.AuditLogEntry) error); ok {
|
||||
r0 = rf(ctx, entry)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockAuthAuditLogStorage_AddEntry_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddEntry'
|
||||
type MockAuthAuditLogStorage_AddEntry_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AddEntry is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - entry audit.AuditLogEntry
|
||||
func (_e *MockAuthAuditLogStorage_Expecter) AddEntry(ctx interface{}, entry interface{}) *MockAuthAuditLogStorage_AddEntry_Call {
|
||||
return &MockAuthAuditLogStorage_AddEntry_Call{Call: _e.mock.On("AddEntry", ctx, entry)}
|
||||
}
|
||||
|
||||
func (_c *MockAuthAuditLogStorage_AddEntry_Call) Run(run func(ctx context.Context, entry audit.AuditLogEntry)) *MockAuthAuditLogStorage_AddEntry_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(audit.AuditLogEntry))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthAuditLogStorage_AddEntry_Call) Return(_a0 error) *MockAuthAuditLogStorage_AddEntry_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthAuditLogStorage_AddEntry_Call) RunAndReturn(run func(context.Context, audit.AuditLogEntry) error) *MockAuthAuditLogStorage_AddEntry_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockAuthAuditLogStorage creates a new instance of MockAuthAuditLogStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockAuthAuditLogStorage(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockAuthAuditLogStorage {
|
||||
mock := &MockAuthAuditLogStorage{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
@ -0,0 +1,377 @@
|
||||
// Code generated by mockery v2.48.0. DO NOT EDIT.
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
models "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockAuthStorage is an autogenerated mock type for the AuthStorage type
|
||||
type MockAuthStorage struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockAuthStorage_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockAuthStorage) EXPECT() *MockAuthStorage_Expecter {
|
||||
return &MockAuthStorage_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// AddSession provides a mock function with given fields: ctx, ses
|
||||
func (_m *MockAuthStorage) AddSession(ctx context.Context, ses *models.Session) (int64, error) {
|
||||
ret := _m.Called(ctx, ses)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddSession")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.Session) (int64, error)); ok {
|
||||
return rf(ctx, ses)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.Session) int64); ok {
|
||||
r0 = rf(ctx, ses)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *models.Session) error); ok {
|
||||
r1 = rf(ctx, ses)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockAuthStorage_AddSession_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddSession'
|
||||
type MockAuthStorage_AddSession_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AddSession is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - ses *models.Session
|
||||
func (_e *MockAuthStorage_Expecter) AddSession(ctx interface{}, ses interface{}) *MockAuthStorage_AddSession_Call {
|
||||
return &MockAuthStorage_AddSession_Call{Call: _e.mock.On("AddSession", ctx, ses)}
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_AddSession_Call) Run(run func(ctx context.Context, ses *models.Session)) *MockAuthStorage_AddSession_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*models.Session))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_AddSession_Call) Return(_a0 int64, _a1 error) *MockAuthStorage_AddSession_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_AddSession_Call) RunAndReturn(run func(context.Context, *models.Session) (int64, error)) *MockAuthStorage_AddSession_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// AddUser provides a mock function with given fields: ctx, login, username, passwordHash
|
||||
func (_m *MockAuthStorage) AddUser(ctx context.Context, login string, username string, passwordHash []byte) (int64, error) {
|
||||
ret := _m.Called(ctx, login, username, passwordHash)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddUser")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, []byte) (int64, error)); ok {
|
||||
return rf(ctx, login, username, passwordHash)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, []byte) int64); ok {
|
||||
r0 = rf(ctx, login, username, passwordHash)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, []byte) error); ok {
|
||||
r1 = rf(ctx, login, username, passwordHash)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockAuthStorage_AddUser_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddUser'
|
||||
type MockAuthStorage_AddUser_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AddUser is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - login string
|
||||
// - username string
|
||||
// - passwordHash []byte
|
||||
func (_e *MockAuthStorage_Expecter) AddUser(ctx interface{}, login interface{}, username interface{}, passwordHash interface{}) *MockAuthStorage_AddUser_Call {
|
||||
return &MockAuthStorage_AddUser_Call{Call: _e.mock.On("AddUser", ctx, login, username, passwordHash)}
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_AddUser_Call) Run(run func(ctx context.Context, login string, username string, passwordHash []byte)) *MockAuthStorage_AddUser_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].([]byte))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_AddUser_Call) Return(_a0 int64, _a1 error) *MockAuthStorage_AddUser_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_AddUser_Call) RunAndReturn(run func(context.Context, string, string, []byte) (int64, error)) *MockAuthStorage_AddUser_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetSession provides a mock function with given fields: ctx, sessionToken
|
||||
func (_m *MockAuthStorage) GetSession(ctx context.Context, sessionToken string) (*models.Session, error) {
|
||||
ret := _m.Called(ctx, sessionToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetSession")
|
||||
}
|
||||
|
||||
var r0 *models.Session
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.Session, error)); ok {
|
||||
return rf(ctx, sessionToken)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) *models.Session); ok {
|
||||
r0 = rf(ctx, sessionToken)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.Session)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, sessionToken)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockAuthStorage_GetSession_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSession'
|
||||
type MockAuthStorage_GetSession_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetSession is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - sessionToken string
|
||||
func (_e *MockAuthStorage_Expecter) GetSession(ctx interface{}, sessionToken interface{}) *MockAuthStorage_GetSession_Call {
|
||||
return &MockAuthStorage_GetSession_Call{Call: _e.mock.On("GetSession", ctx, sessionToken)}
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetSession_Call) Run(run func(ctx context.Context, sessionToken string)) *MockAuthStorage_GetSession_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetSession_Call) Return(_a0 *models.Session, _a1 error) *MockAuthStorage_GetSession_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetSession_Call) RunAndReturn(run func(context.Context, string) (*models.Session, error)) *MockAuthStorage_GetSession_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetUserByID provides a mock function with given fields: ctx, id
|
||||
func (_m *MockAuthStorage) GetUserByID(ctx context.Context, id uint64) (*models.User, error) {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetUserByID")
|
||||
}
|
||||
|
||||
var r0 *models.User
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, uint64) (*models.User, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, uint64) *models.User); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.User)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockAuthStorage_GetUserByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUserByID'
|
||||
type MockAuthStorage_GetUserByID_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetUserByID is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - id uint64
|
||||
func (_e *MockAuthStorage_Expecter) GetUserByID(ctx interface{}, id interface{}) *MockAuthStorage_GetUserByID_Call {
|
||||
return &MockAuthStorage_GetUserByID_Call{Call: _e.mock.On("GetUserByID", ctx, id)}
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetUserByID_Call) Run(run func(ctx context.Context, id uint64)) *MockAuthStorage_GetUserByID_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(uint64))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetUserByID_Call) Return(_a0 *models.User, _a1 error) *MockAuthStorage_GetUserByID_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetUserByID_Call) RunAndReturn(run func(context.Context, uint64) (*models.User, error)) *MockAuthStorage_GetUserByID_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetUserByLogin provides a mock function with given fields: ctx, login
|
||||
func (_m *MockAuthStorage) GetUserByLogin(ctx context.Context, login string) (*models.User, error) {
|
||||
ret := _m.Called(ctx, login)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetUserByLogin")
|
||||
}
|
||||
|
||||
var r0 *models.User
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.User, error)); ok {
|
||||
return rf(ctx, login)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) *models.User); ok {
|
||||
r0 = rf(ctx, login)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.User)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, login)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockAuthStorage_GetUserByLogin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUserByLogin'
|
||||
type MockAuthStorage_GetUserByLogin_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetUserByLogin is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - login string
|
||||
func (_e *MockAuthStorage_Expecter) GetUserByLogin(ctx interface{}, login interface{}) *MockAuthStorage_GetUserByLogin_Call {
|
||||
return &MockAuthStorage_GetUserByLogin_Call{Call: _e.mock.On("GetUserByLogin", ctx, login)}
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetUserByLogin_Call) Run(run func(ctx context.Context, login string)) *MockAuthStorage_GetUserByLogin_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetUserByLogin_Call) Return(_a0 *models.User, _a1 error) *MockAuthStorage_GetUserByLogin_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_GetUserByLogin_Call) RunAndReturn(run func(context.Context, string) (*models.User, error)) *MockAuthStorage_GetUserByLogin_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// RemoveSession provides a mock function with given fields: ctx, id
|
||||
func (_m *MockAuthStorage) RemoveSession(ctx context.Context, id int64) error {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for RemoveSession")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockAuthStorage_RemoveSession_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveSession'
|
||||
type MockAuthStorage_RemoveSession_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// RemoveSession is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - id int64
|
||||
func (_e *MockAuthStorage_Expecter) RemoveSession(ctx interface{}, id interface{}) *MockAuthStorage_RemoveSession_Call {
|
||||
return &MockAuthStorage_RemoveSession_Call{Call: _e.mock.On("RemoveSession", ctx, id)}
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_RemoveSession_Call) Run(run func(ctx context.Context, id int64)) *MockAuthStorage_RemoveSession_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(int64))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_RemoveSession_Call) Return(_a0 error) *MockAuthStorage_RemoveSession_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockAuthStorage_RemoveSession_Call) RunAndReturn(run func(context.Context, int64) error) *MockAuthStorage_RemoveSession_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockAuthStorage creates a new instance of MockAuthStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockAuthStorage(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockAuthStorage {
|
||||
mock := &MockAuthStorage{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
// Code generated by mockery v2.48.0. DO NOT EDIT.
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
context "context"
|
||||
os "os"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockBlobStorage is an autogenerated mock type for the BlobStorage type
|
||||
type MockBlobStorage struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockBlobStorage_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockBlobStorage) EXPECT() *MockBlobStorage_Expecter {
|
||||
return &MockBlobStorage_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// DeleteFile provides a mock function with given fields: ctx, id
|
||||
func (_m *MockBlobStorage) DeleteFile(ctx context.Context, id int64) error {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteFile")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockBlobStorage_DeleteFile_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteFile'
|
||||
type MockBlobStorage_DeleteFile_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// DeleteFile is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - id int64
|
||||
func (_e *MockBlobStorage_Expecter) DeleteFile(ctx interface{}, id interface{}) *MockBlobStorage_DeleteFile_Call {
|
||||
return &MockBlobStorage_DeleteFile_Call{Call: _e.mock.On("DeleteFile", ctx, id)}
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_DeleteFile_Call) Run(run func(ctx context.Context, id int64)) *MockBlobStorage_DeleteFile_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(int64))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_DeleteFile_Call) Return(_a0 error) *MockBlobStorage_DeleteFile_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_DeleteFile_Call) RunAndReturn(run func(context.Context, int64) error) *MockBlobStorage_DeleteFile_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetFile provides a mock function with given fields: ctx, id
|
||||
func (_m *MockBlobStorage) GetFile(ctx context.Context, id int64) (*os.File, error) {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetFile")
|
||||
}
|
||||
|
||||
var r0 *os.File
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) (*os.File, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) *os.File); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*os.File)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockBlobStorage_GetFile_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFile'
|
||||
type MockBlobStorage_GetFile_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetFile is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - id int64
|
||||
func (_e *MockBlobStorage_Expecter) GetFile(ctx interface{}, id interface{}) *MockBlobStorage_GetFile_Call {
|
||||
return &MockBlobStorage_GetFile_Call{Call: _e.mock.On("GetFile", ctx, id)}
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_GetFile_Call) Run(run func(ctx context.Context, id int64)) *MockBlobStorage_GetFile_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(int64))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_GetFile_Call) Return(_a0 *os.File, _a1 error) *MockBlobStorage_GetFile_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_GetFile_Call) RunAndReturn(run func(context.Context, int64) (*os.File, error)) *MockBlobStorage_GetFile_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SaveBlob provides a mock function with given fields: ctx, id, data
|
||||
func (_m *MockBlobStorage) SaveBlob(ctx context.Context, id int64, data []byte) error {
|
||||
ret := _m.Called(ctx, id, data)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SaveBlob")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64, []byte) error); ok {
|
||||
r0 = rf(ctx, id, data)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockBlobStorage_SaveBlob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveBlob'
|
||||
type MockBlobStorage_SaveBlob_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SaveBlob is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - id int64
|
||||
// - data []byte
|
||||
func (_e *MockBlobStorage_Expecter) SaveBlob(ctx interface{}, id interface{}, data interface{}) *MockBlobStorage_SaveBlob_Call {
|
||||
return &MockBlobStorage_SaveBlob_Call{Call: _e.mock.On("SaveBlob", ctx, id, data)}
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_SaveBlob_Call) Run(run func(ctx context.Context, id int64, data []byte)) *MockBlobStorage_SaveBlob_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(int64), args[2].([]byte))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_SaveBlob_Call) Return(_a0 error) *MockBlobStorage_SaveBlob_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockBlobStorage_SaveBlob_Call) RunAndReturn(run func(context.Context, int64, []byte) error) *MockBlobStorage_SaveBlob_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockBlobStorage creates a new instance of MockBlobStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockBlobStorage(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockBlobStorage {
|
||||
mock := &MockBlobStorage{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
@ -0,0 +1,377 @@
|
||||
// Code generated by mockery v2.48.0. DO NOT EDIT.
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
models "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockDatabase is an autogenerated mock type for the Database type
|
||||
type MockDatabase struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockDatabase_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockDatabase) EXPECT() *MockDatabase_Expecter {
|
||||
return &MockDatabase_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// AddSession provides a mock function with given fields: ctx, ses
|
||||
func (_m *MockDatabase) AddSession(ctx context.Context, ses *models.Session) (int64, error) {
|
||||
ret := _m.Called(ctx, ses)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddSession")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.Session) (int64, error)); ok {
|
||||
return rf(ctx, ses)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *models.Session) int64); ok {
|
||||
r0 = rf(ctx, ses)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *models.Session) error); ok {
|
||||
r1 = rf(ctx, ses)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockDatabase_AddSession_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddSession'
|
||||
type MockDatabase_AddSession_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AddSession is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - ses *models.Session
|
||||
func (_e *MockDatabase_Expecter) AddSession(ctx interface{}, ses interface{}) *MockDatabase_AddSession_Call {
|
||||
return &MockDatabase_AddSession_Call{Call: _e.mock.On("AddSession", ctx, ses)}
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_AddSession_Call) Run(run func(ctx context.Context, ses *models.Session)) *MockDatabase_AddSession_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*models.Session))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_AddSession_Call) Return(_a0 int64, _a1 error) *MockDatabase_AddSession_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_AddSession_Call) RunAndReturn(run func(context.Context, *models.Session) (int64, error)) *MockDatabase_AddSession_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// AddUser provides a mock function with given fields: ctx, login, username, passwordHash
|
||||
func (_m *MockDatabase) AddUser(ctx context.Context, login string, username string, passwordHash []byte) (int64, error) {
|
||||
ret := _m.Called(ctx, login, username, passwordHash)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddUser")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, []byte) (int64, error)); ok {
|
||||
return rf(ctx, login, username, passwordHash)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, []byte) int64); ok {
|
||||
r0 = rf(ctx, login, username, passwordHash)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, []byte) error); ok {
|
||||
r1 = rf(ctx, login, username, passwordHash)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockDatabase_AddUser_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddUser'
|
||||
type MockDatabase_AddUser_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AddUser is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - login string
|
||||
// - username string
|
||||
// - passwordHash []byte
|
||||
func (_e *MockDatabase_Expecter) AddUser(ctx interface{}, login interface{}, username interface{}, passwordHash interface{}) *MockDatabase_AddUser_Call {
|
||||
return &MockDatabase_AddUser_Call{Call: _e.mock.On("AddUser", ctx, login, username, passwordHash)}
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_AddUser_Call) Run(run func(ctx context.Context, login string, username string, passwordHash []byte)) *MockDatabase_AddUser_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].([]byte))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_AddUser_Call) Return(_a0 int64, _a1 error) *MockDatabase_AddUser_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_AddUser_Call) RunAndReturn(run func(context.Context, string, string, []byte) (int64, error)) *MockDatabase_AddUser_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetSession provides a mock function with given fields: ctx, sessionToken
|
||||
func (_m *MockDatabase) GetSession(ctx context.Context, sessionToken string) (*models.Session, error) {
|
||||
ret := _m.Called(ctx, sessionToken)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetSession")
|
||||
}
|
||||
|
||||
var r0 *models.Session
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.Session, error)); ok {
|
||||
return rf(ctx, sessionToken)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) *models.Session); ok {
|
||||
r0 = rf(ctx, sessionToken)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.Session)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, sessionToken)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockDatabase_GetSession_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSession'
|
||||
type MockDatabase_GetSession_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetSession is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - sessionToken string
|
||||
func (_e *MockDatabase_Expecter) GetSession(ctx interface{}, sessionToken interface{}) *MockDatabase_GetSession_Call {
|
||||
return &MockDatabase_GetSession_Call{Call: _e.mock.On("GetSession", ctx, sessionToken)}
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetSession_Call) Run(run func(ctx context.Context, sessionToken string)) *MockDatabase_GetSession_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetSession_Call) Return(_a0 *models.Session, _a1 error) *MockDatabase_GetSession_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetSession_Call) RunAndReturn(run func(context.Context, string) (*models.Session, error)) *MockDatabase_GetSession_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetUserByID provides a mock function with given fields: ctx, id
|
||||
func (_m *MockDatabase) GetUserByID(ctx context.Context, id uint64) (*models.User, error) {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetUserByID")
|
||||
}
|
||||
|
||||
var r0 *models.User
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, uint64) (*models.User, error)); ok {
|
||||
return rf(ctx, id)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, uint64) *models.User); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.User)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok {
|
||||
r1 = rf(ctx, id)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockDatabase_GetUserByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUserByID'
|
||||
type MockDatabase_GetUserByID_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetUserByID is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - id uint64
|
||||
func (_e *MockDatabase_Expecter) GetUserByID(ctx interface{}, id interface{}) *MockDatabase_GetUserByID_Call {
|
||||
return &MockDatabase_GetUserByID_Call{Call: _e.mock.On("GetUserByID", ctx, id)}
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetUserByID_Call) Run(run func(ctx context.Context, id uint64)) *MockDatabase_GetUserByID_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(uint64))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetUserByID_Call) Return(_a0 *models.User, _a1 error) *MockDatabase_GetUserByID_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetUserByID_Call) RunAndReturn(run func(context.Context, uint64) (*models.User, error)) *MockDatabase_GetUserByID_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetUserByLogin provides a mock function with given fields: ctx, login
|
||||
func (_m *MockDatabase) GetUserByLogin(ctx context.Context, login string) (*models.User, error) {
|
||||
ret := _m.Called(ctx, login)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetUserByLogin")
|
||||
}
|
||||
|
||||
var r0 *models.User
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.User, error)); ok {
|
||||
return rf(ctx, login)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) *models.User); ok {
|
||||
r0 = rf(ctx, login)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.User)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, login)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockDatabase_GetUserByLogin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUserByLogin'
|
||||
type MockDatabase_GetUserByLogin_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetUserByLogin is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - login string
|
||||
func (_e *MockDatabase_Expecter) GetUserByLogin(ctx interface{}, login interface{}) *MockDatabase_GetUserByLogin_Call {
|
||||
return &MockDatabase_GetUserByLogin_Call{Call: _e.mock.On("GetUserByLogin", ctx, login)}
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetUserByLogin_Call) Run(run func(ctx context.Context, login string)) *MockDatabase_GetUserByLogin_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetUserByLogin_Call) Return(_a0 *models.User, _a1 error) *MockDatabase_GetUserByLogin_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_GetUserByLogin_Call) RunAndReturn(run func(context.Context, string) (*models.User, error)) *MockDatabase_GetUserByLogin_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// RemoveSession provides a mock function with given fields: ctx, id
|
||||
func (_m *MockDatabase) RemoveSession(ctx context.Context, id int64) error {
|
||||
ret := _m.Called(ctx, id)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for RemoveSession")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
|
||||
r0 = rf(ctx, id)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockDatabase_RemoveSession_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveSession'
|
||||
type MockDatabase_RemoveSession_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// RemoveSession is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - id int64
|
||||
func (_e *MockDatabase_Expecter) RemoveSession(ctx interface{}, id interface{}) *MockDatabase_RemoveSession_Call {
|
||||
return &MockDatabase_RemoveSession_Call{Call: _e.mock.On("RemoveSession", ctx, id)}
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_RemoveSession_Call) Run(run func(ctx context.Context, id int64)) *MockDatabase_RemoveSession_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(int64))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_RemoveSession_Call) Return(_a0 error) *MockDatabase_RemoveSession_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockDatabase_RemoveSession_Call) RunAndReturn(run func(context.Context, int64) error) *MockDatabase_RemoveSession_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockDatabase creates a new instance of MockDatabase. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockDatabase(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockDatabase {
|
||||
mock := &MockDatabase{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
// Code generated by mockery v2.48.0. DO NOT EDIT.
|
||||
|
||||
package storage
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// MockFileStorage is an autogenerated mock type for the FileStorage type
|
||||
type MockFileStorage struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockFileStorage_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockFileStorage) EXPECT() *MockFileStorage_Expecter {
|
||||
return &MockFileStorage_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// NewMockFileStorage creates a new instance of MockFileStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockFileStorage(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockFileStorage {
|
||||
mock := &MockFileStorage{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
// Code generated by mockery v2.48.0. DO NOT EDIT.
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockMetaStorage is an autogenerated mock type for the MetaStorage type
|
||||
type MockMetaStorage struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockMetaStorage_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockMetaStorage) EXPECT() *MockMetaStorage_Expecter {
|
||||
return &MockMetaStorage_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// SaveMetadata provides a mock function with given fields: ctx, fileType, size, ext
|
||||
func (_m *MockMetaStorage) SaveMetadata(ctx context.Context, fileType string, size int64, ext string) (int64, error) {
|
||||
ret := _m.Called(ctx, fileType, size, ext)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SaveMetadata")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, int64, string) (int64, error)); ok {
|
||||
return rf(ctx, fileType, size, ext)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, int64, string) int64); ok {
|
||||
r0 = rf(ctx, fileType, size, ext)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, int64, string) error); ok {
|
||||
r1 = rf(ctx, fileType, size, ext)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockMetaStorage_SaveMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveMetadata'
|
||||
type MockMetaStorage_SaveMetadata_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SaveMetadata is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - fileType string
|
||||
// - size int64
|
||||
// - ext string
|
||||
func (_e *MockMetaStorage_Expecter) SaveMetadata(ctx interface{}, fileType interface{}, size interface{}, ext interface{}) *MockMetaStorage_SaveMetadata_Call {
|
||||
return &MockMetaStorage_SaveMetadata_Call{Call: _e.mock.On("SaveMetadata", ctx, fileType, size, ext)}
|
||||
}
|
||||
|
||||
func (_c *MockMetaStorage_SaveMetadata_Call) Run(run func(ctx context.Context, fileType string, size int64, ext string)) *MockMetaStorage_SaveMetadata_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string), args[2].(int64), args[3].(string))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockMetaStorage_SaveMetadata_Call) Return(_a0 int64, _a1 error) *MockMetaStorage_SaveMetadata_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockMetaStorage_SaveMetadata_Call) RunAndReturn(run func(context.Context, string, int64, string) (int64, error)) *MockMetaStorage_SaveMetadata_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockMetaStorage creates a new instance of MockMetaStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockMetaStorage(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockMetaStorage {
|
||||
mock := &MockMetaStorage{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
Loading…
Reference in New Issue
Block a user