Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
fcefed60
Unverified
Commit
fcefed60
authored
Mar 02, 2021
by
yann300
Committed by
GitHub
Mar 02, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #932 from ethereum/open-save-workspace
Forbids plugin to access root file system
parents
a744d8aa
ad9dd82d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
58 additions
and
36 deletions
+58
-36
app.js
apps/remix-ide/src/app.js
+1
-1
fileManager.js
apps/remix-ide/src/app/files/fileManager.js
+15
-14
fileProvider.js
apps/remix-ide/src/app/files/fileProvider.js
+3
-1
file-panel.js
apps/remix-ide/src/app/panels/file-panel.js
+23
-7
migrateFileSystem.js
apps/remix-ide/src/migrateFileSystem.js
+8
-7
remix-ui-workspace.tsx
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
+8
-6
No files found.
apps/remix-ide/src/app.js
View file @
fcefed60
...
@@ -485,7 +485,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
...
@@ -485,7 +485,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
// get the file list from the parent iframe
// get the file list from the parent iframe
loadFileFromParent
(
fileManager
)
loadFileFromParent
(
fileManager
)
migrateToWorkspace
(
fileManager
)
migrateToWorkspace
(
fileManager
,
filePanel
)
if
(
params
.
embed
)
framingService
.
embed
()
if
(
params
.
embed
)
framingService
.
embed
()
}
}
apps/remix-ide/src/app/files/fileManager.js
View file @
fcefed60
...
@@ -57,6 +57,10 @@ class FileManager extends Plugin {
...
@@ -57,6 +57,10 @@ class FileManager extends Plugin {
this
.
mode
=
mode
this
.
mode
=
mode
}
}
limitPluginScope
(
path
)
{
return
path
.
replace
(
/^
\/
browser
\/
/
,
''
).
replace
(
/^browser
\/
/
,
''
)
// forbids plugin to access the root filesystem
}
/**
/**
* Emit error if path doesn't exist
* Emit error if path doesn't exist
* @param {string} path path of the file/directory
* @param {string} path path of the file/directory
...
@@ -110,6 +114,7 @@ class FileManager extends Plugin {
...
@@ -110,6 +114,7 @@ class FileManager extends Plugin {
* @returns {boolean} true if the path exists
* @returns {boolean} true if the path exists
*/
*/
exists
(
path
)
{
exists
(
path
)
{
path
=
this
.
limitPluginScope
(
path
)
const
provider
=
this
.
fileProviderOf
(
path
)
const
provider
=
this
.
fileProviderOf
(
path
)
const
result
=
provider
.
exists
(
path
,
(
err
,
result
)
=>
{
const
result
=
provider
.
exists
(
path
,
(
err
,
result
)
=>
{
if
(
err
)
return
false
if
(
err
)
return
false
...
@@ -149,6 +154,7 @@ class FileManager extends Plugin {
...
@@ -149,6 +154,7 @@ class FileManager extends Plugin {
* @returns {void}
* @returns {void}
*/
*/
async
open
(
path
)
{
async
open
(
path
)
{
path
=
this
.
limitPluginScope
(
path
)
await
this
.
_handleExists
(
path
,
`Cannot open file
${
path
}
`
)
await
this
.
_handleExists
(
path
,
`Cannot open file
${
path
}
`
)
await
this
.
_handleIsFile
(
path
,
`Cannot open file
${
path
}
`
)
await
this
.
_handleIsFile
(
path
,
`Cannot open file
${
path
}
`
)
return
this
.
openFile
(
path
)
return
this
.
openFile
(
path
)
...
@@ -161,6 +167,7 @@ class FileManager extends Plugin {
...
@@ -161,6 +167,7 @@ class FileManager extends Plugin {
* @returns {void}
* @returns {void}
*/
*/
async
writeFile
(
path
,
data
)
{
async
writeFile
(
path
,
data
)
{
path
=
this
.
limitPluginScope
(
path
)
if
(
await
this
.
exists
(
path
))
{
if
(
await
this
.
exists
(
path
))
{
await
this
.
_handleIsFile
(
path
,
`Cannot write file
${
path
}
`
)
await
this
.
_handleIsFile
(
path
,
`Cannot write file
${
path
}
`
)
return
await
this
.
setFileContent
(
path
,
data
)
return
await
this
.
setFileContent
(
path
,
data
)
...
@@ -177,6 +184,7 @@ class FileManager extends Plugin {
...
@@ -177,6 +184,7 @@ class FileManager extends Plugin {
* @returns {string} content of the file
* @returns {string} content of the file
*/
*/
async
readFile
(
path
)
{
async
readFile
(
path
)
{
path
=
this
.
limitPluginScope
(
path
)
await
this
.
_handleExists
(
path
,
`Cannot read file
${
path
}
`
)
await
this
.
_handleExists
(
path
,
`Cannot read file
${
path
}
`
)
await
this
.
_handleIsFile
(
path
,
`Cannot read file
${
path
}
`
)
await
this
.
_handleIsFile
(
path
,
`Cannot read file
${
path
}
`
)
return
this
.
getFileContent
(
path
)
return
this
.
getFileContent
(
path
)
...
@@ -189,6 +197,8 @@ class FileManager extends Plugin {
...
@@ -189,6 +197,8 @@ class FileManager extends Plugin {
* @returns {void}
* @returns {void}
*/
*/
async
copyFile
(
src
,
dest
)
{
async
copyFile
(
src
,
dest
)
{
src
=
this
.
limitPluginScope
(
src
)
dest
=
this
.
limitPluginScope
(
dest
)
await
this
.
_handleExists
(
src
,
`Cannot copy from
${
src
}
`
)
await
this
.
_handleExists
(
src
,
`Cannot copy from
${
src
}
`
)
await
this
.
_handleIsFile
(
src
,
`Cannot copy from
${
src
}
`
)
await
this
.
_handleIsFile
(
src
,
`Cannot copy from
${
src
}
`
)
await
this
.
_handleIsFile
(
dest
,
`Cannot paste content into
${
dest
}
`
)
await
this
.
_handleIsFile
(
dest
,
`Cannot paste content into
${
dest
}
`
)
...
@@ -204,6 +214,8 @@ class FileManager extends Plugin {
...
@@ -204,6 +214,8 @@ class FileManager extends Plugin {
* @returns {void}
* @returns {void}
*/
*/
async
rename
(
oldPath
,
newPath
)
{
async
rename
(
oldPath
,
newPath
)
{
oldPath
=
this
.
limitPluginScope
(
oldPath
)
newPath
=
this
.
limitPluginScope
(
newPath
)
await
this
.
_handleExists
(
oldPath
,
`Cannot rename
${
oldPath
}
`
)
await
this
.
_handleExists
(
oldPath
,
`Cannot rename
${
oldPath
}
`
)
const
isFile
=
await
this
.
isFile
(
oldPath
)
const
isFile
=
await
this
.
isFile
(
oldPath
)
const
newPathExists
=
await
this
.
exists
(
newPath
)
const
newPathExists
=
await
this
.
exists
(
newPath
)
...
@@ -230,6 +242,7 @@ class FileManager extends Plugin {
...
@@ -230,6 +242,7 @@ class FileManager extends Plugin {
* @returns {void}
* @returns {void}
*/
*/
async
mkdir
(
path
)
{
async
mkdir
(
path
)
{
path
=
this
.
limitPluginScope
(
path
)
if
(
await
this
.
exists
(
path
))
{
if
(
await
this
.
exists
(
path
))
{
throw
createError
({
code
:
'EEXIST'
,
message
:
`Cannot create directory
${
path
}
`
})
throw
createError
({
code
:
'EEXIST'
,
message
:
`Cannot create directory
${
path
}
`
})
}
}
...
@@ -244,6 +257,7 @@ class FileManager extends Plugin {
...
@@ -244,6 +257,7 @@ class FileManager extends Plugin {
* @returns {string[]} list of the file/directory name in this directory
* @returns {string[]} list of the file/directory name in this directory
*/
*/
async
readdir
(
path
)
{
async
readdir
(
path
)
{
path
=
this
.
limitPluginScope
(
path
)
await
this
.
_handleExists
(
path
)
await
this
.
_handleExists
(
path
)
await
this
.
_handleIsDir
(
path
)
await
this
.
_handleIsDir
(
path
)
...
@@ -263,6 +277,7 @@ class FileManager extends Plugin {
...
@@ -263,6 +277,7 @@ class FileManager extends Plugin {
* @returns {void}
* @returns {void}
*/
*/
async
remove
(
path
)
{
async
remove
(
path
)
{
path
=
this
.
limitPluginScope
(
path
)
await
this
.
_handleExists
(
path
,
`Cannot remove file or directory
${
path
}
`
)
await
this
.
_handleExists
(
path
,
`Cannot remove file or directory
${
path
}
`
)
const
provider
=
this
.
fileProviderOf
(
path
)
const
provider
=
this
.
fileProviderOf
(
path
)
...
@@ -585,20 +600,6 @@ class FileManager extends Plugin {
...
@@ -585,20 +600,6 @@ class FileManager extends Plugin {
if
(
callback
)
callback
(
error
)
if
(
callback
)
callback
(
error
)
})
})
}
}
async
createWorkspace
(
name
)
{
const
workspaceProvider
=
this
.
_deps
.
filesProviders
.
workspace
const
workspacePath
=
'browser/'
+
workspaceProvider
.
workspacesPath
+
'/'
+
name
const
workspaceRootPath
=
'browser/'
+
workspaceProvider
.
workspacesPath
if
(
!
this
.
exists
(
workspaceRootPath
))
await
this
.
mkdir
(
workspaceRootPath
)
if
(
!
this
.
exists
(
workspacePath
))
await
this
.
mkdir
(
workspacePath
)
}
async
workspaceExists
(
name
)
{
const
workspaceProvider
=
this
.
_deps
.
filesProviders
.
workspace
const
workspacePath
=
'browser/'
+
workspaceProvider
.
workspacesPath
+
'/'
+
name
return
this
.
exists
(
workspacePath
)
}
}
}
module
.
exports
=
FileManager
module
.
exports
=
FileManager
apps/remix-ide/src/app/files/fileProvider.js
View file @
fcefed60
...
@@ -66,7 +66,9 @@ class FileProvider {
...
@@ -66,7 +66,9 @@ class FileProvider {
exists
(
path
,
cb
)
{
exists
(
path
,
cb
)
{
// todo check the type (directory/file) as well #2386
// todo check the type (directory/file) as well #2386
// currently it is not possible to have a file and folder with same path
// currently it is not possible to have a file and folder with same path
return
cb
(
null
,
this
.
_exists
(
path
))
const
ret
=
this
.
_exists
(
path
)
if
(
cb
)
cb
(
null
,
ret
)
return
ret
}
}
_exists
(
path
)
{
_exists
(
path
)
{
...
...
apps/remix-ide/src/app/panels/file-panel.js
View file @
fcefed60
...
@@ -131,7 +131,6 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -131,7 +131,6 @@ module.exports = class Filepanel extends ViewPlugin {
async
initWorkspace
()
{
async
initWorkspace
()
{
const
queryParams
=
new
QueryParams
()
const
queryParams
=
new
QueryParams
()
const
gistHandler
=
new
GistHandler
()
const
gistHandler
=
new
GistHandler
()
const
workspacesPath
=
this
.
_deps
.
fileProviders
.
workspace
.
workspacesPath
const
params
=
queryParams
.
get
()
const
params
=
queryParams
.
get
()
// get the file from gist
// get the file from gist
const
loadedFromGist
=
gistHandler
.
loadFromGist
(
params
,
this
.
_deps
.
fileManager
)
const
loadedFromGist
=
gistHandler
.
loadFromGist
(
params
,
this
.
_deps
.
fileManager
)
...
@@ -139,12 +138,12 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -139,12 +138,12 @@ module.exports = class Filepanel extends ViewPlugin {
if
(
loadedFromGist
)
return
if
(
loadedFromGist
)
return
if
(
params
.
code
)
{
if
(
params
.
code
)
{
try
{
try
{
await
this
.
_deps
.
fileManager
.
c
reateWorkspace
(
'code-sample'
)
await
this
.
processC
reateWorkspace
(
'code-sample'
)
this
.
_deps
.
fileProviders
.
workspace
.
setWorkspace
(
'code-sample'
)
this
.
_deps
.
fileProviders
.
workspace
.
setWorkspace
(
'code-sample'
)
var
hash
=
ethutil
.
bufferToHex
(
ethutil
.
keccak
(
params
.
code
))
var
hash
=
ethutil
.
bufferToHex
(
ethutil
.
keccak
(
params
.
code
))
const
fileName
=
'contract-'
+
hash
.
replace
(
'0x'
,
''
).
substring
(
0
,
10
)
+
'.sol'
const
fileName
=
'contract-'
+
hash
.
replace
(
'0x'
,
''
).
substring
(
0
,
10
)
+
'.sol'
const
path
=
'browser/'
+
workspacesPath
+
'/code-sample/'
+
fileName
const
path
=
fileName
await
this
.
_deps
.
file
Manager
.
writeFile
(
path
,
atob
(
params
.
code
))
await
this
.
_deps
.
file
Providers
.
workspace
.
set
(
path
,
atob
(
params
.
code
))
this
.
initialWorkspace
=
'code-sample'
this
.
initialWorkspace
=
'code-sample'
await
this
.
_deps
.
fileManager
.
openFile
(
fileName
)
await
this
.
_deps
.
fileManager
.
openFile
(
fileName
)
}
catch
(
e
)
{
}
catch
(
e
)
{
...
@@ -170,13 +169,30 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -170,13 +169,30 @@ module.exports = class Filepanel extends ViewPlugin {
return
await
this
.
request
.
uploadFile
()
return
await
this
.
request
.
uploadFile
()
}
}
async
processCreateWorkspace
(
name
)
{
const
workspaceProvider
=
this
.
_deps
.
fileProviders
.
workspace
const
browserProvider
=
this
.
_deps
.
fileProviders
.
browser
const
workspacePath
=
'browser/'
+
workspaceProvider
.
workspacesPath
+
'/'
+
name
const
workspaceRootPath
=
'browser/'
+
workspaceProvider
.
workspacesPath
if
(
!
browserProvider
.
exists
(
workspaceRootPath
))
browserProvider
.
createDir
(
workspaceRootPath
)
if
(
!
browserProvider
.
exists
(
workspacePath
))
browserProvider
.
createDir
(
workspacePath
)
}
async
workspaceExists
(
name
)
{
const
workspaceProvider
=
this
.
_deps
.
fileProviders
.
workspace
const
browserProvider
=
this
.
_deps
.
fileProviders
.
browser
const
workspacePath
=
'browser/'
+
workspaceProvider
.
workspacesPath
+
'/'
+
name
return
browserProvider
.
exists
(
workspacePath
)
}
async
createWorkspace
(
workspaceName
)
{
async
createWorkspace
(
workspaceName
)
{
if
(
await
this
.
_deps
.
fileManager
.
workspaceExists
(
workspaceName
))
throw
new
Error
(
'workspace already exists'
)
if
(
await
this
.
workspaceExists
(
workspaceName
))
throw
new
Error
(
'workspace already exists'
)
const
browserProvider
=
this
.
_deps
.
fileProviders
.
browser
const
workspacesPath
=
this
.
_deps
.
fileProviders
.
workspace
.
workspacesPath
const
workspacesPath
=
this
.
_deps
.
fileProviders
.
workspace
.
workspacesPath
await
this
.
_deps
.
fileManager
.
c
reateWorkspace
(
workspaceName
)
await
this
.
processC
reateWorkspace
(
workspaceName
)
for
(
const
file
in
examples
)
{
for
(
const
file
in
examples
)
{
try
{
try
{
await
this
.
_deps
.
fileManager
.
writeFile
(
'browser/'
+
workspacesPath
+
'/'
+
workspaceName
+
'/'
+
examples
[
file
].
name
,
examples
[
file
].
content
)
await
browserProvider
.
set
(
'browser/'
+
workspacesPath
+
'/'
+
workspaceName
+
'/'
+
examples
[
file
].
name
,
examples
[
file
].
content
)
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
error
)
console
.
error
(
error
)
}
}
...
...
apps/remix-ide/src/migrateFileSystem.js
View file @
fcefed60
...
@@ -21,7 +21,7 @@ export default (fileProvider) => {
...
@@ -21,7 +21,7 @@ export default (fileProvider) => {
fileStorageBrowserFS
.
set
(
flag
,
'done'
)
fileStorageBrowserFS
.
set
(
flag
,
'done'
)
}
}
export
async
function
migrateToWorkspace
(
fileManager
)
{
export
async
function
migrateToWorkspace
(
fileManager
,
filePanel
)
{
const
browserProvider
=
fileManager
.
getProvider
(
'browser'
)
const
browserProvider
=
fileManager
.
getProvider
(
'browser'
)
const
workspaceProvider
=
fileManager
.
getProvider
(
'workspace'
)
const
workspaceProvider
=
fileManager
.
getProvider
(
'workspace'
)
const
flag
=
'status'
const
flag
=
'status'
...
@@ -31,19 +31,20 @@ export async function migrateToWorkspace (fileManager) {
...
@@ -31,19 +31,20 @@ export async function migrateToWorkspace (fileManager) {
console
.
log
(
files
)
console
.
log
(
files
)
const
workspaceName
=
'default_workspace'
const
workspaceName
=
'default_workspace'
const
workspacePath
=
joinPath
(
'browser'
,
workspaceProvider
.
workspacesPath
,
workspaceName
)
const
workspacePath
=
joinPath
(
'browser'
,
workspaceProvider
.
workspacesPath
,
workspaceName
)
await
fileManager
.
createWorkspace
(
workspaceName
)
await
filePanel
.
createWorkspace
(
workspaceName
)
await
populateWorkspace
(
workspacePath
,
files
,
fileManager
)
filePanel
.
getWorkspaces
()
// refresh list
await
populateWorkspace
(
workspacePath
,
files
,
browserProvider
)
fileStorageBrowserWorkspace
.
set
(
flag
,
'done'
)
fileStorageBrowserWorkspace
.
set
(
flag
,
'done'
)
}
}
const
populateWorkspace
=
async
(
workspace
,
json
,
fileManag
er
)
=>
{
const
populateWorkspace
=
async
(
workspace
,
json
,
browserProvid
er
)
=>
{
for
(
const
item
in
json
)
{
for
(
const
item
in
json
)
{
const
isFolder
=
json
[
item
].
content
===
undefined
const
isFolder
=
json
[
item
].
content
===
undefined
if
(
isFolder
)
{
if
(
isFolder
)
{
await
fileManager
.
mkd
ir
(
joinPath
(
workspace
,
item
))
browserProvider
.
createD
ir
(
joinPath
(
workspace
,
item
))
await
populateWorkspace
(
workspace
,
json
[
item
].
children
,
fileManag
er
)
await
populateWorkspace
(
workspace
,
json
[
item
].
children
,
browserProvid
er
)
}
else
{
}
else
{
await
fileManager
.
writeFile
(
joinPath
(
workspace
,
item
),
json
[
item
].
content
)
await
browserProvider
.
set
(
joinPath
(
workspace
,
item
),
json
[
item
].
content
)
}
}
}
}
}
}
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
View file @
fcefed60
...
@@ -62,12 +62,7 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -62,12 +62,7 @@ export const Workspace = (props: WorkspaceProps) => {
useEffect
(()
=>
{
useEffect
(()
=>
{
const
getWorkspaces
=
async
()
=>
{
const
getWorkspaces
=
async
()
=>
{
if
(
props
.
workspaces
&&
Array
.
isArray
(
props
.
workspaces
))
{
if
(
props
.
workspaces
&&
Array
.
isArray
(
props
.
workspaces
))
{
if
(
props
.
initialWorkspace
)
{
if
(
props
.
workspaces
.
length
>
0
&&
state
.
currentWorkspace
===
NO_WORKSPACE
)
{
props
.
workspace
.
setWorkspace
(
props
.
initialWorkspace
)
setState
(
prevState
=>
{
return
{
...
prevState
,
workspaces
:
props
.
workspaces
,
currentWorkspace
:
props
.
initialWorkspace
}
})
}
else
if
(
props
.
workspaces
.
length
>
0
&&
state
.
currentWorkspace
===
NO_WORKSPACE
)
{
props
.
workspace
.
setWorkspace
(
props
.
workspaces
[
0
])
props
.
workspace
.
setWorkspace
(
props
.
workspaces
[
0
])
setState
(
prevState
=>
{
setState
(
prevState
=>
{
return
{
...
prevState
,
workspaces
:
props
.
workspaces
,
currentWorkspace
:
props
.
workspaces
[
0
]
}
return
{
...
prevState
,
workspaces
:
props
.
workspaces
,
currentWorkspace
:
props
.
workspaces
[
0
]
}
...
@@ -91,6 +86,13 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -91,6 +86,13 @@ export const Workspace = (props: WorkspaceProps) => {
props
.
localhost
.
event
.
register
(
'disconnected'
,
(
event
)
=>
{
props
.
localhost
.
event
.
register
(
'disconnected'
,
(
event
)
=>
{
remixdExplorer
.
hide
()
remixdExplorer
.
hide
()
})
})
if
(
props
.
initialWorkspace
)
{
props
.
workspace
.
setWorkspace
(
props
.
initialWorkspace
)
setState
(
prevState
=>
{
return
{
...
prevState
,
currentWorkspace
:
props
.
initialWorkspace
}
})
}
},
[])
},
[])
const
[
state
,
setState
]
=
useState
({
const
[
state
,
setState
]
=
useState
({
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment