-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathcloudIntegrationService.ts
140 lines (126 loc) · 4.35 KB
/
cloudIntegrationService.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import type { IntegrationId } from '../../../constants.integrations';
import type { Container } from '../../../container';
import { Logger } from '../../../system/logger';
import { getLogScope } from '../../../system/logger.scope';
import type { ServerConnection } from '../../gk/serverConnection';
import type { CloudIntegrationAuthenticationSession, CloudIntegrationConnection } from './models';
import { toCloudIntegrationType } from './models';
export class CloudIntegrationService {
constructor(
private readonly container: Container,
private readonly connection: ServerConnection,
) {}
async getConnections(): Promise<CloudIntegrationConnection[] | undefined> {
const scope = getLogScope();
const providersRsp = await this.connection.fetchGkApi(
'v1/provider-tokens',
{ method: 'GET' },
{ organizationId: false },
);
if (!providersRsp.ok) {
const error = (await providersRsp.json())?.error;
const errorMessage =
typeof error === 'string' ? error : (error?.message as string) ?? providersRsp.statusText;
if (error != null) {
Logger.error(undefined, scope, `Failed to get connected providers from cloud: ${errorMessage}`);
}
if (this.container.telemetry.enabled) {
this.container.telemetry.sendEvent('cloudIntegrations/getConnections/failed', {
code: providersRsp.status,
});
}
return undefined;
}
return (await providersRsp.json())?.data as Promise<CloudIntegrationConnection[] | undefined>;
}
async getConnectionSession(
id: IntegrationId,
refreshToken?: string,
): Promise<CloudIntegrationAuthenticationSession | undefined> {
const scope = getLogScope();
const refresh = Boolean(refreshToken);
const cloudIntegrationType = toCloudIntegrationType[id];
if (cloudIntegrationType == null) {
Logger.error(undefined, scope, `Unsupported cloud integration type: ${id}`);
return undefined;
}
const reqInitOptions = refreshToken
? {
method: 'POST',
body: JSON.stringify({
access_token: refreshToken,
}),
}
: { method: 'GET' };
const tokenRsp = await this.connection.fetchGkApi(
`v1/provider-tokens/${cloudIntegrationType}${refresh ? '/refresh' : ''}`,
reqInitOptions,
{ organizationId: false },
);
if (!tokenRsp.ok) {
const error = (await tokenRsp.json())?.error;
const errorMessage = typeof error === 'string' ? error : (error?.message as string) ?? tokenRsp.statusText;
if (error != null) {
Logger.error(
undefined,
scope,
`Failed to ${refresh ? 'refresh' : 'get'} ${id} token from cloud: ${errorMessage}`,
);
}
if (this.container.telemetry.enabled) {
this.container.telemetry.sendEvent(
refreshToken
? 'cloudIntegrations/refreshConnection/failed'
: 'cloudIntegrations/getConnection/failed',
{
code: tokenRsp.status,
'integration.id': id,
},
);
}
if (refresh) {
// try once to just get the lastest token if the refresh fails, and give up if that fails too
const newTokenRsp = await this.connection.fetchGkApi(
`v1/provider-tokens/${cloudIntegrationType}`,
{ method: 'GET' },
{ organizationId: false },
);
if (newTokenRsp.ok) {
return (await newTokenRsp.json())?.data as Promise<
CloudIntegrationAuthenticationSession | undefined
>;
}
}
return undefined;
}
return (await tokenRsp.json())?.data as Promise<CloudIntegrationAuthenticationSession | undefined>;
}
async disconnect(id: IntegrationId): Promise<boolean> {
const scope = getLogScope();
const cloudIntegrationType = toCloudIntegrationType[id];
if (cloudIntegrationType == null) {
Logger.error(undefined, scope, `Unsupported cloud integration type: ${id}`);
return false;
}
const tokenRsp = await this.connection.fetchGkApi(
`v1/provider-tokens/${cloudIntegrationType}`,
{ method: 'DELETE' },
{ organizationId: false },
);
if (!tokenRsp.ok) {
const error = (await tokenRsp.json())?.error;
const errorMessage = typeof error === 'string' ? error : (error?.message as string) ?? tokenRsp.statusText;
if (error != null) {
Logger.error(undefined, scope, `Failed to disconnect ${id} token from cloud: ${errorMessage}`);
}
if (this.container.telemetry.enabled) {
this.container.telemetry.sendEvent('cloudIntegrations/disconnect/failed', {
code: tokenRsp.status,
'integration.id': id,
});
}
return false;
}
return true;
}
}