[server] Query and return inherited permissions

This commit is contained in:
Abhishek Shroff
2025-05-11 08:00:25 +05:30
parent 8be329b83d
commit 5a229c4e98
5 changed files with 103 additions and 59 deletions
@@ -10,7 +10,7 @@ class ResourceInfoRequest extends ApiRequest {
@override
BaseRequest createRequest(ApiClient api, {Uint8List? data}) {
final uri = api.createUriBuilder('/api/v1/fs/info/$resourceId');
final uri = api.createUriBuilder('/api/v1/fs/info/$resourceId:');
return Request('get', uri.build());
}
}
+12 -12
View File
@@ -39,18 +39,18 @@ func ResourceFromFS(r fs.Resource) Resource {
deleted = r.Deleted().Time.UnixMilli()
}
return Resource{
ID: r.ID(),
Name: r.Name(),
Dir: r.Dir(),
Created: r.Created().UnixMilli(),
Modified: r.Modified().UnixMilli(),
Deleted: deleted,
ContentLength: r.ContentLength(),
ContentType: r.ContentType(),
ContentSHA256: r.ContentSHA256(),
Permissions: string(r.Permissions()),
Grants: string(r.Grants()),
Links: r.Links(),
ID: r.ID(),
Name: r.Name(),
Dir: r.Dir(),
Created: r.Created().UnixMilli(),
Modified: r.Modified().UnixMilli(),
Deleted: deleted,
ContentLength: r.ContentLength(),
ContentType: r.ContentType(),
ContentSHA256: r.ContentSHA256(),
InheritedPermissions: string(r.InheritedPermissions()),
Grants: string(r.Grants()),
Links: r.Links(),
}
}
+12 -12
View File
@@ -16,18 +16,18 @@ type Ancestor struct {
}
type Resource struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Dir bool `json:"dir"`
Created int64 `json:"created"`
Modified int64 `json:"modified"`
Deleted int64 `json:"deleted"`
ContentLength int `json:"c_len"`
ContentType string `json:"c_type"`
ContentSHA256 string `json:"c_sha256"`
Permissions string `json:"permissions"`
Grants string `json:"grants"`
Links json.RawMessage `json:"publinks"`
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Dir bool `json:"dir"`
Created int64 `json:"created"`
Modified int64 `json:"modified"`
Deleted int64 `json:"deleted"`
ContentLength int `json:"c_len"`
ContentType string `json:"c_type"`
ContentSHA256 string `json:"c_sha256"`
InheritedPermissions string `json:"inherited_permissions,omitempty"`
Grants string `json:"grants"`
Links json.RawMessage `json:"publinks"`
}
type ResourceFull struct {
+8 -2
View File
@@ -9,7 +9,10 @@ import (
)
func (f filesystem) ResourceByID(id uuid.UUID) (Resource, error) {
const query = "SELECT r.*, (SELECT " + publinkFieldsQuery + " FROM publinks l WHERE l.root = r.id) AS links FROM resources r WHERE id = $1::UUID"
const query = `SELECT r.*,
(SELECT ` + publinkFieldsQuery + ` FROM publinks l WHERE l.root = r.id) AS links
(SELECT p.permissions FROM resources p WHERE p.id = r.parent) AS inheritedPermissions
FROM resources r WHERE id = $1::UUID`
if rows, err := f.db.Query(query, id); err != nil {
return Resource{}, err
} else {
@@ -56,7 +59,10 @@ func (f filesystem) ResourceByPath(path string) (Resource, error) {
UnionAll(sub)
l := goqu.T("publinks").As("l")
q := pg.Select(resources.All(), pg.Select(goqu.L(publinkFieldsQuery)).From(l).Where(l.Col("root").Eq(resources.Col("id")))).
q := pg.Select(resources.All(),
pg.Select(goqu.L(publinkFieldsQuery)).From(l).Where(l.Col("root").Eq(resources.Col("id"))),
pg.Select(goqu.L("(SELECT p.permissions FROM resources p WHERE p.id = r.parent)")),
).
From(resources).
WithRecursive("nodes(id, parent, search, depth)", rec).
Join(nodes, goqu.On(resources.Col("id").Eq(nodes.Col("id")))).
+70 -32
View File
@@ -10,45 +10,47 @@ import (
)
type Resource struct {
f filesystem
id uuid.UUID
parentID pgtype.UUID
name string
dir bool
created time.Time
modified time.Time
deleted pgtype.Timestamp
contentLength int
contentType string
contentSHA256 string
permissions []byte
grants []byte
links []byte
userPermission Permission
f filesystem
id uuid.UUID
parentID pgtype.UUID
name string
dir bool
created time.Time
modified time.Time
deleted pgtype.Timestamp
contentLength int
contentType string
contentSHA256 string
permissions []byte
inheritedPermissions []byte
grants []byte
links []byte
userPermission Permission
}
func (r Resource) ID() uuid.UUID { return r.id }
func (r Resource) ParentID() pgtype.UUID { return r.parentID }
func (r Resource) Name() string { return r.name }
func (r Resource) Dir() bool { return r.dir }
func (r Resource) Created() time.Time { return r.created }
func (r Resource) Modified() time.Time { return r.modified }
func (r Resource) Deleted() pgtype.Timestamp { return r.deleted }
func (r Resource) ContentLength() int { return r.contentLength }
func (r Resource) ContentSHA256() string { return r.contentSHA256 }
func (r Resource) ContentType() string { return r.contentType }
func (r Resource) Permissions() []byte { return r.permissions }
func (r Resource) Grants() []byte { return r.grants }
func (r Resource) Links() []byte { return r.links }
func (r Resource) ID() uuid.UUID { return r.id }
func (r Resource) ParentID() pgtype.UUID { return r.parentID }
func (r Resource) Name() string { return r.name }
func (r Resource) Dir() bool { return r.dir }
func (r Resource) Created() time.Time { return r.created }
func (r Resource) Modified() time.Time { return r.modified }
func (r Resource) Deleted() pgtype.Timestamp { return r.deleted }
func (r Resource) ContentLength() int { return r.contentLength }
func (r Resource) ContentSHA256() string { return r.contentSHA256 }
func (r Resource) ContentType() string { return r.contentType }
func (r Resource) Permissions() []byte { return r.permissions }
func (r Resource) InheritedPermissions() []byte { return r.inheritedPermissions }
func (r Resource) Grants() []byte { return r.grants }
func (r Resource) Links() []byte { return r.links }
func (r Resource) hasPermission(p Permission) bool {
return r.userPermission&p != 0
}
func (f filesystem) collectResource(rows pgx.Rows, includeLinks bool) (Resource, error) {
scanner := f.scanLinkedResource
if !includeLinks {
scanner = f.scanResource
func (f filesystem) collectResource(rows pgx.Rows, scanFullResource bool) (Resource, error) {
scanner := f.scanResource
if scanFullResource {
scanner = f.scanFullResource
}
if r, err := pgx.CollectExactlyOneRow(rows, scanner); err == nil {
return r, nil
@@ -61,6 +63,42 @@ func (f filesystem) collectResource(rows pgx.Rows, includeLinks bool) (Resource,
}
func (f filesystem) scanFullResource(row pgx.CollectableRow) (Resource, error) {
r := Resource{f: f}
err := row.Scan(
&r.id,
&r.name,
&r.parentID,
&r.dir,
&r.created,
&r.modified,
&r.deleted,
&r.contentLength,
&r.contentType,
&r.contentSHA256,
&r.permissions,
&r.grants,
&r.links,
&r.inheritedPermissions,
)
if err != nil {
return r, err
}
permission := Permission(0)
if f.fullAccess {
permission = -1
} else if p, err := readPermissionFromJson(r.permissions, f.username); err != nil {
return Resource{}, err
} else {
permission = p
}
if permission&PermissionRead == 0 {
return Resource{}, ErrResourceNotFound
}
r.userPermission = permission
return r, err
}
func (f filesystem) scanLinkedResource(row pgx.CollectableRow) (Resource, error) {
r := Resource{f: f}
err := row.Scan(