コード例 #1
0
ファイル: test_command.py プロジェクト: GOsa3/gosa
    def test_sendEvent(self):
        e = EventMaker()

        backendChangeData = e.Event(
            e.BackendChange(e.ModificationTime("20150101000000Z"),
                            e.ChangeType("modify")))
        data = e.Event(
            e.ObjectChanged(e.ModificationTime("20150101000000Z"),
                            e.ChangeType("modify")))
        data_str = '<Event xmlns="http://www.gonicus.de/Events"><ObjectChanged><ModificationTime>20150101000000Z</ModificationTime><ChangeType>modify</ChangeType></ObjectChanged></Event>'

        mocked_resolver = mock.MagicMock()
        mocked_resolver.check.return_value = False
        mocked_resolver.isAdmin.return_value = False
        with mock.patch.dict("gosa.backend.command.PluginRegistry.modules", {'ACLResolver': mocked_resolver}),\
                mock.patch("gosa.backend.command.SseHandler.send_message") as mocked_sse:

            with pytest.raises(EventNotAuthorized):
                self.reg.sendEvent('admin', data)

            mocked_resolver.check.return_value = True

            with pytest.raises(etree.XMLSyntaxError):
                # message without content
                self.reg.sendEvent('admin', e.Event(e.ObjectChanged()))

            # add listener
            handle_event = mock.MagicMock()

            ZopeEventConsumer(event_type='ObjectChanged',
                              callback=handle_event.process)
            self.reg.sendEvent('admin', backendChangeData)
            assert not handle_event.process.called

            # send data as str
            self.reg.sendEvent('admin', data_str)
            assert handle_event.process.called
            args, kwargs = handle_event.process.call_args
            called_string = etree.tostring(args[0])
            assert called_string.decode() == data_str
            handle_event.reset_mock()

            # send data as bytes
            self.reg.sendEvent('admin', bytes(data_str, 'utf-8'))
            assert handle_event.process.called
            args, kwargs = handle_event.process.call_args
            called_string = etree.tostring(args[0])
            assert called_string.decode() == data_str
            handle_event.reset_mock()

            # send data as xml
            self.reg.sendEvent('admin', data)
            assert handle_event.process.called
            args, kwargs = handle_event.process.call_args
            called_string = etree.tostring(args[0])
            assert called_string.decode() == data_str
            handle_event.reset_mock()
コード例 #2
0
    def test_post(self):

        # create webhook post
        e = EventMaker()
        update = e.Event(
            e.BackendChange(
                e.DN("cn=Test,ou=people,dc=example,dc=net"),
                e.ModificationTime(datetime.now().strftime("%Y%m%d%H%M%SZ")),
                e.ChangeType("update")
            )
        )
        payload = etree.tostring(update)

        token = bytes(Environment.getInstance().config.get("webhooks.ldap_monitor_token"), 'ascii')
        signature_hash = hmac.new(token, msg=payload, digestmod="sha512")
        signature = 'sha1=' + signature_hash.hexdigest()

        headers = {
            'Content-Type': 'application/vnd.gosa.event+xml',
            'HTTP_X_HUB_SENDER': 'backend-monitor',
            'HTTP_X_HUB_SIGNATURE': signature
        }
        with mock.patch("gosa.backend.plugins.webhook.registry.zope.event.notify") as m_notify:
            AsyncHTTPTestCase.fetch(self, "/hooks/", method="POST", headers=headers, body=payload)
            assert m_notify.called
            m_notify.reset_mock()

            # unregistered sender
            headers['HTTP_X_HUB_SENDER'] = 'unknown'
            resp = AsyncHTTPTestCase.fetch(self, "/hooks/", method="POST", headers=headers, body=payload)
            assert resp.code == 401
            assert not m_notify.called

            # wrong signature
            headers['HTTP_X_HUB_SENDER'] = 'backend-monitor'
            headers['HTTP_X_HUB_SIGNATURE'] = 'sha1=823rjadfkjlasasddfdgasdfgasd'
            resp = AsyncHTTPTestCase.fetch(self, "/hooks/", method="POST", headers=headers, body=payload)
            assert resp.code == 401
            assert not m_notify.called

            # no signature
            del headers['HTTP_X_HUB_SIGNATURE']
            resp = AsyncHTTPTestCase.fetch(self, "/hooks/", method="POST", headers=headers, body=payload)
            assert resp.code == 401
            assert not m_notify.called

            # no handler for content type
            headers['HTTP_X_HUB_SIGNATURE'] = signature
            headers['Content-Type'] = 'application/vnd.gosa.unknown+xml'
            resp = AsyncHTTPTestCase.fetch(self, "/hooks/", method="POST", headers=headers, body=payload)
            assert resp.code == 401
            assert not m_notify.called
