diff --git a/cmd/main.go b/cmd/main.go index a20812a..f5ce44d 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -26,7 +26,7 @@ func main() { engine := filesengine.NewFilesEngine(nil, nil) - go app.New(pg, engine). + go app.New(ctx, pg, engine). Run(ctx) <-ctx.Done() diff --git a/go.mod b/go.mod index 4d3dc38..54bf2ae 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ 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 @@ -12,9 +11,9 @@ require ( github.com/jmoiron/sqlx v1.4.0 github.com/nats-io/nats.go v1.37.0 github.com/spf13/viper v1.19.0 - github.com/stretchr/testify v1.9.0 golang.org/x/crypto v0.28.0 golang.org/x/sync v0.8.0 + google.golang.org/grpc v1.62.1 ) require ( @@ -28,6 +27,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect @@ -44,7 +44,6 @@ require ( github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // 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 @@ -52,7 +51,6 @@ 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 @@ -63,6 +61,7 @@ require ( golang.org/x/net v0.25.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index ddd07a2..12ae1f8 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,12 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -115,7 +119,6 @@ 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= @@ -153,6 +156,13 @@ golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/app/app.go b/internal/app/app.go index 90b02cf..e85a34f 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -2,14 +2,12 @@ package app import ( "context" - "errors" - "net/http" "git.optclblast.xyz/draincloud/draincloud-core/internal/app/handlers" - "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/processor" resolvedispatcher "git.optclblast.xyz/draincloud/draincloud-core/internal/resolve_dispatcher" + "git.optclblast.xyz/draincloud/draincloud-core/internal/resolvers/auth" "git.optclblast.xyz/draincloud/draincloud-core/internal/storage" "github.com/gin-gonic/gin" ) @@ -23,12 +21,18 @@ type DrainCloud struct { } func New( + ctx context.Context, database storage.Database, filesEngine *filesengine.FilesEngine, ) *DrainCloud { mux := gin.Default() dispatcher := resolvedispatcher.New() + dispatcher.RegisterResolver( + ctx, + auth.AuthResolverV1Name, + auth.NewAuthResolver(database), + ) d := &DrainCloud{ database: database, @@ -36,19 +40,36 @@ func New( ginProcessor: processor.NewGinProcessor(database, dispatcher), } + // TODO. Maybe overkill + internalGroup := mux.Group("/_internal") + { + regGroup := internalGroup.Group("/register") + { + regGroup.POST("/resolver", d.ginProcessor.Process( + handlers.NewInternalRegisterResolverHandler(dispatcher), + )) + regGroup.POST("/plugin", func(ctx *gin.Context) {}) + } + + + } + // Built-in auth component of DrainCloud-Core authGroup := mux.Group("/auth") { - // authGroup.POST("/register", d.Register) authGroup.POST("/register", d.ginProcessor.Process( handlers.NewRegisterHandler(database), )) - authGroup.POST("/logon", d.Login) + authGroup.POST("/logon", d.ginProcessor.Process( + handlers.NewLogonHandler(database), + )) } filesGroup := mux.Group("/files") { - filesGroup.POST("/upload", d.UploadFile) + filesGroup.POST("/upload", d.ginProcessor.Process( + handlers.NewUploadFileHandler(filesEngine), + )) } d.mux = mux @@ -59,23 +80,3 @@ func New( func (d *DrainCloud) Run(ctx context.Context) error { return d.mux.Run() } - -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(), - }) - case errors.Is(err, ErrorSessionExpired): - ctx.JSON(http.StatusInternalServerError, domain.ErrorJson{ - Code: http.StatusForbidden, - Message: err.Error(), - }) - default: - ctx.JSON(http.StatusInternalServerError, domain.ErrorJson{ - Code: http.StatusInternalServerError, - Message: "Internal Error", - }) - } -} diff --git a/internal/app/auth.go b/internal/app/auth.go deleted file mode 100644 index 808e7ed..0000000 --- a/internal/app/auth.go +++ /dev/null @@ -1,63 +0,0 @@ -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 -} diff --git a/internal/app/login.go b/internal/app/handlers/logon.go similarity index 50% rename from internal/app/login.go rename to internal/app/handlers/logon.go index 133614f..d2b82b2 100644 --- a/internal/app/login.go +++ b/internal/app/handlers/logon.go @@ -1,84 +1,100 @@ -package app +package handlers import ( "bytes" + "context" + "encoding/json" "errors" "fmt" "log/slog" "net/http" "time" + "git.optclblast.xyz/draincloud/draincloud-core/internal/common" "git.optclblast.xyz/draincloud/draincloud-core/internal/domain" + "git.optclblast.xyz/draincloud/draincloud-core/internal/errs" + "git.optclblast.xyz/draincloud/draincloud-core/internal/handler" "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" - "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models" - "github.com/gin-gonic/gin" + "git.optclblast.xyz/draincloud/draincloud-core/internal/storage" + "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/auth" "github.com/google/uuid" "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) +type LogonHandler struct { + *handler.BaseHandler + authStorage storage.AuthStorage } -func (d *DrainCloud) login(ctx *gin.Context, req *domain.LoginRequest) (*domain.LoginResponse, error) { - session, err := d.getSession(ctx) +func NewLogonHandler( + authStorage storage.AuthStorage, +) *LogonHandler { + h := &LogonHandler{ + authStorage: authStorage, + BaseHandler: handler.New(). + WithName("logonv1"). + WithRequiredResolveParams(), + } + h.WithProcessFunc(h.process) + return h +} + +func (h *LogonHandler) process(ctx context.Context, req *common.Request, w handler.Writer) error { + logger.Debug(ctx, "[Logon] new request") + + body := new(domain.LogonRequest) + err := json.Unmarshal(req.Body, body) + if err != nil { + logger.Error(ctx, "[Logon] failed to bind request", logger.Err(err)) + w.Write(ctx, map[string]string{ + "error": "bad request", + }, handler.WithCode(http.StatusBadRequest)) + return nil + } + + session, err := h.getSession(ctx, req) if err != nil && !errors.Is(err, http.ErrNoCookie) { - return nil, err + return err } if session != nil { - if err := validateSession(ctx, session); err != nil { + if err := validateSession(req, session); err != nil { // TODO add audit log entry - return nil, err + return err } - logger.Debug(ctx, "[login] user is already logged in", slog.String("session_id", session.ID.String())) - return &domain.LoginResponse{ + w.Write(ctx, &domain.LogonResponse{ Ok: true, - }, nil + }) + return nil } - logger.Debug(ctx, "[login] session not found. trying to authorize") + logger.Debug(ctx, "[login] session not founh. trying to authorize") + resp, err := h.login(ctx, body, session, w) + if err != nil { + logger.Error(ctx, "[Logon] failed to login user", logger.Err(err)) + return err + } + + w.Write(ctx, resp) + return nil +} + +func (h *LogonHandler) login(ctx context.Context, req *domain.LogonRequest, session *auth.Session, w handler.Writer) (*domain.LogonResponse, error) { 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) + user, err := h.authStorage.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 + return nil, errs.ErrorAccessDenied } sessionCreatedAt := time.Now() @@ -88,20 +104,20 @@ func (d *DrainCloud) login(ctx *gin.Context, req *domain.LoginRequest) (*domain. 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) + w.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) + w.SetCookie(csrfTokenCookie, csrfToken, int(sessionExpiredAt.Sub(sessionCreatedAt).Seconds()), "_path", "_domain", true, false) sessionID, err := uuid.NewV7() if err != nil { return nil, fmt.Errorf("failed to generate session id: %w", err) } - if _, err = d.database.AddSession(ctx, &models.Session{ + if _, err = h.authStorage.AddSession(ctx, &auth.Session{ ID: sessionID, SessionToken: sessionToken, CsrfToken: csrfToken, @@ -114,17 +130,17 @@ func (d *DrainCloud) login(ctx *gin.Context, req *domain.LoginRequest) (*domain. // TODO add audit log entry - return &domain.LoginResponse{ + return &domain.LogonResponse{ Ok: true, }, nil } -func (d *DrainCloud) getSession(ctx *gin.Context) (*models.Session, error) { - token, err := ctx.Cookie(sessionTokenCookie) +func (h *LogonHandler) getSession(ctx context.Context, req *common.Request) (*auth.Session, error) { + token, err := common.GetValue[string](req.Metadata, sessionTokenCookie) if err != nil { return nil, fmt.Errorf("failed to fetch session cookie from request: %w", err) } - csrfToken, err := ctx.Cookie(csrfTokenCookie) + csrfToken, err := common.GetValue[string](req.Metadata, csrfTokenCookie) if err != nil { return nil, fmt.Errorf("failed to fetch csrf cookie from request: %w", err) } @@ -133,7 +149,7 @@ func (d *DrainCloud) getSession(ctx *gin.Context) (*models.Session, error) { return nil, fmt.Errorf("session token or csrf token is empty") } - session, err := d.database.GetSession(ctx, token) + session, err := h.authStorage.GetSession(ctx, token) if err != nil { return nil, fmt.Errorf("failed to fetch session from repo: %w", err) } @@ -141,22 +157,22 @@ func (d *DrainCloud) getSession(ctx *gin.Context) (*models.Session, error) { return session, nil } -func validateSession(ctx *gin.Context, session *models.Session) error { +func validateSession(req *common.Request, session *auth.Session) error { if session == nil { - return ErrorAccessDenied + return errs.ErrorAccessDenied } - csrfToken, err := ctx.Cookie(csrfTokenCookie) + csrfToken, err := common.GetValue[string](req.Metadata, csrfTokenCookie) if err != nil { return fmt.Errorf("failed to fetch csrf cookie from request: %w", err) } if session.CsrfToken != csrfToken { - return ErrorAccessDenied + return errs.ErrorAccessDenied } if session.ExpiredAt.Before(time.Now()) { - return ErrorSessionExpired + return errs.ErrorSessionExpired } return nil diff --git a/internal/app/handlers/register.go b/internal/app/handlers/register.go index dcae355..ca5b543 100644 --- a/internal/app/handlers/register.go +++ b/internal/app/handlers/register.go @@ -11,7 +11,7 @@ import ( "git.optclblast.xyz/draincloud/draincloud-core/internal/handler" "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" "git.optclblast.xyz/draincloud/draincloud-core/internal/storage" - "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models" + "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/auth" "github.com/google/uuid" "golang.org/x/crypto/bcrypt" ) @@ -71,7 +71,7 @@ func (d *RegisterHandler) register( return nil, fmt.Errorf("failed to generate user id: %w", err) } - user := &models.User{ + user := &auth.User{ ID: userID, Username: req.Login, Login: req.Login, @@ -103,7 +103,7 @@ func (d *RegisterHandler) register( return nil, fmt.Errorf("failed to generate session id: %w", err) } - if _, err = d.authStorage.AddSession(ctx, &models.Session{ + if _, err = d.authStorage.AddSession(ctx, &auth.Session{ ID: sessionID, SessionToken: sessionToken, CsrfToken: csrfToken, diff --git a/internal/app/handlers/register_resolver.go b/internal/app/handlers/register_resolver.go new file mode 100644 index 0000000..4c91410 --- /dev/null +++ b/internal/app/handlers/register_resolver.go @@ -0,0 +1,38 @@ +package handlers + +import ( + "context" + "fmt" + + "git.optclblast.xyz/draincloud/draincloud-core/internal/common" + "git.optclblast.xyz/draincloud/draincloud-core/internal/handler" + resolvedispatcher "git.optclblast.xyz/draincloud/draincloud-core/internal/resolve_dispatcher" +) + +// TODO. Maybe remove +type InternalRegisterResolverHandler struct { + *handler.BaseHandler + resolveDispatcher *resolvedispatcher.ResolveDispatcher +} + +func NewInternalRegisterResolverHandler( + resolveDispatcher *resolvedispatcher.ResolveDispatcher, +) *InternalRegisterResolverHandler { + h := &InternalRegisterResolverHandler{ + resolveDispatcher: resolveDispatcher, + } + h.BaseHandler = handler.New(). + WithName("internal_registerresolver"). + WithProcessFunc(h.process) + + return h +} + +func (h *InternalRegisterResolverHandler) process( + ctx context.Context, + req *common.Request, + w handler.Writer, +) error { + //_, ok := h.resolveDispatcher.GetResolver() + return fmt.Errorf("uniplemented") +} diff --git a/internal/app/handlers/upload_file.go b/internal/app/handlers/upload_file.go new file mode 100644 index 0000000..5d25f6a --- /dev/null +++ b/internal/app/handlers/upload_file.go @@ -0,0 +1,95 @@ +package handlers + +import ( + "context" + + "git.optclblast.xyz/draincloud/draincloud-core/internal/common" + filesengine "git.optclblast.xyz/draincloud/draincloud-core/internal/files_engine" + "git.optclblast.xyz/draincloud/draincloud-core/internal/handler" + "git.optclblast.xyz/draincloud/draincloud-core/internal/resolvers/auth" +) + +const ( + maxFileSize = 10 << 30 +) + +type UploadFileHandler struct { + *handler.BaseHandler + filesEngine *filesengine.FilesEngine +} + +func NewUploadFileHandler( + filesEngine *filesengine.FilesEngine, +) *UploadFileHandler { + h := &UploadFileHandler{ + filesEngine: filesEngine, + BaseHandler: handler.New(). + WithName("uploadfilev1"). + WithRequiredResolveParams( + auth.AuthResolverV1Name, + // TODO with MultipartReaderResolverV1Name + // or + // MultipartDataResolverV1Name + ), + } + h.WithProcessFunc(h.process) + return h +} + +func (d *UploadFileHandler) process(ctx context.Context, req *common.Request, w handler.Writer) error { + // TODO fetch (interface{ ParseMultipartForm(size int) error }) from req.GetValue[ParseMultipartFormer](req.ResolveValues) + + // if err := req.RawReq.ParseMultipartForm(maxFileSize); err != nil { + // logger.Error(ctx, "uploadFile handler error", logger.Err(err)) + // return err + // } + + // if err := d.uploadFile(ctx, userID); err != nil { + // logger.Error(ctx, "uploadFile handle", logger.Err(err)) + // writeError(ctx, err) + // return + // } + return nil +} + +// func (d *UploadFileHandler) uploadFile(ctx context.Context, req *common.Request) error { +// title := ctx.PostForm("file") +// logger.Info(ctx, "uploadFile", slog.Any("postForm data", spew.Sdump(title))) + +// file, header, err := req.RawReq.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 +// } + +// ext := parseExtension(header.Filename) + +// id, err := d.filesEngine.SaveFile(ctx, filesengine.File{ +// Name: header.Filename, +// UserID: userID, +// Data: data, +// Ext: ext, +// Size: int64(len(data)), +// Type: "", // че такое type? +// }) +// if err != nil { +// return fmt.Errorf("failed to save file: %w", err) +// } +// logger.Debug(ctx, "new file id", "id", id) + +// return nil +// } + +// func parseExtension(filename string) string { +// parts := strings.Split(filename, ".") +// if len(parts) == 0 { +// return "" +// } + +// return parts[len(parts)-1] +// } diff --git a/internal/app/middleware.go b/internal/app/middleware.go deleted file mode 100644 index 40bd7f3..0000000 --- a/internal/app/middleware.go +++ /dev/null @@ -1,28 +0,0 @@ -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) - } -} diff --git a/internal/app/upload_file.go b/internal/app/upload_file.go deleted file mode 100644 index 8ca83b8..0000000 --- a/internal/app/upload_file.go +++ /dev/null @@ -1,81 +0,0 @@ -package app - -import ( - "fmt" - "io" - "log/slog" - "strings" - - 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/reqcontext" - "github.com/davecgh/go-spew/spew" - "github.com/gin-gonic/gin" - "github.com/google/uuid" -) - -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 - } - - userID, err := reqcontext.GetUserID(ctx) - if err != nil { - writeError(ctx, ErrorAccessDenied) - return - } - - if err := d.uploadFile(ctx, userID); err != nil { - logger.Error(ctx, "uploadFile handle", logger.Err(err)) - writeError(ctx, err) - return - } -} - -func (d *DrainCloud) uploadFile(ctx *gin.Context, userID uuid.UUID) 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 - } - - ext := parseExtension(header.Filename) - - id, err := d.filesEngine.SaveFile(ctx, filesengine.File{ - Name: header.Filename, - UserID: userID, - Data: data, - Ext: ext, - Size: int64(len(data)), - Type: "", // че такое type? - }) - if err != nil { - return fmt.Errorf("failed to save file: %w", err) - } - logger.Debug(ctx, "new file id", "id", id) - - return nil -} - -func parseExtension(filename string) string { - parts := strings.Split(filename, ".") - if len(parts) == 0 { - return "" - } - - return parts[len(parts)-1] -} diff --git a/internal/closer/closer.go b/internal/closer/closer.go index b011a8c..1af7517 100644 --- a/internal/closer/closer.go +++ b/internal/closer/closer.go @@ -3,6 +3,8 @@ package closer import ( "context" "errors" + "fmt" + "sync/atomic" "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" ) @@ -12,14 +14,22 @@ var globalCloser *Closer = &Closer{ } type Closer struct { + _lock atomic.Bool closeFns []func() error } func (c *Closer) Add(fn func() error) { + if c._lock.Load() { + return + } c.closeFns = append(c.closeFns, fn) } func (c *Closer) Close() error { + if !c._lock.CompareAndSwap(false, true) { + return fmt.Errorf("already closed") + } + var commonErr error for _, fn := range c.closeFns { if err := fn(); err != nil { diff --git a/internal/common/request.go b/internal/common/request.go index b7bda24..c05a6ef 100644 --- a/internal/common/request.go +++ b/internal/common/request.go @@ -8,7 +8,7 @@ import ( "sync" "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" - "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models" + "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/auth" "github.com/google/uuid" ) @@ -46,15 +46,14 @@ func NewRequestPool() *RequestPool { type Request struct { ID string - Session *models.Session - User *models.User + Session *auth.Session + User *auth.User // ResolveValues - data required to process request. ResolveValues *sync.Map // Metadata - an additional data, usually added with preprocessing. Metadata *sync.Map // Request body - Body []byte - RawReq *http.Request + Body []byte } // NewRequestFromHttp builds a new *Request struct from raw http Request. No auth data validated. @@ -65,7 +64,6 @@ func NewRequestFromHttp(pool *RequestPool, req *http.Request) *Request { headers := req.Header out.Metadata = &sync.Map{} - out.RawReq = req for _, cookie := range cookies { out.Metadata.Store(cookie.Name, cookie.Value) diff --git a/internal/domain/internal.go b/internal/domain/internal.go new file mode 100644 index 0000000..1e5dbc4 --- /dev/null +++ b/internal/domain/internal.go @@ -0,0 +1,7 @@ +package domain + +type RegisterResolverRequest struct { + ResolverName string `json:"resolver_name"` + ResolverEndpoint string `json:"resolver_endpoint"` + RequiredResolveParams []string `json:"required_resolve_params"` +} diff --git a/internal/domain/requests.go b/internal/domain/requests.go index 65113e5..eadfc37 100644 --- a/internal/domain/requests.go +++ b/internal/domain/requests.go @@ -10,12 +10,12 @@ type RegisterResponse struct { Message string `json:"message"` } -type LoginRequest struct { +type LogonRequest struct { Login string `json:"login"` Password string `json:"password"` } -type LoginResponse struct { +type LogonResponse struct { Ok bool `json:"ok"` Message string `json:"message"` } diff --git a/internal/handler/call_handler.go b/internal/handler/call_handler.go new file mode 100644 index 0000000..8f54221 --- /dev/null +++ b/internal/handler/call_handler.go @@ -0,0 +1,9 @@ +package handler + +import ( + "context" + + "git.optclblast.xyz/draincloud/draincloud-core/internal/common" +) + +type CallHandler func(ctx context.Context, req *common.Request) ([]byte, error) diff --git a/internal/handler/handler.go b/internal/handler/handler.go index 716e865..65161c0 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -6,8 +6,20 @@ import ( "git.optclblast.xyz/draincloud/draincloud-core/internal/common" ) +type WriteOptions struct { + Code int +} + +type WriteOption func(opts *WriteOptions) + +func WithCode(code int) WriteOption { + return func(opts *WriteOptions) { + opts.Code = code + } +} + type Writer interface { - Write(ctx context.Context, resp any) + Write(ctx context.Context, resp any, opts ...WriteOption) SetCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) } diff --git a/internal/plugin/processor.go b/internal/plugin/processor.go new file mode 100644 index 0000000..16fc241 --- /dev/null +++ b/internal/plugin/processor.go @@ -0,0 +1,24 @@ +package plugin + +import ( + "context" + "fmt" + + "git.optclblast.xyz/draincloud/draincloud-core/internal/common" + "git.optclblast.xyz/draincloud/draincloud-core/internal/handler" +) + +type PluginHandler struct { + *handler.BaseHandler + store *PluginStore +} + +func (_ *PluginHandler) GetName() string { + return "pluginv1" +} + +func (p *PluginHandler) GetProcessFn() func(ctx context.Context, req *common.Request, w handler.Writer) error { + return func(ctx context.Context, req *common.Request, w handler.Writer) error { + return fmt.Errorf("unimplemented") + } +} diff --git a/internal/plugin/store.go b/internal/plugin/store.go index a32c394..b9651fe 100644 --- a/internal/plugin/store.go +++ b/internal/plugin/store.go @@ -23,6 +23,15 @@ func (s *PluginStore) Add(plugin *Plugin) { s.plugins[PluginStoreKey(plugin.md.Namespace, plugin.md.Name, plugin.md.Version)] = plugin } +func (s *PluginStore) Get(plugin string) *Plugin { + s.m.RLock() + defer s.m.RUnlock() + if p, ok := s.plugins[plugin]; ok { + return p + } + return nil +} + func PluginStoreKey(ns, name string, v int) string { return fmt.Sprintf("%s.%s.%v", ns, name, v) } diff --git a/internal/processor/gin_processor.go b/internal/processor/gin_processor.go index b6433e9..55e719b 100644 --- a/internal/processor/gin_processor.go +++ b/internal/processor/gin_processor.go @@ -48,9 +48,11 @@ func (p *GinProcessor) Process(handler handler.Handler) gin.HandlerFunc { } // 3. Call preprocessing fn's, middlewares etc. - if err = handler.GetPreprocessFn()(ctx, req, wrapGin(ctx)); err != nil { - p.writeError(ctx, err) - return + if preprocessFn := handler.GetPreprocessFn(); preprocessFn != nil { + if err = preprocessFn(ctx, req, wrapGin(ctx)); err != nil { + p.writeError(ctx, err) + return + } } // 4. Call handler.ProcessFn @@ -61,8 +63,8 @@ func (p *GinProcessor) Process(handler handler.Handler) gin.HandlerFunc { } } -func (p *GinProcessor) resolve(ctx context.Context, h handler.Handler, req *common.Request) error { - eg, ctx := errgroup.WithContext(ctx) +func (p *GinProcessor) resolve(ctx *gin.Context, h handler.Handler, req *common.Request) error { + eg, c := errgroup.WithContext(ctx) for _, r := range h.GetRequiredResolveParams() { resolver, err := p.resolveDispatcher.GetResolver(r) if err != nil { @@ -71,7 +73,7 @@ func (p *GinProcessor) resolve(ctx context.Context, h handler.Handler, req *comm resolveValueName := r eg.Go(func() error { - if resolveErr := resolver.Resolve(ctx, req); resolveErr != nil { + if resolveErr := resolver.Resolve(c, req, ctx); resolveErr != nil { return fmt.Errorf("failed to resolve '%s' value: %w", resolveValueName, resolveErr) } return nil @@ -87,6 +89,9 @@ func (p *GinProcessor) resolve(ctx context.Context, h handler.Handler, req *comm func (p *GinProcessor) writeError(ctx *gin.Context, err error) { logger.Error(ctx, "error process request", logger.Err(err)) + + // TODO do a custom error handling for resolvers / handlers / processors etc + switch { case errors.Is(err, errs.ErrorAccessDenied): ctx.JSON(http.StatusInternalServerError, domain.ErrorJson{ diff --git a/internal/processor/gin_writer.go b/internal/processor/gin_writer.go index fbdf225..3248210 100644 --- a/internal/processor/gin_writer.go +++ b/internal/processor/gin_writer.go @@ -4,6 +4,7 @@ import ( "context" "net/http" + "git.optclblast.xyz/draincloud/draincloud-core/internal/handler" "github.com/gin-gonic/gin" ) @@ -17,8 +18,15 @@ func wrapGin(ctx *gin.Context) ginWriter { } } -func (w ginWriter) Write(ctx context.Context, resp any) { - w.ctx.JSON(http.StatusOK, resp) +func (w ginWriter) Write(ctx context.Context, resp any, opts ...handler.WriteOption) { + params := &handler.WriteOptions{ + Code: http.StatusOK, + } + for _, o := range opts { + o(params) + } + + w.ctx.JSON(params.Code, resp) } func (w ginWriter) SetCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) { diff --git a/internal/reqcontext/auth.go b/internal/reqcontext/auth.go index 883aad6..4268feb 100644 --- a/internal/reqcontext/auth.go +++ b/internal/reqcontext/auth.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models" + "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/auth" "github.com/google/uuid" ) @@ -26,12 +26,12 @@ func GetUserID(ctx context.Context) (uuid.UUID, error) { return uuid.Nil, fmt.Errorf("userID not passed with context") } -func WithSession(parent context.Context, session *models.Session) context.Context { +func WithSession(parent context.Context, session *auth.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 { +func GetSession(ctx context.Context) (*auth.Session, error) { + if ses, ok := ctx.Value(UserIDCtxKey).(*auth.Session); ok { return ses, nil } return nil, fmt.Errorf("session not passed with context") diff --git a/internal/resolvers/auth/auth_resolver.go b/internal/resolvers/auth/auth_resolver_v1.go similarity index 86% rename from internal/resolvers/auth/auth_resolver.go rename to internal/resolvers/auth/auth_resolver_v1.go index 49f3554..9a963e5 100644 --- a/internal/resolvers/auth/auth_resolver.go +++ b/internal/resolvers/auth/auth_resolver_v1.go @@ -12,7 +12,11 @@ import ( "git.optclblast.xyz/draincloud/draincloud-core/internal/errs" "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" "git.optclblast.xyz/draincloud/draincloud-core/internal/storage" - "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models" + models "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/auth" +) + +const ( + AuthResolverV1Name = "auth.v1" ) const ( @@ -24,10 +28,20 @@ type AuthResolver struct { authStorage storage.AuthStorage } -func (r *AuthResolver) Resolve(ctx context.Context, req *common.Request) error { +func NewAuthResolver(authStorage storage.AuthStorage) *AuthResolver { + return &AuthResolver{ + authStorage: authStorage, + } +} + +func (r *AuthResolver) Resolve(ctx context.Context, req *common.Request, _ any) error { return r.authorize(ctx, req) } +func (r *AuthResolver) GetRequiredResolveParams() []string { + return nil +} + func (p *AuthResolver) authorize(ctx context.Context, req *common.Request) error { session, err := p.getSession(ctx, req) if err != nil && !errors.Is(err, http.ErrNoCookie) { diff --git a/internal/resolvers/plugin_name/plugin_name.go b/internal/resolvers/plugin_name/plugin_name.go new file mode 100644 index 0000000..7219482 --- /dev/null +++ b/internal/resolvers/plugin_name/plugin_name.go @@ -0,0 +1,33 @@ +package pluginname + +import ( + "context" + + "git.optclblast.xyz/draincloud/draincloud-core/internal/common" + "github.com/gin-gonic/gin" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +const ( + PluginNameResolverName = "plugin_name" +) + +type PluginNameResolver struct{} + +func (p *PluginNameResolver) Resolve(ctx context.Context, req *common.Request, rawReq any) error { + ginCtx, ok := rawReq.(*gin.Context) + if !ok { + return status.Errorf(codes.Internal, "invalid request type") + } + pluginName := ginCtx.Param("plugin_name") + if pluginName == "" { + return status.Error(codes.InvalidArgument, "plugin name is empty") + } + req.ResolveValues.Store(PluginNameResolverName, pluginName) + return nil +} + +func (p *PluginNameResolver) GetRequiredResolveParams() []string { + return nil +} diff --git a/internal/resolvers/resolver.go b/internal/resolvers/resolver.go index 7994d8d..275cbd1 100644 --- a/internal/resolvers/resolver.go +++ b/internal/resolvers/resolver.go @@ -7,5 +7,6 @@ import ( ) type Resolver interface { - Resolve(ctx context.Context, req *common.Request) error + Resolve(ctx context.Context, req *common.Request, reqReq any) error + GetRequiredResolveParams() []string } diff --git a/internal/resolvers/seal/acl.go b/internal/resolvers/seal/acl.go new file mode 100644 index 0000000..9ec3b83 --- /dev/null +++ b/internal/resolvers/seal/acl.go @@ -0,0 +1,6 @@ +package seal + +// TODO +type SealResolver struct { + wardenClient any +} diff --git a/internal/storage/filestorage/fs/storage.go b/internal/storage/filestorage/fs/storage.go index a22aa03..c130a6d 100644 --- a/internal/storage/filestorage/fs/storage.go +++ b/internal/storage/filestorage/fs/storage.go @@ -12,6 +12,8 @@ import ( type Storage struct { lm *sync.Map dir string + // If file is not belongs to current node FS - redirect to corresponding node + // cluster DrainCloudCluster } func NewFSStorage(dir string) *Storage { @@ -42,7 +44,7 @@ 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)) + file, err := os.Open(getFilePath(s.dir, id)) if err != nil { return fmt.Errorf("failed to open file: %w", err) } @@ -63,9 +65,7 @@ func (s *Storage) DeleteFile(ctx context.Context, id int64) error { tx := lockFile(s.lm, id) defer unlockFile(s.lm, id, tx) - - - return nil + return nil } func getFilePath(dir string, id int64) string { diff --git a/internal/storage/interface.go b/internal/storage/interface.go index fcb372e..45fc5ce 100644 --- a/internal/storage/interface.go +++ b/internal/storage/interface.go @@ -4,8 +4,8 @@ import ( "context" "os" - "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models" auditmodels "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/audit" + "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/auth" "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/files" "github.com/google/uuid" ) @@ -16,11 +16,11 @@ type Database interface { type AuthStorage interface { AddUser(ctx context.Context, id uuid.UUID, login string, username string, passwordHash []byte) error - GetUserByLogin(ctx context.Context, login string) (*models.User, error) - GetUserByID(ctx context.Context, id uuid.UUID) (*models.User, error) + GetUserByLogin(ctx context.Context, login string) (*auth.User, error) + GetUserByID(ctx context.Context, id uuid.UUID) (*auth.User, error) - AddSession(ctx context.Context, ses *models.Session) (uuid.UUID, error) - GetSession(ctx context.Context, sessionToken string) (*models.Session, error) + AddSession(ctx context.Context, ses *auth.Session) (uuid.UUID, error) + GetSession(ctx context.Context, sessionToken string) (*auth.Session, error) RemoveSession(ctx context.Context, id uuid.UUID) error } diff --git a/internal/storage/models/auth.go b/internal/storage/models/auth/auth.go similarity index 96% rename from internal/storage/models/auth.go rename to internal/storage/models/auth/auth.go index a75853d..6cacf2a 100644 --- a/internal/storage/models/auth.go +++ b/internal/storage/models/auth/auth.go @@ -1,4 +1,4 @@ -package models +package auth import ( "time" diff --git a/internal/storage/postgres/database.go b/internal/storage/postgres/database.go index de44d28..abfc651 100644 --- a/internal/storage/postgres/database.go +++ b/internal/storage/postgres/database.go @@ -9,7 +9,7 @@ import ( "git.optclblast.xyz/draincloud/draincloud-core/internal/closer" "git.optclblast.xyz/draincloud/draincloud-core/internal/logger" - "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models" + "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/auth" "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgconn" @@ -45,19 +45,19 @@ func (d *Database) AddUser(ctx context.Context, id uuid.UUID, login string, user return addUser(ctx, d.db, id, login, username, passwordHash) } -func (d *Database) GetUserByID(ctx context.Context, id uuid.UUID) (*models.User, error) { +func (d *Database) GetUserByID(ctx context.Context, id uuid.UUID) (*auth.User, error) { return getUserByID(ctx, d.db, id) } -func (d *Database) GetUserByLogin(ctx context.Context, login string) (*models.User, error) { +func (d *Database) GetUserByLogin(ctx context.Context, login string) (*auth.User, error) { return getUserByLogin(ctx, d.db, login) } -func (d *Database) AddSession(ctx context.Context, ses *models.Session) (uuid.UUID, error) { +func (d *Database) AddSession(ctx context.Context, ses *auth.Session) (uuid.UUID, error) { return addSession(ctx, d.db, ses) } -func (d *Database) GetSession(ctx context.Context, sessionToken string) (*models.Session, error) { +func (d *Database) GetSession(ctx context.Context, sessionToken string) (*auth.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 @@ -77,7 +77,7 @@ func (d *Database) GetSession(ctx context.Context, sessionToken string) (*models return nil, err } - return &models.Session{ + return &auth.Session{ ID: id, SessionToken: sesToken, CsrfToken: csrfToken, @@ -112,9 +112,9 @@ func addUser(ctx context.Context, conn dbtx, id uuid.UUID, login string, usernam return nil } -func getUserByID(ctx context.Context, conn dbtx, id uuid.UUID) (*models.User, error) { +func getUserByID(ctx context.Context, conn dbtx, id uuid.UUID) (*auth.User, error) { const stmt = `SELECT * FROM users WHERE id = $1 LIMIT 1` - u := new(models.User) + u := new(auth.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) @@ -123,9 +123,9 @@ func getUserByID(ctx context.Context, conn dbtx, id uuid.UUID) (*models.User, er return u, nil } -func getUserByLogin(ctx context.Context, conn dbtx, login string) (*models.User, error) { +func getUserByLogin(ctx context.Context, conn dbtx, login string) (*auth.User, error) { const stmt = `SELECT * FROM users WHERE login = $1 LIMIT 1` - u := new(models.User) + u := new(auth.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) @@ -134,7 +134,7 @@ func getUserByLogin(ctx context.Context, conn dbtx, login string) (*models.User, return u, nil } -func addSession(ctx context.Context, conn dbtx, session *models.Session) (uuid.UUID, error) { +func addSession(ctx context.Context, conn dbtx, session *auth.Session) (uuid.UUID, error) { const stmt = `INSERT INTO sessions (id,session_token, csrf_token, user_id, created_at, expired_at) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id;` var id uuid.UUID diff --git a/internal/transport/pool/pool.go b/internal/transport/pool/pool.go index aec589f..3de5071 100644 --- a/internal/transport/pool/pool.go +++ b/internal/transport/pool/pool.go @@ -1,3 +1,4 @@ +// TODO wtf? package pool import ( diff --git a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_AuthAuditLogStorage.go b/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_AuthAuditLogStorage.go deleted file mode 100644 index 840d37a..0000000 --- a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_AuthAuditLogStorage.go +++ /dev/null @@ -1,85 +0,0 @@ -// 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 -} diff --git a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_AuthStorage.go b/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_AuthStorage.go deleted file mode 100644 index c8bb2ad..0000000 --- a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_AuthStorage.go +++ /dev/null @@ -1,377 +0,0 @@ -// 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 -} diff --git a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_BlobStorage.go b/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_BlobStorage.go deleted file mode 100644 index 2bc2787..0000000 --- a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_BlobStorage.go +++ /dev/null @@ -1,191 +0,0 @@ -// 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 -} diff --git a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_Database.go b/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_Database.go deleted file mode 100644 index 90c7c42..0000000 --- a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_Database.go +++ /dev/null @@ -1,377 +0,0 @@ -// 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 -} diff --git a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_FileStorage.go b/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_FileStorage.go deleted file mode 100644 index 58900cb..0000000 --- a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_FileStorage.go +++ /dev/null @@ -1,32 +0,0 @@ -// 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 -} diff --git a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_MetaStorage.go b/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_MetaStorage.go deleted file mode 100644 index b6f8492..0000000 --- a/mocks/git.optclblast.xyz/draincloud/draincloud-core/internal/storage/mock_MetaStorage.go +++ /dev/null @@ -1,95 +0,0 @@ -// 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 -}