1# This file is part of Xpra.
2# Copyright (C) 2017-2020 Antoine Martin <antoine@xpra.org>
3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
4# later version. See the file COPYING for details.
5
6import sys
7import gi
8gi.require_version("Gtk", "3.0")
9gi.require_version("Pango", "1.0")
10gi.require_version("GdkPixbuf", "2.0")
11from gi.repository import GLib, Pango, Gtk
12
13from xpra.gtk_common.gtk_util import add_close_accel, get_icon_pixbuf
14from xpra.gtk_common.gobject_compat import register_os_signals
15from xpra.log import Logger
16
17log = Logger("util")
18
19
20class AuthDialog(Gtk.Window):
21
22    def __init__(self, title="Session Access Request", info="unknown user from unknown location", timeout=600):
23        super().__init__()
24        self.timeout = timeout
25        self.exit_code = 1
26        self.set_title(title)
27        self.set_border_width(20)
28        self.set_resizable(True)
29        self.set_decorated(True)
30        icon = get_icon_pixbuf("authentication.png")
31        if icon:
32            self.set_icon(icon)
33        add_close_accel(self, self.quit)
34        self.connect("delete_event", self.quit)
35
36        self.vbox = Gtk.VBox(False, 20)
37        self.add(self.vbox)
38
39        title_label = Gtk.Label(title)
40        title_label.modify_font(Pango.FontDescription("sans 14"))
41        self.vbox.add(title_label)
42
43        info_label = Gtk.Label(info)
44        info_label.modify_font(Pango.FontDescription("sans 12"))
45        self.vbox.add(info_label)
46
47        if self.timeout>0:
48            self.timeout_label = Gtk.Label()
49            self.update_timeout()
50            self.vbox.add(self.timeout_label)
51            GLib.timeout_add(1000, self.update_timeout)
52
53        #buttons:
54        al = Gtk.Alignment(xalign=1.0, yalign=0.5, xscale=0.0, yscale=0.0)
55        al.set_padding(0, 0, 10, 10)
56        hbox = Gtk.HBox(False, 10)
57        al.add(hbox)
58        hbox.add(self.btn("Cancel", Gtk.STOCK_NO, self.cancel))
59        hbox.add(self.btn("Accept", Gtk.STOCK_OK, self.accept))
60        self.vbox.add(al)
61
62        register_os_signals(self.app_signal, "Authentication Dialog")
63        self.show_all()
64
65    def btn(self, label, stock_icon, callback):
66        btn = Gtk.Button(label)
67        settings = btn.get_settings()
68        settings.set_property('gtk-button-images', True)
69        btn.connect("clicked", callback)
70        if stock_icon:
71            image = Gtk.Image.new_from_stock(stock_icon, Gtk.IconSize.BUTTON)
72            if image:
73                btn.set_image(image)
74        return btn
75
76    def update_timeout(self):
77        if self.timeout<=0:
78            self.exit_code = 2
79            self.quit()
80            return False
81        self.timeout_label.set_text("This request will timeout in %i seconds" % self.timeout)
82        self.timeout -= 1
83        return True
84
85    def cancel(self, _btn):
86        self.exit_code = 3
87        self.quit()
88
89    def accept(self, _btn):
90        self.exit_code = 0
91        self.quit()
92
93    def quit(self, *args):
94        log("quit%s", args)
95        self.do_quit()
96
97    def do_quit(self):
98        log("do_quit()")
99        Gtk.main_quit()
100
101    def app_signal(self, signum):
102        self.exit_code = 128 + signum
103        log("app_signal(%s) exit_code=%i", signum, self.exit_code)
104        self.do_quit()
105
106
107def main():
108    from xpra.platform import program_context
109    with program_context("Session Access"):
110        from xpra.platform.gui import init as gui_init
111        gui_init()
112        if len(sys.argv)<2:
113            sys.stderr.write("usage: %s 'message' [timeout-in-seconds]\n" % sys.argv[0])
114            sys.exit(4)
115        info = sys.argv[1]
116        if len(sys.argv)>=3:
117            timeout = int(sys.argv[2])
118        else:
119            timeout = 600
120        w = AuthDialog(info=info, timeout=timeout)
121        Gtk.main()
122        return w.exit_code
123
124
125if __name__ == "__main__":
126    r = main()
127    sys.exit(r)
128