mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-05-01 01:31:01 -05:00
[server] Query and return inherited permissions
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")))).
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user