[server] basic public share creation

This commit is contained in:
Abhishek Shroff
2024-10-28 00:37:40 +05:30
parent 9dfb1c9e55
commit cf13a7488e
7 changed files with 151 additions and 2 deletions

View File

@@ -5,6 +5,7 @@ import (
"path"
"github.com/shroff/phylum/server/internal/command/fs"
"github.com/shroff/phylum/server/internal/command/public.go"
"github.com/shroff/phylum/server/internal/command/schema"
"github.com/shroff/phylum/server/internal/command/serve"
storagecmd "github.com/shroff/phylum/server/internal/command/storage"
@@ -64,6 +65,7 @@ func SetupCommand() {
user.SetupCommand(),
storagecmd.SetupCommand(),
fs.SetupCommand(),
public.SetupCommand(),
serve.SetupCommand(),
}...)
rootCmd.Execute()

View File

@@ -17,7 +17,7 @@ func SetupCommand() *cobra.Command {
flags.StringP("default-storage-dir", "S", "storage/default", "Default Storage Directory")
viper.BindPFlag("default_storage_dir", flags.Lookup("default-storage-dir"))
flags.StringP("user", "u", "phylum", "Specify user for resource operations")
flags.StringP("user", "u", "phylum", "User")
cmd.AddCommand(
setupCatCommand(),

View File

@@ -0,0 +1,24 @@
package public
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func SetupCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "public",
Short: "Public Share",
}
flags := cmd.PersistentFlags()
flags.Bool("auto-migrate", true, "Automatically migrate database schema")
viper.BindPFlag("auto_migrate", flags.Lookup("auto-migrate"))
flags.StringP("user", "u", "phylum", "User")
cmd.AddCommand(
setupCreateCommand(),
)
return cmd
}

View File

@@ -0,0 +1,31 @@
package public
import (
"fmt"
"github.com/shroff/phylum/server/internal/command/common"
"github.com/shroff/phylum/server/internal/core/fs"
"github.com/spf13/cobra"
)
func setupCreateCommand() *cobra.Command {
cmd := cobra.Command{
Use: "create <name> (<path> | <uuid>)",
Short: "Create Public Share",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
if err := createPublicShare(common.UserFileSystem(cmd), args[0], args[1]); err != nil {
fmt.Println("could not create public share '" + args[0] + "': " + err.Error())
}
},
}
return &cmd
}
func createPublicShare(f fs.FileSystem, name, pathOrUUID string) error {
r, err := f.ResourceByPathOrUUID(pathOrUUID)
if err != nil {
return err
}
return r.CreatePublicShare(name, nil, nil, nil)
}

View File

@@ -7,6 +7,9 @@ package db
import (
"context"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
const accessPublicShare = `-- name: AccessPublicShare :exec
@@ -18,6 +21,38 @@ func (q *Queries) AccessPublicShare(ctx context.Context, id string) error {
return err
}
const createPublicShare = `-- name: CreatePublicShare :exec
INSERT INTO public_shares(id, created_by, root, password_hash, expires, accesses_left) VALUES(
$1::text,
$2::text,
$3::uuid,
$4::text,
$5::timestamp,
$6::int
)
`
type CreatePublicShareParams struct {
ID string
CreatedBy string
Root uuid.UUID
PasswordHash pgtype.Text
Expires pgtype.Timestamp
AccessesLeft pgtype.Int4
}
func (q *Queries) CreatePublicShare(ctx context.Context, arg CreatePublicShareParams) error {
_, err := q.db.Exec(ctx, createPublicShare,
arg.ID,
arg.CreatedBy,
arg.Root,
arg.PasswordHash,
arg.Expires,
arg.AccessesLeft,
)
return err
}
const publicShare = `-- name: PublicShare :one
SELECT id, created, deleted, created_by, root, password_hash, expires, accesses_left from public_shares WHERE id = $1
`

View File

@@ -1,5 +1,52 @@
package fs
func (f filesystem) CreatePublicShare(r Resource) {
import (
"time"
"github.com/jackc/pgx/v5/pgtype"
"github.com/shroff/phylum/server/internal/core/db"
"github.com/shroff/phylum/server/internal/core/util/crypt"
)
func (r Resource) CreatePublicShare(name string, password *string, maxAge *time.Time, maxDownloads *int) error {
if !r.hasPermission(PermissionShare | PermissionRead) {
return ErrInsufficientPermissions
}
passwordHash := pgtype.Text{}
expires := pgtype.Timestamp{}
accessesLeft := pgtype.Int4{}
if password != nil {
hash, err := crypt.GenerateArgon2EncodedHash(*password)
if err != nil {
return err
}
passwordHash = pgtype.Text{
String: hash,
Valid: true,
}
}
if maxAge != nil {
expires = pgtype.Timestamp{
Time: *maxAge,
Valid: true,
}
}
if maxDownloads != nil {
accessesLeft = pgtype.Int4{
Int32: int32(*maxDownloads),
Valid: true,
}
}
return r.f.db.CreatePublicShare(r.f.ctx, db.CreatePublicShareParams{
ID: name,
CreatedBy: r.f.username,
Root: r.ID,
PasswordHash: passwordHash,
Expires: expires,
AccessesLeft: accessesLeft,
})
}

View File

@@ -3,3 +3,13 @@ SELECT * from public_shares WHERE id = $1;
-- name: AccessPublicShare :exec
UPDATE public_shares SET accesses_left = accesses_left - 1 WHERE id = $1;
-- name: CreatePublicShare :exec
INSERT INTO public_shares(id, created_by, root, password_hash, expires, accesses_left) VALUES(
@id::text,
@created_by::text,
@root::uuid,
sqlc.narg('password_hash')::text,
sqlc.narg('expires')::timestamp,
sqlc.narg('accesses_left')::int
);