Skip to content

Commit 521d945

Browse files
committed
feat: add AWS credential provider support & more detailed schema for DBs
1 parent a5a1d95 commit 521d945

File tree

5 files changed

+155
-27
lines changed

5 files changed

+155
-27
lines changed

config.schema.json

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -192,17 +192,20 @@
192192
"additionalProperties": false,
193193
"properties": {
194194
"text": {
195-
"type": "string"
195+
"type": "string",
196+
"description": "Tooltip text"
196197
},
197198
"links": {
198199
"type": "array",
200+
"description": "An array of links to display under the tooltip text, providing additional context about the question",
199201
"items": {
200202
"type": "object",
201203
"additionalProperties": false,
202204
"properties": {
203-
"text": { "type": "string" },
204-
"url": { "type": "string", "format": "url" }
205-
}
205+
"text": { "type": "string", "description": "Link text" },
206+
"url": { "type": "string", "format": "url", "description": "Link URL" }
207+
},
208+
"required": ["text", "url"]
206209
}
207210
}
208211
},
@@ -377,15 +380,56 @@
377380
"required": ["project", "name", "url"]
378381
},
379382
"database": {
380-
"type": "object",
381-
"properties": {
382-
"type": { "type": "string" },
383-
"enabled": { "type": "boolean" },
384-
"connectionString": { "type": "string" },
385-
"options": { "type": "object" },
386-
"params": { "type": "object" }
387-
},
388-
"required": ["type", "enabled"]
383+
"description": "Configuration entry for a database",
384+
"oneOf": [
385+
{
386+
"type": "object",
387+
"name": "MongoDB Config",
388+
"description": "Connection properties for mongoDB. Options may be passed in either the connection string or broken out in the options object",
389+
"properties": {
390+
"type": { "type": "string", "const": "mongo" },
391+
"enabled": { "type": "boolean" },
392+
"connectionString": {
393+
"type": "string",
394+
"description": "mongoDB Client connection string, see https://www.mongodb.com/docs/manual/reference/connection-string/"
395+
},
396+
"options": {
397+
"type": "object",
398+
"description": "mongoDB Client connection options. Please note that only custom options are described here, see https://www.mongodb.com/docs/drivers/node/current/connect/connection-options/ for all config options.",
399+
"properties": {
400+
"authMechanismProperties": {
401+
"type": "object",
402+
"properties": {
403+
"AWS_CREDENTIAL_PROVIDER": {
404+
"type": "boolean",
405+
"description": "If set to true fromNodeProviderChain() from @aws-sdk/credential-providers is passed as the AWS_CREDENTIAL_PROVIDER"
406+
}
407+
},
408+
"additionalProperties": true
409+
}
410+
},
411+
"required": [],
412+
"additionalProperties": true
413+
}
414+
},
415+
"required": ["type", "enabled", "connectionString"]
416+
},
417+
{
418+
"type": "object",
419+
"name": "File-based DB Config",
420+
"description": "Connection properties for an neDB file-based database",
421+
"properties": {
422+
"type": { "type": "string", "const": "fs" },
423+
"enabled": { "type": "boolean" },
424+
"params": {
425+
"type": "object",
426+
"description": "Legacy config property not currently used",
427+
"deprecated": true
428+
}
429+
},
430+
"required": ["type", "enabled"]
431+
}
432+
]
389433
},
390434
"authenticationElement": {
391435
"type": "object",

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"url": "https://github.com/finos/git-proxy"
8282
},
8383
"dependencies": {
84+
"@aws-sdk/credential-providers": "^3.940.0",
8485
"@material-ui/core": "^4.12.4",
8586
"@material-ui/icons": "4.11.3",
8687
"@primer/octicons-react": "^19.21.0",

src/config/generated/config.ts

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ export interface Ls {
157157
*/
158158
export interface AuthenticationElement {
159159
enabled: boolean;
160-
type: Type;
160+
type: AuthenticationElementType;
161161
/**
162162
* Additional Active Directory configuration supporting LDAP connection which can be used to
163163
* confirm group membership. For the full set of available options see the activedirectory 2
@@ -251,7 +251,7 @@ export interface OidcConfig {
251251
[property: string]: any;
252252
}
253253

254-
export enum Type {
254+
export enum AuthenticationElementType {
255255
ActiveDirectory = 'ActiveDirectory',
256256
Jwt = 'jwt',
257257
Local = 'local',
@@ -286,13 +286,26 @@ export interface Question {
286286
* and used to provide additional guidance to the reviewer.
287287
*/
288288
export interface QuestionTooltip {
289+
/**
290+
* An array of links to display under the tooltip text, providing additional context about
291+
* the question
292+
*/
289293
links?: Link[];
294+
/**
295+
* Tooltip text
296+
*/
290297
text: string;
291298
}
292299

293300
export interface Link {
294-
text?: string;
295-
url?: string;
301+
/**
302+
* Link text
303+
*/
304+
text: string;
305+
/**
306+
* Link URL
307+
*/
308+
url: string;
296309
}
297310

298311
export interface AuthorisedRepo {
@@ -458,15 +471,59 @@ export interface RateLimit {
458471
windowMs: number;
459472
}
460473

474+
/**
475+
* Configuration entry for a database
476+
*
477+
* Connection properties for mongoDB. Options may be passed in either the connection string
478+
* or broken out in the options object
479+
*
480+
* Connection properties for an neDB file-based database
481+
*/
461482
export interface Database {
483+
/**
484+
* mongoDB Client connection string, see
485+
* https://www.mongodb.com/docs/manual/reference/connection-string/
486+
*/
462487
connectionString?: string;
463488
enabled: boolean;
464-
options?: { [key: string]: any };
489+
/**
490+
* mongoDB Client connection options. Please note that only custom options are described
491+
* here, see https://www.mongodb.com/docs/drivers/node/current/connect/connection-options/
492+
* for all config options.
493+
*/
494+
options?: Options;
495+
type: DatabaseType;
496+
/**
497+
* Legacy config property not currently used
498+
*/
465499
params?: { [key: string]: any };
466-
type: string;
467500
[property: string]: any;
468501
}
469502

503+
/**
504+
* mongoDB Client connection options. Please note that only custom options are described
505+
* here, see https://www.mongodb.com/docs/drivers/node/current/connect/connection-options/
506+
* for all config options.
507+
*/
508+
export interface Options {
509+
authMechanismProperties?: AuthMechanismProperties;
510+
[property: string]: any;
511+
}
512+
513+
export interface AuthMechanismProperties {
514+
/**
515+
* If set to true fromNodeProviderChain() from @aws-sdk/credential-providers is passed as
516+
* the AWS_CREDENTIAL_PROVIDER
517+
*/
518+
AWS_CREDENTIAL_PROVIDER?: boolean;
519+
[property: string]: any;
520+
}
521+
522+
export enum DatabaseType {
523+
FS = 'fs',
524+
Mongo = 'mongo',
525+
}
526+
470527
/**
471528
* Toggle the generation of temporary password for git-proxy admin user
472529
*/
@@ -747,7 +804,7 @@ const typeMap: any = {
747804
AuthenticationElement: o(
748805
[
749806
{ json: 'enabled', js: 'enabled', typ: true },
750-
{ json: 'type', js: 'type', typ: r('Type') },
807+
{ json: 'type', js: 'type', typ: r('AuthenticationElementType') },
751808
{ json: 'adConfig', js: 'adConfig', typ: u(undefined, r('AdConfig')) },
752809
{ json: 'adminGroup', js: 'adminGroup', typ: u(undefined, '') },
753810
{ json: 'domain', js: 'domain', typ: u(undefined, '') },
@@ -807,8 +864,8 @@ const typeMap: any = {
807864
),
808865
Link: o(
809866
[
810-
{ json: 'text', js: 'text', typ: u(undefined, '') },
811-
{ json: 'url', js: 'url', typ: u(undefined, '') },
867+
{ json: 'text', js: 'text', typ: '' },
868+
{ json: 'url', js: 'url', typ: '' },
812869
],
813870
false,
814871
),
@@ -875,12 +932,26 @@ const typeMap: any = {
875932
[
876933
{ json: 'connectionString', js: 'connectionString', typ: u(undefined, '') },
877934
{ json: 'enabled', js: 'enabled', typ: true },
878-
{ json: 'options', js: 'options', typ: u(undefined, m('any')) },
935+
{ json: 'options', js: 'options', typ: u(undefined, r('Options')) },
936+
{ json: 'type', js: 'type', typ: r('DatabaseType') },
879937
{ json: 'params', js: 'params', typ: u(undefined, m('any')) },
880-
{ json: 'type', js: 'type', typ: '' },
881938
],
882939
'any',
883940
),
941+
Options: o(
942+
[
943+
{
944+
json: 'authMechanismProperties',
945+
js: 'authMechanismProperties',
946+
typ: u(undefined, r('AuthMechanismProperties')),
947+
},
948+
],
949+
'any',
950+
),
951+
AuthMechanismProperties: o(
952+
[{ json: 'AWS_CREDENTIAL_PROVIDER', js: 'AWS_CREDENTIAL_PROVIDER', typ: u(undefined, true) }],
953+
'any',
954+
),
884955
TempPassword: o(
885956
[
886957
{ json: 'emailConfig', js: 'emailConfig', typ: u(undefined, m('any')) },
@@ -911,5 +982,6 @@ const typeMap: any = {
911982
],
912983
'any',
913984
),
914-
Type: ['ActiveDirectory', 'jwt', 'local', 'openidconnect'],
985+
AuthenticationElementType: ['ActiveDirectory', 'jwt', 'local', 'openidconnect'],
986+
DatabaseType: ['fs', 'mongo'],
915987
};

src/db/mongo/helper.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { MongoClient, Db, Collection, Filter, Document, FindOptions } from 'mongodb';
22
import { getDatabase } from '../../config';
33
import MongoDBStore from 'connect-mongo';
4+
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
45

56
let _db: Db | null = null;
67

@@ -15,6 +16,11 @@ export const connect = async (collectionName: string): Promise<Collection> => {
1516
throw new Error('MongoDB connection string is not provided');
1617
}
1718

19+
if (options?.authMechanismProperties?.AWS_CREDENTIAL_PROVIDER) {
20+
// we break from the config types here as we're providing a function to the mongoDB client
21+
(options.authMechanismProperties.AWS_CREDENTIAL_PROVIDER as any) = fromNodeProviderChain();
22+
}
23+
1824
const client = new MongoClient(connectionString, options);
1925
await client.connect();
2026
_db = client.db();

src/service/passport/jwtAuthHandler.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import { assignRoles, validateJwt } from './jwtUtils';
22
import type { Request, Response, NextFunction } from 'express';
33
import { getAPIAuthMethods } from '../../config';
4-
import { AuthenticationElement, JwtConfig, RoleMapping, Type } from '../../config/generated/config';
4+
import {
5+
AuthenticationElement,
6+
JwtConfig,
7+
RoleMapping,
8+
AuthenticationElementType,
9+
} from '../../config/generated/config';
510

611
export const type = 'jwt';
712

813
export const jwtAuthHandler = (overrideConfig: JwtConfig | null = null) => {
914
return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
1015
const apiAuthMethods: AuthenticationElement[] = overrideConfig
11-
? [{ type: 'jwt' as Type, enabled: true, jwtConfig: overrideConfig }]
16+
? [{ type: 'jwt' as AuthenticationElementType, enabled: true, jwtConfig: overrideConfig }]
1217
: getAPIAuthMethods();
1318

1419
const jwtAuthMethod = apiAuthMethods.find((method) => method.type.toLowerCase() === type);

0 commit comments

Comments
 (0)