Use the new SudoDialog
This commit is contained in:
parent
beab6c6611
commit
67513c2357
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.16.1 -->
|
<!-- Generated with glade 3.18.3 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.6"/>
|
<requires lib="gtk+" version="3.6"/>
|
||||||
<!-- interface-requires mugshot_window 1.0 -->
|
<requires lib="mugshot_window" version="1.0"/>
|
||||||
<!-- interface-local-resource-path ../media -->
|
<!-- interface-local-resource-path ../media -->
|
||||||
<object class="GtkBox" id="box8">
|
<object class="GtkBox" id="box8">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
|
@ -192,7 +192,7 @@ class MugshotWindow(Window):
|
||||||
self.fax_entry = builder.get_object('fax')
|
self.fax_entry = builder.get_object('fax')
|
||||||
|
|
||||||
# Users without sudo rights cannot change their name.
|
# Users without sudo rights cannot change their name.
|
||||||
self.set_name_editable(SudoDialog.check_sudo())
|
self.set_name_editable(SudoDialog.check_dependencies(['chfn']))
|
||||||
|
|
||||||
# Stock photo browser
|
# Stock photo browser
|
||||||
self.stock_browser = builder.get_object('stock_browser')
|
self.stock_browser = builder.get_object('stock_browser')
|
||||||
|
@ -311,13 +311,24 @@ class MugshotWindow(Window):
|
||||||
changes."""
|
changes."""
|
||||||
logger.debug('Applying changes...')
|
logger.debug('Applying changes...')
|
||||||
if self.get_chfn_details_updated():
|
if self.get_chfn_details_updated():
|
||||||
if not self.save_chfn_details():
|
success, response = self.save_chfn_details()
|
||||||
|
if not success:
|
||||||
# Password was incorrect, complain.
|
# Password was incorrect, complain.
|
||||||
primary = _("Authentication Failed")
|
if response in [Gtk.ResponseType.NONE,
|
||||||
|
Gtk.ResponseType.CANCEL,
|
||||||
|
Gtk.ResponseType.DELETE_EVENT]:
|
||||||
|
msg_type = Gtk.MessageType.WARNING
|
||||||
|
primary = _("Authentication cancelled.")
|
||||||
|
elif response == Gtk.ResponseType.REJECT:
|
||||||
|
msg_type = Gtk.MessageType.WARNING
|
||||||
|
primary = _("Authentication failed.")
|
||||||
|
else:
|
||||||
|
msg_type = Gtk.MessageType.ERROR
|
||||||
|
primary = _("An error occurred when saving changes.")
|
||||||
|
|
||||||
secondary = _("User details were not updated.")
|
secondary = _("User details were not updated.")
|
||||||
dialog = Gtk.MessageDialog(transient_for=self, flags=0,
|
dialog = Gtk.MessageDialog(transient_for=self, flags=0,
|
||||||
message_type=
|
message_type=msg_type,
|
||||||
Gtk.MessageType.WARNING,
|
|
||||||
buttons=Gtk.ButtonsType.OK,
|
buttons=Gtk.ButtonsType.OK,
|
||||||
text=primary)
|
text=primary)
|
||||||
dialog.format_secondary_text(secondary)
|
dialog.format_secondary_text(secondary)
|
||||||
|
@ -555,8 +566,7 @@ class MugshotWindow(Window):
|
||||||
"""Handle password prompts from the interactive chfn commands."""
|
"""Handle password prompts from the interactive chfn commands."""
|
||||||
# Force the C language for guaranteed english strings in the script.
|
# Force the C language for guaranteed english strings in the script.
|
||||||
logger.debug('Executing: %s' % command)
|
logger.debug('Executing: %s' % command)
|
||||||
child = pexpect.spawn(command, env={"LANG": "C"})
|
child = SudoDialog.env_spawn(command, 5)
|
||||||
child.timeout = 5
|
|
||||||
child.write_to_stdout = True
|
child.write_to_stdout = True
|
||||||
try:
|
try:
|
||||||
child.expect([".*ssword.*", pexpect.EOF])
|
child.expect([".*ssword.*", pexpect.EOF])
|
||||||
|
@ -582,13 +592,13 @@ class MugshotWindow(Window):
|
||||||
sudo_dialog.format_secondary_text(_("This is a security measure to "
|
sudo_dialog.format_secondary_text(_("This is a security measure to "
|
||||||
"prevent unwanted updates\n"
|
"prevent unwanted updates\n"
|
||||||
"to your personal information."))
|
"to your personal information."))
|
||||||
sudo_dialog.run()
|
response = sudo_dialog.run()
|
||||||
sudo_dialog.hide()
|
sudo_dialog.hide()
|
||||||
password = sudo_dialog.get_password()
|
password = sudo_dialog.get_password()
|
||||||
sudo_dialog.destroy()
|
sudo_dialog.destroy()
|
||||||
|
|
||||||
if not password:
|
if not password:
|
||||||
return False
|
return (False, response)
|
||||||
|
|
||||||
sudo = which('sudo')
|
sudo = which('sudo')
|
||||||
chfn = which('chfn')
|
chfn = which('chfn')
|
||||||
|
@ -606,7 +616,7 @@ class MugshotWindow(Window):
|
||||||
home_phone = 'none'
|
home_phone = 'none'
|
||||||
|
|
||||||
# Full name can only be modified by root. Try using sudo to modify.
|
# Full name can only be modified by root. Try using sudo to modify.
|
||||||
if SudoDialog.check_sudo():
|
if SudoDialog.check_dependencies(['chfn']):
|
||||||
logger.debug('Updating Full Name...')
|
logger.debug('Updating Full Name...')
|
||||||
command = "%s %s -f \"%s\" %s" % (sudo, chfn, full_name, username)
|
command = "%s %s -f \"%s\" %s" % (sudo, chfn, full_name, username)
|
||||||
if self.process_terminal_password(command, password):
|
if self.process_terminal_password(command, password):
|
||||||
|
@ -629,7 +639,7 @@ class MugshotWindow(Window):
|
||||||
else:
|
else:
|
||||||
success = False
|
success = False
|
||||||
|
|
||||||
return success
|
return (success, response)
|
||||||
|
|
||||||
# = LibreOffice ========================================================= #
|
# = LibreOffice ========================================================= #
|
||||||
def get_libreoffice_details_updated(self):
|
def get_libreoffice_details_updated(self):
|
||||||
|
|
|
@ -23,22 +23,70 @@ from locale import gettext as _
|
||||||
|
|
||||||
import pexpect
|
import pexpect
|
||||||
|
|
||||||
|
gtk_version = (Gtk.get_major_version(),
|
||||||
|
Gtk.get_minor_version(),
|
||||||
|
Gtk.get_micro_version())
|
||||||
|
|
||||||
def check_sudo():
|
|
||||||
"""Return True if user has permission to use sudo."""
|
def check_gtk_version(major_version, minor_version, micro=0):
|
||||||
child = pexpect.spawn('sudo -v', env={"LANG": "C"})
|
"""Return true if running gtk >= requested version"""
|
||||||
child.timeout = 1
|
return gtk_version >= (major_version, minor_version, micro)
|
||||||
# Check for failure message.
|
|
||||||
try:
|
# Check if the LANG variable needs to be set
|
||||||
child.expect(["Sorry", pexpect.EOF])
|
use_env = False
|
||||||
child.close()
|
|
||||||
|
|
||||||
|
def check_dependencies(commands=[]):
|
||||||
|
"""Check for the existence of required commands, and sudo access"""
|
||||||
|
# Check for sudo
|
||||||
|
if pexpect.which("sudo") is None:
|
||||||
return False
|
return False
|
||||||
except:
|
|
||||||
|
# Check for required commands
|
||||||
|
for command in commands:
|
||||||
|
if pexpect.which(command) is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check for LANG requirements
|
||||||
|
child = env_spawn('sudo -v', 1)
|
||||||
|
if child.expect([".*ssword.*", "Sorry",
|
||||||
|
pexpect.EOF,
|
||||||
|
pexpect.TIMEOUT]) == 3:
|
||||||
|
global use_env
|
||||||
|
use_env = True
|
||||||
child.close()
|
child.close()
|
||||||
|
|
||||||
|
# Check for sudo rights
|
||||||
|
child = env_spawn('sudo -v', 1)
|
||||||
|
try:
|
||||||
|
index = child.expect([".*ssword.*", "Sorry",
|
||||||
|
pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
child.close()
|
||||||
|
if index == 0 or index == 2:
|
||||||
|
# User in sudoers, or already admin
|
||||||
return True
|
return True
|
||||||
|
elif index == 1 or index == 3:
|
||||||
|
# User not in sudoers
|
||||||
|
return False
|
||||||
|
|
||||||
|
except:
|
||||||
|
# Something else went wrong.
|
||||||
|
child.close()
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class SudoDialog(Gtk.MessageDialog):
|
def env_spawn(command, timeout):
|
||||||
|
"""Use pexpect.spawn, adapt for timeout and env requirements."""
|
||||||
|
if use_env:
|
||||||
|
child = pexpect.spawn(command, env={"LANG": "C"})
|
||||||
|
else:
|
||||||
|
child = pexpect.spawn(command)
|
||||||
|
child.timeout = timeout
|
||||||
|
return child
|
||||||
|
|
||||||
|
|
||||||
|
class SudoDialog(Gtk.Dialog):
|
||||||
'''
|
'''
|
||||||
Creates a new SudoDialog. This is a replacement for using gksudo which
|
Creates a new SudoDialog. This is a replacement for using gksudo which
|
||||||
provides additional flexibility when performing sudo commands.
|
provides additional flexibility when performing sudo commands.
|
||||||
|
@ -58,34 +106,94 @@ class SudoDialog(Gtk.MessageDialog):
|
||||||
- REJECT: Password invalid.
|
- REJECT: Password invalid.
|
||||||
- ACCEPT: Password valid.
|
- ACCEPT: Password valid.
|
||||||
'''
|
'''
|
||||||
def __init__(self, parent=None, icon=None, message=None, name=None,
|
def __init__(self, title=None, parent=None, icon=None, message=None,
|
||||||
retries=-1):
|
name=None, retries=-1):
|
||||||
"""Initialize the SudoDialog."""
|
"""Initialize the SudoDialog."""
|
||||||
# default dialog parameters
|
|
||||||
message_type = Gtk.MessageType.QUESTION
|
|
||||||
buttons = Gtk.ButtonsType.NONE
|
|
||||||
|
|
||||||
# initialize the dialog
|
# initialize the dialog
|
||||||
super(SudoDialog, self).__init__(transient_for=parent,
|
super(SudoDialog, self).__init__(title=title,
|
||||||
|
transient_for=parent,
|
||||||
modal=True,
|
modal=True,
|
||||||
destroy_with_parent=True,
|
destroy_with_parent=True)
|
||||||
message_type=message_type,
|
#
|
||||||
buttons=buttons,
|
|
||||||
text='')
|
|
||||||
self.set_dialog_icon(icon)
|
|
||||||
self.connect("show", self.on_show)
|
self.connect("show", self.on_show)
|
||||||
|
if title is None:
|
||||||
|
title = _("Password Required")
|
||||||
|
self.set_title(title)
|
||||||
|
|
||||||
# add buttons
|
self.set_border_width(5)
|
||||||
button_box = self.get_children()[0].get_children()[1]
|
|
||||||
self.add_button(_("Cancel"), Gtk.ResponseType.CANCEL)
|
# Content Area
|
||||||
|
content_area = self.get_content_area()
|
||||||
|
grid = Gtk.Grid.new()
|
||||||
|
grid.set_row_spacing(6)
|
||||||
|
grid.set_column_spacing(12)
|
||||||
|
grid.set_margin_left(5)
|
||||||
|
grid.set_margin_right(5)
|
||||||
|
content_area.add(grid)
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
self.dialog_icon = Gtk.Image.new_from_icon_name("dialog-password",
|
||||||
|
Gtk.IconSize.DIALOG)
|
||||||
|
grid.attach(self.dialog_icon, 0, 0, 1, 2)
|
||||||
|
|
||||||
|
# Text
|
||||||
|
self.primary_text = Gtk.Label.new("")
|
||||||
|
self.primary_text.set_use_markup(True)
|
||||||
|
self.primary_text.set_halign(Gtk.Align.START)
|
||||||
|
self.secondary_text = Gtk.Label.new("")
|
||||||
|
self.secondary_text.set_use_markup(True)
|
||||||
|
self.secondary_text.set_halign(Gtk.Align.START)
|
||||||
|
self.secondary_text.set_margin_top(6)
|
||||||
|
grid.attach(self.primary_text, 1, 0, 1, 1)
|
||||||
|
grid.attach(self.secondary_text, 1, 1, 1, 1)
|
||||||
|
|
||||||
|
# Infobar
|
||||||
|
self.infobar = Gtk.InfoBar.new()
|
||||||
|
self.infobar.set_margin_top(12)
|
||||||
|
self.infobar.set_message_type(Gtk.MessageType.WARNING)
|
||||||
|
content_area = self.infobar.get_content_area()
|
||||||
|
infobar_icon = Gtk.Image.new_from_icon_name("dialog-warning",
|
||||||
|
Gtk.IconSize.BUTTON)
|
||||||
|
label = Gtk.Label.new(_("Incorrect password... try again."))
|
||||||
|
content_area.add(infobar_icon)
|
||||||
|
content_area.add(label)
|
||||||
|
grid.attach(self.infobar, 0, 2, 2, 1)
|
||||||
|
content_area.show_all()
|
||||||
|
self.infobar.set_no_show_all(True)
|
||||||
|
|
||||||
|
# Password
|
||||||
|
label = Gtk.Label.new("")
|
||||||
|
label.set_use_markup(True)
|
||||||
|
label.set_markup("<b>%s</b>" % _("Password:"))
|
||||||
|
label.set_halign(Gtk.Align.START)
|
||||||
|
label.set_margin_top(12)
|
||||||
|
self.password_entry = Gtk.Entry()
|
||||||
|
self.password_entry.set_visibility(False)
|
||||||
|
self.password_entry.set_activates_default(True)
|
||||||
|
self.password_entry.set_margin_top(12)
|
||||||
|
grid.attach(label, 0, 3, 1, 1)
|
||||||
|
grid.attach(self.password_entry, 1, 3, 1, 1)
|
||||||
|
|
||||||
|
# Buttons
|
||||||
|
button = self.add_button(_("Cancel"), Gtk.ResponseType.CANCEL)
|
||||||
|
button_box = button.get_parent()
|
||||||
|
button_box.set_margin_top(24)
|
||||||
ok_button = Gtk.Button.new_with_label(_("OK"))
|
ok_button = Gtk.Button.new_with_label(_("OK"))
|
||||||
ok_button.connect("clicked", self.on_ok_clicked)
|
ok_button.connect("clicked", self.on_ok_clicked)
|
||||||
ok_button.set_receives_default(True)
|
ok_button.set_receives_default(True)
|
||||||
ok_button.set_can_default(True)
|
ok_button.set_can_default(True)
|
||||||
ok_button.set_sensitive(False)
|
ok_button.set_sensitive(False)
|
||||||
self.set_default(ok_button)
|
self.set_default(ok_button)
|
||||||
|
if check_gtk_version(3, 12):
|
||||||
|
button_box.pack_start(ok_button, True, True, 0)
|
||||||
|
else:
|
||||||
button_box.pack_start(ok_button, False, False, 0)
|
button_box.pack_start(ok_button, False, False, 0)
|
||||||
|
|
||||||
|
self.password_entry.connect("changed", self.on_password_changed,
|
||||||
|
ok_button)
|
||||||
|
|
||||||
|
self.set_dialog_icon(icon)
|
||||||
|
|
||||||
# add primary and secondary text
|
# add primary and secondary text
|
||||||
if message:
|
if message:
|
||||||
primary_text = message
|
primary_text = message
|
||||||
|
@ -98,47 +206,11 @@ class SudoDialog(Gtk.MessageDialog):
|
||||||
self.format_primary_text(primary_text)
|
self.format_primary_text(primary_text)
|
||||||
self.format_secondary_text(secondary_text)
|
self.format_secondary_text(secondary_text)
|
||||||
|
|
||||||
# Pack the content area with password-related widgets.
|
|
||||||
content_area = self.get_content_area()
|
|
||||||
|
|
||||||
# Use an alignment to move align the password widgets with the text.
|
|
||||||
self.password_alignment = Gtk.Alignment()
|
|
||||||
# Make an educated guess about how for to align.
|
|
||||||
left_align = Gtk.icon_size_lookup(Gtk.IconSize.DIALOG)[1] + 16
|
|
||||||
self.password_alignment.set_padding(12, 12, left_align, 0)
|
|
||||||
|
|
||||||
# Outer password box for incorrect password label and inner widgets.
|
|
||||||
password_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
|
|
||||||
spacing=12)
|
|
||||||
password_outer.set_orientation(Gtk.Orientation.VERTICAL)
|
|
||||||
# Password error label, only displayed when unsuccessful.
|
|
||||||
self.password_info = Gtk.Label(label="")
|
|
||||||
self.password_info.set_markup("<b>%s</b>" %
|
|
||||||
_("Incorrect password... try again."))
|
|
||||||
|
|
||||||
# Inner password box for Password: label and password entry.
|
|
||||||
password_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
|
|
||||||
spacing=12)
|
|
||||||
password_label = Gtk.Label(label=_("Password:"))
|
|
||||||
self.password_entry = Gtk.Entry()
|
|
||||||
self.password_entry.set_visibility(False)
|
|
||||||
self.password_entry.set_activates_default(True)
|
|
||||||
self.password_entry.connect("changed", self.on_password_changed,
|
|
||||||
ok_button)
|
|
||||||
|
|
||||||
# Pack all the widgets.
|
|
||||||
password_box.pack_start(password_label, False, False, 0)
|
|
||||||
password_box.pack_start(self.password_entry, True, True, 0)
|
|
||||||
password_outer.pack_start(self.password_info, True, True, 0)
|
|
||||||
password_outer.pack_start(password_box, True, True, 0)
|
|
||||||
self.password_alignment.add(password_outer)
|
|
||||||
content_area.pack_start(self.password_alignment, True, True, 0)
|
|
||||||
content_area.show_all()
|
|
||||||
self.password_info.set_visible(False)
|
|
||||||
|
|
||||||
self.attempted_logins = 0
|
self.attempted_logins = 0
|
||||||
self.max_attempted_logins = retries
|
self.max_attempted_logins = retries
|
||||||
|
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
def on_password_changed(self, widget, button):
|
def on_password_changed(self, widget, button):
|
||||||
"""Set the apply button sensitivity based on password input."""
|
"""Set the apply button sensitivity based on password input."""
|
||||||
button.set_sensitive(len(widget.get_text()) > 0)
|
button.set_sensitive(len(widget.get_text()) > 0)
|
||||||
|
@ -146,11 +218,14 @@ class SudoDialog(Gtk.MessageDialog):
|
||||||
def format_primary_text(self, message_format):
|
def format_primary_text(self, message_format):
|
||||||
'''
|
'''
|
||||||
Format the primary text widget.
|
Format the primary text widget.
|
||||||
|
|
||||||
API extension to match with format_secondary_text.
|
|
||||||
'''
|
'''
|
||||||
label = self.get_message_area().get_children()[0]
|
self.primary_text.set_markup("<big><b>%s</b></big>" % message_format)
|
||||||
label.set_text(message_format)
|
|
||||||
|
def format_secondary_text(self, message_format):
|
||||||
|
'''
|
||||||
|
Format the secondary text widget.
|
||||||
|
'''
|
||||||
|
self.secondary_text.set_markup(message_format)
|
||||||
|
|
||||||
def set_dialog_icon(self, icon=None):
|
def set_dialog_icon(self, icon=None):
|
||||||
'''
|
'''
|
||||||
|
@ -166,24 +241,21 @@ class SudoDialog(Gtk.MessageDialog):
|
||||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(icon,
|
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(icon,
|
||||||
icon_size,
|
icon_size,
|
||||||
icon_size)
|
icon_size)
|
||||||
image = Gtk.Image.new_from_pixbuf(pixbuf)
|
self.dialog_icon.set_from_pixbuf(pixbuf)
|
||||||
self.set_icon_from_file(icon)
|
self.set_icon_from_file(icon)
|
||||||
else:
|
else:
|
||||||
# icon is an named icon, so load it directly to an image
|
# icon is an named icon, so load it directly to an image
|
||||||
image = Gtk.Image.new_from_icon_name(icon, icon_size)
|
self.dialog_icon.set_from_icon_name(icon, icon_size)
|
||||||
self.set_icon_name(icon)
|
self.set_icon_name(icon)
|
||||||
else:
|
else:
|
||||||
# fallback on password icon
|
# fallback on password icon
|
||||||
image = Gtk.Image.new_from_icon_name('dialog-password', icon_size)
|
self.dialog_icon.set_from_icon_name('dialog-password', icon_size)
|
||||||
self.set_icon_name('dialog-password')
|
self.set_icon_name('dialog-password')
|
||||||
# align, show, and set the image.
|
|
||||||
image.set_alignment(Gtk.Align.CENTER, Gtk.Align.FILL)
|
|
||||||
image.show()
|
|
||||||
self.set_image(image)
|
|
||||||
|
|
||||||
def on_show(self, widget):
|
def on_show(self, widget):
|
||||||
'''When the dialog is displayed, clear the password.'''
|
'''When the dialog is displayed, clear the password.'''
|
||||||
self.set_password('')
|
self.set_password('')
|
||||||
|
self.password_valid = False
|
||||||
|
|
||||||
def on_ok_clicked(self, widget):
|
def on_ok_clicked(self, widget):
|
||||||
'''
|
'''
|
||||||
|
@ -193,26 +265,22 @@ class SudoDialog(Gtk.MessageDialog):
|
||||||
If unsuccessful, try again until reaching maximum attempted logins,
|
If unsuccessful, try again until reaching maximum attempted logins,
|
||||||
then emit the response signal with REJECT.
|
then emit the response signal with REJECT.
|
||||||
'''
|
'''
|
||||||
top, bottom, left, right = self.password_alignment.get_padding()
|
if self.attempt_login():
|
||||||
# Password cannot be validated without sudo
|
|
||||||
if (not check_sudo()) or self.attempt_login():
|
|
||||||
self.password_valid = True
|
self.password_valid = True
|
||||||
# Adjust the dialog for attactiveness.
|
|
||||||
self.password_alignment.set_padding(12, bottom, left, right)
|
|
||||||
self.password_info.hide()
|
|
||||||
self.emit("response", Gtk.ResponseType.ACCEPT)
|
self.emit("response", Gtk.ResponseType.ACCEPT)
|
||||||
else:
|
else:
|
||||||
self.password_valid = False
|
self.password_valid = False
|
||||||
# Adjust the dialog for attactiveness.
|
# Adjust the dialog for attactiveness.
|
||||||
self.password_alignment.set_padding(0, bottom, left, right)
|
self.infobar.show()
|
||||||
self.password_info.show()
|
self.password_entry.grab_focus()
|
||||||
self.set_password('')
|
|
||||||
if self.attempted_logins == self.max_attempted_logins:
|
if self.attempted_logins == self.max_attempted_logins:
|
||||||
self.attempted_logins = 0
|
self.attempted_logins = 0
|
||||||
self.emit("response", Gtk.ResponseType.REJECT)
|
self.emit("response", Gtk.ResponseType.REJECT)
|
||||||
|
|
||||||
def get_password(self):
|
def get_password(self):
|
||||||
'''Return the currently entered password, or None if blank.'''
|
'''Return the currently entered password, or None if blank.'''
|
||||||
|
if not self.password_valid:
|
||||||
|
return None
|
||||||
password = self.password_entry.get_text()
|
password = self.password_entry.get_text()
|
||||||
if password == '':
|
if password == '':
|
||||||
return None
|
return None
|
||||||
|
@ -232,12 +300,11 @@ class SudoDialog(Gtk.MessageDialog):
|
||||||
Return True if successful.
|
Return True if successful.
|
||||||
'''
|
'''
|
||||||
# Set the pexpect variables and spawn the process.
|
# Set the pexpect variables and spawn the process.
|
||||||
child = pexpect.spawn('sudo /bin/true', env={"LANG": "C"})
|
child = env_spawn('sudo /bin/true', 1)
|
||||||
child.timeout = 1
|
|
||||||
try:
|
try:
|
||||||
# Check for password prompt or program exit.
|
# Check for password prompt or program exit.
|
||||||
child.expect([".*ssword.*", pexpect.EOF])
|
child.expect([".*ssword.*", pexpect.EOF])
|
||||||
child.sendline(self.get_password())
|
child.sendline(self.password_entry.get_text())
|
||||||
child.expect(pexpect.EOF)
|
child.expect(pexpect.EOF)
|
||||||
except pexpect.TIMEOUT:
|
except pexpect.TIMEOUT:
|
||||||
# If we timeout, that means the password was unsuccessful.
|
# If we timeout, that means the password was unsuccessful.
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2014-08-24 10:25-0400\n"
|
"POT-Creation-Date: 2014-08-24 11:44-0400\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -61,7 +61,7 @@ msgstr ""
|
||||||
msgid "Browse…"
|
msgid "Browse…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../data/ui/MugshotWindow.ui.h:9 ../mugshot/MugshotWindow.py:579
|
#: ../data/ui/MugshotWindow.ui.h:9 ../mugshot/MugshotWindow.py:589
|
||||||
msgid "Mugshot"
|
msgid "Mugshot"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -130,70 +130,82 @@ msgstr ""
|
||||||
msgid "Retry"
|
msgid "Retry"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Password was incorrect, complain.
|
#: ../mugshot/MugshotWindow.py:321
|
||||||
#: ../mugshot/MugshotWindow.py:316
|
msgid "Authentication cancelled."
|
||||||
msgid "Authentication Failed"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot/MugshotWindow.py:317
|
#: ../mugshot/MugshotWindow.py:324
|
||||||
|
msgid "Authentication failed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../mugshot/MugshotWindow.py:327
|
||||||
|
msgid "An error occurred when saving changes."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../mugshot/MugshotWindow.py:329
|
||||||
msgid "User details were not updated."
|
msgid "User details were not updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot/MugshotWindow.py:488
|
#: ../mugshot/MugshotWindow.py:499
|
||||||
msgid "Update Pidgin buddy icon?"
|
msgid "Update Pidgin buddy icon?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot/MugshotWindow.py:489
|
#: ../mugshot/MugshotWindow.py:500
|
||||||
msgid "Would you also like to update your Pidgin buddy icon?"
|
msgid "Would you also like to update your Pidgin buddy icon?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot/MugshotWindow.py:580
|
#: ../mugshot/MugshotWindow.py:590
|
||||||
msgid "Enter your password to change user details."
|
msgid "Enter your password to change user details."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot/MugshotWindow.py:582
|
#: ../mugshot/MugshotWindow.py:592
|
||||||
msgid ""
|
msgid ""
|
||||||
"This is a security measure to prevent unwanted updates\n"
|
"This is a security measure to prevent unwanted updates\n"
|
||||||
"to your personal information."
|
"to your personal information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot/MugshotWindow.py:787
|
#: ../mugshot/MugshotWindow.py:797
|
||||||
msgid "Update LibreOffice user details?"
|
msgid "Update LibreOffice user details?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot/MugshotWindow.py:788
|
#: ../mugshot/MugshotWindow.py:798
|
||||||
msgid "Would you also like to update your user details in LibreOffice?"
|
msgid "Would you also like to update your user details in LibreOffice?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot_lib/SudoDialog.py:80
|
#: ../mugshot_lib/SudoDialog.py:120
|
||||||
|
msgid "Password Required"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../mugshot_lib/SudoDialog.py:157
|
||||||
|
msgid "Incorrect password... try again."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../mugshot_lib/SudoDialog.py:167
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Buttons
|
||||||
|
#: ../mugshot_lib/SudoDialog.py:178
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot_lib/SudoDialog.py:81
|
#: ../mugshot_lib/SudoDialog.py:181
|
||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot_lib/SudoDialog.py:94
|
#: ../mugshot_lib/SudoDialog.py:202
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enter your password to\n"
|
"Enter your password to\n"
|
||||||
"perform administrative tasks."
|
"perform administrative tasks."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot_lib/SudoDialog.py:96
|
#: ../mugshot_lib/SudoDialog.py:204
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"The application '%s' lets you\n"
|
"The application '%s' lets you\n"
|
||||||
"modify essential parts of your system."
|
"modify essential parts of your system."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../mugshot_lib/SudoDialog.py:117
|
|
||||||
msgid "Incorrect password... try again."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../mugshot_lib/SudoDialog.py:122
|
|
||||||
msgid "Password:"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../data/appdata/mugshot.appdata.xml.in.h:1
|
#: ../data/appdata/mugshot.appdata.xml.in.h:1
|
||||||
msgid "Lightweight user configuration"
|
msgid "Lightweight user configuration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
Loading…
Reference in New Issue