diff --git a/server/internal/app/core/filesystem.go b/server/internal/app/core/filesystem.go index ac96ffb8..83095280 100644 --- a/server/internal/app/core/filesystem.go +++ b/server/internal/app/core/filesystem.go @@ -108,9 +108,12 @@ func (f filesystem) ResourceByPath(path string) (Resource, error) { func (f filesystem) ResourceByID(id uuid.UUID) (Resource, error) { res, err := f.db.Queries().ResourceByIdWithPermissions(f.ctx, sql.ResourceByIdWithPermissionsParams{Root: f.root.ID(), ResourceID: id, UserID: f.user}) // TODO: check found - if err == pgx.ErrNoRows || res.Permission.Int32 == 0 || !res.Found { + if err == pgx.ErrNoRows || !res.Found { err = fs.ErrNotExist } + if res.Permission == 0 { + err = ErrInsufficientPermissions + } if err != nil { return nil, err } @@ -118,7 +121,7 @@ func (f filesystem) ResourceByID(id uuid.UUID) (Resource, error) { return resource{ id: res.ID, owner: res.Owner, - permission: res.Permission.Int32, + permission: res.Permission, parentID: res.Parent, name: res.Name, size: res.Size.Int64, diff --git a/server/internal/command/appcmd/admincmd/admin.go b/server/internal/command/appcmd/admincmd/admin.go index c33da1af..5c959dd5 100644 --- a/server/internal/command/appcmd/admincmd/admin.go +++ b/server/internal/command/appcmd/admincmd/admin.go @@ -12,7 +12,6 @@ func SetupCommand() *cobra.Command { cmd.AddCommand([]*cobra.Command{ setupStorageCommand(), setupUserCommand(), - setupResourceCommand(), }...) return cmd diff --git a/server/internal/command/appcmd/appcmd.go b/server/internal/command/appcmd/appcmd.go index 78336470..ce50d2ca 100644 --- a/server/internal/command/appcmd/appcmd.go +++ b/server/internal/command/appcmd/appcmd.go @@ -36,6 +36,7 @@ func SetupCommand(db **db.DbHandler, debug bool) *cobra.Command { cmd.AddCommand([]*cobra.Command{ admincmd.SetupCommand(), setupServeCommand(), + setupResourceCommand(), }...) return cmd diff --git a/server/internal/command/appcmd/admincmd/resource.go b/server/internal/command/appcmd/resource.go similarity index 99% rename from server/internal/command/appcmd/admincmd/resource.go rename to server/internal/command/appcmd/resource.go index 015332ab..f8b31456 100644 --- a/server/internal/command/appcmd/admincmd/resource.go +++ b/server/internal/command/appcmd/resource.go @@ -1,4 +1,4 @@ -package admincmd +package appcmd import ( "context" diff --git a/server/internal/migrations/data/005_permissions.sql b/server/internal/migrations/data/005_permissions.sql index d72965b1..c301da09 100644 --- a/server/internal/migrations/data/005_permissions.sql +++ b/server/internal/migrations/data/005_permissions.sql @@ -1,7 +1,7 @@ CREATE TABLE permissions( resource_id uuid NOT NULL, user_id INTEGER NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE, - permission INT NOT NULL, + permission INT NOT NULL DEFAULT 0, PRIMARY KEY(resource_id, user_id) ); diff --git a/server/internal/sql/permissions.sql.go b/server/internal/sql/permissions.sql.go index 80ef3020..07f07254 100644 --- a/server/internal/sql/permissions.sql.go +++ b/server/internal/sql/permissions.sql.go @@ -20,7 +20,7 @@ WITH RECURSIVE nodes(id, owner, parent, name, dir, created, modified, size, etag UNION ALL SELECT r.id, r.owner, r.parent, r.name, r.dir, r.created, r.modified, r.size, r.etag, n.depth + 1, concat(n.path, '/', r.name), CASE - WHEN r.owner = $4::int THEN 255 + WHEN r.owner = $4::int THEN 127 WHEN p.permission IS NULL THEN n.permission ELSE p.permission END @@ -100,14 +100,34 @@ func (q *Queries) ReadDir(ctx context.Context, arg ReadDirParams) ([]ReadDirRow, const resourceByIdWithPermissions = `-- name: ResourceByIdWithPermissions :one WITH RECURSIVE nodes(resid, id, parent, found, permission) AS ( - SELECT $2::uuid, r.id, r.parent, CASE WHEN r.id = $1::uuid THEN true ELSE false END, p.permission + SELECT $2::uuid, r.id, r.parent, + CASE + WHEN r.id = $1::uuid THEN true + ELSE false + END, + CASE + WHEN r.owner = $3::int THEN 127 + WHEN p.permission IS NOT NULL THEN p.permission + ELSE 0 + END FROM resources r LEFT JOIN permissions p on r.id = p.resource_id AND p.user_id = $3::int WHERE r.id = $2::uuid UNION ALL - SELECT n.resid, r.id, r.parent, CASE WHEN r.id = $1::uuid THEN true ELSE n.found END, CASE WHEN (n.permission IS NULL OR p.permission > n.permission) THEN p.permission ELSE n.permission END + SELECT n.resid, r.id, r.parent, + CASE + WHEN r.id = $1::uuid + THEN true + ELSE n.found + END, + CASE + WHEN n.permission IS NOT NULL THEN n.permission + WHEN r.owner = $3::int THEN 127 + WHEN p.permission IS NOT NULL THEN p.permission + ELSE 0 + END FROM resources r JOIN nodes n ON r.id = n.parent @@ -131,7 +151,7 @@ type ResourceByIdWithPermissionsRow struct { ID uuid.UUID Found bool Owner int32 - Permission pgtype.Int4 + Permission int32 ID_2 uuid.UUID Parent uuid.UUID Name string @@ -232,11 +252,17 @@ func (q *Queries) ResourceByPath(ctx context.Context, arg ResourceByPathParams) } const rootResource = `-- name: RootResource :one -SELECT r.name, r.owner, r.modified, p.permission +SELECT r.name, r.owner, r.modified, + CASE + WHEN r.owner = $1::int THEN 127 + WHEN p.permission IS NOT NULL THEN p.permission + ELSE 0 + END AS permission FROM resources r - JOIN permissions p + LEFT JOIN permissions p ON p.resource_id = r.id AND p.user_id = $1::int + WHERE r.id = '00000000-0000-0000-0000-000000000000'::uuid ` type RootResourceRow struct { diff --git a/server/sql/queries/permissions.sql b/server/sql/queries/permissions.sql index 4b441331..754748f3 100644 --- a/server/sql/queries/permissions.sql +++ b/server/sql/queries/permissions.sql @@ -82,11 +82,17 @@ ON r.id = n.resid WHERE n.id = @root::uuid; -- name: RootResource :one -SELECT r.name, r.owner, r.modified, p.permission +SELECT r.name, r.owner, r.modified, + CASE + WHEN r.owner = @user_id::int THEN 127 + WHEN p.permission IS NOT NULL THEN p.permission + ELSE 0 + END AS permission FROM resources r - JOIN permissions p + LEFT JOIN permissions p ON p.resource_id = r.id - AND p.user_id = @user_id::int; + AND p.user_id = @user_id::int + WHERE r.id = '00000000-0000-0000-0000-000000000000'::uuid; -- name: UpdatePermissionsForResource :exec INSERT INTO permissions(resource_id, user_id, permission)