diff --git a/cmd/main.go b/cmd/main.go index 3f67c6a..893a8a7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -21,6 +21,7 @@ func main() { pg := postgres.New(ctx, "postgres://draincloud:draincloud@localhost:5432/draincloud?sslmode=disable") + // TODO move cron on a separate job (k8s cronjob / docker cron) cleanupSessionsCron := cleanupsessions.New(pg) cleanupSessionsCron.Run(ctx) diff --git a/go.mod b/go.mod index c63c765..c3ce09d 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,10 @@ require ( github.com/fatih/color v1.17.0 github.com/fsnotify/fsnotify v1.7.0 github.com/gin-gonic/gin v1.10.0 + github.com/google/uuid v1.4.0 github.com/jackc/pgx/v5 v5.7.1 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 @@ -38,7 +40,6 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/nats-io/nats.go v1.37.0 // indirect 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 diff --git a/go.sum b/go.sum index 0db5302..6a37bc1 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,8 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG 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/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= diff --git a/internal/app/app.go b/internal/app/app.go index e689f4d..9c08abd 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -32,7 +32,7 @@ func New( authGroup := mux.Group("/auth") { authGroup.POST("/register", d.Register) - authGroup.POST("/login", d.Login) + authGroup.POST("/logon", d.Login) } filesGroup := mux.Group("/files") diff --git a/internal/files_engine/engine.go b/internal/files_engine/engine.go index 0866b0d..90aab39 100644 --- a/internal/files_engine/engine.go +++ b/internal/files_engine/engine.go @@ -6,6 +6,7 @@ import ( "git.optclblast.xyz/draincloud/draincloud-core/internal/storage" "git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models/files" + "github.com/google/uuid" ) type FilesEngine struct { @@ -25,7 +26,7 @@ func NewFilesEngine( type File struct { Name string - UserID int64 + UserID uuid.UUID Ext string Type string Size int64 @@ -36,14 +37,14 @@ type File struct { func (e *FilesEngine) SaveFile( ctx context.Context, file File, -) (int64, error) { +) (uuid.UUID, error) { fileID, err := e.metaStorage.SaveMetadata(ctx, files.FileMetadata{}) if err != nil { - return -1, fmt.Errorf("failed to create new file metadata: %w", err) + return uuid.Nil, fmt.Errorf("failed to create new file metadata: %w", err) } if err = e.blobStorage.SaveBlob(ctx, fileID, file.Data); err != nil { - return -1, fmt.Errorf("failed to save file data: %w", err) + return uuid.Nil, fmt.Errorf("failed to save file data: %w", err) } return fileID, nil diff --git a/internal/storage/interface.go b/internal/storage/interface.go index 2fc922f..27d9759 100644 --- a/internal/storage/interface.go +++ b/internal/storage/interface.go @@ -7,6 +7,7 @@ import ( "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/files" + "github.com/google/uuid" ) type Database interface { @@ -14,13 +15,13 @@ type Database interface { } type AuthStorage interface { - AddUser(ctx context.Context, login string, username string, passwordHash []byte) (int64, error) + AddUser(ctx context.Context, login string, username string, passwordHash []byte) (uuid.UUID, error) GetUserByLogin(ctx context.Context, login string) (*models.User, error) - GetUserByID(ctx context.Context, id uint64) (*models.User, error) + GetUserByID(ctx context.Context, id uuid.UUID) (*models.User, error) - AddSession(ctx context.Context, ses *models.Session) (int64, error) + AddSession(ctx context.Context, ses *models.Session) (uuid.UUID, error) GetSession(ctx context.Context, sessionToken string) (*models.Session, error) - RemoveSession(ctx context.Context, id int64) error + RemoveSession(ctx context.Context, id uuid.UUID) error } type AuthAuditLogStorage interface { @@ -28,11 +29,11 @@ type AuthAuditLogStorage interface { } type MetaStorage interface { - SaveMetadata(ctx context.Context, meta files.FileMetadata) (int64, error) + SaveMetadata(ctx context.Context, meta files.FileMetadata) (uuid.UUID, 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 + GetFile(ctx context.Context, id uuid.UUID) (*os.File, error) + SaveBlob(ctx context.Context, id uuid.UUID, data []byte) error + DeleteFile(ctx context.Context, id uuid.UUID) error } diff --git a/internal/storage/models/auth.go b/internal/storage/models/auth.go index 503e291..a75853d 100644 --- a/internal/storage/models/auth.go +++ b/internal/storage/models/auth.go @@ -1,18 +1,22 @@ package models -import "time" +import ( + "time" + + "github.com/google/uuid" +) type Session struct { - ID int64 + ID uuid.UUID SessionToken string CsrfToken string - UserID int64 + UserID uuid.UUID CreatedAt time.Time ExpiredAt time.Time } type User struct { - ID int64 + ID uuid.UUID Username string Login string PasswordHash []byte diff --git a/internal/storage/models/files/files.go b/internal/storage/models/files/files.go index 599b07e..8e26b1e 100644 --- a/internal/storage/models/files/files.go +++ b/internal/storage/models/files/files.go @@ -1,7 +1,9 @@ package files +import "github.com/google/uuid" + type FileMetadata struct { - Id int64 + Id uuid.UUID Name string UserID int64 Ext string diff --git a/internal/storage/postgres/database.go b/internal/storage/postgres/database.go index b9feb00..700e2ad 100644 --- a/internal/storage/postgres/database.go +++ b/internal/storage/postgres/database.go @@ -10,6 +10,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" + "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgconn" ) @@ -39,11 +40,11 @@ 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) (int64, error) { +func (d *Database) AddUser(ctx context.Context, login string, username string, passwordHash []byte) (uuid.UUID, error) { return addUser(ctx, d.db, login, username, passwordHash) } -func (d *Database) GetUserByID(ctx context.Context, id uint64) (*models.User, error) { +func (d *Database) GetUserByID(ctx context.Context, id uuid.UUID) (*models.User, error) { return getUserByID(ctx, d.db, id) } @@ -51,7 +52,7 @@ 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) (int64, error) { +func (d *Database) AddSession(ctx context.Context, ses *models.Session) (uuid.UUID, error) { return addSession(ctx, d.db, ses) } @@ -64,9 +65,9 @@ func (d *Database) GetSession(ctx context.Context, sessionToken string) (*models row := d.db.QueryRow(ctx, stmt, sessionToken) var ( - id int64 + id uuid.UUID sesToken, csrfToken string - userID int64 + userID uuid.UUID createdAt sql.NullTime expiredAt sql.NullTime ) @@ -85,7 +86,7 @@ func (d *Database) GetSession(ctx context.Context, sessionToken string) (*models }, nil } -func (d *Database) RemoveSession(ctx context.Context, id int64) error { +func (d *Database) RemoveSession(ctx context.Context, id uuid.UUID) error { const stmt = `DELETE FROM sessions WHERE id = $1;` _, err := d.db.Exec(ctx, stmt, id) return err @@ -98,20 +99,20 @@ func (d *Database) RemoveExpiredSessions(ctx context.Context) error { return err } -func addUser(ctx context.Context, conn dbtx, login string, username string, passwordHash []byte) (int64, error) { +func addUser(ctx context.Context, conn dbtx, login string, username string, passwordHash []byte) (uuid.UUID, 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 int64 + var id uuid.UUID if err := row.Scan(&id); err != nil { - return 0, fmt.Errorf("failed to insert user data into users table: %w", err) + return uuid.Nil, fmt.Errorf("failed to insert user data into users table: %w", err) } return id, nil } -func getUserByID(ctx context.Context, conn dbtx, id uint64) (*models.User, error) { +func getUserByID(ctx context.Context, conn dbtx, id uuid.UUID) (*models.User, error) { const stmt = `SELECT * FROM users WHERE id = $1 LIMIT 1` u := new(models.User) row := conn.QueryRow(ctx, stmt, id) @@ -133,13 +134,13 @@ func getUserByLogin(ctx context.Context, conn dbtx, login string) (*models.User, return u, nil } -func addSession(ctx context.Context, conn dbtx, session *models.Session) (int64, error) { +func addSession(ctx context.Context, conn dbtx, session *models.Session) (uuid.UUID, 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 int64 + var id uuid.UUID 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) + return uuid.Nil, fmt.Errorf("failed to insert new session: %w", err) } return id, nil diff --git a/migrations/20241214071428_init.sql b/migrations/20241214071428_init.sql index e8be9e3..702f49a 100644 --- a/migrations/20241214071428_init.sql +++ b/migrations/20241214071428_init.sql @@ -4,7 +4,7 @@ SELECT 'up SQL query'; -- Users as auth data create table if not exists users ( - id bigserial primary key, + id uuid primary key, username text default null, login text not null unique, password bytea not null, @@ -18,10 +18,10 @@ create index idx_users_username on users (username); -- Sessions and auth data create table sessions ( - id bigserial primary key, + id uuid primary key, session_token varchar(200) not null unique, csrf_token varchar(200) not null unique, - user_id bigserial references users(id), + user_id uuid references users(id), created_at timestamp default current_timestamp, expired_at timestamp not null ); @@ -30,13 +30,13 @@ create index if not exists idx_sessions_session_token_csrf_token on sessions (se -- Files create table files_metadata ( - id bigserial primary key, + id uuid primary key, name text not null, fslink text not null, size bigint not null, ext text not null, - owner_id bigint not null, - parent_dir bigint not null, + owner_id uuid not null, + parent_dir uuid not null, created_at timestamptz default current_timestamp, updated_at timestamptz default null, deleted_at timestamptz default null @@ -46,10 +46,10 @@ create index idx_fm_owner_id on files_metadata(owner_id); create index idx_fm_owner_id_parent_dir on files_metadata(owner_id, parent_dir); create table directories ( - id bigserial primary key, + id uuid primary key, name text not null, - owner_id bigint not null, - parent_dir bigint not null, + owner_id uuid not null, + parent_dir uuid not null, created_at timestamptz default current_timestamp, updated_at timestamptz default null, deleted_at timestamptz default null @@ -58,9 +58,9 @@ create table directories ( create index idx_directories_owner_id_parent_dir on directories(owner_id, parent_dir); create table directory_users_access ( - id bigserial primary key, - dir_id bigint not null, - user_id bigint not null, + id uuid primary key, + dir_id uuid not null, + user_id uuid not null, assess_flag integer, created_at timestamptz default current_timestamp, updated_at timestamptz default null @@ -68,8 +68,4 @@ create table directory_users_access ( create index idx_dua_owner_id_parent_dir on directories(owner_id, parent_dir); --- +goose Down --- +goose StatementBegin -SELECT 'down SQL query'; --- +goose StatementEnd