Add login dialog and username/password command line options
This commit is contained in:
parent
1f9f08c3c5
commit
c048ebcfbb
@ -180,6 +180,8 @@ class ArgHandler:
|
||||
self.imports = []
|
||||
self.exports = []
|
||||
self.removes = parser.removes
|
||||
self.username = parser.username
|
||||
self.password = parser.password
|
||||
|
||||
self.open = self.__handle_open_option(parser.open, parser.create)
|
||||
self.sanitize_args(parser.imports, parser.exports)
|
||||
@ -505,7 +507,7 @@ class ArgHandler:
|
||||
newdb.write_version(self.imp_db_path)
|
||||
|
||||
try:
|
||||
self.smgr.open_activate(self.imp_db_path)
|
||||
self.smgr.open_activate(self.imp_db_path, self.username, self.password)
|
||||
msg = _("Created empty Family Tree successfully")
|
||||
print(msg, file=sys.stderr)
|
||||
except:
|
||||
@ -532,7 +534,7 @@ class ArgHandler:
|
||||
|
||||
# we load this file for use
|
||||
try:
|
||||
self.smgr.open_activate(self.open)
|
||||
self.smgr.open_activate(self.open, self.username, self.password)
|
||||
print(_("Opened successfully!"), file=sys.stderr)
|
||||
except:
|
||||
print(_("Error opening the file."), file=sys.stderr)
|
||||
|
@ -62,6 +62,8 @@ Help options
|
||||
|
||||
Application options
|
||||
-O, --open=FAMILY_TREE Open Family Tree
|
||||
-U, --username=USERNAME Database username
|
||||
-P, --password=PASSWORD Database password
|
||||
-C, --create=FAMILY_TREE Create on open if new Family Tree
|
||||
-i, --import=FILENAME Import file
|
||||
-e, --export=FILENAME Export file
|
||||
@ -138,6 +140,8 @@ class ArgParser:
|
||||
The valid options are:
|
||||
|
||||
-O, --open=FAMILY_TREE Open Family Tree
|
||||
-U, --username=USERNAME Database username
|
||||
-P, --password=PASSWORD Database password
|
||||
-C, --create=FAMILY_TREE Create on open if new Family Tree
|
||||
-i, --import=FILENAME Import file
|
||||
-e, --export=FILENAME Export file
|
||||
@ -196,6 +200,8 @@ class ArgParser:
|
||||
|
||||
self.open_gui = None
|
||||
self.open = None
|
||||
self.username = None
|
||||
self.password = None
|
||||
self.exports = []
|
||||
self.actions = []
|
||||
self.imports = []
|
||||
@ -279,6 +285,10 @@ class ArgParser:
|
||||
self.open = value
|
||||
elif option in ['-C', '--create']:
|
||||
self.create = value
|
||||
elif option in ['-U', '--username']:
|
||||
self.username = value
|
||||
elif option in ['-P', '--password']:
|
||||
self.password = value
|
||||
elif option in ['-i', '--import']:
|
||||
family_tree_format = None
|
||||
if (opt_ix < len(options) - 1
|
||||
|
@ -132,7 +132,7 @@ class CLIDbLoader:
|
||||
"""
|
||||
pass
|
||||
|
||||
def read_file(self, filename):
|
||||
def read_file(self, filename, username, password):
|
||||
"""
|
||||
This method takes care of changing database, and loading the data.
|
||||
In 3.0 we only allow reading of real databases of filetype
|
||||
@ -173,7 +173,8 @@ class CLIDbLoader:
|
||||
self._begin_progress()
|
||||
|
||||
try:
|
||||
self.dbstate.db.load(filename, self._pulse_progress, mode)
|
||||
self.dbstate.db.load(filename, self._pulse_progress, mode,
|
||||
username=username, password=password)
|
||||
except DbEnvironmentError as msg:
|
||||
self.dbstate.no_database()
|
||||
self._errordialog(_("Cannot open database"), str(msg))
|
||||
@ -240,11 +241,11 @@ class CLIManager:
|
||||
self._pmgr = BasePluginManager.get_instance()
|
||||
self.user = user
|
||||
|
||||
def open_activate(self, path):
|
||||
def open_activate(self, path, username, password):
|
||||
"""
|
||||
Open and make a family tree active
|
||||
"""
|
||||
self._read_recent_file(path)
|
||||
self._read_recent_file(path, username, password)
|
||||
|
||||
def _errordialog(self, title, errormessage):
|
||||
"""
|
||||
@ -253,7 +254,7 @@ class CLIManager:
|
||||
print(_('ERROR: %s') % errormessage, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def _read_recent_file(self, filename):
|
||||
def _read_recent_file(self, filename, username, password):
|
||||
"""
|
||||
Called when a file needs to be loaded
|
||||
"""
|
||||
@ -274,7 +275,7 @@ class CLIManager:
|
||||
"that the database is not in use."))
|
||||
return
|
||||
|
||||
if self.db_loader.read_file(filename):
|
||||
if self.db_loader.read_file(filename, username, password):
|
||||
# Attempt to figure out the database title
|
||||
path = os.path.join(filename, "name.txt")
|
||||
try:
|
||||
|
@ -163,8 +163,6 @@ register('database.backup-path', USER_HOME)
|
||||
register('database.backup-on-exit', True)
|
||||
register('database.autobackup', 0)
|
||||
register('database.path', os.path.join(HOME_DIR, 'grampsdb'))
|
||||
register('database.user', '')
|
||||
register('database.password', '')
|
||||
register('database.host', '')
|
||||
register('database.port', '')
|
||||
|
||||
|
@ -288,6 +288,8 @@ LONGOPTS = [
|
||||
"oaf-ior-fd=",
|
||||
"oaf-private",
|
||||
"open=",
|
||||
"username=",
|
||||
"password=",
|
||||
"create=",
|
||||
"options=",
|
||||
"screen=",
|
||||
@ -303,7 +305,7 @@ LONGOPTS = [
|
||||
"quiet",
|
||||
]
|
||||
|
||||
SHORTOPTS = "O:C:i:e:f:a:p:d:c:r:lLthuv?syq"
|
||||
SHORTOPTS = "O:U:P:C:i:e:f:a:p:d:c:r:lLthuv?syq"
|
||||
|
||||
GRAMPS_UUID = uuid.UUID('516cd010-5a41-470f-99f8-eb22f1098ad6')
|
||||
|
||||
|
@ -1427,6 +1427,11 @@ class DbReadBase:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def requires_login(self):
|
||||
"""
|
||||
Returns True for backends that require a login dialog, else False.
|
||||
"""
|
||||
return False
|
||||
|
||||
class DbWriteBase(DbReadBase):
|
||||
"""
|
||||
|
@ -575,7 +575,7 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
if directory:
|
||||
self.load(directory)
|
||||
|
||||
def _initialize(self, directory):
|
||||
def _initialize(self, directory, username, password):
|
||||
"""
|
||||
Initialize database backend.
|
||||
"""
|
||||
@ -586,12 +586,14 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
force_bsddb_upgrade=False,
|
||||
force_bsddb_downgrade=False,
|
||||
force_python_upgrade=False,
|
||||
update=True):
|
||||
update=True,
|
||||
username=None,
|
||||
password=None):
|
||||
"""
|
||||
If update is False: then don't update any files
|
||||
"""
|
||||
# run backend-specific code:
|
||||
self._initialize(directory)
|
||||
self._initialize(directory, username, password)
|
||||
|
||||
# We use the existence of the person table as a proxy for the database
|
||||
# being new
|
||||
|
@ -1471,14 +1471,6 @@ class GrampsPreferences(ConfigureDialog):
|
||||
current_line += 1
|
||||
|
||||
self.connection_widgets = []
|
||||
entry = self.add_entry(grid, _('Username'), current_line,
|
||||
'database.user', col_attach=1)
|
||||
self.connection_widgets.append(entry)
|
||||
current_line += 1
|
||||
entry = self.add_entry(grid, _('Password'), current_line,
|
||||
'database.password', col_attach=1)
|
||||
self.connection_widgets.append(entry)
|
||||
current_line += 1
|
||||
entry = self.add_entry(grid, _('Host'), current_line,
|
||||
'database.host', col_attach=1)
|
||||
self.connection_widgets.append(entry)
|
||||
|
@ -144,7 +144,7 @@ class DbLoader(CLIDbLoader):
|
||||
return ""
|
||||
return self.import_info.info_text()
|
||||
|
||||
def read_file(self, filename):
|
||||
def read_file(self, filename, username=None, password=None):
|
||||
"""
|
||||
This method takes care of changing database, and loading the data.
|
||||
In 3.0 we only allow reading of real databases of filetype
|
||||
@ -181,6 +181,13 @@ class DbLoader(CLIDbLoader):
|
||||
db.disable_signals()
|
||||
self.dbstate.no_database()
|
||||
|
||||
if db.requires_login() and username is None:
|
||||
login = GrampsLoginDialog(self.uistate)
|
||||
credentials = login.run()
|
||||
if credentials is None:
|
||||
return
|
||||
username, password = credentials
|
||||
|
||||
self._begin_progress()
|
||||
|
||||
force_schema_upgrade = False
|
||||
@ -194,7 +201,9 @@ class DbLoader(CLIDbLoader):
|
||||
mode, force_schema_upgrade,
|
||||
force_bsddb_upgrade,
|
||||
force_bsddb_downgrade,
|
||||
force_python_upgrade)
|
||||
force_python_upgrade,
|
||||
username=username,
|
||||
password=password)
|
||||
if self.dbstate.is_open():
|
||||
self.dbstate.db.close(
|
||||
user=User(callback=self._pulse_progress,
|
||||
@ -383,6 +392,49 @@ def format_maker():
|
||||
box.show_all()
|
||||
return (box, type_selector)
|
||||
|
||||
class GrampsLoginDialog(ManagedWindow):
|
||||
|
||||
def __init__(self, uistate):
|
||||
"""
|
||||
A login dialog to obtain credentials to connect to a database
|
||||
"""
|
||||
self.title = _("Login")
|
||||
ManagedWindow.__init__(self, uistate, [], self.__class__, modal=True)
|
||||
|
||||
dialog = Gtk.Dialog(parent=uistate.window)
|
||||
grid = Gtk.Grid()
|
||||
grid.set_border_width(6)
|
||||
grid.set_row_spacing(6)
|
||||
grid.set_column_spacing(6)
|
||||
label = Gtk.Label(label=_('Username: '))
|
||||
grid.attach(label, 0, 0, 1, 1)
|
||||
self.username = Gtk.Entry()
|
||||
self.username.set_hexpand(True)
|
||||
grid.attach(self.username, 1, 0, 1, 1)
|
||||
label = Gtk.Label(label=_('Password: '))
|
||||
grid.attach(label, 0, 1, 1, 1)
|
||||
self.password = Gtk.Entry()
|
||||
self.password.set_hexpand(True)
|
||||
self.password.set_visibility(False)
|
||||
self.password.set_input_purpose(Gtk.InputPurpose.PASSWORD)
|
||||
grid.attach(self.password, 1, 1, 1, 1)
|
||||
dialog.vbox.pack_start(grid, True, True, 0)
|
||||
dialog.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('Login'), Gtk.ResponseType.OK)
|
||||
self.set_window(dialog, None, self.title)
|
||||
|
||||
def run(self):
|
||||
self.show()
|
||||
response = self.window.run()
|
||||
username = self.username.get_text()
|
||||
password = self.password.get_text()
|
||||
if response == Gtk.ResponseType.CANCEL:
|
||||
self.close()
|
||||
return None
|
||||
elif response == Gtk.ResponseType.OK:
|
||||
self.close()
|
||||
return (username, password)
|
||||
|
||||
class GrampsImportFileDialog(ManagedWindow):
|
||||
|
||||
def __init__(self, dbstate, uistate, callback=None):
|
||||
|
@ -536,7 +536,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
@catch_db_error
|
||||
def load(self, name, callback=None, mode=DBMODE_W, force_schema_upgrade=False,
|
||||
force_bsddb_upgrade=False, force_bsddb_downgrade=False,
|
||||
force_python_upgrade=False, update=True):
|
||||
force_python_upgrade=False, update=True,
|
||||
username=None, password=None):
|
||||
"""
|
||||
If update is False: then don't update any files; open read-only
|
||||
"""
|
||||
|
@ -65,7 +65,7 @@ class DBAPI(DbGeneric):
|
||||
with open(versionpath, "w") as version_file:
|
||||
version_file.write(self.__class__.__name__.lower())
|
||||
|
||||
def _initialize(self, directory):
|
||||
def _initialize(self, directory, username, password):
|
||||
raise NotImplementedError
|
||||
|
||||
def _create_schema(self):
|
||||
|
@ -66,13 +66,14 @@ class PostgreSQL(DBAPI):
|
||||
})
|
||||
return summary
|
||||
|
||||
def _initialize(self, directory):
|
||||
def requires_login(self):
|
||||
return True
|
||||
|
||||
def _initialize(self, directory, username, password):
|
||||
config_file = os.path.join(directory, 'settings.ini')
|
||||
config_mgr = ConfigManager(config_file)
|
||||
config_mgr.register('database.dbname', '')
|
||||
config_mgr.register('database.host', '')
|
||||
config_mgr.register('database.user', '')
|
||||
config_mgr.register('database.password', '')
|
||||
config_mgr.register('database.port', '')
|
||||
|
||||
if not os.path.exists(config_file):
|
||||
@ -81,8 +82,6 @@ class PostgreSQL(DBAPI):
|
||||
dbname = file.readline().strip()
|
||||
config_mgr.set('database.dbname', dbname)
|
||||
config_mgr.set('database.host', config.get('database.host'))
|
||||
config_mgr.set('database.user', config.get('database.user'))
|
||||
config_mgr.set('database.password', config.get('database.password'))
|
||||
config_mgr.set('database.port', config.get('database.port'))
|
||||
config_mgr.save()
|
||||
|
||||
@ -93,6 +92,10 @@ class PostgreSQL(DBAPI):
|
||||
value = config_mgr.get('database.' + key)
|
||||
if value:
|
||||
dbkwargs[key] = value
|
||||
if username:
|
||||
dbkwargs['user'] = username
|
||||
if password:
|
||||
dbkwargs['password'] = password
|
||||
|
||||
try:
|
||||
self.dbapi = Connection(**dbkwargs)
|
||||
|
@ -64,7 +64,7 @@ class SQLite(DBAPI):
|
||||
})
|
||||
return summary
|
||||
|
||||
def _initialize(self, directory):
|
||||
def _initialize(self, directory, username, password):
|
||||
if directory == ':memory:':
|
||||
path_to_db = ':memory:'
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user