Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
4a875e0d
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4a875e0d
编写于
5月 11, 2020
作者:
R
Rachel Macfarlane
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add getSession and hasSessions to authentication namespace
上级
4da345ea
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
149 addition
and
1 deletion
+149
-1
src/vs/vscode.proposed.d.ts
src/vs/vscode.proposed.d.ts
+34
-0
src/vs/workbench/api/browser/mainThreadAuthentication.ts
src/vs/workbench/api/browser/mainThreadAuthentication.ts
+68
-1
src/vs/workbench/api/common/extHost.api.impl.ts
src/vs/workbench/api/common/extHost.api.impl.ts
+6
-0
src/vs/workbench/api/common/extHost.protocol.ts
src/vs/workbench/api/common/extHost.protocol.ts
+1
-0
src/vs/workbench/api/common/extHostAuthentication.ts
src/vs/workbench/api/common/extHostAuthentication.ts
+40
-0
未找到文件。
src/vs/vscode.proposed.d.ts
浏览文件 @
4a875e0d
...
...
@@ -108,6 +108,40 @@ declare module 'vscode' {
*/
export
const
providerIds
:
string
[];
/**
* Returns whether a provider has any sessions matching the requested scopes. This request
* is transparent to the user, not UI is shown. Rejects if a provider with providerId is not
* registered.
* @param providerId The id of the provider
* @param scopes A list of scopes representing the permissions requested. These are dependent on the authentication
* provider
*/
export
function
hasSessions
(
providerId
:
string
,
scopes
:
string
[]):
Thenable
<
boolean
>
;
export
interface
GetSessionOptions
{
/**
* Whether login should be performed if there is no matching session. Defaults to false.
*/
createIfNone
?:
boolean
;
/**
* Whether the existing user session preference should be cleared. Set to allow the user to switch accounts.
* Defaults to false.
*/
clearSessionPreference
?:
boolean
;
}
/**
* Get an authentication session matching the desired scopes. Rejects if a provider with providerId is not
* registered, or if the user does not consent to sharing authentication information with
* the extension. If there are multiple sessions with the same scopes, the user will be shown a
* quickpick to select which account they would like to use.
* @param providerId The id of the provider to use
* @param scopes A list of scopes representing the permissions requested. These are dependent on the authentication provider
* @param options The [getSessionOptions](#GetSessionOptions) to use
*/
export
function
getSession
(
providerId
:
string
,
scopes
:
string
[],
options
:
GetSessionOptions
):
Thenable
<
AuthenticationSession
|
undefined
>
;
/**
* Get existing authentication sessions. Rejects if a provider with providerId is not
* registered, or if the user does not consent to sharing authentication information with
...
...
src/vs/workbench/api/browser/mainThreadAuthentication.ts
浏览文件 @
4a875e0d
...
...
@@ -294,7 +294,8 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
@
IStorageService
private
readonly
storageService
:
IStorageService
,
@
INotificationService
private
readonly
notificationService
:
INotificationService
,
@
IStorageKeysSyncRegistryService
private
readonly
storageKeysSyncRegistryService
:
IStorageKeysSyncRegistryService
,
@
IRemoteAgentService
private
readonly
remoteAgentService
:
IRemoteAgentService
@
IRemoteAgentService
private
readonly
remoteAgentService
:
IRemoteAgentService
,
@
IQuickInputService
private
readonly
quickInputService
:
IQuickInputService
)
{
super
();
this
.
_proxy
=
extHostContext
.
getProxy
(
ExtHostContext
.
ExtHostAuthentication
);
...
...
@@ -314,6 +315,72 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
this
.
authenticationService
.
sessionsUpdate
(
id
,
event
);
}
async
$getSession
(
providerId
:
string
,
providerName
:
string
,
extensionId
:
string
,
extensionName
:
string
,
potentialSessions
:
modes
.
AuthenticationSession
[],
scopes
:
string
[],
clearSessionPreference
:
boolean
):
Promise
<
modes
.
AuthenticationSession
>
{
if
(
!
potentialSessions
.
length
)
{
throw
new
Error
(
'
No potential sessions found
'
);
}
if
(
clearSessionPreference
)
{
this
.
storageService
.
remove
(
`
${
extensionName
}
-
${
providerId
}
`
,
StorageScope
.
GLOBAL
);
}
else
{
const
existingSessionPreference
=
this
.
storageService
.
get
(
`
${
extensionName
}
-
${
providerId
}
`
,
StorageScope
.
GLOBAL
);
if
(
existingSessionPreference
)
{
const
matchingSession
=
potentialSessions
.
find
(
session
=>
session
.
id
===
existingSessionPreference
);
if
(
matchingSession
)
{
const
allowed
=
await
this
.
$getSessionsPrompt
(
providerId
,
matchingSession
.
account
.
displayName
,
providerName
,
extensionId
,
extensionName
);
if
(
allowed
)
{
return
matchingSession
;
}
}
}
}
return
new
Promise
((
resolve
,
reject
)
=>
{
const
quickPick
=
this
.
quickInputService
.
createQuickPick
<
{
label
:
string
,
session
?:
modes
.
AuthenticationSession
}
>
();
quickPick
.
ignoreFocusOut
=
true
;
const
items
:
{
label
:
string
,
session
?:
modes
.
AuthenticationSession
}[]
=
potentialSessions
.
map
(
session
=>
{
return
{
label
:
session
.
account
.
displayName
,
session
};
});
items
.
push
({
label
:
nls
.
localize
(
'
useOtherAccount
'
,
"
Sign in to another account
"
)
});
quickPick
.
items
=
items
;
quickPick
.
title
=
nls
.
localize
(
'
selectAccount
'
,
"
The extension '{0}' wants to access a {1} account
"
,
extensionName
,
providerName
);
quickPick
.
placeholder
=
nls
.
localize
(
'
getSessionPlateholder
'
,
"
Select an account for '{0}' to use or Esc to cancel
"
,
extensionName
);
quickPick
.
onDidAccept
(
async
_
=>
{
const
selected
=
quickPick
.
selectedItems
[
0
];
const
session
=
selected
.
session
??
await
this
.
authenticationService
.
login
(
providerId
,
scopes
);
const
accountName
=
session
.
account
.
displayName
;
const
allowList
=
readAllowedExtensions
(
this
.
storageService
,
providerId
,
accountName
);
allowList
.
push
({
id
:
extensionId
,
name
:
extensionName
});
this
.
storageService
.
store
(
`
${
providerId
}
-
${
accountName
}
`
,
JSON
.
stringify
(
allowList
),
StorageScope
.
GLOBAL
);
this
.
storageService
.
store
(
`
${
extensionName
}
-
${
providerId
}
`
,
session
.
id
,
StorageScope
.
GLOBAL
);
quickPick
.
dispose
();
resolve
(
session
);
});
quickPick
.
onDidHide
(
_
=>
{
if
(
!
quickPick
.
selectedItems
[
0
])
{
reject
(
'
User did not consent to account access
'
);
}
quickPick
.
dispose
();
});
quickPick
.
show
();
});
}
async
$getSessionsPrompt
(
providerId
:
string
,
accountName
:
string
,
providerName
:
string
,
extensionId
:
string
,
extensionName
:
string
):
Promise
<
boolean
>
{
addAccountUsage
(
providerId
,
accountName
,
extensionName
);
...
...
src/vs/workbench/api/common/extHost.api.impl.ts
浏览文件 @
4a875e0d
...
...
@@ -196,6 +196,12 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
get
providerIds
():
string
[]
{
return
extHostAuthentication
.
providerIds
;
},
hasSessions
(
providerId
:
string
,
scopes
:
string
[]):
Thenable
<
boolean
>
{
return
extHostAuthentication
.
hasSessions
(
providerId
,
scopes
);
},
getSession
(
providerId
:
string
,
scopes
:
string
[],
options
:
vscode
.
authentication
.
GetSessionOptions
):
Thenable
<
vscode
.
AuthenticationSession
|
undefined
>
{
return
extHostAuthentication
.
getSession
(
extension
,
providerId
,
scopes
,
options
);
},
getSessions
(
providerId
:
string
,
scopes
:
string
[]):
Thenable
<
readonly
vscode
.
AuthenticationSession
[]
>
{
return
extHostAuthentication
.
getSessions
(
extension
,
providerId
,
scopes
);
},
...
...
src/vs/workbench/api/common/extHost.protocol.ts
浏览文件 @
4a875e0d
...
...
@@ -160,6 +160,7 @@ export interface MainThreadAuthenticationShape extends IDisposable {
$registerAuthenticationProvider
(
id
:
string
,
displayName
:
string
):
void
;
$unregisterAuthenticationProvider
(
id
:
string
):
void
;
$onDidChangeSessions
(
providerId
:
string
,
event
:
modes
.
AuthenticationSessionsChangeEvent
):
void
;
$getSession
(
providerId
:
string
,
providerName
:
string
,
extensionId
:
string
,
extensionName
:
string
,
potentialSessions
:
modes
.
AuthenticationSession
[],
scopes
:
string
[],
clearSessionPreference
:
boolean
):
Promise
<
modes
.
AuthenticationSession
>
;
$getSessionsPrompt
(
providerId
:
string
,
accountName
:
string
,
providerName
:
string
,
extensionId
:
string
,
extensionName
:
string
):
Promise
<
boolean
>
;
$loginPrompt
(
providerName
:
string
,
extensionName
:
string
):
Promise
<
boolean
>
;
$setTrustedExtension
(
providerId
:
string
,
accountName
:
string
,
extensionId
:
string
,
extensionName
:
string
):
Promise
<
void
>
;
...
...
src/vs/workbench/api/common/extHostAuthentication.ts
浏览文件 @
4a875e0d
...
...
@@ -33,6 +33,46 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
return
ids
;
}
async
hasSessions
(
providerId
:
string
,
scopes
:
string
[]):
Promise
<
boolean
>
{
const
provider
=
this
.
_authenticationProviders
.
get
(
providerId
);
if
(
!
provider
)
{
throw
new
Error
(
`No authentication provider with id '
${
providerId
}
' is currently registered.`
);
}
const
orderedScopes
=
scopes
.
sort
().
join
(
'
'
);
return
!!
(
await
provider
.
getSessions
()).
filter
(
session
=>
session
.
scopes
.
sort
().
join
(
'
'
)
===
orderedScopes
).
length
;
}
async
getSession
(
requestingExtension
:
IExtensionDescription
,
providerId
:
string
,
scopes
:
string
[],
options
:
vscode
.
authentication
.
GetSessionOptions
):
Promise
<
vscode
.
AuthenticationSession
|
undefined
>
{
const
provider
=
this
.
_authenticationProviders
.
get
(
providerId
);
if
(
!
provider
)
{
throw
new
Error
(
`No authentication provider with id '
${
providerId
}
' is currently registered.`
);
}
const
orderedScopes
=
scopes
.
sort
().
join
(
'
'
);
const
sessions
=
(
await
provider
.
getSessions
()).
filter
(
session
=>
session
.
scopes
.
sort
().
join
(
'
'
)
===
orderedScopes
);
if
(
sessions
.
length
)
{
// On renderer side, confirm consent, ask user to choose between accounts if multiple sessions are valid
const
extensionName
=
requestingExtension
.
displayName
||
requestingExtension
.
name
;
const
selected
=
await
this
.
_proxy
.
$getSession
(
provider
.
id
,
provider
.
displayName
,
ExtensionIdentifier
.
toKey
(
requestingExtension
.
identifier
),
extensionName
,
sessions
,
scopes
,
!!
options
.
clearSessionPreference
);
return
sessions
.
find
(
session
=>
session
.
id
===
selected
.
id
);
}
else
{
if
(
options
.
createIfNone
)
{
const
extensionName
=
requestingExtension
.
displayName
||
requestingExtension
.
name
;
const
isAllowed
=
await
this
.
_proxy
.
$loginPrompt
(
provider
.
displayName
,
extensionName
);
if
(
!
isAllowed
)
{
throw
new
Error
(
'
User did not consent to login.
'
);
}
const
session
=
await
provider
.
login
(
scopes
);
await
this
.
_proxy
.
$setTrustedExtension
(
provider
.
id
,
session
.
account
.
displayName
,
ExtensionIdentifier
.
toKey
(
requestingExtension
.
identifier
),
extensionName
);
return
session
;
}
else
{
return
undefined
;
}
}
}
async
getSessions
(
requestingExtension
:
IExtensionDescription
,
providerId
:
string
,
scopes
:
string
[]):
Promise
<
readonly
vscode
.
AuthenticationSession
[]
>
{
const
provider
=
this
.
_authenticationProviders
.
get
(
providerId
);
if
(
!
provider
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录