Commit a36ea794 authored by Diego Molteni's avatar Diego Molteni
Browse files

Added abstracted infrastracture for handle custom auth provider [GOOGLE ONLY]

parent b76265a8
......@@ -26,9 +26,12 @@ The following software have components provided under the terms of this license:
- @google-cloud/projectify (from https://www.npmjs.com/package/@google-cloud/projectify)
- @google-cloud/promisify (from https://www.npmjs.com/package/@google-cloud/promisify)
- @google-cloud/pubsub (from https://www.npmjs.com/package/@google-cloud/pubsub)
- @google-cloud/secret-manager (from https://www.npmjs.com/package/@google-cloud/secret-manager)
- @google-cloud/storage (from https://www.npmjs.com/package/@google-cloud/storage)
- @google-cloud/trace-agent (from https://www.npmjs.com/package/@google-cloud/trace-agent)
- @grpc/grpc-js (from https://www.npmjs.com/package/@grpc/grpc-js)
- @grpc/grpc-js (from https://www.npmjs.com/package/@grpc/grpc-js)
- @grpc/proto-loader (from https://www.npmjs.com/package/@grpc/proto-loader)
- @grpc/proto-loader (from https://www.npmjs.com/package/@grpc/proto-loader)
- @grpc/proto-loader (from https://www.npmjs.com/package/@grpc/proto-loader)
- @opencensus/core (from https://www.npmjs.com/package/@opencensus/core)
......@@ -56,12 +59,15 @@ The following software have components provided under the terms of this license:
- ecdsa-sig-formatter (from https://www.npmjs.com/package/ecdsa-sig-formatter)
- eventid (from https://www.npmjs.com/package/eventid)
- fast-text-encoding (from https://www.npmjs.com/package/fast-text-encoding)
- fast-text-encoding (from https://www.npmjs.com/package/fast-text-encoding)
- forever-agent (from https://github.com/mikeal/forever-agent)
- gaxios (from https://www.npmjs.com/package/gaxios)
- gaxios (from https://www.npmjs.com/package/gaxios)
- gaxios (from https://www.npmjs.com/package/gaxios)
- gaxios (from https://www.npmjs.com/package/gaxios)
- gaxios (from https://www.npmjs.com/package/gaxios)
- gaxios (from https://www.npmjs.com/package/gaxios)
- gcp-metadata (from https://www.npmjs.com/package/gcp-metadata)
- gcp-metadata (from https://www.npmjs.com/package/gcp-metadata)
- gcp-metadata (from https://www.npmjs.com/package/gcp-metadata)
- gcp-metadata (from https://www.npmjs.com/package/gcp-metadata)
......@@ -69,6 +75,8 @@ The following software have components provided under the terms of this license:
- google-auth-library (from https://www.npmjs.com/package/google-auth-library)
- google-auth-library (from https://www.npmjs.com/package/google-auth-library)
- google-auth-library (from https://www.npmjs.com/package/google-auth-library)
- google-auth-library (from https://www.npmjs.com/package/google-auth-library)
- google-gax (from https://www.npmjs.com/package/google-gax)
- google-gax (from https://www.npmjs.com/package/google-gax)
- google-p12-pem (from https://www.npmjs.com/package/google-p12-pem)
- google-p12-pem (from https://www.npmjs.com/package/google-p12-pem)
......@@ -157,6 +165,7 @@ The following software have components provided under the terms of this license:
- continuation-local-storage (from https://github.com/othiym23/node-continuation-local-storage#readme)
- emitter-listener (from https://github.com/othiym23/emitter-listener)
- google-gax (from https://www.npmjs.com/package/google-gax)
- google-gax (from https://www.npmjs.com/package/google-gax)
- ieee754 (from https://github.com/feross/ieee754#readme)
- json-schema (from http://github.com/kriszyp/json-schema)
- node-forge (from https://github.com/digitalbazaar/forge)
......@@ -464,6 +473,7 @@ The following software have components provided under the terms of this license:
- gcp-metadata (from https://www.npmjs.com/package/gcp-metadata)
- gcp-metadata (from https://www.npmjs.com/package/gcp-metadata)
- gcp-metadata (from https://www.npmjs.com/package/gcp-metadata)
- gcp-metadata (from https://www.npmjs.com/package/gcp-metadata)
- gcs-resumable-upload (from https://www.npmjs.com/package/gcs-resumable-upload)
- get-caller-file (from https://www.npmjs.com/package/get-caller-file)
- get-intrinsic (from https://www.npmjs.com/package/get-intrinsic)
......@@ -603,6 +613,7 @@ The following software have components provided under the terms of this license:
- npmlog (from https://github.com/npm/npmlog#readme)
- number-is-nan (from https://github.com/sindresorhus/number-is-nan#readme)
- object-assign (from https://github.com/sindresorhus/object-assign#readme)
- object-hash (from https://www.npmjs.com/package/object-hash)
- object-inspect (from https://github.com/substack/object-inspect)
- object-inspect (from https://github.com/substack/object-inspect)
- object-keys (from https://github.com/ljharb/object-keys#readme)
......
......@@ -991,6 +991,139 @@
}
}
},
"@google-cloud/secret-manager": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/@google-cloud/secret-manager/-/secret-manager-3.7.1.tgz",
"integrity": "sha512-QXFNBQai0/6VW7m8u5GobyqnHOyn4xt/9RlflWvQKzgzetkOasZr7YbG5umhon/Gp70nTiDySLUV0NjCDQcY2g==",
"requires": {
"google-gax": "^2.12.0"
},
"dependencies": {
"@grpc/grpc-js": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz",
"integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==",
"requires": {
"@types/node": ">=12.12.47"
}
},
"@grpc/proto-loader": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.2.tgz",
"integrity": "sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg==",
"requires": {
"@types/long": "^4.0.1",
"lodash.camelcase": "^4.3.0",
"long": "^4.0.0",
"protobufjs": "^6.10.0",
"yargs": "^16.1.1"
}
},
"fast-text-encoding": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz",
"integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig=="
},
"gaxios": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz",
"integrity": "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg==",
"requires": {
"abort-controller": "^3.0.0",
"extend": "^3.0.2",
"https-proxy-agent": "^5.0.0",
"is-stream": "^2.0.0",
"node-fetch": "^2.3.0"
}
},
"gcp-metadata": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.0.tgz",
"integrity": "sha512-L9XQUpvKJCM76YRSmcxrR4mFPzPGsgZUH+GgHMxAET8qc6+BhRJq63RLhWakgEO2KKVgeSDVfyiNjkGSADwNTA==",
"requires": {
"gaxios": "^4.0.0",
"json-bigint": "^1.0.0"
}
},
"google-auth-library": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.1.2.tgz",
"integrity": "sha512-FMipHgfe2u1LzWsf2n9zEB9KsJ8M3n8OYTHbHtlkzPCyo7IknXQR5X99nfvwUHGuX+iEpihUZxDuPm7+qBYeXg==",
"requires": {
"arrify": "^2.0.0",
"base64-js": "^1.3.0",
"ecdsa-sig-formatter": "^1.0.11",
"fast-text-encoding": "^1.0.0",
"gaxios": "^4.0.0",
"gcp-metadata": "^4.2.0",
"gtoken": "^5.0.4",
"jws": "^4.0.0",
"lru-cache": "^6.0.0"
}
},
"google-gax": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.15.0.tgz",
"integrity": "sha512-jfShUgX1DVu+DiOeAcsT5JbWlLdUnb2FsdWRb+Q/pNz6kNAUbmq8sFLB2uaWjlTxoSGHZLfrt3vJ9lpArzzQPA==",
"requires": {
"@grpc/grpc-js": "~1.3.0",
"@grpc/proto-loader": "^0.6.1",
"@types/long": "^4.0.0",
"abort-controller": "^3.0.0",
"duplexify": "^4.0.0",
"fast-text-encoding": "^1.0.3",
"google-auth-library": "^7.0.2",
"is-stream-ended": "^0.1.4",
"node-fetch": "^2.6.1",
"object-hash": "^2.1.1",
"protobufjs": "^6.10.2",
"retry-request": "^4.0.0"
}
},
"is-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
},
"jwa": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
"requires": {
"jwa": "^2.0.0",
"safe-buffer": "^5.0.1"
}
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"object-hash": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw=="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
"@google-cloud/storage": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.7.0.tgz",
......
// ============================================================================
// Copyright 2017-2020, Schlumberger
// Copyright 2017-2021, Schlumberger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
......@@ -23,6 +23,60 @@ import { Cache, Error, Utils } from '../shared';
import { AuthGroups } from './groups';
import { createHash } from 'crypto';
// ===============================================================================================
// This class is used to register all auth provider
// ===============================================================================================
export class AuthProviderFactoryBuilder {
public static register(providerLabel: string) {
return (target: any) => {
if(AuthProviderFactoryBuilder.providers[providerLabel]) {
AuthProviderFactoryBuilder.providers[providerLabel].push(target);
} else {
AuthProviderFactoryBuilder.providers[providerLabel] = [target];
}
return target;
};
}
public static build(providerLabel: string, referenceAbstraction: any, args: { [key: string]: any } = {}) {
if (providerLabel === undefined || providerLabel === 'unknown') {
throw (Error.make(Error.Status.UNKNOWN,
`Unrecognized auth provider: ${providerLabel}`));
}
for(const provider of AuthProviderFactoryBuilder.providers[providerLabel]) {
if (provider.prototype instanceof referenceAbstraction) {
return new provider(args);
}
}
throw (Error.make(Error.Status.UNKNOWN,
`The auth provider builder that extend ${referenceAbstraction} has not been found`));
}
private static providers: { [key: string]: any[] } = {};
}
// ===============================================================================================
// These are the service auth provider methods used for example to generate an impersonation token
// ===============================================================================================
export interface IAuthProvider {
generateAuthCredential(): Promise<any>;
}
export abstract class AbstractAuthProvider implements IAuthProvider {
public abstract generateAuthCredential(): Promise<any>;
}
export class AuthProviderFactory extends AuthProviderFactoryBuilder {
public static build(providerLabel: string): AbstractAuthProvider {
return AuthProviderFactoryBuilder.build(providerLabel, AbstractAuthProvider) as IAuthProvider;
}
}
// ===============================================================================================
// Generic Auth provider class to manage Authorizations in SDMS
// ===============================================================================================
export class Auth {
private static _cache: Cache<boolean>;
......
// ============================================================================
// Copyright 2017-2020, Schlumberger
// Copyright 2017-2021, Schlumberger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
......@@ -17,3 +17,7 @@
export { Auth } from './auth';
export { AuthRoles } from './roles';
export { AuthGroups } from './groups';
export { AuthProviderFactory } from './auth';
// Providers
export * from './providers';
\ No newline at end of file
// ============================================================================
// Copyright 2017-2021, Schlumberger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================
import { Error } from '../../../shared';
import { AbstractAuthProvider, AuthProviderFactory } from '../../auth';
@AuthProviderFactory.register('generic')
export class GenericAuthProvider extends AbstractAuthProvider {
public async generateAuthCredential(): Promise<any> {
throw (Error.make(Error.Status.NOT_IMPLEMENTED,
'The required feature is not supported, the credential auth provider has not been found.'));
}
}
\ No newline at end of file
// ============================================================================
// Copyright 2017-2021, Schlumberger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================
export { GenericAuthProvider } from './auth';
// ============================================================================
// Copyright 2017-2021, Schlumberger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================
export * as generic from './generic';
\ No newline at end of file
......@@ -49,6 +49,8 @@ export interface ConfigModel {
SSL_CERT_PATH?: string;
ENFORCE_SCHEMA_BY_KEY?: boolean;
CORRELATION_ID?: string;
SERVICE_AUTH_PROVIDER?: string;
SERVICE_AUTH_PROVIDER_CREDENTIAL?: string;
FEATURE_FLAG_AUTHORIZATION: boolean;
FEATURE_FLAG_LEGALTAG: boolean;
FEATURE_FLAG_SEISMICMETA_STORAGE: boolean;
......@@ -144,6 +146,16 @@ export abstract class Config implements IConfig {
// The Key name of the header correlation ID
public static CORRELATION_ID: string;
// service auth provider and identity (optional)
// The CSP identity is used to interact with CSP solutions like db/storage/log/etc...
// This account, if set, can be used to sign an impersonation token credential.
// This account, if set, can be used to perform Auth Operations like credentials exchange.
// Introduced because different auth providers can be used on a CSP deployment
// The decoding policy is defined in the src/auth/auth.ts and implemented in src/auth/providers/*
public static SERVICE_AUTH_PROVIDER_CREDENTIAL: string;
// This id build the auth provider in the abstraction implemented in src/auth/providers/*
public static SERVICE_AUTH_PROVIDER: string;
// WriteLock Skip
// This is an open issue to discuss.
// Checking the write lock is the correct behavior and this variable should be set to "false".
......@@ -214,6 +226,9 @@ export abstract class Config implements IConfig {
Config.CORRELATION_ID = model.CORRELATION_ID || undefined;
Config.SERVICE_AUTH_PROVIDER = model.SERVICE_AUTH_PROVIDER || 'generic';
Config.SERVICE_AUTH_PROVIDER_CREDENTIAL = model.SERVICE_AUTH_PROVIDER_CREDENTIAL || 'undefined';
Config.checkRequiredConfig(Config.CLOUDPROVIDER, 'CLOUDPROVIDER');
Config.checkRequiredConfig(Config.SERVICE_ENV, 'SERVICE_ENV');
Config.checkRequiredConfig(Config.IMP_SERVICE_ACCOUNT_SIGNER, 'IMP_SERVICE_ACCOUNT_SIGNER');
......
// ============================================================================
// Copyright 2017-2019, Schlumberger
// Copyright 2017-2021, Schlumberger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
......@@ -16,6 +16,7 @@
import fs from 'fs';
import { Config, ConfigFactory } from '../../config';
import { Secrets } from './secrets'
@ConfigFactory.register('google')
export class ConfigGoogle extends Config {
......@@ -54,6 +55,17 @@ export class ConfigGoogle extends Config {
// pubsub topic
public static PUBSUBTOPIC: string;
// service auth provider and credentials (optional)
// The google workload identity is used to interact with GCP solutions like datastore/gcs/log/etc...
// This account, if set, can be used to sign an impersonation token credential.
// This account, if set, can be used to perform Auth Operations like credentials exchange.
// Introduced because different auth providers can be used on a CSP deployment
// This variable should be a serialized json containing id/secrets/etc...
// The decoding policy is defined in the src/auth/auth.ts and src/auth/providers/*
public static SERVICE_AUTH_PROVIDER_CREDENTIAL: string;
// This id build the auth provider in the abstraction implemented in src/auth/providers/*
public static SERVICE_AUTH_PROVIDER: string;
public async init(): Promise<void> {
// load des target audience for service to service communication
......@@ -75,6 +87,11 @@ export class ConfigGoogle extends Config {
ConfigGoogle.PUBSUBTOPIC = process.env.PUBSUBTOPIC !== undefined ? process.env.PUBSUBTOPIC : 'subproject-operations';
// read the optional auth provider id and secret
ConfigGoogle.SERVICE_AUTH_PROVIDER = process.env.SERVICE_AUTH_PROVIDER;
ConfigGoogle.SERVICE_AUTH_PROVIDER_CREDENTIAL = await new Secrets().getSecret(
'sdms-svc-auth-provider-credential', false);
await Config.initServiceConfiguration({
SERVICE_ENV: process.env.APP_ENVIRONMENT_IDENTIFIER,
SERVICE_PORT: +process.env.PORT || 5000,
......@@ -98,6 +115,8 @@ export class ConfigGoogle extends Config {
JWT_ENABLE_FEATURE: process.env.JWT_ENABLE_FEATURE ? process.env.JWT_ENABLE_FEATURE === 'true' : false,
ENFORCE_SCHEMA_BY_KEY: true,
CORRELATION_ID: 'correlation-id',
SERVICE_AUTH_PROVIDER: ConfigGoogle.SERVICE_AUTH_PROVIDER,
SERVICE_AUTH_PROVIDER_CREDENTIAL: ConfigGoogle.SERVICE_AUTH_PROVIDER_CREDENTIAL,
TENANT_JOURNAL_ON_DATA_PARTITION: false,
FEATURE_FLAG_AUTHORIZATION: process.env.FEATURE_FLAG_AUTHORIZATION !== undefined ?
process.env.FEATURE_FLAG_AUTHORIZATION !== 'false' : true,
......
// ============================================================================
// Copyright 2017-2021, Schlumberger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
import { Error } from '../../../shared';
import { ConfigGoogle } from './config';
export class Secrets{
private client = new SecretManagerServiceClient({
keyFilename: ConfigGoogle.SERVICE_IDENTITY_KEY_FILENAME,
projectId: ConfigGoogle.SERVICE_CLOUD_PROJECT
});
public async getSecret(secretName: string, required = true): Promise<string> {
try {
const [secret] = await this.client.accessSecretVersion({
name: `projects/${ConfigGoogle.SERVICE_CLOUD_PROJECT}/secrets/${secretName}/versions/latest`
});
return secret.payload.data.toString();
} catch (error) {
if(required) {
throw (Error.make(Error.Status.UNKNOWN,
`The required "${secretName}" secret cannot be correctly retrieved from the SecretManager`));
} else {
return undefined;
}
}
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment