2019-11-02 13:43:20 -04:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
OnionShare | https://onionshare.org/
|
|
|
|
|
2020-08-27 19:13:08 -04:00
|
|
|
Copyright (C) 2014-2020 Micah Lee, et al. <micah@micahflee.com>
|
2019-11-02 13:43:20 -04:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
"""
|
2019-11-02 20:01:47 -04:00
|
|
|
import os
|
2019-11-03 00:00:23 -04:00
|
|
|
import json
|
2020-08-21 14:49:23 -04:00
|
|
|
import platform
|
|
|
|
|
|
|
|
if platform.system() == "Darwin":
|
|
|
|
import pwd
|
2019-11-02 13:43:20 -04:00
|
|
|
|
|
|
|
|
|
|
|
class ModeSettings:
|
|
|
|
"""
|
|
|
|
This stores the settings for a single instance of an OnionShare mode. In CLI there
|
2019-11-28 22:30:48 -05:00
|
|
|
is only one ModeSettings, and in the GUI there is a separate ModeSettings for each tab
|
2019-11-02 13:43:20 -04:00
|
|
|
"""
|
|
|
|
|
2019-11-03 00:45:55 -04:00
|
|
|
def __init__(self, common, filename=None, id=None):
|
2019-11-02 13:43:20 -04:00
|
|
|
self.common = common
|
|
|
|
|
2019-11-03 00:00:23 -04:00
|
|
|
self.default_settings = {
|
2019-12-08 13:13:56 -05:00
|
|
|
"onion": {
|
2019-11-02 13:43:20 -04:00
|
|
|
"private_key": None,
|
2019-11-10 20:32:34 -05:00
|
|
|
"hidservauth_string": None,
|
2019-11-02 13:43:20 -04:00
|
|
|
"password": None,
|
|
|
|
},
|
2019-12-08 13:13:56 -05:00
|
|
|
"persistent": {"mode": None, "enabled": False},
|
2019-11-02 13:43:20 -04:00
|
|
|
"general": {
|
|
|
|
"public": False,
|
|
|
|
"autostart_timer": False,
|
|
|
|
"autostop_timer": False,
|
|
|
|
"legacy": False,
|
|
|
|
"client_auth": False,
|
2019-11-10 20:32:34 -05:00
|
|
|
"service_id": None,
|
2019-11-02 13:43:20 -04:00
|
|
|
},
|
2019-11-03 00:00:23 -04:00
|
|
|
"share": {"autostop_sharing": True, "filenames": []},
|
2019-11-02 20:06:13 -04:00
|
|
|
"receive": {"data_dir": self.build_default_receive_data_dir()},
|
2019-11-03 00:00:23 -04:00
|
|
|
"website": {"disable_csp": False, "filenames": []},
|
2020-03-08 05:21:43 -04:00
|
|
|
"chat": {"room": "default"},
|
2019-11-02 13:43:20 -04:00
|
|
|
}
|
2019-11-03 00:00:23 -04:00
|
|
|
self._settings = {}
|
|
|
|
|
|
|
|
self.just_created = False
|
2019-11-03 00:45:55 -04:00
|
|
|
if id:
|
|
|
|
self.id = id
|
|
|
|
else:
|
|
|
|
self.id = self.common.build_password(3)
|
2019-11-03 00:00:23 -04:00
|
|
|
|
|
|
|
self.load(filename)
|
|
|
|
|
|
|
|
def fill_in_defaults(self):
|
|
|
|
"""
|
|
|
|
If there are any missing settings from self._settings, replace them with
|
|
|
|
their default values.
|
|
|
|
"""
|
|
|
|
for key in self.default_settings:
|
|
|
|
if key in self._settings:
|
|
|
|
for inner_key in self.default_settings[key]:
|
|
|
|
if inner_key not in self._settings[key]:
|
|
|
|
self._settings[key][inner_key] = self.default_settings[key][
|
|
|
|
inner_key
|
|
|
|
]
|
|
|
|
else:
|
|
|
|
self._settings[key] = self.default_settings[key]
|
2019-11-02 13:43:20 -04:00
|
|
|
|
|
|
|
def get(self, group, key):
|
2019-11-03 00:00:23 -04:00
|
|
|
return self._settings[group][key]
|
2019-11-02 13:43:20 -04:00
|
|
|
|
|
|
|
def set(self, group, key, val):
|
2019-11-03 00:00:23 -04:00
|
|
|
self._settings[group][key] = val
|
|
|
|
self.common.log(
|
|
|
|
"ModeSettings", "set", f"updating {self.id}: {group}.{key} = {val}"
|
|
|
|
)
|
|
|
|
self.save()
|
2019-11-02 20:01:47 -04:00
|
|
|
|
2019-11-02 20:06:13 -04:00
|
|
|
def build_default_receive_data_dir(self):
|
2019-11-02 20:01:47 -04:00
|
|
|
"""
|
|
|
|
Returns the path of the default Downloads directory for receive mode.
|
|
|
|
"""
|
|
|
|
|
|
|
|
if self.common.platform == "Darwin":
|
|
|
|
# We can't use os.path.expanduser() in macOS because in the sandbox it
|
|
|
|
# returns the path to the sandboxed homedir
|
|
|
|
real_homedir = pwd.getpwuid(os.getuid()).pw_dir
|
|
|
|
return os.path.join(real_homedir, "OnionShare")
|
|
|
|
elif self.common.platform == "Windows":
|
|
|
|
# On Windows, os.path.expanduser() needs to use backslash, or else it
|
|
|
|
# retains the forward slash, which breaks opening the folder in explorer.
|
2020-11-01 14:50:11 -05:00
|
|
|
return os.path.expanduser("~\\OnionShare")
|
2019-11-02 20:01:47 -04:00
|
|
|
else:
|
|
|
|
# All other OSes
|
|
|
|
return os.path.expanduser("~/OnionShare")
|
2019-11-02 22:12:06 -04:00
|
|
|
|
2019-11-03 00:00:23 -04:00
|
|
|
def load(self, filename=None):
|
|
|
|
# Load persistent settings from disk. If the file doesn't exist, create it
|
|
|
|
if filename:
|
|
|
|
self.filename = filename
|
|
|
|
else:
|
|
|
|
self.filename = os.path.join(
|
|
|
|
self.common.build_persistent_dir(), f"{self.id}.json"
|
|
|
|
)
|
|
|
|
|
|
|
|
if os.path.exists(self.filename):
|
|
|
|
try:
|
|
|
|
with open(self.filename, "r") as f:
|
|
|
|
self._settings = json.load(f)
|
|
|
|
self.fill_in_defaults()
|
|
|
|
self.common.log("ModeSettings", "load", f"loaded {self.filename}")
|
|
|
|
return
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
# If loading settings didn't work, create the settings file
|
|
|
|
self.common.log("ModeSettings", "load", f"creating {self.filename}")
|
|
|
|
self.fill_in_defaults()
|
|
|
|
self.just_created = True
|
|
|
|
|
2019-11-02 22:12:06 -04:00
|
|
|
def save(self):
|
2019-11-03 00:00:23 -04:00
|
|
|
# Save persistent setting to disk
|
|
|
|
if not self.get("persistent", "enabled"):
|
|
|
|
return
|
|
|
|
|
|
|
|
if self.filename:
|
|
|
|
with open(self.filename, "w") as file:
|
|
|
|
file.write(json.dumps(self._settings, indent=2))
|
2019-11-03 01:06:26 -05:00
|
|
|
|
|
|
|
def delete(self):
|
|
|
|
# Delete the file from disk
|
|
|
|
if os.path.exists(self.filename):
|
|
|
|
os.remove(self.filename)
|