Quellcode durchsuchen

Check public albums for asset

Matthias Rupp vor 2 Jahren
Ursprung
Commit
11407b7e30

+ 14 - 0
server/apps/immich/src/api-v1/album/album-repository.ts

@@ -25,6 +25,7 @@ export interface IAlbumRepository {
   updateAlbum(album: AlbumEntity, updateAlbumDto: UpdateAlbumDto): Promise<AlbumEntity>;
   getListByAssetId(userId: string, assetId: string): Promise<AlbumEntity[]>;
   getCountByUserId(userId: string): Promise<AlbumCountResponseDto>;
+  getSharedAlbumCount(userId: string, assetId: string): Promise<number>;
 }
 
 export const ALBUM_REPOSITORY = 'ALBUM_REPOSITORY';
@@ -283,4 +284,17 @@ export class AlbumRepository implements IAlbumRepository {
 
     return this.albumRepository.save(album);
   }
+
+  async getSharedAlbumCount(userId: string, assetId: string): Promise<number> {
+    const result = await this
+        .userAlbumRepository
+        .createQueryBuilder('usa')
+        .select('count(aa)', 'count')
+        .innerJoin('asset_album', 'aa', 'aa.albumId = usa.albumId')
+        .where('aa.assetId = :assetId', { assetId })
+        .andWhere('usa.sharedUserId = :userId', { userId })
+        .getRawOne();
+
+    return result.count;
+  }
 }

+ 10 - 1
server/apps/immich/src/api-v1/asset/asset.module.ts

@@ -10,13 +10,18 @@ import { CommunicationModule } from '../communication/communication.module';
 import { QueueNameEnum } from '@app/job/constants/queue-name.constant';
 import { AssetRepository, ASSET_REPOSITORY } from './asset-repository';
 import { DownloadModule } from '../../modules/download/download.module';
+import {ALBUM_REPOSITORY, AlbumRepository} from "../album/album-repository";
+import {AlbumEntity} from "@app/database/entities/album.entity";
+import {UserAlbumEntity} from "@app/database/entities/user-album.entity";
+import {UserEntity} from "@app/database/entities/user.entity";
+import {AssetAlbumEntity} from "@app/database/entities/asset-album.entity";
 
 @Module({
   imports: [
     CommunicationModule,
     BackgroundTaskModule,
     DownloadModule,
-    TypeOrmModule.forFeature([AssetEntity]),
+    TypeOrmModule.forFeature([AssetEntity, AlbumEntity, UserAlbumEntity, UserEntity, AssetAlbumEntity]),
     BullModule.registerQueue({
       name: QueueNameEnum.ASSET_UPLOADED,
       defaultJobOptions: {
@@ -42,6 +47,10 @@ import { DownloadModule } from '../../modules/download/download.module';
       provide: ASSET_REPOSITORY,
       useClass: AssetRepository,
     },
+    {
+      provide: ALBUM_REPOSITORY,
+      useClass: AlbumRepository,
+    },
   ],
   exports: [AssetService],
 })

+ 11 - 3
server/apps/immich/src/api-v1/asset/asset.service.ts

@@ -54,6 +54,7 @@ import { InjectQueue } from '@nestjs/bull';
 import { Queue } from 'bull';
 import { DownloadService } from '../../modules/download/download.service';
 import { DownloadDto } from './dto/download-library.dto';
+import { ALBUM_REPOSITORY, IAlbumRepository } from "../album/album-repository";
 
 const fileInfo = promisify(stat);
 
@@ -63,6 +64,9 @@ export class AssetService {
     @Inject(ASSET_REPOSITORY)
     private _assetRepository: IAssetRepository,
 
+    @Inject(ALBUM_REPOSITORY)
+    private _albumRepository: IAlbumRepository,
+
     @InjectRepository(AssetEntity)
     private assetRepository: Repository<AssetEntity>,
 
@@ -627,8 +631,8 @@ export class AssetService {
     return this._assetRepository.getAssetCountByUserId(authUser.id);
   }
 
-  async checkAssetsAccess(authUser: AuthUserDto, assetIds: string[], mustBeOwner: boolean = false) {
-    for (let assetId of assetIds) {
+  async checkAssetsAccess(authUser: AuthUserDto, assetIds: string[], mustBeOwner = false) {
+    for (const assetId of assetIds) {
       // Step 1: Check if user owns asset
       if (await this._assetRepository.countByIdAndUser(assetId, authUser.id) == 1) {
         continue;
@@ -636,9 +640,13 @@ export class AssetService {
 
       // Avoid additional checks if ownership is required
       if (!mustBeOwner) {
+        // Step 2: Check if asset is part of an album shared with me
+        if (await this._albumRepository.getSharedAlbumCount(authUser.id, assetId) > 0) {
+          continue;
+        }
 
+        //TODO: Step 3: Check if asset is part of a public album
       }
-
       throw new ForbiddenException();
     }
   }