Skip to content

Commit 18822f0

Browse files
authored
fix: disable transaction extensions by default (#136)
* fix: disable transaction extensions by default
1 parent 83c3654 commit 18822f0

File tree

2 files changed

+88
-19
lines changed

2 files changed

+88
-19
lines changed

integration_tests/cdk/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def __init__(
8181
instance_type=aws_ec2.InstanceType(app_config.db_instance_type),
8282
add_pgbouncer=True,
8383
removal_policy=RemovalPolicy.DESTROY,
84-
pgstac_version="0.9.2",
84+
pgstac_version="0.9.5",
8585
)
8686

8787
assert pgstac_db.security_group

lib/stac-api/index.ts

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,37 @@ import {
88
Duration,
99
aws_logs,
1010
} from "aws-cdk-lib";
11-
import { IDomainName, HttpApi, ParameterMapping, MappingValue} from "@aws-cdk/aws-apigatewayv2-alpha";
11+
import {
12+
IDomainName,
13+
HttpApi,
14+
ParameterMapping,
15+
MappingValue,
16+
} from "@aws-cdk/aws-apigatewayv2-alpha";
1217
import { HttpLambdaIntegration } from "@aws-cdk/aws-apigatewayv2-integrations-alpha";
1318
import { Construct } from "constructs";
1419
import { CustomLambdaFunctionProps } from "../utils";
15-
import * as path from 'path';
20+
import * as path from "path";
21+
22+
export const EXTENSIONS = {
23+
QUERY: "query",
24+
SORT: "sort",
25+
FIELDS: "fields",
26+
FILTER: "filter",
27+
FREE_TEXT: "free_text",
28+
PAGINATION: "pagination",
29+
COLLECTION_SEARCH: "collection_search",
30+
TRANSACTION: "transaction",
31+
BULK_TRANSACTION: "bulk_transactions",
32+
} as const;
33+
34+
type ExtensionType = (typeof EXTENSIONS)[keyof typeof EXTENSIONS];
35+
36+
/**
37+
* Validates if a given string is a valid STAC extension
38+
*/
39+
function isValidExtension(value: string): value is ExtensionType {
40+
return Object.values(EXTENSIONS).includes(value as any);
41+
}
1642

1743
export class PgStacApiLambda extends Construct {
1844
readonly url: string;
@@ -21,16 +47,40 @@ export class PgStacApiLambda extends Construct {
2147
constructor(scope: Construct, id: string, props: PgStacApiLambdaProps) {
2248
super(scope, id);
2349

50+
const defaultExtensions: ExtensionType[] = [
51+
EXTENSIONS.QUERY,
52+
EXTENSIONS.SORT,
53+
EXTENSIONS.FIELDS,
54+
EXTENSIONS.FILTER,
55+
EXTENSIONS.FREE_TEXT,
56+
EXTENSIONS.PAGINATION,
57+
EXTENSIONS.COLLECTION_SEARCH,
58+
];
59+
60+
if (props.enabledExtensions) {
61+
for (const ext of props.enabledExtensions) {
62+
if (!isValidExtension(ext)) {
63+
throw new Error(
64+
`Invalid extension: "${ext}". Must be one of: ${Object.values(
65+
EXTENSIONS
66+
).join(", ")}`
67+
);
68+
}
69+
}
70+
}
71+
72+
const enabledExtensions = props.enabledExtensions || defaultExtensions;
73+
2474
this.stacApiLambdaFunction = new lambda.Function(this, "lambda", {
2575
// defaults
2676
runtime: lambda.Runtime.PYTHON_3_11,
2777
handler: "handler.handler",
2878
memorySize: 8192,
2979
logRetention: aws_logs.RetentionDays.ONE_WEEK,
3080
timeout: Duration.seconds(30),
31-
code: lambda.Code.fromDockerBuild(path.join(__dirname, '..'), {
81+
code: lambda.Code.fromDockerBuild(path.join(__dirname, ".."), {
3282
file: "stac-api/runtime/Dockerfile",
33-
buildArgs: { PYTHON_VERSION: '3.11' },
83+
buildArgs: { PYTHON_VERSION: "3.11" },
3484
}),
3585
vpc: props.vpc,
3686
vpcSubnets: props.subnetSelection,
@@ -39,28 +89,40 @@ export class PgStacApiLambda extends Construct {
3989
PGSTAC_SECRET_ARN: props.dbSecret.secretArn,
4090
DB_MIN_CONN_SIZE: "0",
4191
DB_MAX_CONN_SIZE: "1",
92+
ENABLED_EXTENSIONS: enabledExtensions.join(","),
4293
...props.apiEnv,
4394
},
4495
// overwrites defaults with user-provided configurable properties
45-
...props.lambdaFunctionOptions
96+
...props.lambdaFunctionOptions,
4697
});
4798

4899
props.dbSecret.grantRead(this.stacApiLambdaFunction);
49100

50-
if (props.vpc){
51-
this.stacApiLambdaFunction.connections.allowTo(props.db, ec2.Port.tcp(5432), "allow connections from stac-fastapi-pgstac");
101+
if (props.vpc) {
102+
this.stacApiLambdaFunction.connections.allowTo(
103+
props.db,
104+
ec2.Port.tcp(5432),
105+
"allow connections from stac-fastapi-pgstac"
106+
);
52107
}
53108

54109
const stacApi = new HttpApi(this, `${Stack.of(this).stackName}-stac-api`, {
55-
defaultDomainMapping: props.stacApiDomainName ? {
56-
domainName: props.stacApiDomainName
57-
} : undefined,
110+
defaultDomainMapping: props.stacApiDomainName
111+
? {
112+
domainName: props.stacApiDomainName,
113+
}
114+
: undefined,
58115
defaultIntegration: new HttpLambdaIntegration(
59116
"integration",
60117
this.stacApiLambdaFunction,
61-
props.stacApiDomainName ? {
62-
parameterMapping: new ParameterMapping().overwriteHeader('host', MappingValue.custom(props.stacApiDomainName.name))
63-
} : undefined
118+
props.stacApiDomainName
119+
? {
120+
parameterMapping: new ParameterMapping().overwriteHeader(
121+
"host",
122+
MappingValue.custom(props.stacApiDomainName.name)
123+
),
124+
}
125+
: undefined
64126
),
65127
});
66128

@@ -102,12 +164,19 @@ export interface PgStacApiLambdaProps {
102164
/**
103165
* Custom Domain Name Options for STAC API,
104166
*/
105-
readonly stacApiDomainName?: IDomainName;
167+
readonly stacApiDomainName?: IDomainName;
168+
169+
/**
170+
* List of STAC API extensions to enable.
171+
*
172+
* @default - query, sort, fields, filter, free_text, pagniation, collection_search
173+
*/
174+
readonly enabledExtensions?: ExtensionType[];
106175

107176
/**
108-
* Can be used to override the default lambda function properties.
109-
*
110-
* @default - defined in the construct.
111-
*/
177+
* Can be used to override the default lambda function properties.
178+
*
179+
* @default - defined in the construct.
180+
*/
112181
readonly lambdaFunctionOptions?: CustomLambdaFunctionProps;
113182
}

0 commit comments

Comments
 (0)