Skip to content

Commit

Permalink
Add file, folder, permission, sharedlink, group and user objects to s…
Browse files Browse the repository at this point in the history
…harepoint
  • Loading branch information
amuwal committed Sep 9, 2024
1 parent 7102605 commit 773227f
Show file tree
Hide file tree
Showing 27 changed files with 2,134 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,41 @@
import { SharepointDriveInput, SharepointDriveOutput } from '@filestorage/drive/services/sharepoint/types';
import {
BoxSharedLinkInput,
BoxSharedLinkOutput,
} from '@filestorage/sharedlink/services/box/types';
import {
SharepointSharedLinkInput,
SharepointSharedLinkOutput,
} from '@filestorage/sharedlink/services/sharepoint/types';

import {
SharepointPermissionInput,
SharepointPermissionOutput,
} from '@filestorage/permission/services/sharepoint/types';

import {
SharepointGroupInput,
SharepointGroupOutput,
} from '@filestorage/group/services/sharepoint/types';

import {
SharepointUserInput,
SharepointUserOutput,
} from '@filestorage/user/services/sharepoint/types';

import {
SharepointFolderInput,
SharepointFolderOutput,
} from '@filestorage/folder/services/sharepoint/types';

import {
SharepointFileInput,
SharepointFileOutput,
} from '@filestorage/file/services/sharepoint/types';

import {
SharepointDriveInput,
SharepointDriveOutput,
} from '@filestorage/drive/services/sharepoint/types';

/* INPUT */

Expand All @@ -20,13 +57,13 @@ import {
} from '@filestorage/user/services/box/types';

/* file */
export type OriginalFileInput = BoxFileInput;
export type OriginalFileInput = BoxFileInput | SharepointFileInput;

/* folder */
export type OriginalFolderInput = BoxFolderInput;
export type OriginalFolderInput = BoxFolderInput | SharepointFolderInput;

/* permission */
export type OriginalPermissionInput = any;
export type OriginalPermissionInput = any | SharepointPermissionInput;

/* shared link */
export type OriginalSharedLinkInput = any;
Expand All @@ -35,10 +72,10 @@ export type OriginalSharedLinkInput = any;
export type OriginalDriveInput = any | SharepointDriveInput;

/* group */
export type OriginalGroupInput = BoxGroupInput;
export type OriginalGroupInput = BoxGroupInput | SharepointGroupInput;

/* user */
export type OriginalUserInput = BoxUserInput;
export type OriginalUserInput = BoxUserInput | SharepointUserInput;

export type FileStorageObjectInput =
| OriginalFileInput
Expand All @@ -52,13 +89,13 @@ export type FileStorageObjectInput =
/* OUTPUT */

/* file */
export type OriginalFileOutput = BoxFileOutput;
export type OriginalFileOutput = BoxFileOutput | SharepointFileOutput;

/* folder */
export type OriginalFolderOutput = BoxFolderOutput;
export type OriginalFolderOutput = BoxFolderOutput | SharepointFolderOutput;

/* permission */
export type OriginalPermissionOutput = any;
export type OriginalPermissionOutput = any | SharepointPermissionOutput;

/* shared link */
export type OriginalSharedLinkOutput = any;
Expand All @@ -67,10 +104,10 @@ export type OriginalSharedLinkOutput = any;
export type OriginalDriveOutput = any | SharepointDriveOutput;

/* group */
export type OriginalGroupOutput = BoxGroupOutput;
export type OriginalGroupOutput = BoxGroupOutput | SharepointGroupOutput;

/* user */
export type OriginalUserOutput = BoxUserOutput;
export type OriginalUserOutput = BoxUserOutput | SharepointUserOutput;

export type FileStorageObjectOutput =
| OriginalFileOutput
Expand All @@ -80,3 +117,11 @@ export type FileStorageObjectOutput =
| OriginalDriveOutput
| OriginalGroupOutput
| OriginalUserOutput;

export type OriginalSharedlinkInput =
| BoxSharedLinkInput
| SharepointSharedLinkInput;

export type OriginalSharedlinkOutput =
| BoxSharedLinkOutput
| SharepointSharedLinkOutput;
4 changes: 4 additions & 0 deletions packages/api/src/filestorage/file/file.module.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { SharepointFileMapper } from './services/sharepoint/mappers';
import { SharepointService } from './services/sharepoint';
import { BullQueueModule } from '@@core/@core-services/queues/queue.module';
import { WebhookService } from '@@core/@core-services/webhooks/panora-webhooks/webhook.service';
import { Module } from '@nestjs/common';
Expand All @@ -24,6 +26,8 @@ import { Utils } from '@filestorage/@lib/@utils';
BoxFileMapper,
/* PROVIDERS SERVICES */
BoxService,
SharepointService,
SharepointFileMapper,
],
exports: [SyncService],
})
Expand Down
92 changes: 92 additions & 0 deletions packages/api/src/filestorage/file/services/sharepoint/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { EncryptionService } from '@@core/@core-services/encryption/encryption.service';
import { LoggerService } from '@@core/@core-services/logger/logger.service';
import { PrismaService } from '@@core/@core-services/prisma/prisma.service';
import { ApiResponse } from '@@core/utils/types';
import { SyncParam } from '@@core/utils/types/interface';
import { FileStorageObject } from '@filestorage/@lib/@types';
import { IFileService } from '@filestorage/file/types';
import { Injectable } from '@nestjs/common';
import axios from 'axios';
import { ServiceRegistry } from '../registry.service';
import { SharepointFileOutput } from './types';

