Philipp Hörist pushed to branch master at gajim / gajim
Commits: 6e9b605c by Daniel Brötzmann at 2019-04-26T17:53:10Z Certificate dialog: Add copy info button
- - - - - a8bd8abe by Philipp Hörist at 2019-04-26T17:53:10Z Add test for CertificateDialog
- - - - -
3 changed files:
- gajim/data/gui/certificate_dialog.ui - gajim/gtk/dialogs.py - + test/gtk/certificate_dialog.py
Changes:
===================================== gajim/data/gui/certificate_dialog.ui ===================================== @@ -160,6 +160,10 @@ <property name="can_focus">False</property> <property name="halign">start</property> <property name="label"><></property> + <property name="wrap">True</property> + <property name="wrap_mode">char</property> + <property name="selectable">True</property> + <property name="max_width_chars">21</property> </object> <packing> <property name="left_attach">1</property> @@ -435,6 +439,31 @@ <property name="width">2</property> </packing> </child> + <child> + <object class="GtkButton" id="copy_cert_info_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes">Copy Certificate Information</property> + <property name="halign">end</property> + <signal name="clicked" handler="_on_copy_cert_info_button_clicked" swapped="no"/> + <child> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">edit-copy-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">17</property> + </packing> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="expand">False</property>
===================================== gajim/gtk/dialogs.py ===================================== @@ -18,6 +18,7 @@ from collections import namedtuple
from gi.repository import GLib from gi.repository import Gtk +from gi.repository import Gdk from gi.repository import Pango
from gajim.common import app @@ -894,39 +895,68 @@ class CertificateDialog(Gtk.ApplicationWindow): self._ui = get_builder('certificate_dialog.ui') self.add(self._ui.certificate_box)
+ self._clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + + # Get data for labels and copy button issuer = cert.get_issuer() subject = cert.get_subject()
- self._ui.label_cert_for_account.set_text( - _('Certificate for account\n%s') % account) - - self._ui.data_it_common_name.set_text(subject.commonName or '') - self._ui.data_it_organization.set_text(subject.organizationName or '') - self._ui.data_it_organizational_unit.set_text( - subject.organizationalUnitName or '') - self._ui.data_it_serial_number.set_text(str(cert.get_serial_number())) - - self._ui.data_ib_common_name.set_text(issuer.commonName or '') - self._ui.data_ib_organization.set_text(issuer.organizationName or '') - self._ui.data_ib_organizational_unit.set_text( - issuer.organizationalUnitName or '') - + self._headline = _('Certificate for account\n%s') % account + self._it_common_name = subject.commonName or '' + self._it_organization = subject.organizationName or '' + self._it_org_unit = subject.organizationalUnitName or '' + self._it_serial_number = str(cert.get_serial_number()) + self._ib_common_name = issuer.commonName or '' + self._ib_organization = issuer.organizationName or '' + self._ib_org_unit = issuer.organizationalUnitName or '' issued = datetime.strptime(cert.get_notBefore().decode('ascii'), - '%Y%m%d%H%M%SZ') - issued = issued.strftime('%B %d, %Y, %H:%M:%S %z') - self._ui.data_issued_on.set_text(issued) + '%Y%m%d%H%M%SZ') + self._issued = issued.strftime('%B %d, %Y, %H:%M:%S %z') expires = datetime.strptime(cert.get_notAfter().decode('ascii'), - '%Y%m%d%H%M%SZ') - expires = expires.strftime('%B %d, %Y, %H:%M:%S %z') - self._ui.data_expires_on.set_text(expires) - - self._ui.data_sha1.set_text(cert.digest('sha1').decode('utf-8')) - self._ui.data_sha256.set_text(cert.digest('sha256').decode('utf-8')) + '%Y%m%d%H%M%SZ') + self._expires = expires.strftime('%B %d, %Y, %H:%M:%S %z') + self._sha1 = cert.digest('sha1').decode('utf-8') + self._sha256 = cert.digest('sha256').decode('utf-8') + + # Set labels + self._ui.label_cert_for_account.set_text(self._headline) + self._ui.data_it_common_name.set_text(self._it_common_name) + self._ui.data_it_organization.set_text(self._it_organization) + self._ui.data_it_organizational_unit.set_text(self._it_org_unit) + self._ui.data_it_serial_number.set_text(self._it_serial_number) + self._ui.data_ib_common_name.set_text(self._ib_common_name) + self._ui.data_ib_organization.set_text(self._ib_organization) + self._ui.data_ib_organizational_unit.set_text(self._ib_org_unit) + self._ui.data_issued_on.set_text(self._issued) + self._ui.data_expires_on.set_text(self._expires) + self._ui.data_sha1.set_text(self._sha1) + self._ui.data_sha256.set_text(self._sha256)
self.set_transient_for(transient_for) self._ui.connect_signals(self) self.show_all()
+ def _on_copy_cert_info_button_clicked(self, widget): + clipboard_text = \ + self._headline + '\n\n' + \ + _('Issued to\n') + \ + _('Common Name (CN): ') + self._it_common_name + '\n' + \ + _('Organization (O): ') + self._it_organization + '\n' + \ + _('Organizational Unit (OU): ') + self._it_org_unit + '\n' + \ + _('Serial Number: ') + self._it_serial_number + '\n\n' + \ + _('Issued by\n') + \ + _('Common Name (CN): ') + self._ib_common_name + '\n' + \ + _('Organization (O): ') + self._ib_organization + '\n' + \ + _('Organizational Unit (OU): ') + self._ib_org_unit + '\n\n' + \ + _('Validity\n') + \ + _('Issued on: ') + self._issued + '\n' + \ + _('Expires on: ') + self._expires + '\n\n' + \ + _('SHA-1:') + '\n' + \ + self._sha1 + '\n' + \ + _('SHA-256:') + '\n' + \ + self._sha256 + '\n' + self._clipboard.set_text(clipboard_text, -1) +
class SSLErrorDialog(ConfirmationDialogDoubleCheck): def __init__(self, account, certificate, pritext, sectext, checktext1,
===================================== test/gtk/certificate_dialog.py ===================================== @@ -0,0 +1,51 @@ +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +import OpenSSL + +from test.gtk import util +from gajim.common.const import CSSPriority +from gajim.gtk.dialogs import CertificateDialog + +util.load_style('gajim.css', CSSPriority.APPLICATION) + +cert = ''' +-----BEGIN CERTIFICATE----- +MIIFhDCCBGygAwIBAgISA4oUEifTr7Y+mcdiwu6KWpcVMA0GCSqGSIb3DQEBCwUA +MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD +ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTA0MDMxODE3NDVaFw0x +OTA3MDIxODE3NDVaMBsxGTAXBgNVBAMMECoubGlnaHR3aXRjaC5vcmcwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/3mcevikse7QwDYwPcGAD9zHw3UWE +7J8SJR349/rFTF2tBFDvEa62OUKTCg5vPKVKaXHlzruk/A7blgqsEdugycORwPD1 +7YNJ27EldrRtotjclurzKL6D/MgcaQ4cTkPOD3cWbf/L+HClGrpFt7su6Z6cTutC +wiAYAdlfmVgSSv15F1xOTyFyfGJKQnW628Xs8xUvZh5H/SsEEum4MwVVGW06Z/A/ +mwX2jmJUb2M25S1Ma025nZpGYyAAqecTmPb3fStnXm4sdytfZhm4+nj9mH9GQIU1 +t/jO/7X7IFpc9DvVRSumSVqvNaVgiWmTLP4VxlCVJO6mibOXXUUDA5RfAgMBAAGj +ggKRMIICjTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG +AQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFC4/ZRurw2wVFsgJBTb9Fh/3 +0aV9MB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMG8GCCsGAQUFBwEB +BGMwYTAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0 +Lm9yZzAvBggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNyeXB0 +Lm9yZy8wSQYDVR0RBEIwQIIQKi5saWdodHdpdGNoLm9yZ4IOKi5tZXRyb25vbWUu +aW2CDmxpZ2h0d2l0Y2gub3JnggxtZXRyb25vbWUuaW0wTAYDVR0gBEUwQzAIBgZn +gQwBAgEwNwYLKwYBBAGC3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5s +ZXRzZW5jcnlwdC5vcmcwggECBgorBgEEAdZ5AgQCBIHzBIHwAO4AdQB0ftqDMa0z +EJEhnM4lT0Jwwr/9XkIgCMY3NXnmEHvMVgAAAWnkosBAAAAEAwBGMEQCICEfmTBk +OxS95eiYsfTH5HdL7kfp68BSin5LqeGyyxk9AiA3qeDZNKklJTdWqYjto7kUqJNd +YiL99SrqwzR6w+AqSwB1ACk8UZZUyDlluqpQ/FgH1Ldvv1h6KXLcpMMM9OVFR/R4 +AAABaeSiwEUAAAQDAEYwRAIgFxouOkJeqkQUe6zNI5w/6YBIQFrsrIZdPcX+r6JI +is8CIEEETzlEyj9lWR/BSSruSp0FT5CuoNNeEG7HxrJ+gVhZMA0GCSqGSIb3DQEB +CwUAA4IBAQAQtfs1NPNMmBQRcKsZyGLZsvpp2hIhdYi72RYnHnIl4MXbhyNj9xtI +cJr9PQ+3FsSnxy7LDjZMpbmBuXhawOyPBPw2M0f0Tv6Eo6miwvP/X1kLE3VjTzCo +6JPh6bEB5wa+kH/pUcGlV6uyT7IuXOiArx0VmIpTA3uwlVdfynOnR3CF20Ds4FLc +JxbGMqRuw/sGiTLKlXc1xVil8WZjL3hokzrgI7K6np2skUjWuMZvhJgwi5QiE7/C +ejsJoYkpvcaiaLAyVymTY/n/oM2oQpv5Mqjit+18RB9c2P+ifH5iDKC/jTKn4NNz +8xSTlUlCBTCozjzscZVeVDIojmejWclT +-----END CERTIFICATE-----''' + +cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) +win = CertificateDialog(None, 'testacc', cert) +win.connect("destroy", Gtk.main_quit) +win.show_all() +Gtk.main()
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/5d795b4c1e631d45fa7bf59455b40e9d47...