Skip to content

Commit

Permalink
fix: s3 to use region even without access keys
Browse files Browse the repository at this point in the history
  • Loading branch information
drodil committed Mar 27, 2024
1 parent 43e8409 commit a83cec5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 45 deletions.
23 changes: 3 additions & 20 deletions plugins/qeta-backend/src/service/routes/attachments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ import S3StoreEngine from '../upload/s3';
import fs from 'fs';
import FileType from 'file-type';
import { File } from '../types';
import {
S3Client,
GetObjectCommand,
GetObjectCommandOutput,
} from '@aws-sdk/client-s3';
import { GetObjectCommand, GetObjectCommandOutput } from '@aws-sdk/client-s3';
import { getS3Client } from '../util';

const DEFAULT_IMAGE_SIZE_LIMIT = 2500000;
const DEFAULT_MIME_TYPES = [
Expand Down Expand Up @@ -110,24 +107,10 @@ export const attachmentsRoutes = (router: Router, options: RouterOptions) => {
imageBuffer = attachment.binaryImage;
} else if (attachment.locationType === 's3') {
const bucket = config.getOptionalString('qeta.storage.bucket');
const accessKeyId = config.getOptionalString('qeta.storage.accessKeyId');
const secretAccessKey = config.getOptionalString(
'qeta.storage.secretAccessKey',
);
const region = config.getOptionalString('qeta.storage.region');
if (!bucket) {
throw new Error('Bucket name is required for S3 storage');
}
const s3 =
accessKeyId && secretAccessKey && region
? new S3Client({
credentials: {
accessKeyId,
secretAccessKey,
},
region,
})
: new S3Client();
const s3 = getS3Client(config);
const object: GetObjectCommandOutput = await s3.send(
new GetObjectCommand({
Bucket: bucket,
Expand Down
28 changes: 3 additions & 25 deletions plugins/qeta-backend/src/service/upload/s3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { Config } from '@backstage/config';
import { QetaStore } from '../../database/QetaStore';
import { Attachment } from '@drodil/backstage-plugin-qeta-common';
import { File } from '../types';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { PutObjectCommand } from '@aws-sdk/client-s3';
import { getS3Client } from '../util';

type Options = {
config: Config;
Expand All @@ -19,41 +20,18 @@ class S3StoreEngine {
folder: string;

bucket?: string;
accessKeyId?: string;
secretAccessKey?: string;
region?: string;

constructor(opts: Options) {
this.config = opts.config;
this.database = opts.database;
this.backendBaseUrl = this.config.getString('backend.baseUrl');
this.qetaUrl = `${this.backendBaseUrl}/api/qeta/attachments`;
this.bucket = this.config.getOptionalString('qeta.storage.bucket');
this.accessKeyId = this.config.getOptionalString(
'qeta.storage.accessKeyId',
);
this.secretAccessKey = this.config.getOptionalString(
'qeta.storage.secretAccessKey',
);
this.folder =
this.config.getOptionalString('qeta.storage.folder') ||
'/backstage-qeta-images';
this.region = this.config.getOptionalString('qeta.storage.region');
}

newClient = (): S3Client => {
if (this.accessKeyId && this.secretAccessKey && this.region) {
return new S3Client({
credentials: {
accessKeyId: this.accessKeyId,
secretAccessKey: this.secretAccessKey,
},
region: this.region,
});
}
return new S3Client({});
};

handleFile = async (file: File): Promise<Attachment> => {
if (!this.bucket) {
throw new Error('Bucket name is required for S3 storage');
Expand All @@ -62,7 +40,7 @@ class S3StoreEngine {
const filename = `image-${imageUuid}-${Date.now()}.${file.ext}`;
const newPath = `${this.folder}/${filename}`;
const imageURI = `${this.qetaUrl}/${imageUuid}`;
const client = this.newClient();
const client = getS3Client(this.config);
const uploadArgs = {
Bucket: this.bucket,
Key: newPath,
Expand Down
20 changes: 20 additions & 0 deletions plugins/qeta-backend/src/service/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
} from '@backstage/plugin-permission-common';
import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node';
import { MaybeAnswer, MaybeQuestion } from '../database/QetaStore';
import { Config } from '@backstage/config';
import { S3Client } from '@aws-sdk/client-s3';

export const getUsername = async (
req: Request<unknown>,
Expand Down Expand Up @@ -149,3 +151,21 @@ export const stringDateTime = (dayString: string) => {

return formattedDate;
};

export const getS3Client = (config: Config) => {
const accessKeyId = config.getOptionalString('qeta.storage.accessKeyId');
const secretAccessKey = config.getOptionalString(
'qeta.storage.secretAccessKey',
);
const region = config.getOptionalString('qeta.storage.region');
if (accessKeyId && secretAccessKey) {
return new S3Client({
credentials: {
accessKeyId,
secretAccessKey,
},
region,
});
}
return new S3Client({ region });
};

0 comments on commit a83cec5

Please sign in to comment.