Skip to content

Commit 77a456f

Browse files
authored
feat: allow disabling s3 protocol (#595)
1 parent 277de4e commit 77a456f

File tree

7 files changed

+52
-3
lines changed

7 files changed

+52
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE tenants ADD COLUMN IF NOT EXISTS feature_s3_protocol boolean DEFAULT true NOT NULL;

src/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ type StorageConfigType = {
108108
tusPartSize: number
109109
tusUseFileVersionSeparator: boolean
110110
defaultMetricsEnabled: boolean
111+
s3ProtocolEnabled: boolean
111112
s3ProtocolPrefix: string
112113
s3ProtocolAllowForwardedHeader: boolean
113114
s3ProtocolEnforceRegion: boolean
@@ -252,6 +253,7 @@ export function getConfig(options?: { reload?: boolean }): StorageConfigType {
252253
getOptionalConfigFromEnv('TUS_USE_FILE_VERSION_SEPARATOR') === 'true',
253254

254255
// S3 Protocol
256+
s3ProtocolEnabled: getOptionalConfigFromEnv('S3_PROTOCOL_ENABLED') !== 'false',
255257
s3ProtocolPrefix: getOptionalConfigFromEnv('S3_PROTOCOL_PREFIX') || '',
256258
s3ProtocolAllowForwardedHeader:
257259
getOptionalConfigFromEnv('S3_ALLOW_FORWARDED_HEADER') === 'true',

src/http/routes/admin/tenants.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { FastifyInstance, RequestGenericInterface } from 'fastify'
22
import { FromSchema } from 'json-schema-to-ts'
33
import apiKey from '../../plugins/apikey'
4-
import { decrypt, encrypt } from '../../../internal/auth'
4+
import { decrypt, encrypt } from '@internal/auth'
55
import {
66
deleteTenantConfig,
77
TenantMigrationStatus,
88
multitenantKnex,
99
lastMigrationName,
1010
runMigrationsOnTenant,
1111
progressiveMigrations,
12-
} from '../../../internal/database'
12+
} from '@internal/database'
1313
import { dbSuperUser, storage } from '../../plugins'
1414

1515
const patchSchema = {
@@ -35,6 +35,12 @@ const patchSchema = {
3535
maxResolution: { type: 'number', nullable: true },
3636
},
3737
},
38+
s3Protocol: {
39+
type: 'object',
40+
properties: {
41+
enabled: { type: 'boolean' },
42+
},
43+
},
3844
},
3945
},
4046
},
@@ -75,6 +81,7 @@ interface tenantDBInterface {
7581
} | null
7682
service_key: string
7783
file_size_limit?: number
84+
feature_s3_protocol?: boolean
7885
feature_image_transformation?: boolean
7986
image_transformation_max_resolution?: number
8087
}
@@ -96,6 +103,7 @@ export default async function routes(fastify: FastifyInstance) {
96103
jwks,
97104
service_key,
98105
feature_image_transformation,
106+
feature_s3_protocol,
99107
image_transformation_max_resolution,
100108
migrations_version,
101109
migrations_status,
@@ -118,6 +126,9 @@ export default async function routes(fastify: FastifyInstance) {
118126
enabled: feature_image_transformation,
119127
maxResolution: image_transformation_max_resolution,
120128
},
129+
s3Protocol: {
130+
enabled: feature_s3_protocol,
131+
},
121132
},
122133
})
123134
)
@@ -137,6 +148,7 @@ export default async function routes(fastify: FastifyInstance) {
137148
jwt_secret,
138149
jwks,
139150
service_key,
151+
feature_s3_protocol,
140152
feature_image_transformation,
141153
image_transformation_max_resolution,
142154
migrations_version,
@@ -163,6 +175,9 @@ export default async function routes(fastify: FastifyInstance) {
163175
enabled: feature_image_transformation,
164176
maxResolution: image_transformation_max_resolution,
165177
},
178+
s3Protocol: {
179+
enabled: feature_s3_protocol,
180+
},
166181
},
167182
migrationVersion: migrations_version,
168183
migrationStatus: migrations_status,
@@ -197,6 +212,7 @@ export default async function routes(fastify: FastifyInstance) {
197212
jwks,
198213
service_key: encrypt(serviceKey),
199214
feature_image_transformation: features?.imageTransformation?.enabled ?? false,
215+
feature_s3_protocol: features?.s3Protocol?.enabled ?? true,
200216
migrations_version: null,
201217
migrations_status: null,
202218
tracing_mode: tracingMode,
@@ -250,6 +266,7 @@ export default async function routes(fastify: FastifyInstance) {
250266
jwks,
251267
service_key: serviceKey !== undefined ? encrypt(serviceKey) : undefined,
252268
feature_image_transformation: features?.imageTransformation?.enabled,
269+
feature_s3_protocol: features?.s3Protocol?.enabled,
253270
image_transformation_max_resolution:
254271
features?.imageTransformation?.maxResolution === null
255272
? null
@@ -315,6 +332,10 @@ export default async function routes(fastify: FastifyInstance) {
315332
?.image_transformation_max_resolution as number | undefined
316333
}
317334

335+
if (typeof features?.s3Protocol?.enabled !== 'undefined') {
336+
tenantInfo.feature_s3_protocol = features?.s3Protocol?.enabled
337+
}
338+
318339
if (databasePoolUrl) {
319340
tenantInfo.database_pool_url = encrypt(databasePoolUrl)
320341
}

src/http/routes/s3/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import { FastifyInstance, RouteHandlerMethod } from 'fastify'
22
import { JSONSchema } from 'json-schema-to-ts'
33
import { trace } from '@opentelemetry/api'
4-
import { db, jsonToXml, signatureV4, storage } from '../../plugins'
4+
import { db, jsonToXml, requireTenantFeature, signatureV4, storage } from '../../plugins'
55
import { findArrayPathsInSchemas, getRouter, RequestInput } from './router'
66
import { s3ErrorHandler } from './error-handler'
7+
import { getConfig } from '../../../config'
8+
9+
const { s3ProtocolEnabled } = getConfig()
710

811
export default async function routes(fastify: FastifyInstance) {
12+
if (!s3ProtocolEnabled) {
13+
return
14+
}
15+
916
fastify.register(async (fastify) => {
1017
const s3Router = getRouter()
1118
const s3Routes = s3Router.routes()
@@ -97,6 +104,8 @@ export default async function routes(fastify: FastifyInstance) {
97104
}
98105

99106
fastify.register(async (localFastify) => {
107+
localFastify.register(requireTenantFeature('s3Protocol'))
108+
100109
const disableContentParser = routesByMethod?.some(
101110
(route) => route.disableContentTypeParser
102111
)

src/internal/database/tenant.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ export interface Features {
4141
enabled: boolean
4242
maxResolution?: number
4343
}
44+
s3Protocol: {
45+
enabled: boolean
46+
}
4447
}
4548

4649
export enum TenantMigrationStatus {
@@ -203,6 +206,7 @@ export async function getTenantConfig(tenantId: string): Promise<TenantConfig> {
203206
jwks,
204207
service_key,
205208
feature_image_transformation,
209+
feature_s3_protocol,
206210
image_transformation_max_resolution,
207211
database_pool_url,
208212
max_connections,
@@ -231,6 +235,9 @@ export async function getTenantConfig(tenantId: string): Promise<TenantConfig> {
231235
enabled: feature_image_transformation,
232236
maxResolution: image_transformation_max_resolution,
233237
},
238+
s3Protocol: {
239+
enabled: feature_s3_protocol,
240+
},
234241
},
235242
migrationVersion: migrations_version,
236243
migrationStatus: migrations_status,

src/test/tenant.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ const payload = {
2323
enabled: true,
2424
maxResolution: null,
2525
},
26+
s3Protocol: {
27+
enabled: true,
28+
},
2629
},
2730
}
2831

@@ -43,6 +46,9 @@ const payload2 = {
4346
enabled: false,
4447
maxResolution: null,
4548
},
49+
s3Protocol: {
50+
enabled: true,
51+
},
4652
},
4753
}
4854

src/test/x-forwarded-host.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ beforeAll(async () => {
2626
imageTransformation: {
2727
enabled: true,
2828
},
29+
s3Protocol: {
30+
enabled: true,
31+
},
2932
},
3033
}))
3134

0 commit comments

Comments
 (0)