Skip to content

Commit 582c857

Browse files
authored
feat(presto-client): allow basic authentication (#19)
1 parent a35bf9d commit 582c857

File tree

3 files changed

+97
-3
lines changed

3 files changed

+97
-3
lines changed

presto-client/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ The Presto client can be configured with the following parameters:
4646
- `schema`: The default schema to use for queries. (Default: `undefined`)
4747
- `source`: The name of the source you want to use for reporting purposes (Default: `presto-js-client`)
4848
- `timezone`: The timezone to use for queries. (Default: `undefined`)
49+
- `authorizationToken`: The value to send as-is in the Authorization header. _Note_: The `Bearer` scheme is automatically added. (Default: `undefined`)
50+
- `basicAuthentication`: An object with a user and password inside, to be used for basic authentication. (Default: `undefined`)
51+
- `extraHeaders`: An dictionary of key-values to send as extra headers in all requests to the API. (Default: `undefined`)
4952
- `interval`: (DEPRECATED) The interval in milliseconds between checks for the status of a running query. (Default: `100`)
5053

5154
## Querying
@@ -164,3 +167,59 @@ const columns: Column[] = await prestoClient.getColumns({
164167
})
165168
console.log(columns)
166169
```
170+
171+
## Authentication
172+
173+
When creating the client instance, you optionally pass one of two authentication methods.
174+
175+
### Basic authentication
176+
177+
You can send a basic authorization user and password in this way:
178+
179+
```typescript
180+
const client = new PrestoClient({
181+
basicAuthentication: {
182+
user: 'my-user',
183+
password: 'my-password',
184+
},
185+
catalog: 'tpcds',
186+
host: 'http://localhost',
187+
port: 8080,
188+
schema: 'sf1',
189+
user: 'root',
190+
})
191+
```
192+
193+
### Auth token
194+
195+
You can send an authorization token in the following way:
196+
197+
```typescript
198+
const client = new PrestoClient({
199+
// Do not include `Bearer` here, it is automatically added by the client
200+
authorizationToken: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`,
201+
catalog: 'tpcds',
202+
host: 'http://localhost',
203+
port: 8080,
204+
schema: 'sf1',
205+
user: 'root',
206+
})
207+
```
208+
209+
## Extra headers
210+
211+
You can pass any extra custom headers to the Presto client to be send on all requests performed against the host:
212+
213+
```typescript
214+
const client = new PrestoClient({
215+
catalog: 'tpcds',
216+
extraHeaders: {
217+
'X-My-Custom-Header-1': 'value',
218+
'X-My-Custom-Header-2': 'value',
219+
},
220+
host: 'http://localhost',
221+
port: 8080,
222+
schema: 'sf1',
223+
user: 'root',
224+
})
225+
```

presto-client/src/client.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ export class PrestoClient {
1515
/**
1616
* Creates an instance of PrestoClient.
1717
* @param {PrestoClientConfig} config - Configuration object for the PrestoClient.
18+
* @param {Object} config.basicAuthorization - Optional object for basic authorization.
19+
* @param {Object} config.basicAuthorization.user - The basic auth user name.
20+
* @param {Object} config.basicAuthorization.password - The basic auth password.
21+
* @param {string} config.authorizationToken - An optional token to be sent in the authorization header. Takes precedence over the basic auth.
1822
* @param {string} config.catalog - The default catalog to be used.
23+
* @param {Record<string, string>} config.extraHeaders - Any extra headers to include in the API requests. Optional.
1924
* @param {string} config.host - The host address of the Presto server.
2025
* @param {number} config.interval - The polling interval in milliseconds for query status checks.
2126
* @param {number} config.port - The port number on which the Presto server is listening.
@@ -24,7 +29,19 @@ export class PrestoClient {
2429
* @param {string} [config.timezone] - The timezone to be used for the session. Optional.
2530
* @param {string} config.user - The username to be used for the Presto session.
2631
*/
27-
constructor({ catalog, host, interval, port, schema, source, timezone, user }: PrestoClientConfig) {
32+
constructor({
33+
basicAuthentication,
34+
authorizationToken,
35+
catalog,
36+
extraHeaders,
37+
host,
38+
interval,
39+
port,
40+
schema,
41+
source,
42+
timezone,
43+
user,
44+
}: PrestoClientConfig) {
2845
this.baseUrl = `${host || 'http://localhost'}:${port || 8080}/v1/statement`
2946
this.catalog = catalog
3047
this.interval = interval
@@ -46,7 +63,19 @@ export class PrestoClient {
4663
this.headers['X-Presto-Time-Zone'] = this.timezone
4764
}
4865

49-
// TODO: Set up auth
66+
if (authorizationToken) {
67+
this.headers['Authorization'] = `Bearer ${authorizationToken}`
68+
} else if (basicAuthentication) {
69+
// Note this is only available for Node.js
70+
this.headers['Authorization'] = `Basic ${Buffer.from(
71+
`${basicAuthentication.user}:${basicAuthentication.password}`,
72+
).toString('base64')}`
73+
}
74+
75+
this.headers = {
76+
...extraHeaders,
77+
...this.headers,
78+
}
5079
}
5180

5281
/**
@@ -197,7 +226,7 @@ export class PrestoClient {
197226
const data = []
198227

199228
do {
200-
const response = await this.request({ method: 'GET', url: nextUri })
229+
const response = await this.request({ headers, method: 'GET', url: nextUri })
201230

202231
// Server is overloaded, wait a bit
203232
if (response.status === 503) {

presto-client/src/client.types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
export interface PrestoClientConfig {
2+
authorizationToken?: string
3+
basicAuthentication?: {
4+
user: string
5+
password: string
6+
}
27
catalog?: string
8+
extraHeaders?: Record<string, string>
39
host?: string
410
interval?: number
511
port?: number

0 commit comments

Comments
 (0)