Skip to content

Commit

Permalink
work on s3client
Browse files Browse the repository at this point in the history
  • Loading branch information
ddecrulle committed Oct 24, 2024
1 parent a70b3da commit 3268092
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 4 deletions.
15 changes: 15 additions & 0 deletions web/src/core/adapters/s3Client/s3Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,21 @@ export function createS3Client(

return [...directories, ...files];
},
"putBucketPolicy": async ({ path, policy }) => {
const { getAwsS3Client } = await prApi;
const { awsS3Client } = await getAwsS3Client();

const { bucketName } = bucketNameAndObjectNameFromS3Path(path);

const command = new (
await import("@aws-sdk/client-s3")
).PutBucketPolicyCommand({
"Bucket": bucketName,
"Policy": JSON.stringify(policy)
});

await awsS3Client.send(command);
},
"uploadFile": async ({ blob, path, onUploadProgress }) => {
const { getAwsS3Client } = await prApi;

Expand Down
45 changes: 45 additions & 0 deletions web/src/core/adapters/s3Client/utils/policySchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { S3BucketPolicy } from "core/ports/S3Client";
import { assert, Equals } from "tsafe";
import { z } from "zod";

const s3ActionSchema = z.enum([
"s3:AbortMultipartUpload",
"s3:BypassGovernanceRetention",
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:DeleteBucketPolicy",
"s3:DeleteObject",
"s3:DeleteObjectTagging",
"s3:GetBucketAcl",
"s3:GetBucketPolicy",
"s3:GetObject",
"s3:GetObjectTagging",
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutBucketPolicy",
"s3:ReplicateObject",
"s3:RestoreObject",
"s3:ListMultipartUploadParts",
"s3:ListBucketVersions",
"s3:ListBucketMultipartUploads",
"s3:PutBucketVersioning",
"s3:PutBucketTagging",
"s3:GetBucketTagging",
"s3:*"
]);

const s3PolicyStatementSchema = z.object({
Effect: z.enum(["Allow", "Deny"]),
Principal: z.union([z.string(), z.object({ AWS: z.string().array() })]),
Action: z.union([s3ActionSchema, s3ActionSchema.array()]),
Resource: z.union([z.string(), z.string().array()]),
Condition: z.record(z.any()).optional()
});

const s3BucketPolicySchema = z.object({
Version: z.literal("2012-10-17"),
Statement: z.array(s3PolicyStatementSchema)
});

assert<Equals<z.infer<typeof s3BucketPolicySchema>, S3BucketPolicy>>(true);
40 changes: 39 additions & 1 deletion web/src/core/ports/S3Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ export type S3Client = {
directories: string[];
files: string[];
}>;

listObjects: (params: { path: string }) => Promise<S3Object[]>;

putBucketPolicy: (params: { path: string; policy: S3BucketPolicy }) => Promise<void>;

/** Completed when 100% uploaded */
uploadFile: (params: {
blob: Blob;
Expand All @@ -55,3 +56,40 @@ export type S3Client = {
validityDurationSecond: number;
}) => Promise<string>;
};

type S3Actions =
| "s3:AbortMultipartUpload"
| "s3:BypassGovernanceRetention"
| "s3:CreateBucket"
| "s3:DeleteBucket"
| "s3:DeleteBucketPolicy"
| "s3:DeleteObject"
| "s3:DeleteObjectTagging"
| "s3:GetBucketAcl"
| "s3:GetBucketPolicy"
| "s3:GetObject"
| "s3:GetObjectTagging"
| "s3:ListBucket"
| "s3:PutObject"
| "s3:PutObjectAcl"
| "s3:PutBucketPolicy"
| "s3:ReplicateObject"
| "s3:RestoreObject"
| "s3:ListMultipartUploadParts"
| "s3:ListBucketVersions"
| "s3:ListBucketMultipartUploads"
| "s3:PutBucketVersioning"
| "s3:PutBucketTagging"
| "s3:GetBucketTagging"
| "s3:*";

export type S3BucketPolicy = {
Version: "2012-10-17";
Statement: Array<{
Effect: "Allow" | "Deny";
Principal: string | { AWS: string[] };
Action: S3Actions | S3Actions[];
Resource: string | string[];
Condition?: Record<string, any>;
}>;
};
6 changes: 4 additions & 2 deletions web/src/core/usecases/fileExplorer/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { relative as pathRelative } from "pathe";
import { assert } from "tsafe/assert";
import { createUsecaseActions } from "clean-architecture";
import type { WritableDraft } from "clean-architecture/immer";
import { S3Object } from "core/ports/S3Client";
import { S3BucketPolicy, S3Object } from "core/ports/S3Client";

//All explorer path are expected to be absolute (start with /)

Expand All @@ -29,6 +29,7 @@ export type State = {
cmd: string;
resp: string | undefined;
}[];
bucketPolicy: S3BucketPolicy | undefined;
};

export const name = "fileExplorer";
Expand All @@ -42,7 +43,8 @@ export const { reducer, actions } = createUsecaseActions({
"isNavigationOngoing": false,
"ongoingOperations": [],
"s3FilesBeingUploaded": [],
"commandLogsEntries": []
"commandLogsEntries": [],
"bucketPolicy": undefined
}),
"reducers": {
"fileUploadStarted": (
Expand Down
2 changes: 1 addition & 1 deletion web/src/core/usecases/s3ConfigConnectionTest/thunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const protectedThunks = {
const s3Client = createS3Client(paramsOfCreateS3Client, getOidc);

try {
await s3Client.list({
await s3Client.listObjects({
"path": workingDirectoryPath
});
} catch (error) {
Expand Down

0 comments on commit 3268092

Please sign in to comment.