def test_department(self):
     '''
     Test department lookups.
     '''
     mockldap = MockLdap({
         'o=Novell': {'o': 'Novell'},
         'cn=mcihar,o=Novell': {
             'mail': ['*****@*****.**'],
             'ou': ['TestDept'],
             'cn': ['mcihar'],
             'uid': ['mcihar'],
         },
         'cn=foobar,o=Novell': {
             'mail': ['*****@*****.**'],
             'ou': ['L3 Maintenance'],
             'cn': ['foobar'],
             'uid': ['foobar'],
         },
     })
     mockldap.start()
     try:
         userinfo = UserInfo('ldap://ldap', 'o=novell')
         # By mail with fixup
         self.assertEqual(
             'L3/Maintenance',
             userinfo.get_department('*****@*****.**')
         )
         # By UID
         self.assertEqual(
             'TestDept',
             userinfo.get_department('mcihar')
         )
         # By UID from cache
         self.assertEqual(
             'TestDept',
             userinfo.get_department('mcihar')
         )
         # By email
         self.assertEqual(
             'TestDept',
             userinfo.get_department('*****@*****.**')
         )
         # Hardcoded entries
         self.assertEqual(
             'Security team',
             userinfo.get_department('*****@*****.**')
         )
         # Non existing entry
         self.assertEqual(
             'N/A',
             userinfo.get_department('nobody')
         )
     finally:
         mockldap.stop()
示例#2
0
def start_ldap_mock():
    """
    Starts LDAP mocking.
    """
    mockldap = MockLdap({
        'o=Novell': {'o': 'Novell'},
        'cn=mcihar,o=Novell': {
            'mail': ['*****@*****.**'],
            'ou': ['TestDept'],
            'cn': ['mcihar'],
            'uid': ['mcihar'],
        },
        'cn=foobar,o=Novell': {
            'mail': ['*****@*****.**'],
            'ou': ['L3 Maintenance'],
            'cn': ['foobar'],
            'uid': ['foobar'],
        },
    })
    mockldap.start()
    return mockldap
 def setUpClass(cls):
     cls.mockldap = MockLdap(cls.directory)
示例#4
0
文件: tests.py 项目: quay/mockldap
    def test_no_default(self):
        mockldap = MockLdap()
        mockldap.start()

        self.assertRaises(KeyError, lambda: mockldap[''])
