tmp 1
This commit is contained in:
parent
f74a4779aa
commit
5bdb7fb0b0
@ -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
3
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
|
||||
|
2
go.sum
2
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=
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user