Files
phylum/server/internal/core/fs/resource.go
2025-04-05 18:51:58 +05:30

147 lines
3.4 KiB
Go

package fs
import (
"encoding/json"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
)
type Resource struct {
f filesystem
id uuid.UUID
parentID uuid.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
}
func (r Resource) ID() uuid.UUID { return r.id }
func (r Resource) ParentID() uuid.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) 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
}
if r, err := pgx.CollectExactlyOneRow(rows, scanner); err == nil {
return r, nil
} else {
if err == pgx.ErrNoRows {
err = ErrResourceNotFound
}
return r, err
}
}
func (f filesystem) scanLinkedResource(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,
)
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) scanResource(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,
)
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 readPermissionFromJson(j []byte, username string) (Permission, error) {
if j == nil {
return PermissionNone, nil
}
p := make(map[string]Permission)
err := json.Unmarshal(j, &p)
if err != nil {
return PermissionNone, err
}
if p, ok := p[username]; ok {
return p, nil
}
return PermissionNone, nil
}