コード例 #3
0
    def test_MqttEventConsumer(self):
        schema = '<?xml version="1.0"?>' \
                 '<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:e="http://www.gonicus.de/Events" ' \
                 'targetNamespace="http://www.gonicus.de/Events" elementFormDefault="qualified">'\
                 '<include schemaLocation="%s"/>'\
                 '<complexType name="Event">'\
                 '<choice maxOccurs="1" minOccurs="1">'\
                 '<group ref="e:Events"/>'\
                 '</choice>'\
                 '</complexType>'\
                 '<group name="Events">'\
                 '<choice>'\
                 '<element name="BackendChange" type="e:BackendChange"/>'\
                 '</choice>'\
                 '</group>'\
                 '<element name="Event" type="e:Event"/>'\
                 '</schema>' % resource_filename('gosa.backend', 'data/events/BackendChange.xsd')

        with unittest.mock.patch("gosa.common.events.PluginRegistry.getEventSchema", return_value=schema):
            e = EventMaker()
            callback = unittest.mock.Mock()
            event = e.Event(
                e.BackendChange(
                    e.DN("dn"),
                    e.ModificationTime("mod_time"),
                    e.ChangeType("type")
                )
            )
            mec = MqttEventConsumer(callback=callback, event_type="BackendChange")
            payload = dumps({
                "sender_id": None,
                "content": etree.tostring(event, pretty_print=True).decode('utf-8')
            })
            message = unittest.mock.MagicMock()
            message.payload = payload
            message.topic = "%s/events" % Environment.getInstance().domain
            mec.mqtt.get_client().client.on_message(None, None, message)

            args, kwargs = callback.call_args
            assert etree.tostring(args[0], pretty_print=True).decode('utf-8') == etree.tostring(event, pretty_print=True).decode('utf-8')
            PluginRegistry._event_parser = None
コード例 #4
0
ファイル: gosa_ldap_monitor.py プロジェクト: peuter/gosa
def monitor(path, modifier, token, webhook_target, initially_failed=False):
    # Initialize dn, timestamp and change type.
    dn = None
    ts = None
    ct = None

    try:
        with open(path, encoding='utf-8', errors='ignore') as f:

            # Collect lines until a newline occurs, fill
            # dn, ts and ct accordingly. Entries that only
            # change administrative values.
            for line in tail(f, initially_failed):

                # Catch dn
                if line.startswith("dn::"):
                    dn = b64decode(line[5:]).decode('utf-8')
                    continue

                elif line.startswith("dn:"):
                    dn = line[4:]
                    continue

                # Catch modifyTimestamp
                if line.startswith("modifyTimestamp:"):
                    ts = line[17:]
                    continue

                # Catch changetype
                if line.startswith("changetype:"):
                    ct = line[12:]
                    continue

                # Check modifiers name and if it's the
                # gosa-backend who triggered the change,
                # just reset the DN, because we don't need
                # to propagate this change.
                if line.startswith("modifiersName:"):
                    if line[14:].lower() == modifier.lower():
                        dn = None
                    continue

                # Trigger on newline.
                if line == "":
                    if dn:
                        if not ts:
                            ts = datetime.now().strftime("%Y%m%d%H%M%SZ")

                        e = EventMaker()
                        update = e.Event(
                            e.BackendChange(
                                e.DN(dn),
                                e.ModificationTime(ts),
                                e.ChangeType(ct)
                            )
                        )
                        payload = etree.tostring(update)

                        headers = {
                            'Content-Type': 'application/vnd.gosa.event+xml',
                            'HTTP_X_HUB_SENDER': 'backend-monitor',
                            'HTTP_X_HUB_SIGNATURE': get_signature(token, payload)
                        }
                        requests.post(webhook_target, data=payload, headers=headers)

                    dn = ts = ct = None

    except Exception as e:
        print("Error:", str(e))