#!/usr/bin/python2
# -*- coding: utf-8 -*-

# This file is part of Cockpit.
#
# Copyright (C) 2015 Red Hat, Inc.
#
# Cockpit is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Cockpit is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.

import parent
from testlib import *
from storagelib import *

class TestStorage(StorageCase):
    def testLuks(self):
        m = self.machine
        b = self.browser

        mount_point_secret = "/run/secret"

        self.login_and_go("/storage")

        # Add a disk and partition it
        m.add_disk("50M", serial="MYDISK")
        b.wait_in_text("#drives", "MYDISK")
        b.click('tr:contains("MYDISK")')
        b.wait_visible("#storage-detail")
        b.click('button:contains(Create partition table)')
        self.dialog({ "type": "gpt" })
        self.content_row_wait_in_col(1, 1, "Free Space")

        assert m.execute("grep -v ^# /etc/crypttab || true").strip() == ""

        # Format it with luks
        self.content_row_action(1, "Create Partition")
        self.dialog({ "size": 10,
                      "type": "luks+ext4",
                      "name": "ENCRYPTED",
                      "passphrase": "vainu-reku-toma-rolle-kaja",
                      "passphrase2": "vainu-reku-toma-rolle-kaja",
                      "store_passphrase": True,
                      "mounting": "custom",
                      "mount_point": mount_point_secret,
                      "crypto_extra_options": CheckBoxText("crypto,options") })
        self.content_row_wait_in_col(1, 1, "Encrypted data")
        self.content_row_wait_in_col(2, 1, "ext4 File System")

        if not self.storaged_is_old_udisks:
            self.wait_in_storaged_configuration(mount_point_secret)
            self.wait_in_storaged_configuration("crypto,options")
            # HACK: Put /etc/crypttab in the journal, in order to debug updating issues
            assert m.execute("cat /etc/crypttab | logger -s 2>&1 | grep 'UUID='") != ""
            assert m.execute("grep %s /etc/fstab" % mount_point_secret) != ""
            assert m.execute("cat /etc/luks-keys/*") == "vainu-reku-toma-rolle-kaja"

        # Lock it
        self.content_head_action(1, "Lock")
        b.wait_not_in_text("#detail-content", "ext4 File System")

        if not self.storaged_is_old_udisks:

            # Unlock, this uses the stored passphrase
            self.content_head_action(1, "Unlock")
            self.content_row_wait_in_col(2, 1, "ext4 File System")

            # Change options.  We keep trying until the stack has synched
            # up with crypttab and we see the old options.
            self.dialog_with_retry(trigger = lambda: self.content_tab_info_action(1, 2, "Options"),
                                   expect = { "crypto_extra_options": CheckBoxText("crypto,options") },
                                   values = { "crypto_extra_options": CheckBoxText("weird,options") })

            assert m.execute("grep 'weird,options' /etc/crypttab") != ""
            self.wait_in_storaged_configuration("weird,options")

            # Change passphrase
            edit_button = self.content_tab_info_row(1, 2, "Stored passphrase") + " button"
            self.dialog_with_retry(trigger = lambda: b.click(edit_button),
                                   expect = { "passphrase": "vainu-reku-toma-rolle-kaja" },
                                   values = { "passphrase": "wrong-passphrase" })

            assert m.execute("cat /etc/luks-keys/*") == "wrong-passphrase"

            # Remove passphrase
            edit_button = self.content_tab_info_row(1, 2, "Stored passphrase") + " button"
            self.dialog_with_retry(trigger = lambda: b.click(edit_button),
                                   expect = { "passphrase": "wrong-passphrase" },
                                   values = { "passphrase": "" })
            self.wait_in_storaged_configuration("'passphrase-path': <b''>")

            # Lock it
            self.content_head_action(1, "Lock")
            b.wait_not_in_text("#detail-content", "ext4 File System")

            # Unlock, this asks for a passphrase
            self.content_head_action(1, "Unlock")
            self.dialog({ "passphrase": "vainu-reku-toma-rolle-kaja" })
            self.content_row_wait_in_col(2, 1, "ext4 File System")

            # Delete the partition.
            self.content_head_action(1, "Delete")
            self.confirm()
            self.content_row_wait_in_col(1, 1, "Free Space")
            b.wait_not_in_text("#detail-content", "ext4 File System")

        else:

            # Unlock, this asks for a passphrase because we don't store one with older UDisks2.
            self.content_head_action(1, "Unlock")
            self.dialog({ "passphrase": "vainu-reku-toma-rolle-kaja" })
            self.content_row_wait_in_col(2, 1, "ext4 File System")

        assert m.execute("grep -v ^# /etc/crypttab || true").strip() == ""
        assert m.execute("grep %s /etc/fstab || true" % mount_point_secret) == ""

if __name__ == '__main__':
    test_main()