示例#5
0
class MinarcaDiskSpaceTest(WebCase):

    # Reset app and testcases on every test
    reset_app = True
    reset_testcases = False

    # Disable interactive mode.
    interactive = False

    # Data for LDAP mock.
    basedn = ('dc=nodomain', {
        'dc': ['nodomain'],
        'o': ['nodomain']})
    people = ('ou=People,dc=nodomain', {
        'ou': ['People'],
        'objectClass': ['organizationalUnit']})
    bob = ('uid=bob,ou=People,dc=nodomain', {
        'uid': ['bob'],
        'cn': ['bob'],
        'userPassword': ['password'],
        'homeDirectory': '/tmp/bob',
        'mail': ['*****@*****.**'],
        'description': ['v2'],
        'objectClass': ['person', 'organizationalPerson', 'inetOrgPerson', 'posixAccount']})

    # This is the content of our mock LDAP directory. It takes the form
    # {dn: {attr: [value, ...], ...}, ...}.
    directory = dict([
        basedn,
        people,
        bob,
    ])

    @classmethod
    def setup_server(cls):
        WebCase.setup_server(default_config={
            'AddMissingUser': '******',
            'LdapUri': '__default__',
            'LdapBaseDn': 'dc=nodomain',
            'MinarcaUserBaseDir': '/tmp/minarca-test',
            })

    def setUp(self):
        self.app.store.get_user('admin').user_root = '/tmp'
        # Mock LDAP
        self.mockldap = MockLdap(self.directory)
        self.mockldap.start()
        self.ldapobj = self.mockldap['ldap://localhost/']
        WebCase.setUp(self)
        self.plugin = MinarcaUserSetup(self.app)
        if not os.path.isdir('/tmp/minarca-test'):
            os.mkdir('/tmp/minarca-test')

    def tearDown(self):
        WebCase.tearDown(self)
        # Stop patching ldap.initialize and reset state.
        self.mockldap.stop()
        del self.ldapobj
        del self.mockldap
        shutil.rmtree('/tmp/minarca-test')

    def test_login(self):
        """
        Check if new user is created with user_root and email.
        """
        userobj = self.app.store.login('bob', 'password')
        self.assertIsNotNone(userobj)
        self.assertIsNotNone(self.app.store.get_user('bob'))
        # Check if profile get update from Ldap info.
        self.assertEquals('*****@*****.**', self.app.store.get_user('bob').email)
        self.assertEquals('/tmp/minarca-test/bob', self.app.store.get_user('bob').user_root)

    @httpretty.activate
    def test_set_disk_quota(self):
        httpretty.register_uri(httpretty.POST, "http://localhost:8081/quota/bob",
                               body='{"avail": 2147483648, "used": 0, "size": 2147483648}')
        userobj = self.app.store.add_user('bob')
        self.plugin.set_disk_quota(userobj, quota=1234567)

    @httpretty.activate
    def test_update_userquota_401(self):
        # Checks if exception is raised when authentication is failing.
        httpretty.register_uri(httpretty.POST, "http://localhost:8081/quota/bob",
                               status=401)
        # Make sure an exception is raised.
        userobj = self.app.store.add_user('bob')
        with self.assertRaises(Exception):
            self.plugin.set_disk_quota(userobj, quota=1234567)

    @httpretty.activate
    def test_get_disk_usage(self):
        """
        Check if value is available.
        """
        # Checks if exception is raised when authentication is failing.
        httpretty.register_uri(httpretty.GET, "http://localhost:8081/quota/bob",
                               body='{"avail": 2147483648, "used": 0, "size": 2147483648}')
        # Make sure an exception is raised.
        userobj = self.app.store.add_user('bob')
        self.assertEquals({"avail": 2147483648, "used": 0, "size": 2147483648}, self.plugin.get_disk_usage(userobj))
        
    def test_get_api_minarca(self):
        self.app.cfg['minarcaremotehost'] = None
        self.app.cfg['minarcaremotehostidentity'] = None
        
        self._login('bob', 'password')
        self.getPage("/api/minarca")
        # Check version
        self.assertInBody('version')
        # Check remoteHost
        self.assertInBody('remotehost')
        self.assertInBody('127.0.0.1')
        # Check identity
        self.assertInBody('identity')
        
    def test_get_api_minarca_identity(self):
        self.app.cfg['minarcaremotehost'] = "test.examples:2222"
        self.app.cfg['minarcaremotehostidentity'] = pkg_resources.resource_filename(__name__, '')  # @UndefinedVariable
        self._login(self.USERNAME, self.PASSWORD)
        data = self.getJson("/api/minarca/")
        self.assertIn("[test.examples]:2222", data['identity'])

    def test_get_api_minarca_with_reverse_proxy(self):
        self.app.cfg['minarcaremotehost'] = None
        self.app.cfg['minarcaremotehostidentity'] = None
        
        # When behind an apache reverse proxy, minarca server should make use
        # of the Header to determine the public hostname provided.
        self._login('bob', 'password')
        headers = [
            ('X-Forwarded-For', '10.255.1.106'),
            ('X-Forwarded-Host', 'sestican.patrikdufresne.com'),
            ('X-Forwarded-Server', '10.255.1.106')]

        self.getPage("/api/minarca", headers=headers)
        self.assertInBody('remotehost')
        self.assertInBody('sestican.patrikdufresne.com')
        
    def test_get_help(self):
        # Check if help get redirect
        self.getPage("/help")
        self.assertStatus(303)
        self.assertHeader('Location', 'https://www.ikus-soft.com/en/support/#form')
        
        # Check if the URL can be changed
        self.app.cfg['minarcahelpurl'] = 'https://example.com/help/'
        self.getPage("/help")
        self.assertStatus(303)
        self.assertHeader('Location', 'https://example.com/help/')
示例#6
0
 def setup_class(cls):
     cls.mockldap = MockLdap(cls.directory)
示例#7
0
 def setUp(self):
     self.mock_ldap = MockLdap(self.directory)
     self.mock_ldap.start()
     self.ldapobj = self.mock_ldap['ldap://localhost/']
