Skip to content

Commit 24e1612

Browse files
fix
Signed-off-by: Roman Nikitenko <rnikiten@redhat.com>
1 parent 6f20ec3 commit 24e1612

3 files changed

Lines changed: 30 additions & 8 deletions

File tree

code/extensions/che-github-authentication/src/extension.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,30 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
4747
const deviceAuthentication = container.get(DeviceAuthentication);
4848
authenticationProvider.setDeviceAuthentication(deviceAuthentication);
4949

50-
await authenticationProvider.hydrateFromK8sToken();
50+
const { hydratedFromPat } = await authenticationProvider.hydrateFromK8sToken();
5151

5252
vscode.authentication.registerAuthenticationProvider('github', 'GitHub', authenticationProvider);
53+
54+
if (hydratedFromPat && vscode.extensions.getExtension('github.copilot')) {
55+
promptCopilotSignIn(authenticationProvider);
56+
}
57+
}
58+
59+
const COPILOT_SCOPES = ['read:user', 'user:email', 'repo', 'workflow'];
60+
61+
async function promptCopilotSignIn(provider: GitHubAuthProvider): Promise<void> {
62+
const signIn = 'Sign in';
63+
const action = await vscode.window.showInformationMessage(
64+
'GitHub Copilot requires OAuth sign-in to function. Your current token (PAT) cannot be used for Copilot.',
65+
signIn,
66+
);
67+
if (action === signIn) {
68+
try {
69+
await provider.createSession(COPILOT_SCOPES);
70+
} catch {
71+
// User cancelled Device Flow or it failed — already logged by createSession
72+
}
73+
}
5374
}
5475

5576
export function deactivate(): void {

code/extensions/che-github-authentication/src/github.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
6060
this.deviceAuthentication = deviceAuthentication;
6161
}
6262

63-
async hydrateFromK8sToken(): Promise<void> {
63+
async hydrateFromK8sToken(): Promise<{ hydratedFromPat: boolean }> {
6464
this.logger.info('GitHubAuthProvider: hydrateFromK8sToken started');
6565
let sessions = await this.sessionsPromise;
6666
this.logger.info(`GitHubAuthProvider: found ${sessions.length} stored session(s)`);
@@ -69,7 +69,7 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
6969
try {
7070
await this.githubService.getTokenScopes(sessions[0].accessToken);
7171
this.logger.info('GitHubAuthProvider: existing session token is valid, hydration not needed');
72-
return;
72+
return { hydratedFromPat: false };
7373
} catch (error) {
7474
if (isUnauthorizedError(error)) {
7575
this.logger.warn('GitHubAuthProvider: existing session token is not valid, clearing sessions');
@@ -79,7 +79,7 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
7979
sessions = [];
8080
} else {
8181
this.logger.info(`GitHubAuthProvider: session validation skipped: ${(error as Error).message}`);
82-
return;
82+
return { hydratedFromPat: false };
8383
}
8484
}
8585
}
@@ -92,7 +92,7 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
9292
this.hydrationAttempted = true;
9393
if (tokenScopes.length === 0) {
9494
this.logger.info('GitHubAuthProvider: hydrate skipped, token has no scopes');
95-
return;
95+
return { hydratedFromPat: false };
9696
}
9797

9898
const githubUser = await this.githubService.getUser();
@@ -101,7 +101,7 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
101101
this.logger.info(`GitHubAuthProvider: matching hydration bundles: ${matchingBundles.length}`);
102102
if (matchingBundles.length === 0) {
103103
this.logger.info('GitHubAuthProvider: hydrate skipped, token scopes match no known bundle');
104-
return;
104+
return { hydratedFromPat: false };
105105
}
106106

107107
const account = { label: githubUser.login, id: githubUser.id.toString() };
@@ -115,13 +115,15 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
115115
await this.storeSessions(hydratedSessions);
116116
this.sessionChangeEmitter.fire({ added: hydratedSessions, removed: [], changed: [] });
117117
this.logger.info(`GitHubAuthProvider: hydrated ${hydratedSessions.length} session(s) from K8s token`);
118+
return { hydratedFromPat: true };
118119
} catch (error) {
119120
if (isUnauthorizedError(error)) {
120121
this.hydrationAttempted = true;
121122
this.logger.warn('GitHubAuthProvider: hydrate failed, token is not valid');
122123
} else {
123124
this.logger.warn(`GitHubAuthProvider: hydrate failed with transient error (will retry on next getSessions): ${(error as Error).message}`);
124125
}
126+
return { hydratedFromPat: false };
125127
}
126128
}
127129

@@ -138,7 +140,7 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
138140

139141
if (filteredSessions.length === 0 && sortedScopes.length > 0 && !this.hydrationAttempted) {
140142
this.logger.info('GitHubAuthProvider: no sessions found, attempting lazy hydration');
141-
await this.hydrateFromK8sToken();
143+
await this.hydrateFromK8sToken(); // return value intentionally ignored for lazy hydration
142144
const retried = await this.sessionsPromise;
143145
const retriedFiltered = retried.filter(session => arrayEquals([...session.scopes].sort(), sortedScopes));
144146
this.logger.info(`GitHubAuthProvider: GET sessions (after lazy hydration) - found ${retriedFiltered.length} sessions for scopes: ${JSON.stringify(sessionScopes)}`);

code/extensions/che-github-authentication/src/utils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export function hasAllScopes(existingScopes: string[], requestedScopes: string[]
3838
return requestedScopes.every(scope => existingScopes.includes(scope));
3939
}
4040

41-
/** Scope bundles used by Copilot / github / GHPRI / Agent Host — session keys match vanilla createSession. */
4241
export const HYDRATION_SCOPE_BUNDLES: readonly string[][] = [
4342
['read:user', 'user:email', 'repo', 'workflow', 'project', 'read:org'],
4443
['read:user', 'user:email', 'repo', 'workflow'],

0 commit comments

Comments
 (0)