Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/authentication/test/browser/authenticationService.test.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import { Emitter, Event } from '../../../../../base/common/event.js';
8
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
9
import { URI } from '../../../../../base/common/uri.js';
10
import { AuthenticationAccessService } from '../../browser/authenticationAccessService.js';
11
import { AuthenticationService } from '../../browser/authenticationService.js';
12
import { AuthenticationProviderInformation, AuthenticationSessionsChangeEvent, IAuthenticationProvider } from '../../common/authentication.js';
13
import { TestEnvironmentService } from '../../../../test/browser/workbenchTestServices.js';
14
import { TestExtensionService, TestProductService, TestStorageService } from '../../../../test/common/workbenchTestServices.js';
15
import { NullLogService } from '../../../../../platform/log/common/log.js';
16
17
function createSession() {
18
return { id: 'session1', accessToken: 'token1', account: { id: 'account', label: 'Account' }, scopes: ['test'] };
19
}
20
21
function createProvider(overrides: Partial<IAuthenticationProvider> = {}): IAuthenticationProvider {
22
return {
23
supportsMultipleAccounts: false,
24
onDidChangeSessions: new Emitter<AuthenticationSessionsChangeEvent>().event,
25
id: 'test',
26
label: 'Test',
27
getSessions: async () => [],
28
createSession: async () => createSession(),
29
removeSession: async () => { },
30
...overrides
31
};
32
}
33
34
suite('AuthenticationService', () => {
35
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
36
37
let authenticationService: AuthenticationService;
38
39
setup(() => {
40
const storageService = disposables.add(new TestStorageService());
41
const authenticationAccessService = disposables.add(new AuthenticationAccessService(storageService, TestProductService));
42
authenticationService = disposables.add(new AuthenticationService(new TestExtensionService(), authenticationAccessService, TestEnvironmentService, new NullLogService()));
43
});
44
45
teardown(() => {
46
// Dispose the authentication service after each test
47
authenticationService.dispose();
48
});
49
50
suite('declaredAuthenticationProviders', () => {
51
test('registerDeclaredAuthenticationProvider', async () => {
52
const changed = Event.toPromise(authenticationService.onDidChangeDeclaredProviders);
53
const provider: AuthenticationProviderInformation = {
54
id: 'github',
55
label: 'GitHub'
56
};
57
authenticationService.registerDeclaredAuthenticationProvider(provider);
58
59
// Assert that the provider is added to the declaredProviders array and the event fires
60
assert.equal(authenticationService.declaredProviders.length, 1);
61
assert.deepEqual(authenticationService.declaredProviders[0], provider);
62
await changed;
63
});
64
65
test('unregisterDeclaredAuthenticationProvider', async () => {
66
const provider: AuthenticationProviderInformation = {
67
id: 'github',
68
label: 'GitHub'
69
};
70
authenticationService.registerDeclaredAuthenticationProvider(provider);
71
const changed = Event.toPromise(authenticationService.onDidChangeDeclaredProviders);
72
authenticationService.unregisterDeclaredAuthenticationProvider(provider.id);
73
74
// Assert that the provider is removed from the declaredProviders array and the event fires
75
assert.equal(authenticationService.declaredProviders.length, 0);
76
await changed;
77
});
78
});
79
80
suite('authenticationProviders', () => {
81
test('isAuthenticationProviderRegistered', async () => {
82
const registered = Event.toPromise(authenticationService.onDidRegisterAuthenticationProvider);
83
const provider = createProvider();
84
assert.equal(authenticationService.isAuthenticationProviderRegistered(provider.id), false);
85
authenticationService.registerAuthenticationProvider(provider.id, provider);
86
assert.equal(authenticationService.isAuthenticationProviderRegistered(provider.id), true);
87
const result = await registered;
88
assert.deepEqual(result, { id: provider.id, label: provider.label });
89
});
90
91
test('unregisterAuthenticationProvider', async () => {
92
const unregistered = Event.toPromise(authenticationService.onDidUnregisterAuthenticationProvider);
93
const provider = createProvider();
94
authenticationService.registerAuthenticationProvider(provider.id, provider);
95
assert.equal(authenticationService.isAuthenticationProviderRegistered(provider.id), true);
96
authenticationService.unregisterAuthenticationProvider(provider.id);
97
assert.equal(authenticationService.isAuthenticationProviderRegistered(provider.id), false);
98
const result = await unregistered;
99
assert.deepEqual(result, { id: provider.id, label: provider.label });
100
});
101
102
test('getProviderIds', () => {
103
const provider1 = createProvider({
104
id: 'provider1',
105
label: 'Provider 1'
106
});
107
const provider2 = createProvider({
108
id: 'provider2',
109
label: 'Provider 2'
110
});
111
112
authenticationService.registerAuthenticationProvider(provider1.id, provider1);
113
authenticationService.registerAuthenticationProvider(provider2.id, provider2);
114
115
const providerIds = authenticationService.getProviderIds();
116
117
// Assert that the providerIds array contains the registered provider ids
118
assert.deepEqual(providerIds, [provider1.id, provider2.id]);
119
});
120
121
test('getProvider', () => {
122
const provider = createProvider();
123
124
authenticationService.registerAuthenticationProvider(provider.id, provider);
125
126
const retrievedProvider = authenticationService.getProvider(provider.id);
127
128
// Assert that the retrieved provider is the same as the registered provider
129
assert.deepEqual(retrievedProvider, provider);
130
});
131
132
test('getOrActivateProviderIdForServer - should return undefined when no provider matches the authorization server', async () => {
133
const authorizationServer = URI.parse('https://example.com');
134
const result = await authenticationService.getOrActivateProviderIdForServer(authorizationServer);
135
assert.strictEqual(result, undefined);
136
});
137
138
test('getOrActivateProviderIdForServer - should return provider id if authorizationServerGlobs matches and authorizationServers match', async () => {
139
// Register a declared provider with an authorization server glob
140
const provider: AuthenticationProviderInformation = {
141
id: 'github',
142
label: 'GitHub',
143
authorizationServerGlobs: ['https://github.com/*']
144
};
145
authenticationService.registerDeclaredAuthenticationProvider(provider);
146
147
// Register an authentication provider with matching authorization servers
148
const authProvider = createProvider({
149
id: 'github',
150
label: 'GitHub',
151
authorizationServers: [URI.parse('https://github.com/login')]
152
});
153
authenticationService.registerAuthenticationProvider('github', authProvider);
154
155
// Test with a matching URI
156
const authorizationServer = URI.parse('https://github.com/login');
157
const result = await authenticationService.getOrActivateProviderIdForServer(authorizationServer);
158
159
// Verify the result
160
assert.strictEqual(result, 'github');
161
});
162
163
test('getOrActivateProviderIdForServer - should return undefined if authorizationServerGlobs match but authorizationServers do not match', async () => {
164
// Register a declared provider with an authorization server glob
165
const provider: AuthenticationProviderInformation = {
166
id: 'github',
167
label: 'GitHub',
168
authorizationServerGlobs: ['https://github.com/*']
169
};
170
authenticationService.registerDeclaredAuthenticationProvider(provider);
171
172
// Register an authentication provider with non-matching authorization servers
173
const authProvider = createProvider({
174
id: 'github',
175
label: 'GitHub',
176
authorizationServers: [URI.parse('https://github.com/different')]
177
});
178
authenticationService.registerAuthenticationProvider('github', authProvider);
179
180
// Test with a non-matching URI
181
const authorizationServer = URI.parse('https://github.com/login');
182
const result = await authenticationService.getOrActivateProviderIdForServer(authorizationServer);
183
184
// Verify the result
185
assert.strictEqual(result, undefined);
186
});
187
188
test('getOrActivateProviderIdForAuthorizationServer - should check multiple providers and return the first match', async () => {
189
// Register two declared providers with authorization server globs
190
const provider1: AuthenticationProviderInformation = {
191
id: 'github',
192
label: 'GitHub',
193
authorizationServerGlobs: ['https://github.com/*']
194
};
195
const provider2: AuthenticationProviderInformation = {
196
id: 'microsoft',
197
label: 'Microsoft',
198
authorizationServerGlobs: ['https://login.microsoftonline.com/*']
199
};
200
authenticationService.registerDeclaredAuthenticationProvider(provider1);
201
authenticationService.registerDeclaredAuthenticationProvider(provider2);
202
203
// Register authentication providers
204
const githubProvider = createProvider({
205
id: 'github',
206
label: 'GitHub',
207
authorizationServers: [URI.parse('https://github.com/different')]
208
});
209
authenticationService.registerAuthenticationProvider('github', githubProvider);
210
211
const microsoftProvider = createProvider({
212
id: 'microsoft',
213
label: 'Microsoft',
214
authorizationServers: [URI.parse('https://login.microsoftonline.com/common')]
215
});
216
authenticationService.registerAuthenticationProvider('microsoft', microsoftProvider);
217
218
// Test with a URI that should match the second provider
219
const authorizationServer = URI.parse('https://login.microsoftonline.com/common');
220
const result = await authenticationService.getOrActivateProviderIdForServer(authorizationServer);
221
222
// Verify the result
223
assert.strictEqual(result, 'microsoft');
224
});
225
});
226
227
suite('authenticationSessions', () => {
228
test('getSessions - base case', async () => {
229
let isCalled = false;
230
const provider = createProvider({
231
getSessions: async () => {
232
isCalled = true;
233
return [createSession()];
234
},
235
});
236
authenticationService.registerAuthenticationProvider(provider.id, provider);
237
const sessions = await authenticationService.getSessions(provider.id);
238
239
assert.equal(sessions.length, 1);
240
assert.ok(isCalled);
241
});
242
243
test('getSessions - authorization server is not registered', async () => {
244
let isCalled = false;
245
const provider = createProvider({
246
getSessions: async () => {
247
isCalled = true;
248
return [createSession()];
249
},
250
});
251
authenticationService.registerAuthenticationProvider(provider.id, provider);
252
assert.rejects(() => authenticationService.getSessions(provider.id, [], { authorizationServer: URI.parse('https://example.com') }));
253
assert.ok(!isCalled);
254
});
255
256
test('createSession', async () => {
257
const emitter = new Emitter<AuthenticationSessionsChangeEvent>();
258
const provider = createProvider({
259
onDidChangeSessions: emitter.event,
260
createSession: async () => {
261
const session = createSession();
262
emitter.fire({ added: [session], removed: [], changed: [] });
263
return session;
264
},
265
});
266
const changed = Event.toPromise(authenticationService.onDidChangeSessions);
267
authenticationService.registerAuthenticationProvider(provider.id, provider);
268
const session = await authenticationService.createSession(provider.id, ['repo']);
269
270
// Assert that the created session matches the expected session and the event fires
271
assert.ok(session);
272
const result = await changed;
273
assert.deepEqual(result, {
274
providerId: provider.id,
275
label: provider.label,
276
event: { added: [session], removed: [], changed: [] }
277
});
278
});
279
280
test('removeSession', async () => {
281
const emitter = new Emitter<AuthenticationSessionsChangeEvent>();
282
const session = createSession();
283
const provider = createProvider({
284
onDidChangeSessions: emitter.event,
285
removeSession: async () => emitter.fire({ added: [], removed: [session], changed: [] })
286
});
287
const changed = Event.toPromise(authenticationService.onDidChangeSessions);
288
authenticationService.registerAuthenticationProvider(provider.id, provider);
289
await authenticationService.removeSession(provider.id, session.id);
290
291
const result = await changed;
292
assert.deepEqual(result, {
293
providerId: provider.id,
294
label: provider.label,
295
event: { added: [], removed: [session], changed: [] }
296
});
297
});
298
299
test('onDidChangeSessions', async () => {
300
const emitter = new Emitter<AuthenticationSessionsChangeEvent>();
301
const provider = createProvider({
302
onDidChangeSessions: emitter.event,
303
getSessions: async () => []
304
});
305
authenticationService.registerAuthenticationProvider(provider.id, provider);
306
307
const changed = Event.toPromise(authenticationService.onDidChangeSessions);
308
const session = createSession();
309
emitter.fire({ added: [], removed: [], changed: [session] });
310
311
const result = await changed;
312
assert.deepEqual(result, {
313
providerId: provider.id,
314
label: provider.label,
315
event: { added: [], removed: [], changed: [session] }
316
});
317
});
318
});
319
});
320
321