示例#8
0
def mock_ldap(requires_email=True):
    mock_data = {
        'dc=quay,dc=io': {
            'dc': ['quay', 'io']
        },
        'ou=employees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'employees'
        },
        'ou=otheremployees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'otheremployees'
        },
        'cn=AwesomeFolk,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'cn': 'AwesomeFolk'
        },
        'uid=testy,ou=employees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'employees',
            'uid': ['testy'],
            'userPassword': ['password'],
            'mail': ['*****@*****.**'],
            'memberOf':
            ['cn=AwesomeFolk,dc=quay,dc=io', 'cn=*Guys,dc=quay,dc=io'],
        },
        'uid=someuser,ou=employees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'employees',
            'uid': ['someuser'],
            'userPassword': ['somepass'],
            'mail': ['*****@*****.**'],
            'memberOf':
            ['cn=AwesomeFolk,dc=quay,dc=io', 'cn=*Guys,dc=quay,dc=io'],
        },
        'uid=nomail,ou=employees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'employees',
            'uid': ['nomail'],
            'userPassword': ['somepass']
        },
        'uid=cool.user,ou=employees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'employees',
            'uid': ['cool.user', 'referred'],
            'userPassword': ['somepass'],
            'mail': ['*****@*****.**']
        },
        'uid=referred,ou=employees,dc=quay,dc=io': {
            'uid': ['referred'],
            '_referral': 'ldap:///uid=cool.user,ou=employees,dc=quay,dc=io'
        },
        'uid=invalidreferred,ou=employees,dc=quay,dc=io': {
            'uid': ['invalidreferred'],
            '_referral':
            'ldap:///uid=someinvaliduser,ou=employees,dc=quay,dc=io'
        },
        'uid=multientry,ou=subgroup1,ou=employees,dc=quay,dc=io': {
            'uid': ['multientry'],
            'mail': ['*****@*****.**'],
            'userPassword': ['somepass'],
        },
        'uid=multientry,ou=subgroup2,ou=employees,dc=quay,dc=io': {
            'uid': ['multientry'],
            'another': ['key']
        },
        'uid=secondaryuser,ou=otheremployees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'otheremployees',
            'uid': ['secondaryuser'],
            'userPassword': ['somepass'],
            'mail': ['*****@*****.**']
        },

        # Feature: Email Blacklisting
        'uid=blacklistedcom,ou=otheremployees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'otheremployees',
            'uid': ['blacklistedcom'],
            'userPassword': ['somepass'],
            'mail': ['*****@*****.**']
        },
        'uid=blacklistednet,ou=otheremployees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'otheremployees',
            'uid': ['blacklistednet'],
            'userPassword': ['somepass'],
            'mail': ['*****@*****.**']
        },
        'uid=blacklistedorg,ou=otheremployees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'otheremployees',
            'uid': ['blacklistedorg'],
            'userPassword': ['somepass'],
            'mail': ['*****@*****.**']
        },
        'uid=notblacklistedcom,ou=otheremployees,dc=quay,dc=io': {
            'dc': ['quay', 'io'],
            'ou': 'otheremployees',
            'uid': ['notblacklistedcom'],
            'userPassword': ['somepass'],
            'mail': ['*****@*****.**']
        },
    }

    if not requires_email:
        for path in mock_data:
            mock_data[path].pop('mail', None)

    mockldap = MockLdap(mock_data)

    def initializer(uri, trace_level=0):
        obj = mockldap[uri]

        # Seed to "support" wildcard queries, which MockLDAP does not support natively.
        cool_block = {
            'dc': ['quay', 'io'],
            'ou': 'employees',
            'uid': ['cool.user', 'referred'],
            'userPassword': ['somepass'],
            'mail': ['*****@*****.**']
        }

        if not requires_email:
            cool_block.pop('mail', None)

        obj.search_s.seed('ou=employees,dc=quay,dc=io', 2,
                          '(|(uid=cool*)(mail=cool*))')([
                              ('uid=cool.user,ou=employees,dc=quay,dc=io',
                               cool_block)
                          ])

        obj.search_s.seed('ou=otheremployees,dc=quay,dc=io', 2,
                          '(|(uid=cool*)(mail=cool*))')([])

        obj.search_s.seed('ou=employees,dc=quay,dc=io', 2,
                          '(|(uid=unknown*)(mail=unknown*))')([])
        obj.search_s.seed('ou=otheremployees,dc=quay,dc=io', 2,
                          '(|(uid=unknown*)(mail=unknown*))')([])

        no_users_found_exception = Exception()
        no_users_found_exception.message = {
            'matched': 'dc=quay,dc=io',
            'desc': 'No such object'
        }

        obj.search_s.seed('ou=nonexistent,dc=quay,dc=io',
                          2)(no_users_found_exception)
        obj.search_s.seed('ou=employees,dc=quay,dc=io', 2)([
            ('uid=cool.user,ou=employees,dc=quay,dc=io', cool_block)
        ])
        obj.search.seed('ou=employees,dc=quay,dc=io', 2, '(objectClass=*)')([
            ('uid=cool.user,ou=employees,dc=quay,dc=io', cool_block)
        ])
        obj.search.seed('ou=employees,dc=quay,dc=io', 2)([
            ('uid=cool.user,ou=employees,dc=quay,dc=io', cool_block)
        ])

        obj._results = {}
        original_result_fn = obj.result

        def result(messageid):
            if messageid is None:
                return None, [], None, None

            # NOTE: Added because of weirdness with using mock-ldap.
            if isinstance(messageid, list):
                return None, messageid

            if messageid in obj._results:
                return obj._results[messageid]

            return original_result_fn(messageid)

        def result3(messageid):
            if messageid is None:
                return None, [], None, None

            return obj._results[messageid]

        def search_ext(user_search_dn,
                       scope,
                       search_flt=None,
                       serverctrls=None,
                       sizelimit=None,
                       attrlist=None):
            if scope != ldap.SCOPE_SUBTREE:
                return None

            if not serverctrls:
                if search_flt:
                    rdata = obj.search_s(user_search_dn,
                                         scope,
                                         search_flt,
                                         attrlist=attrlist)
                else:
                    if attrlist:
                        rdata = obj.search_s(user_search_dn,
                                             scope,
                                             attrlist=attrlist)
                    else:
                        rdata = obj.search_s(user_search_dn, scope)

                obj._results['messageid'] = (None, rdata)
                return 'messageid'

            page_control = serverctrls[0]
            if page_control.controlType != ldap.controls.SimplePagedResultsControl.controlType:
                return None

            if search_flt:
                msgid = obj.search(user_search_dn,
                                   scope,
                                   search_flt,
                                   attrlist=attrlist)
            else:
                if attrlist:
                    msgid = obj.search(user_search_dn,
                                       scope,
                                       attrlist=attrlist)
                else:
                    msgid = obj.search(user_search_dn, scope)

            _, rdata = obj.result(msgid)
            msgid = 'messageid'
            cookie = int(page_control.cookie) if page_control.cookie else 0

            results = rdata[cookie:cookie + page_control.size]
            cookie = cookie + page_control.size
            if cookie > len(results):
                page_control.cookie = None
            else:
                page_control.cookie = cookie

            obj._results['messageid'] = (None, results, None, [page_control])
            return msgid

        def search_ext_s(user_search_dn, scope, sizelimit=None):
            return [obj.search_s(user_search_dn, scope)]

        obj.search_ext = search_ext
        obj.result = result
        obj.result3 = result3
        obj.search_ext_s = search_ext_s

        return obj

    mockldap.start()
    with patch('ldap.initialize', new=initializer):
        yield _create_ldap(requires_email=requires_email)
    mockldap.stop()
