Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding service client and tests #16

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
365 changes: 359 additions & 6 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"license": "MIT",
"dependencies": {
"aws-sdk": "^2.773.0",
"axios": "^0.20.0"
"axios": "^0.20.0",
"request": "^2.88.2",
"request-promise": "^4.2.6"
},
"devDependencies": {
"better-docs": "^2.3.2",
Expand Down
3 changes: 2 additions & 1 deletion src/client/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
SimpleOsduClient: require('./simple'),
...require('./aws')
...require('./aws'),
...require('./service')
}
3 changes: 3 additions & 0 deletions src/client/service/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
ServiceConnectionOsduClient: require('./service')
}
65 changes: 65 additions & 0 deletions src/client/service/service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const BaseOsduClient = require('../base.js');
const request = require('request-promise');

/**
* Class that provides a service connection (OAuth client credentials) implementation for OSDU API clients.
* - Uses the OAuth client credentials protocol for service connections not associated with a specific user
* - Will attempt to refresh access token through OAuth client credentials when an unauthorized response is received.
* @class
* @category Clients
* @subcategory Service
*/
class ServiceConnectionOsduClient extends BaseOsduClient {
/**
* @constructor
* @param {Object} params - The configuration parameters defined below
* @param {string} params.api_url - The url for the OSDU API, with or without a trailing `/`
* @param {string} params.oauth_client_id - The client id (client-credentials) for the OSDU OAuth client
* @param {string} params.oauth_client_secret - The client secret (client-credentials) for the OSDU OAuth client
* @param {string} params.oauth_url - The url for the OSDU OAuth
*/
constructor(params) {
super(params.api_url);
this._oauthAuthHeader = `Basic ${Buffer.from(params.oauth_client_id + ':' + params.oauth_client_secret).toString('base64')}`;
this._oauthUrl = params.oauth_url;
}

// Auth
/**
* Internal access token refresh method
* - Brokers communication with OAuth domain to perform service authentication and retrieve a new access token for the OSDU Application
* @protected
* @returns {Promise<void>} Promise resolving after the access token on the client has been updated
*/
async _refreshAccessToken() {
// Request new OAuth access token
var response;
try {
response = await request.post(`${this._oauthUrl}/oauth2/token`, {
form: {
grant_type: 'client_credentials',
scope: 'osduOnAws/osduOnAWSService'
},
headers: {
Authorization: this._oauthAuthHeader
}
});
if (response) {
response = JSON.parse(response);
}
}
catch (error) {
throw new Error(`Unable to retrieve access token from OSDU OAuth: ${error.message}`);
}

// Handle response
if (response && response['access_token']) {
this.accessToken = response['access_token'];
}
else {
throw new Error(`Unable to retrieve access token from OSDU OAuth: Unknown error`);
}
}
}

module.exports = ServiceConnectionOsduClient;
56 changes: 56 additions & 0 deletions tests/client/service.integration.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const {
ServiceConnectionOsduClient,
OsduR2Service,
OsduQueryExpression,
OsduQueryBuilder
} = require('../../src');
const assert = require('assert').strict;
require('dotenv').config();

const createOSDUClient = () => {
return new ServiceConnectionOsduClient({
api_url: process.env.OSDU_API_URL,
oauth_client_id: process.env.OSDU_CLIENT_SECRET_ID,
oauth_client_secret: process.env.OSDU_CLIENT_SECRET,
oauth_url: process.env.OSDU_OAUTH_URL
});
}

describe("ServiceConnectionOsduClient tests", function() {
this.timeout(60000);
it("Can get authentication and refresh tokens", async function() {
// Assemble
var osduClient = createOSDUClient();

// Act
await osduClient._refreshAccessToken();
const firstAccessToken = osduClient.accessToken;
await osduClient._refreshAccessToken();

// Assert
assert.notStrictEqual(firstAccessToken, undefined, "First access token undefined");
assert.notStrictEqual(osduClient.accessToken, undefined, "Second access token undefined");
assert.notStrictEqual(firstAccessToken, osduClient.accessToken, "Access token not refreshed");
});

it("Can perform general query", async function() {
// Assemble
var awsClient = createOSDUClient();
var osduService = new OsduR2Service(awsClient, 'opendes');
const kind = `opendes:osdu:file:0.2.0`;
const limit = 2;

// Act
var queryResults = await osduService.QueryService.query(
(new OsduQueryBuilder())
.kind(kind)
.limit(limit)
.build()
);

// Assert
assert.strictEqual(queryResults.results.length, limit, `Returned exactly the limit amount of records`);
assert.strictEqual(queryResults.results[0].kind, kind, `Returned exactly the kind specified in the query`);
});
});

1 change: 1 addition & 0 deletions types/client/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
declare const _exports: {
ServiceConnectionOsduClient: typeof import("./service/service");
AWSOsduClient: typeof import("./aws/aws");
AWSOsduSimpleCredentialProvider: typeof import("./aws/simpleCredentialProvider");
AWSOsduSSMCredentialProvider: typeof import("./aws/ssmCredentialProvider");
Expand Down
1 change: 1 addition & 0 deletions types/client/service/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ServiceConnectionOsduClient: typeof import("./service");
29 changes: 29 additions & 0 deletions types/client/service/service.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export = ServiceConnectionOsduClient;
/**
* Class that provides a service connection (OAuth client credentials) implementation for OSDU API clients.
* - Uses the OAuth client credentials protocol for service connections not associated with a specific user
* - Will attempt to refresh access token through OAuth client credentials when an unauthorized response is received.
* @class
* @category Clients
* @subcategory Service
*/
declare class ServiceConnectionOsduClient extends BaseOsduClient {
/**
* @constructor
* @param {Object} params - The configuration parameters defined below
* @param {string} params.api_url - The url for the OSDU API, with or without a trailing `/`
* @param {string} params.oauth_client_id - The client id (client-credentials) for the OSDU OAuth client
* @param {string} params.oauth_client_secret - The client secret (client-credentials) for the OSDU OAuth client
* @param {string} params.oauth_url - The url for the OSDU OAuth
*/
constructor(params: {
api_url: string;
oauth_client_id: string;
oauth_client_secret: string;
oauth_url: string;
});
_oauthAuthHeader: string;
_oauthUrl: string;
accessToken: any;
}
import BaseOsduClient = require("../base.js");
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ declare const _exports: {
OsduR2StorageService: typeof import("./service/R2/storage");
OsduQueryBuilder: typeof import("./models/query/osduQueryBuilder");
OsduQueryExpression: typeof import("./models/query/osduQueryExpression");
ServiceConnectionOsduClient: typeof import("./client/service/service");
AWSOsduClient: typeof import("./client/aws/aws");
AWSOsduSimpleCredentialProvider: typeof import("./client/aws/simpleCredentialProvider");
AWSOsduSSMCredentialProvider: typeof import("./client/aws/ssmCredentialProvider");
Expand Down