From f9efb3bc6d4b987ffe5336cb82e881a83b54f72e Mon Sep 17 00:00:00 2001 From: Alonso Vega Date: Thu, 18 Jan 2024 16:13:16 -0600 Subject: [PATCH 1/4] feat(client): allow basic and custom auth, pass extra headers --- presto-client/src/client.ts | 35 ++++++++++++++++++++++++++++--- presto-client/src/client.types.ts | 6 ++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/presto-client/src/client.ts b/presto-client/src/client.ts index ef8071b..890f906 100644 --- a/presto-client/src/client.ts +++ b/presto-client/src/client.ts @@ -15,7 +15,12 @@ export class PrestoClient { /** * Creates an instance of PrestoClient. * @param {PrestoClientConfig} config - Configuration object for the PrestoClient. + * @param {Object} config.basicAuthorization - Optional object for basic authorization. + * @param {Object} config.basicAuthorization.user - The basic auth user name. + * @param {Object} config.basicAuthorization.password - The basic auth password. + * @param {string} config.authorizationToken - An optional token to be sent in the authorization header. Takes precedence over the basic auth. * @param {string} config.catalog - The default catalog to be used. + * @param {Record} config.extraHeaders - Any extra headers to include in the API requests. Optional. * @param {string} config.host - The host address of the Presto server. * @param {number} config.interval - The polling interval in milliseconds for query status checks. * @param {number} config.port - The port number on which the Presto server is listening. @@ -24,7 +29,19 @@ export class PrestoClient { * @param {string} [config.timezone] - The timezone to be used for the session. Optional. * @param {string} config.user - The username to be used for the Presto session. */ - constructor({ catalog, host, interval, port, schema, source, timezone, user }: PrestoClientConfig) { + constructor({ + basicAuthorization, + authorizationToken, + catalog, + extraHeaders, + host, + interval, + port, + schema, + source, + timezone, + user, + }: PrestoClientConfig) { this.baseUrl = `${host || 'http://localhost'}:${port || 8080}/v1/statement` this.catalog = catalog this.interval = interval @@ -46,7 +63,19 @@ export class PrestoClient { this.headers['X-Presto-Time-Zone'] = this.timezone } - // TODO: Set up auth + if (authorizationToken) { + this.headers['Authorization'] = authorizationToken + } else if (basicAuthorization) { + // Note this is only available for Node.js + this.headers['Authorization'] = `Bearer ${Buffer.from( + `${basicAuthorization.user}:${basicAuthorization.password}`, + ).toString('base64')}` + } + + this.headers = { + ...extraHeaders, + ...this.headers, + } } /** @@ -197,7 +226,7 @@ export class PrestoClient { const data = [] do { - const response = await this.request({ method: 'GET', url: nextUri }) + const response = await this.request({ headers, method: 'GET', url: nextUri }) // Server is overloaded, wait a bit if (response.status === 503) { diff --git a/presto-client/src/client.types.ts b/presto-client/src/client.types.ts index c13945d..6931d14 100644 --- a/presto-client/src/client.types.ts +++ b/presto-client/src/client.types.ts @@ -1,5 +1,11 @@ export interface PrestoClientConfig { + authorizationToken?: string + basicAuthorization?: { + user: string + password: string + } catalog?: string + extraHeaders?: Record host?: string interval?: number port?: number From 5f675decc3b7962190d2d7f7f907e694fcbad566 Mon Sep 17 00:00:00 2001 From: Alonso Vega Date: Thu, 18 Jan 2024 16:28:58 -0600 Subject: [PATCH 2/4] docs(client): update README with new params --- presto-client/README.md | 3 +++ presto-client/src/client.ts | 6 +++--- presto-client/src/client.types.ts | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/presto-client/README.md b/presto-client/README.md index 8f5f0e5..eb569b1 100644 --- a/presto-client/README.md +++ b/presto-client/README.md @@ -46,6 +46,9 @@ The Presto client can be configured with the following parameters: - `schema`: The default schema to use for queries. (Default: `undefined`) - `source`: The name of the source you want to use for reporting purposes (Default: `presto-js-client`) - `timezone`: The timezone to use for queries. (Default: `undefined`) +- `authorizationToken`: The value to send as-is in the Authorization header. (Default: `undefined`) +- `basicAuthentication`: An object with a user and password inside, to be used for basic authentication. (Default: `undefined`) +- `extraHeaders`: An dictionary of key-values to send as extra headers in all requests to the API. (Default: `undefined`) - `interval`: (DEPRECATED) The interval in milliseconds between checks for the status of a running query. (Default: `100`) ## Querying diff --git a/presto-client/src/client.ts b/presto-client/src/client.ts index 890f906..ea46536 100644 --- a/presto-client/src/client.ts +++ b/presto-client/src/client.ts @@ -30,7 +30,7 @@ export class PrestoClient { * @param {string} config.user - The username to be used for the Presto session. */ constructor({ - basicAuthorization, + basicAuthentication, authorizationToken, catalog, extraHeaders, @@ -65,10 +65,10 @@ export class PrestoClient { if (authorizationToken) { this.headers['Authorization'] = authorizationToken - } else if (basicAuthorization) { + } else if (basicAuthentication) { // Note this is only available for Node.js this.headers['Authorization'] = `Bearer ${Buffer.from( - `${basicAuthorization.user}:${basicAuthorization.password}`, + `${basicAuthentication.user}:${basicAuthentication.password}`, ).toString('base64')}` } diff --git a/presto-client/src/client.types.ts b/presto-client/src/client.types.ts index 6931d14..aaa07c8 100644 --- a/presto-client/src/client.types.ts +++ b/presto-client/src/client.types.ts @@ -1,6 +1,6 @@ export interface PrestoClientConfig { authorizationToken?: string - basicAuthorization?: { + basicAuthentication?: { user: string password: string } From f70cc2c769397cbfe5a24966d2cf22eafd4028f6 Mon Sep 17 00:00:00 2001 From: Alonso Vega Date: Fri, 19 Jan 2024 13:13:58 -0600 Subject: [PATCH 3/4] fix(client): typo on auth header --- presto-client/src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/presto-client/src/client.ts b/presto-client/src/client.ts index ea46536..5500239 100644 --- a/presto-client/src/client.ts +++ b/presto-client/src/client.ts @@ -67,7 +67,7 @@ export class PrestoClient { this.headers['Authorization'] = authorizationToken } else if (basicAuthentication) { // Note this is only available for Node.js - this.headers['Authorization'] = `Bearer ${Buffer.from( + this.headers['Authorization'] = `Basic ${Buffer.from( `${basicAuthentication.user}:${basicAuthentication.password}`, ).toString('base64')}` } From 14351f34c2163bef3c279a106aa00849f64d744c Mon Sep 17 00:00:00 2001 From: Alonso Vega Date: Tue, 23 Jan 2024 11:07:55 -0600 Subject: [PATCH 4/4] refactor(client): include the `Bearer` schema automatically, update docs --- presto-client/README.md | 58 ++++++++++++++++++++++++++++++++++++- presto-client/src/client.ts | 2 +- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/presto-client/README.md b/presto-client/README.md index eb569b1..a3df602 100644 --- a/presto-client/README.md +++ b/presto-client/README.md @@ -46,7 +46,7 @@ The Presto client can be configured with the following parameters: - `schema`: The default schema to use for queries. (Default: `undefined`) - `source`: The name of the source you want to use for reporting purposes (Default: `presto-js-client`) - `timezone`: The timezone to use for queries. (Default: `undefined`) -- `authorizationToken`: The value to send as-is in the Authorization header. (Default: `undefined`) +- `authorizationToken`: The value to send as-is in the Authorization header. _Note_: The `Bearer` scheme is automatically added. (Default: `undefined`) - `basicAuthentication`: An object with a user and password inside, to be used for basic authentication. (Default: `undefined`) - `extraHeaders`: An dictionary of key-values to send as extra headers in all requests to the API. (Default: `undefined`) - `interval`: (DEPRECATED) The interval in milliseconds between checks for the status of a running query. (Default: `100`) @@ -167,3 +167,59 @@ const columns: Column[] = await prestoClient.getColumns({ }) console.log(columns) ``` + +## Authentication + +When creating the client instance, you optionally pass one of two authentication methods. + +### Basic authentication + +You can send a basic authorization user and password in this way: + +```typescript +const client = new PrestoClient({ + basicAuthentication: { + user: 'my-user', + password: 'my-password', + }, + catalog: 'tpcds', + host: 'http://localhost', + port: 8080, + schema: 'sf1', + user: 'root', +}) +``` + +### Auth token + +You can send an authorization token in the following way: + +```typescript +const client = new PrestoClient({ + // Do not include `Bearer` here, it is automatically added by the client + authorizationToken: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`, + catalog: 'tpcds', + host: 'http://localhost', + port: 8080, + schema: 'sf1', + user: 'root', +}) +``` + +## Extra headers + +You can pass any extra custom headers to the Presto client to be send on all requests performed against the host: + +```typescript +const client = new PrestoClient({ + catalog: 'tpcds', + extraHeaders: { + 'X-My-Custom-Header-1': 'value', + 'X-My-Custom-Header-2': 'value', + }, + host: 'http://localhost', + port: 8080, + schema: 'sf1', + user: 'root', +}) +``` diff --git a/presto-client/src/client.ts b/presto-client/src/client.ts index 5500239..64afb61 100644 --- a/presto-client/src/client.ts +++ b/presto-client/src/client.ts @@ -64,7 +64,7 @@ export class PrestoClient { } if (authorizationToken) { - this.headers['Authorization'] = authorizationToken + this.headers['Authorization'] = `Bearer ${authorizationToken}` } else if (basicAuthentication) { // Note this is only available for Node.js this.headers['Authorization'] = `Basic ${Buffer.from(