示例#9
0
 def setUpClass(cls):
     cls.mockldap = MockLdap(vars.DIRECTORY)
示例#10
0
class BaseTestCase(XMLBaseTest):
    """
    Tests for L{DirectoryService}.
    """

    url = "ldap://localhost/"
    baseDN = u"dc=calendarserver,dc=org"
    realmName = unicode(url)


    def setUp(self):
        if MockLdap is None:
            raise SkipTest("No MockLdap available")

        def matches(self, dn, attrs, upcall=MockLDAPFilterTest.matches):
            if upcall(self, dn, attrs):
                return True
            else:
                return mockldap_matches(self, dn, attrs)


        self.patch(MockLDAPFilterTest, "_parse_expression", mockldap_parse)
        self.patch(MockLDAPFilterTest, "matches", mockldap_matches)

        self.xmlSeedService = xmlService(self.mktemp())
        self.mockData = mockDirectoryDataFromXMLService(self.xmlSeedService)

        if False:
            from pprint import pprint
            print("")
            print("-" * 80)
            pprint(self.mockData)
            print("-" * 80)

        self.mockLDAP = MockLdap(self.mockData)
        self.mockLDAP.start()


    def tearDown(self):
        self.mockLDAP.stop()


    def service(self, **kwargs):
        svc = TestService(
            url=self.url,
            baseDN=self.baseDN,
            fieldNameToAttributesMap=TEST_FIELDNAME_MAP,
            recordTypeSchemas=MappingProxyType({
                RecordType.user: RecordTypeSchema(
                    relativeDN=u"cn=user",

                    # (objectClass=inetOrgPerson)
                    attributes=(
                        (
                            LDAPAttribute.objectClass.value,
                            LDAPObjectClass.inetOrgPerson.value,
                        ),
                    ),
                ),

                RecordType.group: RecordTypeSchema(
                    relativeDN=u"cn=group",

                    # (objectClass=groupOfNames)
                    attributes=(
                        (
                            LDAPAttribute.objectClass.value,
                            LDAPObjectClass.groupOfUniqueNames.value,
                        ),
                    ),
                ),
            }),
            **kwargs
        )
        svc.fieldName = ConstantsContainer(
            (svc.fieldName, TestFieldName)
        )
        return svc
示例#11
0
 def setUpClass(self):
     # We only need to create the MockLdap instance once. The content we
     # pass in will be used for all LDAP connections.
     self.mockldap = MockLdap(self.directory)