@Injectable()
export class SharepointService implements IFileService {
constructor(
private prisma: PrismaService,
private logger: LoggerService,
private cryptoService: EncryptionService,
private registry: ServiceRegistry,
) {
this.logger.setContext(
`${FileStorageObject.file.toUpperCase()}:${SharepointService.name}`,
);
this.registry.registerService('sharepoint', this);
}

// todo: add addFile method

async sync(data: SyncParam): Promise<ApiResponse<SharepointFileOutput[]>> {
try {
const { linkedUserId, id_folder } = data;
if (!id_folder) return;

const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'sharepoint',
vertical: 'filestorage',
},
});

const folder = await this.prisma.fs_folders.findUnique({
where: {
id_fs_folder: id_folder as string,
},
});

const resp = await axios.get(
`${connection.account_url}/drive/items/${folder.remote_id}/children`,
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.cryptoService.decrypt(
connection.access_token,
)}`,
},
},
);

const files: SharepointFileOutput[] = resp.data.value.filter(
(elem) => !elem.folder, // files don't have a folder property
);

// Add permission shared link is also included in permissions in one-drive)
await Promise.all(
files.map(async (driveItem) => {
const resp = await axios.get(
`${connection.account_url}/drive/items/${driveItem.id}/permissions`,
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.cryptoService.decrypt(
connection.access_token,
)}`,
},
},
);
driveItem.permissions = resp.data.value;
}),
);

this.logger.log(`Synced sharepoint files !`);
return {
data: files,
message: "One Drive's files retrieved",
statusCode: 200,
};
} catch (error) {
throw error;
}
}
}
136 changes: 136 additions & 0 deletions packages/api/src/filestorage/file/services/sharepoint/mappers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { MappersRegistry } from '@@core/@core-services/registries/mappers.registry';
import { CoreUnification } from '@@core/@core-services/unification/core-unification.service';
import {
OriginalPermissionOutput,
OriginalSharedLinkOutput,
} from '@@core/utils/types/original/original.file-storage';
import { FileStorageObject } from '@filestorage/@lib/@types';
import { Utils } from '@filestorage/@lib/@utils';
import { IFileMapper } from '@filestorage/file/types';
import {
UnifiedFilestorageFileInput,
UnifiedFilestorageFileOutput,
} from '@filestorage/file/types/model.unified';
import { UnifiedFilestorageSharedlinkOutput } from '@filestorage/sharedlink/types/model.unified';
import { Injectable } from '@nestjs/common';
import { SharepointFileInput, SharepointFileOutput } from './types';

@Injectable()
export class SharepointFileMapper implements IFileMapper {
constructor(
private mappersRegistry: MappersRegistry,
private utils: Utils,
private coreUnificationService: CoreUnification,
) {
this.mappersRegistry.registerService(
'filestorage',
'file',
'sharepoint',
this,
);
}

async desunify(
source: UnifiedFilestorageFileInput,
customFieldMappings?: {
slug: string;
remote_id: string;
}[],
): Promise<SharepointFileInput> {
// todo: do something with customFieldMappings
return {
name: source.name,
file: {
mimeType: source.mime_type,
},
size: parseInt(source.size),
parentReference: {
id: source.folder_id,
},
};
}

async unify(
source: SharepointFileOutput | SharepointFileOutput[],
connectionId: string,
customFieldMappings?: {
slug: string;
remote_id: string;
}[],
): Promise<UnifiedFilestorageFileOutput | UnifiedFilestorageFileOutput[]> {
if (!Array.isArray(source)) {
return await this.mapSingleFileToUnified(
source,
connectionId,
customFieldMappings,
);
}
// Handling array of SharepointFileOutput
return Promise.all(
source.map((file) =>
this.mapSingleFileToUnified(file, connectionId, customFieldMappings),
),
);
}

private async mapSingleFileToUnified(
file: SharepointFileOutput,
connectionId: string,
customFieldMappings?: {
slug: string;
remote_id: string;
}[],
): Promise<UnifiedFilestorageFileOutput> {
const field_mappings: { [key: string]: any } = {};
if (customFieldMappings) {
for (const mapping of customFieldMappings) {
field_mappings[mapping.slug] = file[mapping.remote_id];
}
}

const opts: any = {};
if (file.permissions?.length) {
const permissions = await this.coreUnificationService.unify<
OriginalPermissionOutput[]
>({
sourceObject: file.permissions,
targetType: FileStorageObject.permission,
providerName: 'sharepoint',
vertical: 'filestorage',
connectionId,
customFieldMappings: [],
});
opts.permissions = permissions;

// shared link
if (file.permissions.some((p) => p.link)) {
const sharedLinks =
await this.coreUnificationService.unify<OriginalSharedLinkOutput>({
sourceObject: file.permissions.find((p) => p.link),
targetType: FileStorageObject.sharedlink,
providerName: 'sharepoint',
vertical: 'filestorage',
connectionId,
customFieldMappings: [],
});
opts.shared_links = sharedLinks;
}
}

// todo: handle folder

return {
remote_id: file.id,
remote_data: file,
name: file.name,
file_url: file.webUrl,
mime_type: file.file.mimeType,
size: file.size.toString(),
folder_id: null,
// permission: opts.permissions?.[0] || null,
permission: null,
shared_link: opts.shared_links?.[0] || null,
field_mappings,
};
}
}
Loading

0 comments on commit 773227f

Please sign in to comment.