#!/usr/share/ucs-test/runner python
## desc: Test the UMC group creation, modification and deletion
## bugs: [34792]
## roles:
##  - domaincontroller_master
##  - domaincontroller_backup
## exposure: dangerous

import sys
sys.path.insert(0, '.')
from TestUMCSystemModule import TestUMCSystem

import univention.testing.utils as utils
from univention.testing.strings import random_username


class TestUMCGroupsCreation(TestUMCSystem):

    def __init__(self):
        """Test Class constructor"""
        super(TestUMCGroupsCreation, self).__init__()
        self.ldap_base = None

    def create_group(self, groupname, policynames={}):
        """
        Creates a group with a provided 'groupname' and provided
        'policynames' if any for the test by making a UMC-request 'udm/add'.
        """
        options = [{"object": {"UVMMGroup": False,
                               "sambaGroupType": "2",
                               "name": groupname,
                               "adGroupType": "-2147483646",
                               "$options$": {"samba": True,
                                             "posix": True},
                               "$policies$": policynames},
                               "options": {"container": "cn=groups,"
                                                        + self.ldap_base,
                                           "objectType": "groups/group"}}]

        try:
            request_result = self.Connection.request('udm/add',
                                                     options,
                                                     'groups/group')
            if not request_result:
                utils.fail("Request 'udm/add' group with options '%s' failed, "
                           "hostname '%s'" % (options, self.hostname))
            if not request_result[0].get('success'):
                utils.fail("Request 'udm/add' group with options '%s' failed, "
                           "no success = True in response, hostname '%s'"
                           % (options, self.hostname))
        except Exception as exc:
            utils.fail("Exception while making 'udm/add' group request: %s" %
                       exc)

    def add_group_policy(self, groupname, policyname):
        """
        Adds the provided 'policyname' to the provided 'groupname'
        by making a UMC 'udm/put' request with respective options.
        """
        options = [{"object": {"$policies$":
                                {"policies/umc": "cn=" + policyname
                                                 + ",cn=UMC,cn=policies,"
                                                 + self.ldap_base},
                                 "$dn$": "cn=" + groupname + ",cn=groups,"
                                         + self.ldap_base},
                                 "options": {}}]
        try:
            request_result = self.Connection.request('udm/put',
                                                     options,
                                                     'groups/group')
            if not request_result:
                utils.fail("Request 'udm/put' to add policy to a group "
                           "with options '%s' failed, hostname %s"
                           % (options, self.hostname))
            if not request_result[0].get('success'):
                utils.fail("Request 'udm/put' to add policy to a group "
                           "with options '%s' failed, no success = True in "
                           "response, hostname %s" % (options, self.hostname))
        except Exception as exc:
            utils.fail("Exception while making 'udm/put' request: %s" %
                       exc)

    def get_group_by_name(self, groupname):
        """
        Returns the group data with 'groupname' by making a 'udm/get'
        UMC request.
        """
        options = ["cn=" + groupname + ",cn=groups," + self.ldap_base]
        try:
            request_result = self.Connection.request('udm/get', options,
                                                     'groups/group')
            if not request_result:
                utils.fail("Request 'udm/get' with options '%s' failed, "
                           "hostname '%s'" % (options, self.hostname))
            return request_result
        except Exception as exc:
            utils.fail("Exception while making 'udm/get' request: %s" %
                       exc)

    def main(self):
        """
        Method to test the UMC group creation, modification and deletion
        """
        self.get_ucr_credentials()
        self.create_connection_authenticate()
        self.ldap_base = self.UCR.get('ldap/base')

        test_groupname = 'umc_test_group_' + random_username(6)
        policyname = "default-udm-self"

        try:
            print "Creating a test group with a name '%s'" % test_groupname
            self.create_group(test_groupname)
            if not self.check_obj_exists(test_groupname, "groups/group"):
                utils.fail("Failed to query the newly created group '%s'"
                           % test_groupname)

            print("Adding a '%s' policy to a test group '%s'"
                  % (policyname, test_groupname))
            self.add_group_policy(test_groupname, policyname)

            print("Checking test group '%s' policies for '%s'"
                  % (test_groupname, policyname))
            group_policies = self.get_group_by_name(test_groupname)[0].get(
                                                                  '$policies$')
            if not group_policies:
                utils.fail("The group policies for '%s' are empty or not "
                           "present after '%s' policy was applied to group"
                           % (test_groupname, policyname))

            group_policies = group_policies.get('policies/umc')
            if not group_policies:
                utils.fail("The group 'policies/umc' field for '%s' is empty "
                           "or not present after '%s' policy was applied "
                           "to group" % (test_groupname, policyname))
            if not ('cn=' + policyname + ',cn=UMC,cn=policies,'
                    + self.ldap_base in group_policies):
                utils.fail("The policy '%s' is not in a group '%s' policies "
                           "'%s'" % (policyname,
                                     test_groupname,
                                     group_policies))
        finally:
            print "Removing created test group if it exists"
            if self.check_obj_exists(test_groupname, "groups/group"):
                self.delete_obj(test_groupname, "groups", "groups/group")


if __name__ == '__main__':
    TestUMC = TestUMCGroupsCreation()
    sys.exit(TestUMC.main())