示例#12
0
class OrloAuthTest(TestCase):
    """
    Base test class to setup the app
    """
    top = ('o=test', {'o': ['test']})
    example = ('ou=example,o=test', {'ou': ['example']})
    people = ('ou=people,ou=example,o=test', {'ou': ['other']})
    ldapuser = ('uid=ldapuser,ou=people,ou=example,o=test', {'uid': ['ldapuser'], 'userPassword': ['ldapuserpw']})
    # This is the content of our mock LDAP directory. It takes the form
    # {dn: {attr: [value, ...], ...}, ...}.
    directory = dict([top, example, people, ldapuser])

    def create_app(self):
        self.app = orlo.app
        self.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
        self.app.config['TESTING'] = True
        self.app.config['DEBUG'] = True
        self.app.config['TRAP_HTTP_EXCEPTIONS'] = True
        self.app.config['PRESERVE_CONTEXT_ON_EXCEPTION'] = False

        return self.app

    @classmethod
    def setUpClass(self):
        # We only need to create the MockLdap instance once. The content we
        # pass in will be used for all LDAP connections.
        self.mockldap = MockLdap(self.directory)

    @classmethod
    def tearDownClass(self):
        del self.mockldap

    def setUp(self):
        db.create_all()
        self.mockldap.start()
        self.ldapobj = self.mockldap['ldap://localhost/']
        self.orig_security_enabled = orlo.config.get('security', 'enabled')
        self.orig_security_secret_key = orlo.config.set('security', 'secret_key')
        self.orig_security_ldap_server = orlo.config.set('security', 'ldap_server')
        self.orig_security_ldap_port = orlo.config.set('security', 'ldap_port')
        self.orig_security_user_base_dn = orlo.config.set('security', 'user_base_dn')
        orlo.config.set('security', 'enabled', 'true')
        orlo.config.set('security', 'secret_key', 'It does not matter how slowly you go so long as you do not stop')
        orlo.config.set('security', 'ldap_server', 'localhost')
        orlo.config.set('security', 'ldap_port', '389')
        orlo.config.set('security', 'user_base_dn', 'ou=people,ou=example,o=test')

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.mockldap.stop()
        del self.ldapobj
        orlo.config.set('security', 'enabled', self.orig_security_enabled)
        orlo.config.set('security', 'secret_key', self.orig_security_secret_key)

    def get_with_basic_auth(self, path, username='******', password='******'):
        """
        Do a request with basic auth

        :param path:
        :param username:
        :param password:
        """
        h = Headers()
        h.add('Authorization', 'Basic ' + base64.b64encode(
            '{u}:{p}'.format(u=username, p=password)
        ))
        response = Client.open(self.client, path=path, headers=h)
        return response

    def get_with_ldap_auth(self, path, username='******', password='******'):
        """
        Do a request with ldap auth

        :param path:
        :param username:
        :param password:
        """
        h = Headers()
        h.add('Authorization', 'Basic ' + base64.b64encode(
            '{u}:{p}'.format(u=username, p=password)
        ))
        response = Client.open(self.client, path=path, headers=h)
        return response

    def get_with_token_auth(self, path, token):
        """
        Do a request with token auth

        :param token:
        :param path:
        """
        h = Headers()
        h.add('X-Auth-Token', token)
        response = Client.open(self.client, path=path, headers=h)
        return response

    def post_with_token_auth(self, path, token, data):
        """
        Do a request with token auth

        :param token:
        :param path:
        """
        h = Headers()
        h.add('X-Auth-Token', token)
        h.add('Content-Type', 'application/json')
        response = Client.open(self.client, method='POST', data=data, path=path, headers=h)
        return response

    def get_token(self):
        response = self.get_with_basic_auth('/token')
        return response.json['token']
示例#13
0
def configure_mock_ldap():
    from mockldap import MockLdap
    mockldap = MockLdap(directory)
    mockldap.start()
    yield
    mockldap.stop()
示例#14
0
 def setUpClass(cls):
     settings.DATABASES['ldap']['TLS'] = True
     settings.DATABASES['ldap']['CONNECTION_OPTIONS'] = {
         ldap.OPT_X_TLS_DEMAND: True,
     }
     cls.mockldap = MockLdap(cls.directory)
示例#15
0
 def setUpClass(cls):
     cls.mockldap = MockLdap(cls.directory)
     cls.config, cls.secrets, cls.policies = init_testing()
示例#16
0
def mock_ldap(requires_email=True, user_filter=None):
    mock_data = {
        "dc=quay,dc=io": {"dc": ["quay", "io"]},
        "ou=employees,dc=quay,dc=io": {"dc": ["quay", "io"], "ou": "employees"},
        "ou=otheremployees,dc=quay,dc=io": {"dc": ["quay", "io"], "ou": "otheremployees"},
        "cn=AwesomeFolk,dc=quay,dc=io": {"dc": ["quay", "io"], "cn": "AwesomeFolk"},
        "uid=testy,ou=employees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "employees",
            "uid": ["testy"],
            "userPassword": ["password"],
            "mail": ["*****@*****.**"],
            "memberOf": ["cn=AwesomeFolk,dc=quay,dc=io", "cn=*Guys,dc=quay,dc=io"],
            "filterField": ["somevalue"],
        },
        "uid=someuser,ou=employees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "employees",
            "uid": ["someuser"],
            "userPassword": ["somepass"],
            "mail": ["*****@*****.**"],
            "memberOf": ["cn=AwesomeFolk,dc=quay,dc=io", "cn=*Guys,dc=quay,dc=io"],
            "filterField": ["somevalue"],
        },
        "uid=nomail,ou=employees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "employees",
            "uid": ["nomail"],
            "userPassword": ["somepass"],
            "filterField": ["somevalue"],
        },
        "uid=cool.user,ou=employees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "employees",
            "uid": ["cool.user", "referred"],
            "userPassword": ["somepass"],
            "mail": ["*****@*****.**"],
            "filterField": ["somevalue"],
        },
        "uid=referred,ou=employees,dc=quay,dc=io": {
            "uid": ["referred"],
            "_referral": "ldap:///uid=cool.user,ou=employees,dc=quay,dc=io",
        },
        "uid=invalidreferred,ou=employees,dc=quay,dc=io": {
            "uid": ["invalidreferred"],
            "_referral": "ldap:///uid=someinvaliduser,ou=employees,dc=quay,dc=io",
        },
        "uid=multientry,ou=subgroup1,ou=employees,dc=quay,dc=io": {
            "uid": ["multientry"],
            "mail": ["*****@*****.**"],
            "userPassword": ["somepass"],
            "filterField": ["somevalue"],
        },
        "uid=multientry,ou=subgroup2,ou=employees,dc=quay,dc=io": {
            "uid": ["multientry"],
            "another": ["key"],
            "filterField": ["somevalue"],
        },
        "uid=secondaryuser,ou=otheremployees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "otheremployees",
            "uid": ["secondaryuser"],
            "userPassword": ["somepass"],
            "mail": ["*****@*****.**"],
            "filterField": ["somevalue"],
        },
        # Feature: Email Blacklisting
        "uid=blacklistedcom,ou=otheremployees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "otheremployees",
            "uid": ["blacklistedcom"],
            "userPassword": ["somepass"],
            "mail": ["*****@*****.**"],
            "filterField": ["somevalue"],
        },
        "uid=blacklistednet,ou=otheremployees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "otheremployees",
            "uid": ["blacklistednet"],
            "userPassword": ["somepass"],
            "mail": ["*****@*****.**"],
            "filterField": ["somevalue"],
        },
        "uid=blacklistedorg,ou=otheremployees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "otheremployees",
            "uid": ["blacklistedorg"],
            "userPassword": ["somepass"],
            "mail": ["*****@*****.**"],
            "filterField": ["somevalue"],
        },
        "uid=notblacklistedcom,ou=otheremployees,dc=quay,dc=io": {
            "dc": ["quay", "io"],
            "ou": "otheremployees",
            "uid": ["notblacklistedcom"],
            "userPassword": ["somepass"],
            "mail": ["*****@*****.**"],
            "filterField": ["somevalue"],
        },
    }

    if not requires_email:
        for path in mock_data:
            mock_data[path].pop("mail", None)

    mockldap = MockLdap(mock_data)

    def initializer(uri, trace_level=0):
        obj = mockldap[uri]

        # Seed to "support" wildcard queries, which MockLDAP does not support natively.
        cool_block = {
            "dc": ["quay", "io"],
            "ou": "employees",
            "uid": ["cool.user", "referred"],
            "userPassword": ["somepass"],
            "mail": ["*****@*****.**"],
        }

        if not requires_email:
            cool_block.pop("mail", None)

        obj.search_s.seed("ou=employees,dc=quay,dc=io", 2, "(|(uid=cool*)(mail=cool*))")(
            [("uid=cool.user,ou=employees,dc=quay,dc=io", cool_block)]
        )

        obj.search_s.seed("ou=otheremployees,dc=quay,dc=io", 2, "(|(uid=cool*)(mail=cool*))")([])

        obj.search_s.seed("ou=employees,dc=quay,dc=io", 2, "(|(uid=unknown*)(mail=unknown*))")([])
        obj.search_s.seed("ou=otheremployees,dc=quay,dc=io", 2, "(|(uid=unknown*)(mail=unknown*))")(
            []
        )

        no_users_found_exception = Exception()
        no_users_found_exception.message = {"matched": "dc=quay,dc=io", "desc": "No such object"}

        obj.search_s.seed("ou=nonexistent,dc=quay,dc=io", 2)(no_users_found_exception)
        obj.search_s.seed("ou=employees,dc=quay,dc=io", 2)(
            [("uid=cool.user,ou=employees,dc=quay,dc=io", cool_block)]
        )
        obj.search.seed("ou=employees,dc=quay,dc=io", 2, "(objectClass=*)")(
            [("uid=cool.user,ou=employees,dc=quay,dc=io", cool_block)]
        )
        obj.search.seed("ou=employees,dc=quay,dc=io", 2)(
            [("uid=cool.user,ou=employees,dc=quay,dc=io", cool_block)]
        )

        obj._results = {}
        original_result_fn = obj.result

        def result(messageid):
            if messageid is None:
                return None, [], None, None

            # NOTE: Added because of weirdness with using mock-ldap.
            if isinstance(messageid, list):
                return None, messageid

            if messageid in obj._results:
                return obj._results[messageid]

            return original_result_fn(messageid)

        def result3(messageid):
            if messageid is None:
                return None, [], None, None

            return obj._results[messageid]

        def search_ext(
            user_search_dn, scope, search_flt=None, serverctrls=None, sizelimit=None, attrlist=None
        ):
            if scope != ldap.SCOPE_SUBTREE:
                return None

            if not serverctrls:
                if search_flt:
                    rdata = obj.search_s(user_search_dn, scope, search_flt, attrlist=attrlist)
                else:
                    if attrlist:
                        rdata = obj.search_s(user_search_dn, scope, attrlist=attrlist)
                    else:
                        rdata = obj.search_s(user_search_dn, scope)

                obj._results["messageid"] = (None, rdata)
                return "messageid"

            page_control = serverctrls[0]
            if page_control.controlType != ldap.controls.SimplePagedResultsControl.controlType:
                return None

            if search_flt:
                msgid = obj.search(user_search_dn, scope, search_flt, attrlist=attrlist)
            else:
                if attrlist:
                    msgid = obj.search(user_search_dn, scope, attrlist=attrlist)
                else:
                    msgid = obj.search(user_search_dn, scope)

            _, rdata = obj.result(msgid)
            msgid = "messageid"
            cookie = int(page_control.cookie) if page_control.cookie else 0

            results = rdata[cookie : cookie + page_control.size]
            cookie = cookie + page_control.size
            if cookie > len(results):
                page_control.cookie = None
            else:
                page_control.cookie = cookie

            obj._results["messageid"] = (None, results, None, [page_control])
            return msgid

        def search_ext_s(user_search_dn, scope, sizelimit=None):
            return [obj.search_s(user_search_dn, scope)]

        obj.search_ext = search_ext
        obj.result = result
        obj.result3 = result3
        obj.search_ext_s = search_ext_s

        return obj

    mockldap.start()
    try:
        with patch("ldap.initialize", new=initializer):
            yield _create_ldap(requires_email=requires_email, user_filter=user_filter)
    finally:
        mockldap.stop()
示例#17
0
def mocked_ldap(monkeypatch):
    ldap_mock = MockLdap(_ldap_tree())

    def connect(self, enforce_new=False, enforce_server=None):
        self._default_bind(self._ldap_obj)

    monkeypatch.setattr(ldap.LDAPUserConnector, "connect", connect)
    monkeypatch.setattr(ldap.LDAPUserConnector, "disconnect", lambda self: None)

    ldap_connection = ldap.LDAPUserConnector({
        "id": "default",
        "type": "ldap",
        "description": "Test connection",
        "disabled": False,
        "cache_livetime": 300,
        "suffix": "testldap",
        "active_plugins": {
            'email': {},
            'alias': {},
            'auth_expire': {}
        },
        "directory_type": ("ad", {
            "connect_to": ("fixed_list", {
                "server": "127.0.0.1"
            }),
        }),
        "bind": ("cn=sync-user,ou=users,dc=check-mk,dc=org", "sync-secret"),
        "user_id_umlauts": "keep",
        "user_scope": "sub",
        "user_dn": "ou=users,dc=check-mk,dc=org",
        "group_dn": "ou=groups,dc=check-mk,dc=org",
        "group_scope": "sub",
    })

    ldap_mock.start()
    ldap_connection._ldap_obj = ldap_mock["ldap://127.0.0.1"]

    def search_ext(self,
                   base,
                   scope,
                   filterstr='(objectclass=*)',
                   attrlist=None,
                   attrsonly=0,
                   serverctrls=None):

        # MockLdap does not exactly behave like python ldap library in terms of
        # encoding. The latter want's to have byte encoded strings and MockLdap
        # wants unicode strings :-/. Prepare the data we normally send to
        # python-ldap for MockLdap here.
        if not isinstance(base, str):
            base = base.decode("utf-8")

        if not isinstance(filterstr, str):
            filterstr = filterstr.decode("utf-8")

        return self.search(base, scope, filterstr, attrlist, attrsonly)

    LDAPObject.search_ext = search_ext

    def result_3(self, *args, **kwargs):
        unused_code, response = LDAPObject.result(self, *args, **kwargs)
        return unused_code, encode_to_byte_strings(response), None, []

    LDAPObject.result3 = result_3

    return ldap_connection
