Skip to content

Navigating to any path in a file dialog, then reloading the page without further action, causes "Access denied" when saving anything #9281

@laundmo

Description

@laundmo

Describe the bug

I'm unable to Backup, with a permission error, after using the path input, then reloading the page without any further action.

This seems to set last_storage to None, and by reloading the page i clear the JS state which would otherwise retain the correct value and cause it to be corrected in later operations.

This puts the account in a state where it cannot store/backup anything, as last_storage stays set to None.

This could be alleviated by explicitly switching storages, as that would fix the last_storage value, but if this is disabled or none exist the button to switch storages does not appear.

To Reproduce

  1. Right click > Backup on any DB
  2. Click the folder icon in the "Filename" input
  3. In the "Select File" dialog, enter some path at the top and press (to navigate to it)
  4. Reload the page (important!)
  5. Right click > Backup on any DB
  6. Click the folder icon in the "Filename" input
  7. Enter a name in "Save As" and click "Create" (backupfilename.sql in my example)
  8. Notice that the "Filename" shows None:/backupfilename.sql
  9. Click Backup, and the error should show. No backup is being created.

To check what is happening I ran the following after each step:

$ sqlite3 pgadmin4.db

sqlite> SELECT p.name, up.uid, up.value FROM user_preferences AS up JOIN preferences AS p ON p.id = up.pid;
user_language|1|en
last_storage|1|None
last_directory_visited|1|/
show_hidden_files|1|True

To fix it, i can run UPDATE user_preferences SET value='my_storage' WHERE pid=129 AND uid=1;

Expected behavior

I expected using the path input to never update last_storage to an invalid value.

Error message

Access denied (None:/backupfilename.sql)

Desktop (please complete the following information):

  • OS: Windows 10
  • pgAdmin version: 9.9
  • Mode: Server
  • Browser (if running in server mode): Firefox
  • Package type: Docker container

Additional context

The core issue seems to stem from the enter handler calling openDir without a second argument:

if(e.code === 'Enter') {
e.preventDefault();
await openDir(path);
}

openDir seems to default to null for storage:

const openDir = async (dirPath, changeStoragePath=null)=>{
setErrorMsg('');
setLoaderText('Loading...');
try {
if(fmUtilsObj.isWinDrive(dirPath)) {
dirPath += fmUtilsObj.separator;
}
let newItems = await fmUtilsObj.getFolder(dirPath || fmUtilsObj.currPath, changeStoragePath);
setItems(newItems);
setPath(fmUtilsObj.currPath);
setTimeout(()=>{fmUtilsObj.setLastVisitedDir(dirPath || fmUtilsObj.currPath, changeStoragePath);}, 100);

passing that null through to setLastVisitedDir which finally calls the API:

async setLastVisitedDir(path, ss) {
return this.api.post(url_for('file_manager.save_last_dir', {
trans_id: this.transId,
}), {
'path': path,
'storage_folder': ss
});

which sets the preference without any validity checks:

@blueprint.route(
"/save_last_dir/<int:trans_id>", methods=["POST"], endpoint='save_last_dir'
)
@pga_login_required
def save_last_directory_visited(trans_id):
blueprint.last_directory_visited.set(req.json['path'])
blueprint.last_storage.set(req.json['storage_folder'])
return make_json_response(status=200)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions