mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-14 00:31:25 +10:00
feat: make internal objectbackend methods private
This commit is contained in:
@ -1,5 +1,4 @@
|
||||
import {
|
||||
Object,
|
||||
ObjectBackend,
|
||||
ObjectMetadata,
|
||||
ObjectReference,
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { FsObjectBackend } from "./fsBackend";
|
||||
export const objectHandler = new FsObjectBackend();
|
||||
export default objectHandler
|
||||
import { ObjectHandler } from "./objectHandler";
|
||||
|
||||
export const objectHandler = new ObjectHandler(new FsObjectBackend());
|
||||
export default objectHandler;
|
||||
|
||||
@ -49,21 +49,29 @@ export abstract class ObjectBackend {
|
||||
abstract create(
|
||||
id: string,
|
||||
source: Source,
|
||||
metadata: ObjectMetadata,
|
||||
metadata: ObjectMetadata
|
||||
): Promise<ObjectReference | undefined>;
|
||||
abstract createWithWriteStream(
|
||||
id: string,
|
||||
metadata: ObjectMetadata,
|
||||
metadata: ObjectMetadata
|
||||
): Promise<Writable | undefined>;
|
||||
abstract delete(id: ObjectReference): Promise<boolean>;
|
||||
abstract fetchMetadata(
|
||||
id: ObjectReference,
|
||||
id: ObjectReference
|
||||
): Promise<ObjectMetadata | undefined>;
|
||||
abstract writeMetadata(
|
||||
id: ObjectReference,
|
||||
metadata: ObjectMetadata,
|
||||
metadata: ObjectMetadata
|
||||
): Promise<boolean>;
|
||||
abstract fetchHash(id: ObjectReference): Promise<string | undefined>;
|
||||
}
|
||||
|
||||
export class ObjectHandler {
|
||||
private backend: ObjectBackend;
|
||||
|
||||
constructor(backend: ObjectBackend) {
|
||||
this.backend = backend;
|
||||
}
|
||||
|
||||
private async fetchMimeType(source: Source) {
|
||||
if (source instanceof ReadableStream) {
|
||||
@ -87,13 +95,13 @@ export abstract class ObjectBackend {
|
||||
id: string,
|
||||
sourceFetcher: () => Promise<Source>,
|
||||
metadata: { [key: string]: string },
|
||||
permissions: Array<string>,
|
||||
permissions: Array<string>
|
||||
) {
|
||||
const { source, mime } = await this.fetchMimeType(await sourceFetcher());
|
||||
if (!mime)
|
||||
throw new Error("Unable to calculate MIME type - is the source empty?");
|
||||
|
||||
await this.create(id, source, {
|
||||
await this.backend.create(id, source, {
|
||||
permissions,
|
||||
userMetadata: metadata,
|
||||
mime,
|
||||
@ -103,9 +111,9 @@ export abstract class ObjectBackend {
|
||||
async createWithStream(
|
||||
id: string,
|
||||
metadata: { [key: string]: string },
|
||||
permissions: Array<string>,
|
||||
permissions: Array<string>
|
||||
) {
|
||||
return this.createWithWriteStream(id, {
|
||||
return this.backend.createWithWriteStream(id, {
|
||||
permissions,
|
||||
userMetadata: metadata,
|
||||
mime: "application/octet-stream",
|
||||
@ -113,13 +121,13 @@ export abstract class ObjectBackend {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches object, but also checks if user has perms to access it
|
||||
* @param id
|
||||
* @param userId
|
||||
* @returns
|
||||
* Fetches object, but also checks if user has perms to access it
|
||||
* @param id
|
||||
* @param userId
|
||||
* @returns
|
||||
*/
|
||||
async fetchWithPermissions(id: ObjectReference, userId?: string) {
|
||||
const metadata = await this.fetchMetadata(id);
|
||||
const metadata = await this.backend.fetchMetadata(id);
|
||||
if (!metadata) return;
|
||||
|
||||
// We only need one permission, so find instead of filter is faster
|
||||
@ -137,7 +145,7 @@ export abstract class ObjectBackend {
|
||||
|
||||
// Because any permission can be read or up, we automatically know we can read this object
|
||||
// So just straight return the object
|
||||
const source = await this.fetch(id);
|
||||
const source = await this.backend.fetch(id);
|
||||
if (!source) return undefined;
|
||||
const object: Object = {
|
||||
data: source,
|
||||
@ -146,6 +154,28 @@ export abstract class ObjectBackend {
|
||||
return object;
|
||||
}
|
||||
|
||||
async fetchHashWithWithPermissions(id: ObjectReference, userId?: string) {
|
||||
const metadata = await this.backend.fetchMetadata(id);
|
||||
if (!metadata) return;
|
||||
|
||||
// We only need one permission, so find instead of filter is faster
|
||||
const myPermissions = metadata.permissions.find((e) => {
|
||||
if (userId !== undefined && e.startsWith(userId)) return true;
|
||||
if (userId !== undefined && e.startsWith("internal")) return true;
|
||||
if (e.startsWith("anonymous")) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!myPermissions) {
|
||||
// We do not have access to this object
|
||||
return;
|
||||
}
|
||||
|
||||
// Because any permission can be read or up, we automatically know we can read this object
|
||||
// So just straight return the object
|
||||
return await this.backend.fetchHash(id);
|
||||
}
|
||||
|
||||
// If we need to fetch a remote resource, it doesn't make sense
|
||||
// to immediately fetch the object, *then* check permissions.
|
||||
// Instead the caller can pass a simple anonymous funciton, like
|
||||
@ -154,9 +184,9 @@ export abstract class ObjectBackend {
|
||||
async writeWithPermissions(
|
||||
id: ObjectReference,
|
||||
sourceFetcher: () => Promise<Source>,
|
||||
userId?: string,
|
||||
userId?: string
|
||||
) {
|
||||
const metadata = await this.fetchMetadata(id);
|
||||
const metadata = await this.backend.fetchMetadata(id);
|
||||
if (!metadata) return false;
|
||||
|
||||
const myPermissions = metadata.permissions
|
||||
@ -178,13 +208,13 @@ export abstract class ObjectBackend {
|
||||
if (!hasPermission) return false;
|
||||
|
||||
const source = await sourceFetcher();
|
||||
const result = await this.write(id, source);
|
||||
const result = await this.backend.write(id, source);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async deleteWithPermission(id: ObjectReference, userId?: string) {
|
||||
const metadata = await this.fetchMetadata(id);
|
||||
const metadata = await this.backend.fetchMetadata(id);
|
||||
if (!metadata) return false;
|
||||
|
||||
const myPermissions = metadata.permissions
|
||||
@ -205,7 +235,7 @@ export abstract class ObjectBackend {
|
||||
|
||||
if (!hasPermission) return false;
|
||||
|
||||
const result = await this.delete(id);
|
||||
const result = await this.backend.delete(id);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user