示例#18
0
class OrloAuthTest(TestCase):
    """
    Base test class to setup the app
    """
    top = ('o=test', {'o': ['test']})
    example = ('ou=example,o=test', {'ou': ['example']})
    people = ('ou=people,ou=example,o=test', {'ou': ['other']})
    ldapuser = ('uid=ldapuser,ou=people,ou=example,o=test', {
        'uid': ['ldapuser'],
        'userPassword': ['ldapuserpw']
    })
    # This is the content of our mock LDAP directory. It takes the form
    # {dn: {attr: [value, ...], ...}, ...}.
    directory = dict([top, example, people, ldapuser])

    def create_app(self):
        self.app = orlo.app
        self.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
        self.app.config['TESTING'] = True
        self.app.config['DEBUG'] = False
        self.app.config['TRAP_HTTP_EXCEPTIONS'] = True
        self.app.config['PRESERVE_CONTEXT_ON_EXCEPTION'] = False

        return self.app

    @classmethod
    def setUpClass(self):
        # We only need to create the MockLdap instance once. The content we
        # pass in will be used for all LDAP connections.
        self.mockldap = MockLdap(self.directory)

    @classmethod
    def tearDownClass(self):
        del self.mockldap

    def setUp(self):
        db.create_all()
        self.mockldap.start()
        self.ldapobj = self.mockldap['ldap://localhost/']
        self.orig_security_enabled = orlo.config.get('security', 'enabled')
        self.orig_security_secret_key = orlo.config.set(
            'security', 'secret_key')
        self.orig_security_ldap_server = orlo.config.set(
            'security', 'ldap_server')
        self.orig_security_ldap_port = orlo.config.set('security', 'ldap_port')
        self.orig_security_user_base_dn = orlo.config.set(
            'security', 'user_base_dn')
        orlo.config.set('security', 'enabled', 'true')
        orlo.config.set(
            'security', 'secret_key', 'It does not matter how '
            'slowly you go so long as '
            'you do not stop')
        orlo.config.set('security', 'ldap_server', 'localhost')
        orlo.config.set('security', 'ldap_port', '389')
        orlo.config.set('security', 'user_base_dn',
                        'ou=people,ou=example,o=test')

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.mockldap.stop()
        del self.ldapobj
        orlo.config.set('security', 'enabled', self.orig_security_enabled)
        orlo.config.set('security', 'secret_key',
                        self.orig_security_secret_key)

    def get_with_basic_auth(self, path, username='******', password='******'):
        """
        Do a request with ldap auth

        :param path:
        :param username:
        :param password:
        """
        h = Headers()
        s_auth = base64.b64encode('{u}:{p}'.format(u=username,
                                                   p=password).encode('utf-8'))
        h.add('Authorization', 'Basic ' + s_auth.decode('utf-8'))
        response = Client.open(self.client, path=path, headers=h)
        return response

    def get_with_token_auth(self, path, token):
        """
        Do a request with token auth

        :param token:
        :param path:
        """
        h = Headers()
        h.add('X-Auth-Token', token)
        response = Client.open(self.client, path=path, headers=h)
        return response

    def post_with_token_auth(self, path, token, data):
        """
        Do a request with token auth

        :param token:
        :param path:
        """
        h = Headers()
        h.add('X-Auth-Token', token)
        h.add('Content-Type', 'application/json')
        response = Client.open(self.client,
                               method='POST',
                               data=data,
                               path=path,
                               headers=h)
        return response

    def get_token(self):
        response = self.get_with_basic_auth('/token')
        return response.json['token']
 def setUpClass(cls):
     # We only need to create the MockLdap instance once. The content we
     # pass in will be used for all LDAP connections.
     cls.mockldap = MockLdap(cls.directory)
示例#20
0
 def setUpClass(cls):
     """ """
     cls.mockldap = MockLdap(cls.DIRECTORY)