Skip to content

Commit 0fd21e4

Browse files
authored
Make the --github-auth flag work for extensions (#48)
1 parent 676edaa commit 0fd21e4

File tree

2 files changed

+71
-2
lines changed

2 files changed

+71
-2
lines changed

src/vs/code/browser/workbench/workbench.ts

+65-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { parseLogLevel } from 'vs/platform/log/common/log';
1818
import product from 'vs/platform/product/common/product';
1919
import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/windows';
2020
import { create, ICredentialsProvider, IHomeIndicator, IProductQualityChangeHandler, ISettingsSyncOptions, IURLCallbackProvider, IWelcomeBanner, IWindowIndicator, IWorkbenchConstructionOptions, IWorkspace, IWorkspaceProvider } from 'vs/workbench/workbench.web.api';
21+
import { equals as arrayEquals } from 'vs/base/common/arrays';
2122

2223
function doCreateUri(path: string, queryValues: Map<string, string>): URI {
2324
let query: string | undefined = undefined;
@@ -49,6 +50,14 @@ interface ICredential {
4950
password: string;
5051
}
5152

53+
/** @author coder */
54+
interface IToken {
55+
accessToken: string
56+
account?: { label: string }
57+
id: string
58+
scopes: string[]
59+
}
60+
5261
class LocalStorageCredentialsProvider implements ICredentialsProvider {
5362

5463
static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider';
@@ -76,6 +85,61 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider {
7685
scopes,
7786
accessToken: authSessionInfo!.accessToken
7887
}))));
88+
89+
/**
90+
* Add tokens for extensions to use. This works for extensions like the
91+
* pull requests one or GitLens.
92+
* @author coder
93+
*/
94+
const extensionId = `vscode.${authSessionInfo.providerId}-authentication`;
95+
const service = `${product.urlProtocol}${extensionId}`;
96+
const account = `${authSessionInfo.providerId}.auth`;
97+
// Oddly the scopes need to match exactly so we cannot just have one token
98+
// with all the scopes, instead we have to duplicate the token for each
99+
// expected set of scopes.
100+
const tokens: IToken[] = authSessionInfo.scopes.map((scopes) => ({
101+
id: authSessionInfo!.id,
102+
scopes: scopes.sort(), // Sort for comparing later.
103+
accessToken: authSessionInfo!.accessToken,
104+
}));
105+
this.getPassword(service, account).then((raw) => {
106+
let existing: {
107+
content: IToken[]
108+
} | undefined;
109+
110+
if (raw) {
111+
try {
112+
const json = JSON.parse(raw);
113+
json.content = JSON.parse(json.content);
114+
existing = json;
115+
} catch (error) {
116+
console.log(error);
117+
}
118+
}
119+
120+
// Keep tokens for account and scope combinations we do not have in case
121+
// there is an extension that uses scopes we have not accounted for (in
122+
// these cases the user will need to manually authenticate the extension
123+
// through the UI) or the user has tokens for other accounts.
124+
if (existing?.content) {
125+
existing.content = existing.content.filter((existingToken) => {
126+
const scopes = existingToken.scopes.sort();
127+
return !(tokens.find((token) => {
128+
return arrayEquals(scopes, token.scopes)
129+
&& token.account?.label === existingToken.account?.label;
130+
}))
131+
})
132+
}
133+
134+
return this.setPassword(service, account, JSON.stringify({
135+
extensionId,
136+
...(existing || {}),
137+
content: JSON.stringify([
138+
...tokens,
139+
...(existing?.content || []),
140+
])
141+
}));
142+
})
79143
}
80144
}
81145

@@ -446,7 +510,7 @@ class WindowIndicator implements IWindowIndicator {
446510
/**
447511
* If the value begins with a slash assume it is a file path and convert it to
448512
* use the vscode-remote scheme.
449-
*
513+
*
450514
* We also add the remote authority in toRemote. It needs to be accurate
451515
* otherwise other URIs won't match it, leading to issues such as this one:
452516
* https://github.com/coder/code-server/issues/4630

src/vs/server/webClientServer.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,12 @@ export class WebClientServer {
295295
id: generateUuid(),
296296
providerId: 'github',
297297
accessToken: this._environmentService.args['github-auth'],
298-
scopes: [['user:email'], ['repo']]
298+
/**
299+
* Add a set of scopes for the pull request extension which also wants
300+
* read:user.
301+
* @author coder
302+
*/
303+
scopes: [['read:user', 'user:email', 'repo'], ['user:email'], ['repo']]
299304
} : undefined;
300305

301306
const locale = this._environmentService.args.locale || await getLocaleFromConfig(this._environmentService.argvResource);

0 commit comments

Comments
 (0)