Unable to get full path of file dropped in browser due to security reasons. What to do?
Asked Answered
B

2

1

I'm developing a web-application with Django, which should manage and process a huge amount of user' files in local intranet. As the Django app and user files will host in the same local network, there is no necessity to upload files, it's ok to provide Django with full network path to the file via user's view.

I realised that it's impossible to get full file path from the browser due to security reasons.

There is a lot of files a user will process every day (around 150-200), so it's not ok to ask user to manually copy-paste full file path into the app. Initial design approach supposed user to drag-n-drop files from Windows Explorer to dedicated areas in the browser.

What's my options, community?

  1. rewrite all front-end as Electron app (yikes! Just because of it!) and use Django only as REST API backend;
  2. rewrite ducking everything as desktop app and lose all advantages Django provides (authorization, authentication, ORM, admin panel, gosh -- lots of it);
  3. the third funny option

I feel a little stranded. Need some advice. Thanks!

Borzoi answered 27/1, 2020 at 18:48 Comment(0)
F
0

I have encountered same problem while working on this.

When I think on your options

1- There is no need to re-write whole app

  • Create an api endpoint on server side
  • Create a script(program) on client that will push real paths to server

    Your files should be accessible over network

Here is the script code that I used: Tested with python Python 3.7.4 Prints realpath of all the selected files as a list. source

import tkinter as tk
from tkinter import filedialog
import pathlib

root = tk.Tk()
root.withdraw()

root.attributes("-topmost", True)
file_path = filedialog.askopenfilenames()
# print(file_path) #debug
files = list(file_path)
print(files)

Then you need to import either a requests and generate a Json request to your server endpoint.Or just call a curl with subprocess.

2- By your definition I assume the intranet network is trusted.So is authentication necessary.And there is a question of How many users will use same file after it is processed in server.If its one then there is no need for a django app.

Feodore answered 28/1, 2020 at 8:19 Comment(3)
Thanks for input, Bayram. Unfortunately, use small local GUI app to push the full paths to the web-app isn't an option. It looks really cumbersome: first, user have to push them to the web-app; second, user have to do it's work in web-app (tick some checkboxes and radiobuttons) for every file. Practically it's easier for user to tick the boxes in the same GUI app. And regarding Django app: the project is a multiuser system with various user roles and complex parallel file processing. Celery/RabbitMQ, Postgres, 3rd party APIs and all that stuff, so actually Django helps a lot :)Borzoi
How about converting checkboxes and radiobuttons into RESTful service and creating a local GUI, or you can just create a wrapper around a local GUI app with WebView?Feodore
hmm, it looks like a mix of 1st and 2nd options. Will think about it. Thank you!Borzoi
B
0

Well...
I've solved my problem. With much less blood than expected, which I'm happy of. :)

First, I installed Electron and one of minimal boilerplates into a new folder in my project.

In boilerplate there is a file called main.js (or index.js, depends on boilerplate), which defines Electron application window and its contents. Inside is the line which loads content to Electron BrowserWindow object:

mainWindow.loadFile(path.join(__dirname, 'index.html'));

Fortunately, BrowserWindow object does have method loadURL, which can be used to load webpage instead of local html file:

mainWindow.loadURL('http://127.0.0.1:8000');

It means that all pages rendered by Django will be shown in Electron browser, which runs node.js instead of standard browser javascript engine. Thus, this code in Django page template will work perfectly:

<h1 id="holder">DROP FILES HERE</h1>
<p id="dropped"></p>

<script>
    const dropZone = document.getElementById('holder');

    dropZone.addEventListener('drop', (e) => {
      e.preventDefault();
      e.stopPropagation();
      let filesList = '\n';
      for (const f of e.dataTransfer.files) filesList += f.path + '\n';
      document.getElementById('dropped').innerHTML = `Full file paths: ${filesList}`;
    });

    dropZone.addEventListener('dragover', (e) => {
      e.preventDefault();
      e.stopPropagation();
    });
</script>
Borzoi answered 30/1, 2020 at 16:55 Comment(1)
Does using Electron mean that the application is now a desktop application? Or can you continue using it in the standard browser with the NodeJS engine?Sassy

© 2022 - 2024 — McMap. All rights reserved.