URL: https://github.com/freeipa/freeipa/pull/2355
Author: serg-cymbaluk
 Title: #2355: [Backport][ipa-4-7] Fix translation of "unauthorized" and 
"ssbrowser" WebUI pages
Action: opened

PR body:
"""
This PR was opened automatically because PR #2151 was pushed to master and 
backport to ipa-4-7 is required.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/2355/head:pr2355
git checkout pr2355
From 4b942dcd6047131ab4fa740e0ad607dfa26884a1 Mon Sep 17 00:00:00 2001
From: Stanislav Levin <s...@altlinux.org>
Date: Thu, 12 Jul 2018 22:05:39 +0300
Subject: [PATCH 1/3] Fix translation of "unauthorized.html" Web page

Make this page message translatable as other parts of IPA framework.

Fixes: https://pagure.io/freeipa/issue/7640
---
 install/html/unauthorized.html | 39 ++++++++++++++++++++++++++++++++++
 ipaserver/plugins/internal.py  | 17 +++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/install/html/unauthorized.html b/install/html/unauthorized.html
index 8c57ce822b..c8386f1a57 100644
--- a/install/html/unauthorized.html
+++ b/install/html/unauthorized.html
@@ -5,11 +5,46 @@
     <title>IPA: Identity Policy Audit</title>
     <script type="text/javascript" src="../ui/js/libs/loader.js"></script>
     <script type="text/javascript">
+        var dojoConfig = {
+            baseUrl: "../ui/js",
+            has: {
+                'dojo-firebug': false,
+                'dojo-debug-messages': true
+            },
+            parseOnLoad: false,
+            async: true,
+            packages: [
+                {
+                    name:'dojo',
+                    location:'dojo'
+                },
+                {
+                    name: 'freeipa',
+                    location: 'freeipa'
+                }
+            ]
+        };
         (function() {
             var styles = [
                 '../ui/css/patternfly.css',
                 '../ui/css/ipa.css'
             ];
+            var scripts = [
+                '../ui/js/libs/jquery.js',
+                '../ui/js/dojo/dojo.js'
+            ];
+
+            ipa_loader.scripts(scripts, function() {
+                require([
+                    'dojo/dom',
+                    'freeipa/text',
+                    'dojo/domReady!'],
+                    function(dom, text) {
+                        if (msg = text.get('@i18n:unauthorized-page')) {
+                            dom.byId('unauthorized-msg').innerHTML=msg;
+                        }
+                    });
+            });
             ipa_loader.styles(styles);
         })();
     </script>
@@ -26,6 +61,8 @@
     <div class="container-fluid">
     <div class="row">
     <div class="col-sm-12">
+    <div id="unauthorized-msg">
+    <noscript>
 
         <h1>Unable to verify your Kerberos credentials</h1>
         <p>
@@ -39,6 +76,8 @@ <h2>Browser configuration</h2>
                 If this is your first time, please <a href="ssbrowser.html">configure your browser</a>.
             </p>
         </div>
+    </noscript>
+    </div>
     </div>
     </div>
     </div>
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
index e5c8f720a1..d3574b5eeb 100644
--- a/ipaserver/plugins/internal.py
+++ b/ipaserver/plugins/internal.py
@@ -998,6 +998,23 @@ class i18n_messages(Command):
             "trust": _("Trusts"),
         },
         "true": _("True"),
+        "unauthorized-page": _(
+            "<h1>Unable to verify your Kerberos credentials</h1>\n"
+            "<p>\n"
+            "            Please make sure that you have valid Kerberos "
+            "tickets (obtainable via <strong>kinit</strong>), and that you"
+            " have configured your browser correctly.\n"
+            "</p>\n"
+            "\n"
+            "<h2>Browser configuration</h2>\n"
+            "\n"
+            "<div id=\"first-time\">\n"
+            "<p>\n"
+            "                If this is your first time, please <a href="
+            "\"ssbrowser.html\">configure your browser</a>.\n"
+            "</p>\n"
+            "</div>\n"
+        ),
         "widget": {
             "api_browser": _("API Browser"),
             "first": _("First"),

From acb066b34652ce99d731a30119270aa5d06c2def Mon Sep 17 00:00:00 2001
From: Stanislav Levin <s...@altlinux.org>
Date: Thu, 12 Jul 2018 23:19:04 +0300
Subject: [PATCH 2/3] Fix translation of "ssbrowser.html" Web page

Make this page message translatable as other parts of IPA framework.

Fixes: https://pagure.io/freeipa/issue/7640
---
 install/html/ssbrowser.html   |  46 ++++++++-
 ipaserver/plugins/internal.py | 182 ++++++++++++++++++++++++++++++++++
 2 files changed, 225 insertions(+), 3 deletions(-)

diff --git a/install/html/ssbrowser.html b/install/html/ssbrowser.html
index bf64eda85a..9e3886193f 100644
--- a/install/html/ssbrowser.html
+++ b/install/html/ssbrowser.html
@@ -5,15 +5,53 @@
     <title>IPA: Identity Policy Audit</title>
     <script type="text/javascript" src="../ui/js/libs/loader.js"></script>
     <script type="text/javascript">
+        var dojoConfig = {
+            baseUrl: "../ui/js",
+            has: {
+                'dojo-firebug': false,
+                'dojo-debug-messages': true
+            },
+            parseOnLoad: false,
+            async: true,
+            packages: [
+                {
+                    name:'dojo',
+                    location:'dojo'
+                },
+                {
+                    name: 'freeipa',
+                    location: 'freeipa'
+                }
+            ]
+        };
         (function() {
             var styles = [
                 '../ui/css/patternfly.css',
                 '../ui/css/ipa.css'
             ];
             var scripts = [
-                '../ui/js/libs/jquery.js'
+                '../ui/js/libs/jquery.js',
+                '../ui/js/dojo/dojo.js'
             ];
-            ipa_loader.scripts(scripts);
+            ipa_loader.scripts(scripts, function() {
+                require([
+                    'dojo/dom',
+                    'freeipa/text',
+                    'dojo/domReady!'],
+                    function(dom, text) {
+                        msg = "".concat(
+                            text.get('@i18n:ssbrowser-page.header'),
+                            text.get('@i18n:ssbrowser-page.firefox-header'),
+                            text.get('@i18n:ssbrowser-page.firefox-actions'),
+                            text.get('@i18n:ssbrowser-page.chrome-header'),
+                            text.get('@i18n:ssbrowser-page.chrome-certificate'),
+                            text.get('@i18n:ssbrowser-page.chrome-spnego'),
+                            text.get('@i18n:ssbrowser-page.ie-header'),
+                            text.get('@i18n:ssbrowser-page.ie-actions'),
+                        )
+                        dom.byId('ssbrowser-msg').innerHTML=msg;
+                    });
+            });
             ipa_loader.styles(styles);
         })();
     </script>
@@ -31,7 +69,8 @@
     <div class="container-fluid">
     <div class="row">
     <div class="col-sm-12">
-    <div class="ssbrowser">
+    <div class="ssbrowser" id="ssbrowser-msg">
+    <noscript>
         <h1>Browser Kerberos Setup</h1>
 
         <h2>Firefox</h2>
@@ -149,6 +188,7 @@ <h2>Internet Explorer</h2>
             </ol>
         </div>
 
+    </noscript>
     </div>
     </div>
     </div>
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
index d3574b5eeb..9465287bcc 100644
--- a/ipaserver/plugins/internal.py
+++ b/ipaserver/plugins/internal.py
@@ -972,6 +972,188 @@ class i18n_messages(Command):
             "truncated": _("Query returned more results than the configured size limit. Displaying the first ${counter} results."),
             "unselect_all": _("Unselect All"),
         },
+        "ssbrowser-page": {
+            "header": _(
+                "<h1>Browser Kerberos Setup</h1>\n"
+                "\n"
+            ),
+            "firefox-header": _(
+                "<h2>Firefox</h2>\n"
+                "\n"
+                "<p>\n"
+                "            You can configure Firefox to use Kerberos for "
+                "Single Sign-on. The following instructions will guide you in "
+                "configuring your web browser to send your Kerberos "
+                "credentials to the appropriate Key Distribution Center which "
+                "enables Single Sign-on.\n"
+                "</p>\n"
+                "\n"
+            ),
+            "firefox-actions": _(
+                "<ol>\n"
+                "<li>\n"
+                "<p>\n"
+                "<a href=\"ca.crt\" id=\"ca-link\" class=\"btn btn-default\">"
+                "Import Certificate Authority certificate</a>\n"
+                "</p>\n"
+                "<p>\n"
+                "                    Make sure you select <b>all three</b> "
+                "checkboxes.\n"
+                "</p>\n"
+                "</li>\n"
+                "<li>\n"
+                "                In the address bar of Firefox, type <code>"
+                "about:config</code> to display the list of current "
+                "configuration options.\n"
+                "</li>\n"
+                "<li>\n"
+                "                In the Filter field, type <code>negotiate"
+                "</code> to restrict the list of options.\n"
+                "</li>\n"
+                "<li>\n"
+                "                Double-click the <code>network.negotiate-auth"
+                ".trusted-uris</code> entry to display the Enter string value "
+                "dialog box.\n"
+                "</li>\n"
+                "<li>\n"
+                "                Enter the name of the domain against which "
+                "you want to authenticate, for example, <code class=\""
+                "example-domain\">.example.com.</code>\n"
+                "</li>\n"
+                "<li><a href=\"../ui/index.html\" id=\"return-link\" class=\""
+                "btn btn-default\">Return to Web UI</a></li>\n"
+                "</ol>\n"
+                "\n"
+            ),
+            "chrome-header": _(
+                "<h2>Chrome</h2>\n"
+                "\n"
+                "<p>\n"
+                "            You can configure Chrome to use Kerberos for "
+                "Single Sign-on. The following instructions will guide you in "
+                "configuring your web browser to send your Kerberos "
+                "credentials to the appropriate Key Distribution Center which "
+                "enables Single Sign-on.\n"
+                "</p>\n"
+                "\n"
+            ),
+            "chrome-certificate": _(
+                "<h3>Import CA Certificate</h3>\n"
+                "<ol>\n"
+                "<li>\n"
+                "                Download the <a href=\"ca.crt\">CA "
+                "certificate</a>. Alternatively, if the host is also an IdM "
+                "client, you can find the certificate in /etc/ipa/ca.crt.\n"
+                "</li>\n"
+                "<li>\n"
+                "                Click the menu button with the <em>Customize "
+                "and control Google Chrome</em> tooltip, which is by default "
+                "in the top right-hand corner of Chrome, and click <em>"
+                "Settings</em>.\n"
+                "</li>\n"
+                "<li>\n"
+                "                Click <em>Show advanced settings</em> to "
+                "display more options, and then click the <em>Manage "
+                "certificates</em> button located under the HTTPS/SSL heading."
+                "\n"
+                "</li>\n"
+                "<li>\n"
+                "                In the <em>Authorities</em> tab, click the "
+                "<em>Import</em> button at the bottom.\n"
+                "</li>\n"
+                "<li>Select the CA certificate file that you downloaded in the"
+                " first step.</li>\n"
+                "</ol>\n"
+                "\n"
+            ),
+            "chrome-spnego": _(
+                "<h3>\n"
+                "            Enable SPNEGO (Simple and Protected GSSAPI "
+                "Negotiation Mechanism) to Use Kerberos Authentication\n"
+                "            in Chrome\n"
+                "</h3>\n"
+                "<ol>\n"
+                "<li>\n"
+                "                Make sure you have the necessary directory "
+                "created by running:\n"
+                "<div><code>\n"
+                "                    [root@client]# mkdir -p /etc/opt/chrome/"
+                "policies/managed/\n"
+                "</code></div>\n"
+                "</li>\n"
+                "<li>\n"
+                "                Create a new <code>/etc/opt/chrome/policies/"
+                "managed/mydomain.json</code> file with write privileges "
+                "limited to the system administrator or root, and include the "
+                "following line:\n"
+                "<div><code>\n"
+                "                    { \"AuthServerWhitelist\": \"*<span "
+                "class=\"example-domain\">.example.com.</span>\" }\n"
+                "</code></div>\n"
+                "<div>\n"
+                "                    You can do this by running:\n"
+                "</div>\n"
+                "<div><code>\n"
+                "                    [root@server]# echo \'{ \""
+                "AuthServerWhitelist\": \"*<span class=\"example-domain\">"
+                ".example.com.</span>\" }' > /etc/opt/chrome/policies/managed/"
+                "mydomain.json\n"
+                "</code></div>\n"
+                "</li>\n"
+                "</ol>\n"
+                "<ol>\n"
+                "<p>\n"
+                "<strong>Note:</strong> If using Chromium, use <code>/etc/"
+                "chromium/policies/managed/</code> instead of <code>/etc/opt/"
+                "chrome/policies/managed/</code> for the two SPNEGO Chrome "
+                "configuration steps above.\n"
+                "</p>\n"
+                "</ol>\n"
+                "\n"
+            ),
+            "ie-header": _(
+                "<h2>Internet Explorer</h2>\n"
+                "<p><strong>WARNING:</strong> Internet Explorer is no longer a"
+                " supported browser.</p>\n"
+                "<p>\n"
+                "            Once you are able to log into the workstation "
+                "with your kerberos key you are now able to use that ticket in"
+                " Internet Explorer.\n"
+                "</p>\n"
+                "<p>\n"
+            ),
+            "ie-actions": _(
+                "<strong>Log into the Windows machine using an account of your"
+                " Kerberos realm (administrative domain)</strong>\n"
+                "</p>\n"
+                "<p>\n"
+                "<strong>In Internet Explorer, click Tools, and then click "
+                "Internet Options.</strong>\n"
+                "</p>\n"
+                "<div>\n"
+                "<ol>\n"
+                "<li>Click the Security tab</li>\n"
+                "<li>Click Local intranet</li>\n"
+                "<li>Click Sites </li>\n"
+                "<li>Click Advanced </li>\n"
+                "<li>Add your domain to the list</li>\n"
+                "</ol>\n"
+                "<ol>\n"
+                "<li>Click the Security tab</li>\n"
+                "<li>Click Local intranet</li>\n"
+                "<li>Click Custom Level</li>\n"
+                "<li>Select Automatic logon only in Intranet zone</li>\n"
+                "</ol>\n"
+                "\n"
+                "<ol>\n"
+                "<li> Visit a kerberized web site using IE (You must use the "
+                "fully-qualified Domain Name in the URL)</li>\n"
+                "<li><strong> You are all set.</strong></li>\n"
+                "</ol>\n"
+                "</div>\n"
+                "\n"
+            ),
+        },
         "status": {
             "disable": _("Disable"),
             "disabled": _("Disabled"),

From 0a01abaf0a97ad9bf4f03fe37aba320e94c0913a Mon Sep 17 00:00:00 2001
From: Stanislav Levin <s...@altlinux.org>
Date: Mon, 27 Aug 2018 21:19:11 +0300
Subject: [PATCH 3/3] Add basic tests to web pages which are located at
 /ipa/config/

The goal of these tests is to ensure that the translated text is
synced against a 'noscript' one.

Fixes: https://pagure.io/freeipa/issue/7640
---
 ipatests/test_webui/test_translation.py | 159 ++++++++++++++++++++++++
 1 file changed, 159 insertions(+)
 create mode 100644 ipatests/test_webui/test_translation.py

diff --git a/ipatests/test_webui/test_translation.py b/ipatests/test_webui/test_translation.py
new file mode 100644
index 0000000000..579fffc32d
--- /dev/null
+++ b/ipatests/test_webui/test_translation.py
@@ -0,0 +1,159 @@
+#
+# Copyright (C) 2018  FreeIPA Contributors see COPYING for license
+#
+
+"""
+Test translations
+"""
+
+from ipatests.test_webui.ui_driver import UI_driver
+from ipatests.test_webui.ui_driver import screenshot
+
+try:
+    from selenium.webdriver.common.by import By
+    from selenium.webdriver.support.wait import WebDriverWait
+except ImportError:
+    pass
+
+import pytest
+from re import sub
+from lxml import html
+from ipalib import api, util
+
+
+class ConfigPageBase(UI_driver):
+    """
+    Base class to test translation of pages which are located at /ipa/config/
+    """
+
+    page_name = ''
+
+    def init_app(self):
+        """
+        Load a web page
+        """
+        self.url = '/'.join((self.get_base_url(), self.page_name))
+        self.load()
+
+    def get_base_url(self):
+        """
+        Get FreeIPA Web UI config url
+        """
+        host = self.config.get('ipa_server')
+        if not host:
+            self.skip('FreeIPA server hostname not configured')
+        return 'https://%s/ipa/config' % host
+
+    def files_loaded(self):
+        """
+        Test if dependencies were loaded. (Checks if page has been rendered)
+        """
+        indicator = self.find(".info-page", By.CSS_SELECTOR)
+        return indicator is not None
+
+    def load(self):
+        """
+        Navigate to Web page and wait for loading of all dependencies.
+        """
+        self.driver.get(self.url)
+        runner = self
+        WebDriverWait(self.driver, 10).until(
+            lambda d: runner.files_loaded()
+        )
+
+    def page_raw_source(self):
+        """
+        Retrieve a raw source of the web page
+        """
+        host = api.env.host
+        cacert = api.env.tls_ca_cert
+        conn = util.create_https_connection(host, cafile=cacert)
+        conn.request('GET', self.url)
+        response = conn.getresponse()
+        # check successful response from a server
+        assert response.status == 200
+        return response.read().decode('utf-8')
+
+    def has_no_child(self, tag, child_tag):
+        """
+        Check if element with the given tag has no child with the given one
+        """
+        parent = self.find("#{}".format(tag), By.CSS_SELECTOR)
+        if parent is None:
+            return True
+        child_element = self.find(".//{}".format(child_tag), By.XPATH, parent)
+        return child_element is None
+
+    def innerhtml(self, id):
+        """
+        Extract html text from the current opened page by the given id
+        """
+        dom_element = self.find("#{}".format(id), By.CSS_SELECTOR)
+        return dom_element.get_attribute('innerHTML').split('\n')
+
+    def innerhtml_noscript(self, id, raw_page):
+        """
+        Extract html text from the given raw source of the page under the
+        'noscript' html tag with the given id
+        """
+        html_tree = html.fromstring(raw_page)
+        noscript_tree = html_tree.xpath(
+            "//div[@id='{}']/noscript/*".format(id)
+        )
+        noscript_html_text = ''.join([html.tostring(elem, encoding="unicode")
+                                      for elem in noscript_tree])
+        noscript_html = []
+        # remove trailing whitespaces between close and open tags
+        for html_row in noscript_html_text.split('\n'):
+            noscript_html.append(sub('^[ ]+(?=(<|[ ]*$))', '', html_row))
+        return noscript_html
+
+    def check_noscript_innerhtml(self, html_id):
+        """
+        Compare inner html under enabled javascript and disabled one
+        """
+        # check if js is enabled in browser
+        assert self.has_no_child(html_id, 'noscript')
+        html_js_enabled = self.innerhtml(html_id)
+
+        raw_page = self.page_raw_source()
+        html_js_disabled = self.innerhtml_noscript(html_id, raw_page)
+        assert html_js_enabled == html_js_disabled
+
+
+@pytest.mark.tier1
+class TestSsbrowserPage(ConfigPageBase):
+    """
+    Test translation of ssbrowser.html page
+    """
+
+    page_name = 'ssbrowser.html'
+
+    @screenshot
+    def test_long_text_of_ssbrowser_page(self):
+        """
+        Tests whether the text from '@i18n:ssbrowser-page' is synced
+        against '<noscript>' tag to ensure a similarity of the behavior.
+        """
+
+        self.init_app()
+        self.check_noscript_innerhtml('ssbrowser-msg')
+
+
+@pytest.mark.tier1
+class TestUnauthorizedPage(ConfigPageBase):
+    """
+    Test translation of unauthorized.html page
+    """
+
+    page_name = 'unauthorized.html'
+
+    @screenshot
+    def test_long_text_of_unauthorized_page(self):
+        """
+        Tests whether the text from '@i18n:unauthorized-page' is synced
+        against '<noscript>' tag to ensure a similarity of the behavior.
+        """
+
+        self.init_app()
+        self.check_noscript_innerhtml('unauthorized-msg')
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org

Reply via email to