This commit is contained in:
r8zavetr8v 2024-12-15 11:56:03 -05:00
parent f74a4779aa
commit 5bdb7fb0b0
10 changed files with 57 additions and 48 deletions

View File

@ -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)

3
go.mod
View File

@ -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

2
go.sum
View File

@ -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=

View File

@ -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")

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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