Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
85119afc
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,发现更多精彩内容 >>
提交
85119afc
编写于
3月 30, 2020
作者:
R
Rachel Macfarlane
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Issue distinct sessions per extension, remove session when extension is removed from trusted list
上级
fe48834d
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
97 addition
and
18 deletion
+97
-18
extensions/github-authentication/src/github.ts
extensions/github-authentication/src/github.ts
+2
-1
extensions/vscode-account/package.json
extensions/vscode-account/package.json
+3
-1
extensions/vscode-account/src/AADHelper.ts
extensions/vscode-account/src/AADHelper.ts
+2
-1
extensions/vscode-account/yarn.lock
extensions/vscode-account/yarn.lock
+10
-0
src/vs/workbench/api/browser/mainThreadAuthentication.ts
src/vs/workbench/api/browser/mainThreadAuthentication.ts
+30
-6
src/vs/workbench/api/common/extHost.api.impl.ts
src/vs/workbench/api/common/extHost.api.impl.ts
+1
-1
src/vs/workbench/api/common/extHost.protocol.ts
src/vs/workbench/api/common/extHost.protocol.ts
+1
-1
src/vs/workbench/api/common/extHostAuthentication.ts
src/vs/workbench/api/common/extHostAuthentication.ts
+48
-7
未找到文件。
extensions/github-authentication/src/github.ts
浏览文件 @
85119afc
...
...
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import
*
as
vscode
from
'
vscode
'
;
import
*
as
uuid
from
'
uuid
'
;
import
{
keychain
}
from
'
./common/keychain
'
;
import
{
GitHubServer
}
from
'
./githubServer
'
;
import
Logger
from
'
./common/logger
'
;
...
...
@@ -122,7 +123,7 @@ export class GitHubAuthenticationProvider {
private
async
tokenToSession
(
token
:
string
,
scopes
:
string
[]):
Promise
<
vscode
.
AuthenticationSession
>
{
const
userInfo
=
await
this
.
_githubServer
.
getUserInfo
(
token
);
return
{
id
:
u
serInfo
.
id
,
id
:
u
uid
()
,
getAccessToken
:
()
=>
Promise
.
resolve
(
token
),
accountName
:
userInfo
.
accountName
,
scopes
:
scopes
...
...
extensions/vscode-account/package.json
浏览文件 @
85119afc
...
...
@@ -38,9 +38,11 @@
"typescript"
:
"^3.7.4"
,
"tslint"
:
"^5.12.1"
,
"@types/node"
:
"^10.12.21"
,
"@types/keytar"
:
"^4.0.1"
"@types/keytar"
:
"^4.0.1"
,
"@types/uuid"
:
"^3.4.6"
},
"dependencies"
:
{
"uuid"
:
"^3.3.3"
,
"vscode-nls"
:
"^4.1.1"
}
}
extensions/vscode-account/src/AADHelper.ts
浏览文件 @
85119afc
...
...
@@ -7,6 +7,7 @@ import * as crypto from 'crypto';
import
*
as
https
from
'
https
'
;
import
*
as
querystring
from
'
querystring
'
;
import
*
as
vscode
from
'
vscode
'
;
import
*
as
uuid
from
'
uuid
'
;
import
{
createServer
,
startServer
}
from
'
./authServer
'
;
import
{
keychain
}
from
'
./keychain
'
;
import
Logger
from
'
./logger
'
;
...
...
@@ -407,7 +408,7 @@ export class AzureActiveDirectoryService {
accessToken
:
json
.
access_token
,
refreshToken
:
json
.
refresh_token
,
scope
,
sessionId
:
`
${
claims
.
tid
}
/
${(
claims
.
oid
||
(
claims
.
altsecid
||
''
+
claims
.
ipd
||
''
))}
/
${
scope
}
`
,
sessionId
:
`
${
claims
.
tid
}
/
${(
claims
.
oid
||
(
claims
.
altsecid
||
''
+
claims
.
ipd
||
''
))}
/
${
uuid
()
}
`
,
accountName
:
claims
.
email
||
claims
.
unique_name
||
'
user@example.com
'
};
}
...
...
extensions/vscode-account/yarn.lock
浏览文件 @
85119afc
...
...
@@ -30,6 +30,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.13.tgz#ccebcdb990bd6139cd16e84c39dc2fb1023ca90c"
integrity sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==
"@types/uuid@^3.4.6":
version "3.4.8"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.8.tgz#4ba887fcef88bd9a7515ca2de336d691e3e18318"
integrity sha512-zHWce3allXWSmRx6/AGXKCtSOA7JjeWd2L3t4aHfysNk8mouQnWCocveaT7a4IEIlPVHp81jzlnknqTgCjCLXA==
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
...
...
@@ -635,6 +640,11 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
uuid@^3.3.3:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
vscode-nls@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c"
...
...
src/vs/workbench/api/browser/mainThreadAuthentication.ts
浏览文件 @
85119afc
...
...
@@ -35,6 +35,7 @@ const BUILT_IN_AUTH_DEPENDENTS: AuthDependent[] = [
interface
AllowedExtension
{
id
:
string
;
name
:
string
;
sessionIds
?:
string
[];
}
function
readAllowedExtensions
(
storageService
:
IStorageService
,
providerId
:
string
,
accountName
:
string
):
AllowedExtension
[]
{
...
...
@@ -85,6 +86,16 @@ export class MainThreadAuthenticationProvider extends Disposable {
quickPick
.
onDidAccept
(()
=>
{
const
updatedAllowedList
=
quickPick
.
selectedItems
.
map
(
item
=>
item
.
extension
);
storageService
.
store
(
`
${
this
.
id
}
-
${
accountName
}
`
,
JSON
.
stringify
(
updatedAllowedList
),
StorageScope
.
GLOBAL
);
// Remove sessions of untrusted extensions
const
deselectedItems
=
items
.
filter
(
item
=>
!
quickPick
.
selectedItems
.
includes
(
item
));
deselectedItems
.
forEach
(
item
=>
{
const
extensionData
=
allowedExtensions
.
find
(
extension
=>
item
.
extension
.
id
===
extension
.
id
);
extensionData
?.
sessionIds
?.
forEach
(
sessionId
=>
{
this
.
logout
(
sessionId
);
});
});
quickPick
.
dispose
();
});
...
...
@@ -275,9 +286,19 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
this
.
authenticationService
.
sessionsUpdate
(
id
,
event
);
}
async
$getSessionsPrompt
(
providerId
:
string
,
accountName
:
string
,
providerName
:
string
,
extensionId
:
string
,
extensionName
:
string
):
Promise
<
boolean
>
{
let
allowList
=
readAllowedExtensions
(
this
.
storageService
,
providerId
,
accountName
);
if
(
allowList
.
some
(
extension
=>
extension
.
id
===
extensionId
))
{
async
$getSessionsPrompt
(
providerId
:
string
,
accountName
:
string
,
sessionId
:
string
,
providerName
:
string
,
extensionId
:
string
,
extensionName
:
string
):
Promise
<
boolean
>
{
const
allowList
=
readAllowedExtensions
(
this
.
storageService
,
providerId
,
accountName
);
const
extensionData
=
allowList
.
find
(
extension
=>
extension
.
id
===
extensionId
);
if
(
extensionData
)
{
if
(
!
extensionData
.
sessionIds
)
{
extensionData
.
sessionIds
=
[];
}
if
(
!
extensionData
.
sessionIds
.
find
(
id
=>
id
===
sessionId
))
{
extensionData
.
sessionIds
.
push
(
sessionId
);
this
.
storageService
.
store
(
`
${
providerId
}
-
${
accountName
}
`
,
JSON
.
stringify
(
allowList
),
StorageScope
.
GLOBAL
);
}
return
true
;
}
...
...
@@ -292,7 +313,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
const
allow
=
choice
===
1
;
if
(
allow
)
{
allowList
=
allowList
.
concat
({
id
:
extensionId
,
name
:
extensionName
});
allowList
.
push
({
id
:
extensionId
,
name
:
extensionName
,
sessionIds
:
[
sessionId
]
});
this
.
storageService
.
store
(
`
${
providerId
}
-
${
accountName
}
`
,
JSON
.
stringify
(
allowList
),
StorageScope
.
GLOBAL
);
}
...
...
@@ -313,7 +334,10 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
}
async
$setTrustedExtension
(
providerId
:
string
,
accountName
:
string
,
extensionId
:
string
,
extensionName
:
string
):
Promise
<
void
>
{
const
allowList
=
readAllowedExtensions
(
this
.
storageService
,
providerId
,
accountName
).
concat
({
id
:
extensionId
,
name
:
extensionName
});
const
allowList
=
readAllowedExtensions
(
this
.
storageService
,
providerId
,
accountName
);
if
(
!
allowList
.
find
(
allowed
=>
allowed
.
id
===
extensionId
))
{
allowList
.
push
({
id
:
extensionId
,
name
:
extensionName
,
sessionIds
:
[]
});
this
.
storageService
.
store
(
`
${
providerId
}
-
${
accountName
}
`
,
JSON
.
stringify
(
allowList
),
StorageScope
.
GLOBAL
);
}
}
}
src/vs/workbench/api/common/extHost.api.impl.ts
浏览文件 @
85119afc
...
...
@@ -133,7 +133,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const
extHostLabelService
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHosLabelService
,
new
ExtHostLabelService
(
rpcProtocol
));
const
extHostNotebook
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostNotebook
,
new
ExtHostNotebookController
(
rpcProtocol
,
extHostCommands
,
extHostDocumentsAndEditors
));
const
extHostTheming
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostTheming
,
new
ExtHostTheming
(
rpcProtocol
));
const
extHostAuthentication
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostAuthentication
,
new
ExtHostAuthentication
(
rpcProtocol
));
const
extHostAuthentication
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostAuthentication
,
new
ExtHostAuthentication
(
rpcProtocol
,
extHostStorage
));
const
extHostTimeline
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostTimeline
,
new
ExtHostTimeline
(
rpcProtocol
,
extHostCommands
));
const
extHostWebviews
=
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostWebviews
,
new
ExtHostWebviews
(
rpcProtocol
,
initData
.
environment
,
extHostWorkspace
,
extHostLogService
,
extHostApiDeprecation
,
extHostDocuments
));
...
...
src/vs/workbench/api/common/extHost.protocol.ts
浏览文件 @
85119afc
...
...
@@ -158,7 +158,7 @@ export interface MainThreadAuthenticationShape extends IDisposable {
$registerAuthenticationProvider
(
id
:
string
,
displayName
:
string
):
void
;
$unregisterAuthenticationProvider
(
id
:
string
):
void
;
$onDidChangeSessions
(
providerId
:
string
,
event
:
modes
.
AuthenticationSessionsChangeEvent
):
void
;
$getSessionsPrompt
(
providerId
:
string
,
accountName
:
string
,
providerName
:
string
,
extensionId
:
string
,
extensionName
:
string
):
Promise
<
boolean
>
;
$getSessionsPrompt
(
providerId
:
string
,
accountName
:
string
,
sessionId
:
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
浏览文件 @
85119afc
...
...
@@ -9,6 +9,7 @@ import { Emitter, Event } from 'vs/base/common/event';
import
{
IMainContext
,
MainContext
,
MainThreadAuthenticationShape
,
ExtHostAuthenticationShape
}
from
'
vs/workbench/api/common/extHost.protocol
'
;
import
{
Disposable
}
from
'
vs/workbench/api/common/extHostTypes
'
;
import
{
IExtensionDescription
,
ExtensionIdentifier
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
IExtHostStorage
}
from
'
vs/workbench/api/common/extHostStorage
'
;
export
class
ExtHostAuthentication
implements
ExtHostAuthenticationShape
{
private
_proxy
:
MainThreadAuthenticationShape
;
...
...
@@ -20,7 +21,8 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
private
_onDidChangeSessions
=
new
Emitter
<
{
[
providerId
:
string
]:
vscode
.
AuthenticationSessionsChangeEvent
}
>
();
readonly
onDidChangeSessions
:
Event
<
{
[
providerId
:
string
]:
vscode
.
AuthenticationSessionsChangeEvent
}
>
=
this
.
_onDidChangeSessions
.
event
;
constructor
(
mainContext
:
IMainContext
)
{
constructor
(
mainContext
:
IMainContext
,
@
IExtHostStorage
private
readonly
storageService
:
IExtHostStorage
)
{
this
.
_proxy
=
mainContext
.
getProxy
(
MainContext
.
MainThreadAuthentication
);
}
...
...
@@ -33,15 +35,34 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
return
ids
;
}
private
async
hasNotBeenReadByOtherExtension
(
providerId
:
string
,
session
:
vscode
.
AuthenticationSession
,
extensionId
:
string
):
Promise
<
boolean
>
{
const
readerId
=
await
this
.
storageService
.
getValue
(
true
,
`
${
providerId
}
-
${
session
.
accountName
}
-
${
session
.
id
}
`
);
if
(
!
readerId
)
{
await
this
.
storageService
.
setValue
(
true
,
`
${
providerId
}
-
${
session
.
accountName
}
-
${
session
.
id
}
`
,
extensionId
as
any
);
return
true
;
}
return
readerId
===
extensionId
;
}
private
async
isMatchingSession
(
session
:
vscode
.
AuthenticationSession
,
scopes
:
string
,
providerId
:
string
,
extensionId
:
string
):
Promise
<
boolean
>
{
return
session
.
scopes
.
sort
().
join
(
'
'
)
===
scopes
&&
(
await
this
.
hasNotBeenReadByOtherExtension
(
providerId
,
session
,
extensionId
));
}
async
getSessions
(
requestingExtension
:
IExtensionDescription
,
providerId
:
string
,
scopes
:
string
[]):
Promise
<
readonly
vscode
.
AuthenticationSession
[]
>
{
const
provider
=
this
.
_authenticationProviders
.
get
(
providerId
);
if
(
!
provider
)
{
throw
new
Error
(
`No authentication provider with id '
${
providerId
}
' is currently registered.`
);
}
const
extensionId
=
ExtensionIdentifier
.
toKey
(
requestingExtension
.
identifier
);
const
orderedScopes
=
scopes
.
sort
().
join
(
'
'
);
return
(
await
provider
.
getSessions
())
.
filter
(
session
=>
session
.
scopes
.
sort
().
join
(
'
'
)
===
orderedScopes
)
const
sessions
=
await
provider
.
getSessions
();
const
filteredSessions
=
await
Promise
.
all
(
sessions
.
map
(
session
=>
this
.
isMatchingSession
(
session
,
orderedScopes
,
providerId
,
extensionId
)));
return
sessions
.
filter
((
_
,
i
)
=>
{
return
filteredSessions
[
i
];
})
.
map
(
session
=>
{
return
{
id
:
session
.
id
,
...
...
@@ -51,8 +72,9 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
const
isAllowed
=
await
this
.
_proxy
.
$getSessionsPrompt
(
provider
.
id
,
session
.
accountName
,
session
.
id
,
provider
.
displayName
,
ExtensionIdentifier
.
toKey
(
requestingExtension
.
identifier
)
,
extensionId
,
requestingExtension
.
displayName
||
requestingExtension
.
name
);
if
(
!
isAllowed
)
{
...
...
@@ -77,9 +99,28 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
throw
new
Error
(
'
User did not consent to login.
'
);
}
const
newSession
=
await
provider
.
login
(
scopes
);
await
this
.
_proxy
.
$setTrustedExtension
(
provider
.
id
,
newSession
.
accountName
,
ExtensionIdentifier
.
toKey
(
requestingExtension
.
identifier
),
extensionName
);
return
newSession
;
const
session
=
await
provider
.
login
(
scopes
);
await
this
.
_proxy
.
$setTrustedExtension
(
provider
.
id
,
session
.
accountName
,
ExtensionIdentifier
.
toKey
(
requestingExtension
.
identifier
),
extensionName
);
return
{
id
:
session
.
id
,
accountName
:
session
.
accountName
,
scopes
:
session
.
scopes
,
getAccessToken
:
async
()
=>
{
const
isAllowed
=
await
this
.
_proxy
.
$getSessionsPrompt
(
provider
.
id
,
session
.
accountName
,
session
.
id
,
provider
.
displayName
,
ExtensionIdentifier
.
toKey
(
requestingExtension
.
identifier
),
requestingExtension
.
displayName
||
requestingExtension
.
name
);
if
(
!
isAllowed
)
{
throw
new
Error
(
'
User did not consent to token access.
'
);
}
return
session
.
getAccessToken
();
}
};
}
registerAuthenticationProvider
(
provider
:
vscode
.
AuthenticationProvider
):
vscode
.
Disposable
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录