Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/authentication/browser/authentication.contribution.ts
5245 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 { Disposable } from '../../../../base/common/lifecycle.js';
7
import { localize } from '../../../../nls.js';
8
import { registerAction2 } from '../../../../platform/actions/common/actions.js';
9
import { CommandsRegistry } from '../../../../platform/commands/common/commands.js';
10
import { IExtensionManifest } from '../../../../platform/extensions/common/extensions.js';
11
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
12
import { Registry } from '../../../../platform/registry/common/platform.js';
13
import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from '../../../common/contributions.js';
14
import { SignOutOfAccountAction } from './actions/signOutOfAccountAction.js';
15
import { IBrowserWorkbenchEnvironmentService } from '../../../services/environment/browser/environmentService.js';
16
import { Extensions, IExtensionFeatureTableRenderer, IExtensionFeaturesRegistry, IRenderedData, IRowData, ITableData } from '../../../services/extensionManagement/common/extensionFeatures.js';
17
import { ManageTrustedExtensionsForAccountAction } from './actions/manageTrustedExtensionsForAccountAction.js';
18
import { ManageAccountPreferencesForExtensionAction } from './actions/manageAccountPreferencesForExtensionAction.js';
19
import { IAuthenticationUsageService } from '../../../services/authentication/browser/authenticationUsageService.js';
20
import { ManageAccountPreferencesForMcpServerAction } from './actions/manageAccountPreferencesForMcpServerAction.js';
21
import { ManageTrustedMcpServersForAccountAction } from './actions/manageTrustedMcpServersForAccountAction.js';
22
import { RemoveDynamicAuthenticationProvidersAction } from './actions/manageDynamicAuthenticationProvidersAction.js';
23
import { ManageAccountsAction } from './actions/manageAccountsAction.js';
24
25
const codeExchangeProxyCommand = CommandsRegistry.registerCommand('workbench.getCodeExchangeProxyEndpoints', function (accessor, _) {
26
const environmentService = accessor.get(IBrowserWorkbenchEnvironmentService);
27
return environmentService.options?.codeExchangeProxyEndpoints;
28
});
29
30
class AuthenticationDataRenderer extends Disposable implements IExtensionFeatureTableRenderer {
31
32
readonly type = 'table';
33
34
shouldRender(manifest: IExtensionManifest): boolean {
35
return !!manifest.contributes?.authentication;
36
}
37
38
render(manifest: IExtensionManifest): IRenderedData<ITableData> {
39
const authentication = manifest.contributes?.authentication || [];
40
if (!authentication.length) {
41
return { data: { headers: [], rows: [] }, dispose: () => { } };
42
}
43
44
const headers = [
45
localize('authenticationlabel', "Label"),
46
localize('authenticationid', "ID"),
47
localize('authenticationMcpAuthorizationServers', "MCP Authorization Servers")
48
];
49
50
const rows: IRowData[][] = authentication
51
.sort((a, b) => a.label.localeCompare(b.label))
52
.map(auth => {
53
return [
54
auth.label,
55
auth.id,
56
(auth.authorizationServerGlobs ?? []).join(',\n')
57
];
58
});
59
60
return {
61
data: {
62
headers,
63
rows
64
},
65
dispose: () => { }
66
};
67
}
68
}
69
70
const extensionFeature = Registry.as<IExtensionFeaturesRegistry>(Extensions.ExtensionFeaturesRegistry).registerExtensionFeature({
71
id: 'authentication',
72
label: localize('authentication', "Authentication"),
73
access: {
74
canToggle: false
75
},
76
renderer: new SyncDescriptor(AuthenticationDataRenderer),
77
});
78
79
class AuthenticationContribution extends Disposable implements IWorkbenchContribution {
80
static ID = 'workbench.contrib.authentication';
81
82
constructor() {
83
super();
84
this._register(codeExchangeProxyCommand);
85
this._register(extensionFeature);
86
87
this._registerActions();
88
}
89
90
private _registerActions(): void {
91
this._register(registerAction2(ManageAccountsAction));
92
this._register(registerAction2(SignOutOfAccountAction));
93
this._register(registerAction2(ManageTrustedExtensionsForAccountAction));
94
this._register(registerAction2(ManageAccountPreferencesForExtensionAction));
95
this._register(registerAction2(ManageTrustedMcpServersForAccountAction));
96
this._register(registerAction2(ManageAccountPreferencesForMcpServerAction));
97
this._register(registerAction2(RemoveDynamicAuthenticationProvidersAction));
98
}
99
}
100
101
class AuthenticationUsageContribution implements IWorkbenchContribution {
102
static ID = 'workbench.contrib.authenticationUsage';
103
104
constructor(
105
@IAuthenticationUsageService private readonly _authenticationUsageService: IAuthenticationUsageService,
106
) {
107
this._initializeExtensionUsageCache();
108
}
109
110
private async _initializeExtensionUsageCache() {
111
await this._authenticationUsageService.initializeExtensionUsageCache();
112
}
113
}
114
115
// class AuthenticationExtensionsContribution extends Disposable implements IWorkbenchContribution {
116
// static ID = 'workbench.contrib.authenticationExtensions';
117
118
// constructor(
119
// @IExtensionService private readonly _extensionService: IExtensionService,
120
// @IAuthenticationQueryService private readonly _authenticationQueryService: IAuthenticationQueryService,
121
// @IAuthenticationService private readonly _authenticationService: IAuthenticationService
122
// ) {
123
// super();
124
// void this.run();
125
// this._register(this._extensionService.onDidChangeExtensions(this._onDidChangeExtensions, this));
126
// this._register(
127
// Event.any(
128
// this._authenticationService.onDidChangeDeclaredProviders,
129
// this._authenticationService.onDidRegisterAuthenticationProvider
130
// )(() => this._cleanupRemovedExtensions())
131
// );
132
// }
133
134
// async run(): Promise<void> {
135
// await this._extensionService.whenInstalledExtensionsRegistered();
136
// this._cleanupRemovedExtensions();
137
// }
138
139
// private _onDidChangeExtensions(delta: { readonly added: readonly IExtensionDescription[]; readonly removed: readonly IExtensionDescription[] }): void {
140
// if (delta.removed.length > 0) {
141
// this._cleanupRemovedExtensions(delta.removed);
142
// }
143
// }
144
145
// private _cleanupRemovedExtensions(removedExtensions?: readonly IExtensionDescription[]): void {
146
// const extensionIdsToRemove = removedExtensions
147
// ? new Set(removedExtensions.map(e => e.identifier.value))
148
// : new Set(this._extensionService.extensions.map(e => e.identifier.value));
149
150
// // If we are cleaning up specific removed extensions, we only remove those.
151
// const isTargetedCleanup = !!removedExtensions;
152
153
// const providerIds = this._authenticationQueryService.getProviderIds();
154
// for (const providerId of providerIds) {
155
// this._authenticationQueryService.provider(providerId).forEachAccount(account => {
156
// account.extensions().forEach(extension => {
157
// const shouldRemove = isTargetedCleanup
158
// ? extensionIdsToRemove.has(extension.extensionId)
159
// : !extensionIdsToRemove.has(extension.extensionId);
160
161
// if (shouldRemove) {
162
// extension.removeUsage();
163
// extension.setAccessAllowed(false);
164
// }
165
// });
166
// });
167
// }
168
// }
169
// }
170
171
// class AuthenticationMcpContribution extends Disposable implements IWorkbenchContribution {
172
// static ID = 'workbench.contrib.authenticationMcp';
173
174
// constructor(
175
// @IMcpRegistry private readonly _mcpRegistry: IMcpRegistry,
176
// @IAuthenticationQueryService private readonly _authenticationQueryService: IAuthenticationQueryService,
177
// @IAuthenticationService private readonly _authenticationService: IAuthenticationService
178
// ) {
179
// super();
180
// this._cleanupRemovedMcpServers();
181
182
// // Listen for MCP collections changes using autorun with observables
183
// this._register(autorun(reader => {
184
// // Read the collections observable to register dependency
185
// this._mcpRegistry.collections.read(reader);
186
// // Schedule cleanup for next tick to avoid running during observable updates
187
// queueMicrotask(() => this._cleanupRemovedMcpServers());
188
// }));
189
// this._register(
190
// Event.any(
191
// this._authenticationService.onDidChangeDeclaredProviders,
192
// this._authenticationService.onDidRegisterAuthenticationProvider
193
// )(() => this._cleanupRemovedMcpServers())
194
// );
195
// }
196
197
// private _cleanupRemovedMcpServers(): void {
198
// const currentServerIds = new Set(this._mcpRegistry.collections.get().flatMap(c => c.serverDefinitions.get()).map(s => s.id));
199
// const providerIds = this._authenticationQueryService.getProviderIds();
200
// for (const providerId of providerIds) {
201
// this._authenticationQueryService.provider(providerId).forEachAccount(account => {
202
// account.mcpServers().forEach(server => {
203
// if (!currentServerIds.has(server.mcpServerId)) {
204
// server.removeUsage();
205
// server.setAccessAllowed(false);
206
// }
207
// });
208
// });
209
// }
210
// }
211
// }
212
213
registerWorkbenchContribution2(AuthenticationContribution.ID, AuthenticationContribution, WorkbenchPhase.AfterRestored);
214
registerWorkbenchContribution2(AuthenticationUsageContribution.ID, AuthenticationUsageContribution, WorkbenchPhase.Eventually);
215
// registerWorkbenchContribution2(AuthenticationExtensionsContribution.ID, AuthenticationExtensionsContribution, WorkbenchPhase.Eventually);
216
// registerWorkbenchContribution2(AuthenticationMcpContribution.ID, AuthenticationMcpContribution, WorkbenchPhase.Eventually);
217
218