5
5
6
6
import * as vscode from 'vscode' ;
7
7
import { v4 as uuid } from 'uuid' ;
8
- import Keychain from './common/keychain' ;
8
+ import Keychain from '.. /common/keychain' ;
9
9
import GitpodServer from './gitpodServer' ;
10
- import { arrayEquals } from './common/utils' ;
11
- import { Disposable } from './common/dispose' ;
12
- import TelemetryReporter from './telemetryReporter ' ;
13
- import { UserFlowTelemetry } from './common/telemetry ' ;
14
- import { NotificationService } from './notification ' ;
10
+ import { arrayEquals } from '.. /common/utils' ;
11
+ import { Disposable } from '.. /common/dispose' ;
12
+ import { ITelemetryService , UserFlowTelemetry } from '../services/telemetryService ' ;
13
+ import { INotificationService } from '../services/notificationService ' ;
14
+ import { ILogService } from '../services/logService ' ;
15
15
16
16
interface SessionData {
17
17
id : string ;
@@ -26,7 +26,6 @@ interface SessionData {
26
26
27
27
export default class GitpodAuthenticationProvider extends Disposable implements vscode . AuthenticationProvider {
28
28
private _sessionChangeEmitter = new vscode . EventEmitter < vscode . AuthenticationProviderAuthenticationSessionsChangeEvent > ( ) ;
29
- private _telemetry : TelemetryReporter ;
30
29
31
30
private _gitpodServer ! : GitpodServer ;
32
31
private _keychain ! : Keychain ;
@@ -38,14 +37,12 @@ export default class GitpodAuthenticationProvider extends Disposable implements
38
37
39
38
constructor (
40
39
private readonly context : vscode . ExtensionContext ,
41
- private readonly _logger : vscode . LogOutputChannel ,
42
- telemetry : TelemetryReporter ,
43
- private readonly notifications : NotificationService
40
+ private readonly logService : ILogService ,
41
+ private readonly telemetryService : ITelemetryService ,
42
+ private readonly notificationService : INotificationService
44
43
) {
45
44
super ( ) ;
46
45
47
- this . _telemetry = telemetry ;
48
-
49
46
this . reconcile ( ) ;
50
47
this . _register ( vscode . workspace . onDidChangeConfiguration ( e => {
51
48
if ( e . affectsConfiguration ( 'gitpod.host' ) ) {
@@ -67,9 +64,9 @@ export default class GitpodAuthenticationProvider extends Disposable implements
67
64
this . _serviceUrl = gitpodHostUrl . toString ( ) . replace ( / \/ $ / , '' ) ;
68
65
Object . assign ( this . flow , { gitpodHost : this . _serviceUrl } ) ;
69
66
this . _gitpodServer ?. dispose ( ) ;
70
- this . _gitpodServer = new GitpodServer ( this . _serviceUrl , this . _logger , this . notifications ) ;
71
- this . _keychain = new Keychain ( this . context , `gitpod.auth.${ gitpodHostUrl . hostname } ` , this . _logger ) ;
72
- this . _logger . info ( `Started authentication provider for ${ gitpodHost } ` ) ;
67
+ this . _gitpodServer = new GitpodServer ( this . _serviceUrl , this . logService , this . notificationService ) ;
68
+ this . _keychain = new Keychain ( this . context , `gitpod.auth.${ gitpodHostUrl . hostname } ` , this . logService ) ;
69
+ this . logService . info ( `Started authentication provider for ${ gitpodHost } ` ) ;
73
70
}
74
71
75
72
get onDidChangeSessions ( ) {
@@ -81,16 +78,16 @@ export default class GitpodAuthenticationProvider extends Disposable implements
81
78
const sortedScopes = scopes ?. sort ( ) || [ ] ;
82
79
const validScopes = await this . fetchValidScopes ( ) ;
83
80
const sortedFilteredScopes = sortedScopes . filter ( s => ! validScopes || validScopes . includes ( s ) ) ;
84
- this . _logger . info ( `Getting sessions for ${ sortedScopes . length ? sortedScopes . join ( ',' ) : 'all scopes' } ${ sortedScopes . length !== sortedFilteredScopes . length ? `, but valid scopes are ${ sortedFilteredScopes . join ( ',' ) } ` : '' } ...` ) ;
81
+ this . logService . info ( `Getting sessions for ${ sortedScopes . length ? sortedScopes . join ( ',' ) : 'all scopes' } ${ sortedScopes . length !== sortedFilteredScopes . length ? `, but valid scopes are ${ sortedFilteredScopes . join ( ',' ) } ` : '' } ...` ) ;
85
82
if ( sortedScopes . length !== sortedFilteredScopes . length ) {
86
- this . _logger . warn ( `But valid scopes are ${ sortedFilteredScopes . join ( ',' ) } , returning session with only valid scopes...` ) ;
83
+ this . logService . warn ( `But valid scopes are ${ sortedFilteredScopes . join ( ',' ) } , returning session with only valid scopes...` ) ;
87
84
}
88
85
const sessions = await this . _sessionsPromise ;
89
86
const finalSessions = sortedFilteredScopes . length
90
87
? sessions . filter ( session => arrayEquals ( [ ...session . scopes ] . sort ( ) , sortedFilteredScopes ) )
91
88
: sessions ;
92
89
93
- this . _logger . info ( `Got ${ finalSessions . length } sessions for ${ sortedFilteredScopes ?. join ( ',' ) ?? 'all scopes' } ...` ) ;
90
+ this . logService . info ( `Got ${ finalSessions . length } sessions for ${ sortedFilteredScopes ?. join ( ',' ) ?? 'all scopes' } ...` ) ;
94
91
return finalSessions ;
95
92
}
96
93
@@ -110,7 +107,7 @@ export default class GitpodAuthenticationProvider extends Disposable implements
110
107
return this . _validScopes ;
111
108
}
112
109
} catch ( e ) {
113
- this . _logger . error ( `Error fetching endpoint ${ endpoint } ` , e ) ;
110
+ this . logService . error ( `Error fetching endpoint ${ endpoint } ` , e ) ;
114
111
}
115
112
return undefined ;
116
113
}
@@ -127,7 +124,7 @@ export default class GitpodAuthenticationProvider extends Disposable implements
127
124
const matchesExisting = previousSessions . some ( s => s . id === session . id ) ;
128
125
// Another window added a session to the keychain, add it to our state as well
129
126
if ( ! matchesExisting ) {
130
- this . _logger . info ( 'Adding session found in keychain' ) ;
127
+ this . logService . info ( 'Adding session found in keychain' ) ;
131
128
added . push ( session ) ;
132
129
}
133
130
} ) ;
@@ -136,7 +133,7 @@ export default class GitpodAuthenticationProvider extends Disposable implements
136
133
const matchesExisting = storedSessions . some ( s => s . id === session . id ) ;
137
134
// Another window has logged out, remove from our state
138
135
if ( ! matchesExisting ) {
139
- this . _logger . info ( 'Removing session no longer found in keychain' ) ;
136
+ this . logService . info ( 'Removing session no longer found in keychain' ) ;
140
137
removed . push ( session ) ;
141
138
}
142
139
} ) ;
@@ -149,12 +146,12 @@ export default class GitpodAuthenticationProvider extends Disposable implements
149
146
private async readSessions ( ) : Promise < vscode . AuthenticationSession [ ] > {
150
147
let sessionData : SessionData [ ] ;
151
148
try {
152
- this . _logger . info ( 'Reading sessions from keychain...' ) ;
149
+ this . logService . info ( 'Reading sessions from keychain...' ) ;
153
150
const storedSessions = await this . _keychain . getToken ( ) ;
154
151
if ( ! storedSessions ) {
155
152
return [ ] ;
156
153
}
157
- this . _logger . info ( 'Got stored sessions!' ) ;
154
+ this . logService . info ( 'Got stored sessions!' ) ;
158
155
159
156
try {
160
157
sessionData = JSON . parse ( storedSessions ) ;
@@ -163,7 +160,7 @@ export default class GitpodAuthenticationProvider extends Disposable implements
163
160
throw e ;
164
161
}
165
162
} catch ( e ) {
166
- this . _logger . error ( `Error reading token: ${ e } ` ) ;
163
+ this . logService . error ( `Error reading token: ${ e } ` ) ;
167
164
return [ ] ;
168
165
}
169
166
@@ -175,16 +172,16 @@ export default class GitpodAuthenticationProvider extends Disposable implements
175
172
let userInfo : { id : string ; accountName : string } | undefined ;
176
173
try {
177
174
userInfo = await this . _gitpodServer . getUserInfo ( session . accessToken ) ;
178
- this . _logger . info ( `Verified session with the following scopes: ${ scopesStr } ` ) ;
175
+ this . logService . info ( `Verified session with the following scopes: ${ scopesStr } ` ) ;
179
176
} catch ( e ) {
180
177
// Remove sessions that return unauthorized response
181
178
if ( e . message === 'Unexpected server response: 401' ) {
182
179
return undefined ;
183
180
}
184
- this . _logger . error ( `Error while verifying session with the following scopes: ${ scopesStr } ` , e ) ;
181
+ this . logService . error ( `Error while verifying session with the following scopes: ${ scopesStr } ` , e ) ;
185
182
}
186
183
187
- this . _logger . trace ( `Read the following session from the keychain with the following scopes: ${ scopesStr } ` ) ;
184
+ this . logService . trace ( `Read the following session from the keychain with the following scopes: ${ scopesStr } ` ) ;
188
185
return {
189
186
id : session . id ,
190
187
account : {
@@ -203,7 +200,7 @@ export default class GitpodAuthenticationProvider extends Disposable implements
203
200
. map ( p => ( p as PromiseFulfilledResult < vscode . AuthenticationSession | undefined > ) . value )
204
201
. filter ( < T > ( p ?: T ) : p is T => Boolean ( p ) ) ;
205
202
206
- this . _logger . info ( `Got ${ verifiedSessions . length } verified sessions.` ) ;
203
+ this . logService . info ( `Got ${ verifiedSessions . length } verified sessions.` ) ;
207
204
if ( verifiedSessions . length !== sessionData . length ) {
208
205
await this . storeSessions ( verifiedSessions ) ;
209
206
}
@@ -212,10 +209,10 @@ export default class GitpodAuthenticationProvider extends Disposable implements
212
209
}
213
210
214
211
private async storeSessions ( sessions : vscode . AuthenticationSession [ ] ) : Promise < void > {
215
- this . _logger . info ( `Storing ${ sessions . length } sessions...` ) ;
212
+ this . logService . info ( `Storing ${ sessions . length } sessions...` ) ;
216
213
this . _sessionsPromise = Promise . resolve ( sessions ) ;
217
214
await this . _keychain . setToken ( JSON . stringify ( sessions ) ) ;
218
- this . _logger . info ( `Stored ${ sessions . length } sessions!` ) ;
215
+ this . logService . info ( `Stored ${ sessions . length } sessions!` ) ;
219
216
}
220
217
221
218
public async createSession ( scopes : string [ ] ) : Promise < vscode . AuthenticationSession > {
@@ -226,10 +223,10 @@ export default class GitpodAuthenticationProvider extends Disposable implements
226
223
const validScopes = await this . fetchValidScopes ( ) ;
227
224
const sortedFilteredScopes = sortedScopes . filter ( s => ! validScopes || validScopes . includes ( s ) ) ;
228
225
if ( sortedScopes . length !== sortedFilteredScopes . length ) {
229
- this . _logger . warn ( `Creating session with only valid scopes ${ sortedFilteredScopes . join ( ',' ) } , original scopes were ${ sortedScopes . join ( ',' ) } ` ) ;
226
+ this . logService . warn ( `Creating session with only valid scopes ${ sortedFilteredScopes . join ( ',' ) } , original scopes were ${ sortedScopes . join ( ',' ) } ` ) ;
230
227
}
231
228
flow . scopes = JSON . stringify ( sortedFilteredScopes ) ;
232
- this . _telemetry . sendUserFlowStatus ( 'login' , flow ) ;
229
+ this . telemetryService . sendUserFlowStatus ( 'login' , flow ) ;
233
230
234
231
const scopeString = sortedFilteredScopes . join ( ' ' ) ;
235
232
const token = await this . _gitpodServer . login ( scopeString , flow ) ;
@@ -247,19 +244,19 @@ export default class GitpodAuthenticationProvider extends Disposable implements
247
244
248
245
this . _sessionChangeEmitter . fire ( { added : [ session ] , removed : [ ] , changed : [ ] } ) ;
249
246
250
- this . _logger . info ( 'Login success!' ) ;
247
+ this . logService . info ( 'Login success!' ) ;
251
248
252
- this . _telemetry . sendUserFlowStatus ( 'login_successful' , flow ) ;
249
+ this . telemetryService . sendUserFlowStatus ( 'login_successful' , flow ) ;
253
250
254
251
return session ;
255
252
} catch ( e ) {
256
253
// If login was cancelled, do not notify user.
257
254
if ( e === 'Cancelled' || e . message === 'Cancelled' ) {
258
- this . _telemetry . sendUserFlowStatus ( 'login_cancelled' , flow ) ;
255
+ this . telemetryService . sendUserFlowStatus ( 'login_cancelled' , flow ) ;
259
256
throw e ;
260
257
}
261
- this . notifications . showErrorMessage ( `Sign in failed: ${ e } ` , { flow, id : 'login_failed' } ) ;
262
- this . _logger . error ( e ) ;
258
+ this . notificationService . showErrorMessage ( `Sign in failed: ${ e } ` , { flow, id : 'login_failed' } ) ;
259
+ this . logService . error ( e ) ;
263
260
throw e ;
264
261
}
265
262
}
@@ -277,8 +274,8 @@ export default class GitpodAuthenticationProvider extends Disposable implements
277
274
public async removeSession ( id : string ) {
278
275
const flow = { ...this . flow } ;
279
276
try {
280
- this . _telemetry . sendUserFlowStatus ( 'logout' , flow ) ;
281
- this . _logger . info ( `Logging out of ${ id } ` ) ;
277
+ this . telemetryService . sendUserFlowStatus ( 'logout' , flow ) ;
278
+ this . logService . info ( `Logging out of ${ id } ` ) ;
282
279
283
280
const sessions = await this . _sessionsPromise ;
284
281
const sessionIndex = sessions . findIndex ( session => session . id === id ) ;
@@ -291,12 +288,12 @@ export default class GitpodAuthenticationProvider extends Disposable implements
291
288
292
289
this . _sessionChangeEmitter . fire ( { added : [ ] , removed : [ session ] , changed : [ ] } ) ;
293
290
} else {
294
- this . _logger . error ( 'Session not found' ) ;
291
+ this . logService . error ( 'Session not found' ) ;
295
292
}
296
- this . _telemetry . sendUserFlowStatus ( 'logout_successful' , flow ) ;
293
+ this . telemetryService . sendUserFlowStatus ( 'logout_successful' , flow ) ;
297
294
} catch ( e ) {
298
- this . notifications . showErrorMessage ( `Sign out failed: ${ e } ` , { flow, id : 'logout_failed' } ) ;
299
- this . _logger . error ( e ) ;
295
+ this . notificationService . showErrorMessage ( `Sign out failed: ${ e } ` , { flow, id : 'logout_failed' } ) ;
296
+ this . logService . error ( e ) ;
300
297
throw e ;
301
298
}
302
299
}
0 commit comments