@@ -7,6 +7,7 @@ import { assert, type Equals } from "tsafe";
77import type * as s3CredentialsTest from "core/usecases/_s3Next/s3CredentialsTest" ;
88import type { LocalizedString } from "core/ports/OnyxiaApi" ;
99import type { ResolvedTemplateBookmark } from "./resolveTemplatedBookmark" ;
10+ import type { ResolvedTemplateStsRole } from "./resolveTemplatedStsRole" ;
1011import type { S3UriPrefixObj } from "core/tools/S3Uri" ;
1112
1213export type S3Profile = S3Profile . DefinedInRegion | S3Profile . CreatedByUser ;
@@ -45,9 +46,17 @@ export namespace S3Profile {
4546
4647export function aggregateS3ProfilesFromVaultAndRegionIntoAnUnifiedSet ( params : {
4748 fromVault : projectManagement . ProjectConfigs [ "s3" ] ;
48- fromRegion : ( Omit < DeploymentRegion . S3Next . S3Profile , "bookmarks" > & {
49- bookmarks : ResolvedTemplateBookmark [ ] ;
50- } ) [ ] ;
49+ fromRegion : {
50+ s3Profiles : DeploymentRegion . S3Next . S3Profile [ ] ;
51+ resolvedTemplatedBookmarks : {
52+ correspondingS3ConfigIndexInRegion : number ;
53+ bookmarks : ResolvedTemplateBookmark [ ] ;
54+ } [ ] ;
55+ resolvedTemplatedStsRoles : {
56+ correspondingS3ConfigIndexInRegion : number ;
57+ stsRoles : ResolvedTemplateStsRole [ ] ;
58+ } [ ] ;
59+ } ;
5160 credentialsTestState : s3CredentialsTest . State ;
5261} ) : S3Profile [ ] {
5362 const { fromVault, fromRegion, credentialsTestState } = params ;
@@ -114,40 +123,110 @@ export function aggregateS3ProfilesFromVaultAndRegionIntoAnUnifiedSet(params: {
114123 } ;
115124 } )
116125 . sort ( ( a , b ) => b . creationTime - a . creationTime ) ,
117- ...fromRegion . map ( ( c ) : S3Profile . DefinedInRegion => {
118- const url = c . url ;
119- const pathStyleAccess = c . pathStyleAccess ;
120- const region = c . region ;
121-
122- const paramsOfCreateS3Client : ParamsOfCreateS3Client . Sts = {
123- url,
124- pathStyleAccess,
125- isStsEnabled : true ,
126- stsUrl : c . sts . url ,
127- region,
128- oidcParams : c . sts . oidcParams ,
129- durationSeconds : c . sts . durationSeconds ,
130- role : c . sts . role ,
131- nameOfBucketToCreateIfNotExist : undefined
132- } ;
133-
134- return {
135- origin : "defined in region" ,
136- id : `region-${ fnv1aHashToHex (
137- JSON . stringify ( [ c . url , c . sts . oidcParams . clientId ?? "" ] )
138- ) } `,
139- bookmarks : c . bookmarks . map ( ( { title, s3UriPrefixObj } ) => ( {
140- displayName : title ,
141- s3UriPrefixObj
142- } ) ) ,
143- paramsOfCreateS3Client,
144- credentialsTestStatus : getCredentialsTestStatus ( {
145- paramsOfCreateS3Client
146- } ) ,
147- isXOnyxiaDefault : false ,
148- isExplorerConfig : false
149- } ;
150- } )
126+ ...fromRegion . s3Profiles
127+ . map ( ( c , index ) : S3Profile . DefinedInRegion [ ] => {
128+ const resolvedTemplatedBookmarks_forThisProfile = ( ( ) => {
129+ const entry = fromRegion . resolvedTemplatedBookmarks . find (
130+ e => e . correspondingS3ConfigIndexInRegion === index
131+ ) ;
132+
133+ assert ( entry !== undefined ) ;
134+
135+ return entry . bookmarks ;
136+ } ) ( ) ;
137+
138+ const buildFromRole = ( params : {
139+ resolvedTemplatedStsRole : ResolvedTemplateStsRole | undefined ;
140+ } ) : S3Profile . DefinedInRegion => {
141+ const { resolvedTemplatedStsRole } = params ;
142+
143+ const paramsOfCreateS3Client : ParamsOfCreateS3Client . Sts = {
144+ url : c . url ,
145+ pathStyleAccess : c . pathStyleAccess ,
146+ isStsEnabled : true ,
147+ stsUrl : c . sts . url ,
148+ region : c . region ,
149+ oidcParams : c . sts . oidcParams ,
150+ durationSeconds : c . sts . durationSeconds ,
151+ role : resolvedTemplatedStsRole ,
152+ nameOfBucketToCreateIfNotExist : undefined
153+ } ;
154+
155+ return {
156+ origin : "defined in region" ,
157+ id : `region-${ fnv1aHashToHex (
158+ JSON . stringify ( [ c . url , c . sts . oidcParams . clientId ?? "" ] )
159+ ) } `,
160+ bookmarks : resolvedTemplatedBookmarks_forThisProfile
161+ . filter ( ( { forStsRoleSessionNames } ) => {
162+ if ( forStsRoleSessionNames . length === 0 ) {
163+ return true ;
164+ }
165+
166+ if ( resolvedTemplatedStsRole === undefined ) {
167+ return false ;
168+ }
169+
170+ const getDoMatch = ( params : {
171+ stringWithWildcards : string ;
172+ candidate : string ;
173+ } ) : boolean => {
174+ const { stringWithWildcards, candidate } = params ;
175+
176+ if ( ! stringWithWildcards . includes ( "*" ) ) {
177+ return stringWithWildcards === candidate ;
178+ }
179+
180+ const escapedRegex = stringWithWildcards
181+ . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, "\\$&" )
182+ . replace ( / \\ \* / g, ".*" ) ;
183+
184+ return new RegExp ( `^${ escapedRegex } $` ) . test (
185+ candidate
186+ ) ;
187+ } ;
188+
189+ return forStsRoleSessionNames . some ( stsRoleSessionName =>
190+ getDoMatch ( {
191+ stringWithWildcards : stsRoleSessionName ,
192+ candidate :
193+ resolvedTemplatedStsRole . roleSessionName
194+ } )
195+ ) ;
196+ } )
197+ . map ( ( { title, s3UriPrefixObj } ) => ( {
198+ displayName : title ,
199+ s3UriPrefixObj
200+ } ) ) ,
201+ paramsOfCreateS3Client,
202+ credentialsTestStatus : getCredentialsTestStatus ( {
203+ paramsOfCreateS3Client
204+ } ) ,
205+ isXOnyxiaDefault : false ,
206+ isExplorerConfig : false
207+ } ;
208+ } ;
209+
210+ if ( fromRegion . resolvedTemplatedStsRoles . length === 0 ) {
211+ return [ buildFromRole ( { resolvedTemplatedStsRole : undefined } ) ] ;
212+ }
213+
214+ const resolvedTemplatedStsRoles_forThisProfile = ( ( ) => {
215+ const entry = fromRegion . resolvedTemplatedStsRoles . find (
216+ e => e . correspondingS3ConfigIndexInRegion === index
217+ ) ;
218+
219+ assert ( entry !== undefined ) ;
220+
221+ return entry . stsRoles ;
222+ } ) ( ) ;
223+
224+ return resolvedTemplatedStsRoles_forThisProfile . map (
225+ resolvedTemplatedStsRole =>
226+ buildFromRole ( { resolvedTemplatedStsRole } )
227+ ) ;
228+ } )
229+ . flat ( )
151230 ] ;
152231
153232 (
0 commit comments