lib/conf/gui/linux/prey-config3.py
#!/usr/bin/env python3
################################################
# Prey Configurator for Linux
# By Tomas Pollak
# (c) 2012-2014 - Fork Ltd. (usefork.com)
################################################
# if having trouble with the GTK theme as root, do this:
# sudo ln -s ~/.themes/ /root/.themes
################################################
# base includes
################################################
APP_NAME = "prey-config"
LANG_PATH = "lang"
import sys
import os
import re
import json
import gettext
import shlex
from subprocess import Popen, PIPE, STDOUT
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from gi.repository import Gdk
# locale.setlocale(locale.LC_ALL, '')
# locale.bindtextdomain(app_name, lang_path)
gettext.bindtextdomain(APP_NAME, LANG_PATH)
gettext.textdomain(APP_NAME)
_ = gettext.gettext
################################################
# vars and such
################################################
FORCE_CONFIG = len(sys.argv) > 1 and (sys.argv[1] == "-f" or sys.argv[1] == "--force")
OUT = STDOUT # None
SCRIPT_PATH = os.sys.path[0]
PACKAGE_PATH = SCRIPT_PATH + "/../../../.."
PREY_BIN = PACKAGE_PATH + "/bin/prey"
PREY_CONFIG = PREY_BIN + " config"
PACKAGE_JSON = open(PACKAGE_PATH + "/package.json", "r")
PACKAGE_INFO = json.loads(PACKAGE_JSON.read())
VERSION = PACKAGE_INFO["version"]
PAGES = ["control_panel_options", "new_user", "existing_user", "existing_device"]
EMAIL_REGEX = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,7}|[0-9]{1,3})(\\]?)$"
class PreyConfigurator(object):
################################################
# helper functions
################################################
def get(self, name):
return self.root.get_object(name)
def text(self, name):
return self.get(name).get_text()
################################################
# validations
################################################
def valid_email_regex(self, string):
if len(string) > 7:
if re.match(EMAIL_REGEX, string) is not None:
return True
return False
def validate_email(self, email_field):
if not self.valid_email_regex(self.text(email_field)):
self.show_alert(
_("Invalid email"),
_("Please make sure the email address you typed is valid."),
)
return False
return True
def validate_password(self, password_field):
if len(self.text(password_field)) < 6:
self.show_alert(
_("Bad password"), _("Password should contain at least 6 chars.")
)
return False
return True
def validate_existing_user_fields(self):
if self.text("existing_email") == "":
self.show_alert(_("Empty email!"), _("Please type in your email."))
return False
if self.text("existing_password") == "":
self.show_alert(_("Empty password!"), _("Please type in your password."))
return False
return True
def validate_new_user_fields(self):
if self.text("user_name") == "":
self.show_alert(_("Empty name!"), _("Please type in your name."))
return False
if self.text("email") == "":
self.show_alert(_("Empty email!"), _("Please type in your email."))
return False
if self.text("password") == "":
self.show_alert(_("Empty password!"), _("Please type in your password."))
return False
elif self.text("password") != self.text("password_confirm"):
self.show_alert(
_("Passwords don't match"), _("Please make sure both passwords match.")
)
return False
if not self.get("check_terms_conds").get_active():
self.show_alert(
_("Error"),
_(
"You need to accept the Terms & Conditions and Privacy Policy to continue"
),
)
return False
if not self.get("check_age").get_active():
self.show_alert(
_("Error"), _("You must be older than 16 years old to use Prey")
)
return False
return True
################################################
# dialogs
################################################
def show_alert(self, title, message, quit=False):
dialog = Gtk.MessageDialog(
parent=None,
flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK,
message_format=message,
)
dialog.set_title(title)
if quit is True:
dialog.connect("response", lambda dialog, response: Gtk.main_quit())
else:
dialog.connect("response", lambda dialog, response: dialog.destroy())
self.center_dialog(dialog)
dialog.show()
def show_about(self):
dialog = self.get("about_prey_config")
self.center_dialog(dialog)
dialog.show()
def close_about(self, dialog, response):
dialog.hide()
def center_dialog(self, dialog):
if "window" in self.__dict__:
dialog.set_transient_for(self.window)
dialog.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
################################################
# window and widget management
################################################
def get_page_name(self):
return PAGES[self.pages.get_current_page()]
def toggle_pg3_next_apply(self, button):
button_next = self.get("button_next")
button_apply = self.get("button_apply")
if self.get("use_existing_device").get_active() is False:
button_next.hide()
button_apply.show()
button_apply.grab_default()
else:
button_apply.hide()
button_next.show()
button_next.grab_default()
def next_page(self, button):
page_name = self.get_page_name()
increment = 1
if (
page_name == "control_panel_options"
and self.get("new_user_option").get_active() is False
):
increment = 2
self.pages.set_current_page(self.pages.get_current_page() + increment)
self.toggle_buttons(button, None, 1)
def prev_page(self, button):
page_name = self.get_page_name()
decrement = 1
if page_name == "existing_user":
decrement = 2
# elif page_name == 'standalone_options':
# decrement = 5
if self.pages.get_current_page() != 0:
self.pages.set_current_page(self.pages.get_current_page() - decrement)
self.toggle_buttons(button, None, 1)
def toggle_buttons(self, button, tab, tab_number):
button_prev = self.get("button_prev")
button_next = self.get("button_next")
button_apply = self.get("button_apply")
if self.get_page_name() == "control_panel_options":
button_prev.hide()
button_apply.hide()
button_next.show()
button_next.grab_default()
else:
button_prev.show()
button_next.hide()
button_apply.show()
button_apply.grab_default()
def set_default_action(self, button, ctrl):
button_cancel = self.get("button_cancel")
cancel_has_default = button_cancel.flags() & Gtk.HAS_DEFAULT
button_prev = self.get("button_prev")
prev_has_default = button_prev.flags() & Gtk.HAS_DEFAULT
button_next = self.get("button_next")
button_apply = self.get("button_apply")
if not cancel_has_default and not prev_has_default:
if button_next.flags() & Gtk.VISIBLE:
button_next.grab_default()
else:
button_apply.grab_default()
# ensure the widget focused is visible in the scroll window
def ensure_visible(self, widget, event):
widget_name = widget.get_name()
internal_height = self.get("control_panel_options").get_size()[1]
widget_posn = widget.allocation.y
widget_height = widget.allocation.height
return True
# show about dialog on F1 keypress
def key_pressed(self, widget, event):
if (
(event.keyval == Gdk.KEY_F1)
and (event.get_state() & Gdk.ModifierType.CONTROL_MASK) == 0
and (event.get_state() & Gdk.ModifierType.SHIFT_MASK) == 0
):
self.show_about()
return True
return False
################################################
# setting settings
################################################
def apply_settings(self, button):
self.get("button_apply").set_label(_("Saving..."))
page_name = self.get_page_name()
if page_name == "new_user":
if self.validate_new_user_fields():
self.create_user()
elif page_name == "existing_user":
if self.validate_existing_user_fields():
self.get_existing_user(False)
self.get("button_apply").set_label("gtk-apply")
def client_configured(self):
self.call_prey_config("account verify", "--current")
return self.result == 0
def create_user(self):
name = self.text("user_name")
email = self.text("email")
password = self.text("password")
check_terms = self.get("check_terms_conds").get_active()
check_age = self.get("check_age").get_active()
terms = "no"
age = "no"
if check_terms is True:
terms = "yes"
if check_age is True:
age = "yes"
password = re.escape(password)
self.call_prey_config(
"account signup",
'-n "'
+ name
+ '" -e "'
+ email
+ '" -p '
+ password
+ ' -t "'
+ terms
+ '" -a "'
+ age
+ '"',
)
self.error_or_exit()
def get_existing_user(self, show_devices):
email = self.text("existing_email")
password = self.text("existing_password")
password = re.escape(password)
self.call_prey_config("account authorize", '-e "' + email + '" -p ' + password)
self.error_or_exit()
def call_prey_config(self, action, opts):
return self.run_command(PREY_CONFIG + " " + action + " " + opts)
def run_prey(self):
return self.run_command(PREY_BIN)
def run_command(self, cmd):
args = shlex.split(cmd)
proc = Popen(args, stdout=PIPE, shell=False)
self.out = proc.communicate()[0]
self.result = proc.returncode
return proc
def parse_error(self, line):
if line.find("been taken") != -1:
return "Email has been taken. Seems you already signed up!"
elif line.find("Unexpected status code: 401") != -1:
return "Invalid account credentials. Please try again."
return line
def error_or_exit(self):
if self.result == 0:
return self.exit_ok()
# self.run_prey()
# if self.result == 0:
# self.exit_ok()
# else:
# self.show_alert('Error', 'Something went wrong while running Prey. Please check the logfile for details.')
else:
lines = self.out.strip()
message = self.parse_error(lines)
self.show_error(message)
def show_error(self, message):
self.show_alert(_("Hold on!"), _(message), False)
def exit_ok(self):
self.show_alert(
_("Success"),
_(
"Sweet! Your computer is now protected by Prey. To try it out or to start tracking it, please visit preyproject.com."
),
True,
)
def __init__(self):
if not FORCE_CONFIG and self.client_configured():
return self.exit_ok()
builder = Gtk.Builder()
builder.set_translation_domain(APP_NAME)
builder.add_from_file(SCRIPT_PATH + "/prey-config.glade")
builder.connect_signals(
{
"on_window_destroy": Gtk.main_quit,
"prev_page": self.prev_page,
"next_page": self.next_page,
"toggle_buttons": self.toggle_buttons,
"apply_settings": self.apply_settings,
"toggle_pg3_next_apply": self.toggle_pg3_next_apply,
"set_default_action": self.set_default_action,
"ensure_visible": self.ensure_visible,
"key_pressed": self.key_pressed,
"close_about": self.close_about,
}
)
self.window = builder.get_object("window")
self.window.set_title(self.window.get_title() + " (v" + VERSION + ")")
# self.window.get_settings().set_string_property('gtk-font-name', 'sans normal 11','');
self.pages = builder.get_object("reporting_mode_tabs")
self.root = builder
about = self.get("about_prey_config")
about.set_version(VERSION)
if __name__ == "__main__":
app = PreyConfigurator()
Gtk.main()