def test_004_flagsclear(self): flagsclear = { "event": "FlagsClear", "flagNames": "\Seen", "messages": 3, "modseq": 47, "pid": 489, "service": "imap", "timestamp": "2014-10-20T13:03:31.348+02:00", "uidnext": 7, "uidset": "4", "uri": "imap://[email protected]@kolab.example.org/INBOX;UIDVALIDITY=1411487701", "user": "******", "vnd.cmu.midset": [ "<*****@*****.**>" ], "vnd.cmu.sessionId": "kolab.example.org-489-1413803011-1", "vnd.cmu.unseenMessages": 1 } dealer = BonnieDealer() dealer.run(json.dumps(flagsclear)) # query by message-ID events = self.query_log([('message_id','=','<*****@*****.**>')]) self.assertEqual(len(events), 1) event = events[0] self.assertEqual(event['uidset'], '4') self.assertEqual(event['flag_names'], '\Seen') self.assertEqual(event['unseen_messages'], 1) self.assertTrue(event.has_key('user_id')) self.assertTrue(event.has_key('folder_id'))
def test_003_messageread(self): messageread = { "event": "MessageRead", "messages": 3, "modseq": 64, "pid": 802, "service": "imap", "timestamp": "2014-10-20T13:04:09.077+02:00", "uidnext": 7, "uidset": "4", "uri": "imap://[email protected]@kolab.example.org/INBOX;UIDVALIDITY=1411487701", "user": "******", "vnd.cmu.midset": [ "<*****@*****.**>" ], "vnd.cmu.sessionId": "kolab.example.org-802-1413803049-1", "vnd.cmu.unseenMessages": 0 } dealer = BonnieDealer() dealer.run(json.dumps(messageread)) # query by message-ID events = self.query_log([('message_id','=','<*****@*****.**>')]) self.assertEqual(len(events), 1) event = events[0] self.assertEqual(event['uidset'], '4') self.assertTrue(event.has_key('user_id')) self.assertTrue(event.has_key('folder_id'))
def test_002_messageappend(self): messageappend = { "event": "MessageAppend", "flagNames": "\seen", "messageSize": 555, "messages": 6, "modseq": 12, "pid": 2222, "service": "imap", "timestamp": "2014-10-20T13:33:27.062+02:00", "uidnext": 9, "uidset": "8", "uri": "imap://[email protected]@kolab.example.org/Sent;UIDVALIDITY=1411487701/;UID=8", "user": "******", "vnd.cmu.envelope": "(\"Mon, 20 Oct 2014 13:33:26 +0200\" \"MessageNew event test\" ((\"=?UTF-8?Q?Br=C3=BCederli=2C_Thomas?=\" NIL \"john.doe\" \"example.org\")) ((\"=?UTF-8?Q?Br=C3=BCederli=2C_Thomas?=\" NIL \"john.doe\" \"example.org\")) ((\"=?UTF-8?Q?Br=C3=BCederli=2C_Thomas?=\" NIL \"john.doe\" \"example.org\")) ((\"Doe, John\" NIL \"john.doe\" \"example.org\")) NIL NIL NIL \"<*****@*****.**>\")", "vnd.cmu.midset": [ "<*****@*****.**>" ], "vnd.cmu.sessionId": "kolab.example.org-2222-1413804806-1", "vnd.cmu.unseenMessages": 0, "folder_id": "76b8cd8f85bb435d17fe28d576db64a7", "folder_uniqueid": "f356a1a9-f897-454f-9ada-5646fe4c4117", "messageHeaders": { "8": { "Content-Transfer-Encoding": "7bit", "Content-Type": "text/plain", "Date": "2014-10-20T11:31:11Z", "From": [ "Br\u00fcederli, Thomas <*****@*****.**>" ], "MIME-Version": "1.0", "Message-ID": "<*****@*****.**>", "Subject": "MessageNew event test", "To": [ "Doe, John <*****@*****.**>" ], "User-Agent": "Kolab 3.1/Roundcube 1.1-git", "X-Sender": "*****@*****.**" } }, "messageContent": { "8": "MIME-Version: 1.0\r\nContent-Type: text/plain; charset=US-ASCII;\r\n format=flowed\r\nContent-Transfer-Encoding: 7bit\r\nDate: Mon, 20 Oct 2014 13:31:11 +0200\r\nFrom: =?UTF-8?Q?Br=C3=BCederli=2C_Thomas?= <*****@*****.**>\r\nTo: \"Doe, John\" <*****@*****.**>\r\nSubject: MessageNew event test\r\nMessage-ID: <*****@*****.**>\r\nX-Sender: [email protected]\r\nUser-Agent: Kolab 3.1/Roundcube 1.1-git\r\n\r\nThis message should trigger the MessageNew event for john.doe...\r\n...and MessageAppend to /Sent for the sender." } } dealer = BonnieDealer() dealer.run(json.dumps(messageappend)) events = self.query_log([('event','=','MessageAppend')]) self.assertEqual(len(events), 1) event = events[0] self.assertTrue(event.has_key('user_id')) self.assertIsInstance(event['headers'], dict) self.assertEqual(len(event['headers']['To']), 1) self.assertEqual(event['headers']['Content-Type'], 'text/plain') self.assertTrue(event['headers']['Message-ID'] in event['message_id'])
def test_001_changelog(self): # we assume "messageHeaders" and "messageContent" payload already being collected messageappend = { "event": "MessageAppend", "messageSize": 2932, "messages": 2, "modseq": 107, "pid": 1248, "service": "imap", "timestamp": "2014-10-20T13:10:59.516+02:00", "uidnext": 38, "uidset": "37", "uri": "imap://[email protected]@kolab.example.org/Calendar;UIDVALIDITY=1411487702/;UID=37", "user": "******", "vnd.cmu.envelope": "(\"Mon, 20 Oct 2014 13:10:59 +0200\" \"253E800C973E9FB99D174669001DB19B-FCBB6C4091F28CA0\" ((NIL NIL \"john.doe\" \"example.org\")) ((NIL NIL \"john.doe\" \"example.org\")) ((NIL NIL \"john.doe\" \"example.org\")) ((NIL NIL \"john.doe\" \"example.org\")) NIL NIL NIL NIL)", "vnd.cmu.midset": [ "NIL" ], "vnd.cmu.sessionId": "kolab.example.org-1248-1413803459-1", "vnd.cmu.unseenMessages": 2, "messageHeaders": { "37": { "Content-Type": "multipart/mixed", "Date": "2014-10-20T11:23:40Z", "From": [ " <*****@*****.**>" ], "MIME-Version": "1.0", "Subject": "253E800C973E9FB99D174669001DB19B-FCBB6C4091F28CA0", "To": [ " <*****@*****.**>" ], "User-Agent": "Kolab 3.1/Roundcube 1.1-git", "X-Kolab-Mime-Version": "3.0", "X-Kolab-Type": "application/x-vnd.kolab.event" } }, "messageContent": { "37": "MIME-Version: 1.0\r\nContent-Type: multipart/mixed;\r\n boundary=\"=_46bc539ab7a6c0a8bd4d2ddbf553df00\"\r\nFrom: [email protected]\r\nTo: [email protected]\r\nDate: Mon, 20 Oct 2014 13:23:40 +0200\r\nX-Kolab-Type: application/x-vnd.kolab.event\r\nX-Kolab-Mime-Version: 3.0\r\nSubject: 253E800C973E9FB99D174669001DB19B-FCBB6C4091F28CA0\r\nUser-Agent: Kolab 3.1/Roundcube 1.1-git\r\n\r\n--=_46bc539ab7a6c0a8bd4d2ddbf553df00\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nThis is a Kolab Groupware object....\r\n\r\n--=_46bc539ab7a6c0a8bd4d2ddbf553df00\r\nContent-Transfer-Encoding: 8bit\r\nContent-Type: application/calendar+xml; charset=UTF-8;\r\n name=kolab.xml\r\nContent-Disposition: attachment;\r\n filename=kolab.xml;\r\n size=1954\r\n\r\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\r\n<icalendar xmlns=\"urn:ietf:params:xml:ns:icalendar-2.0\">\r\n\r\n <vcalendar>\r\n <properties>\r\n <prodid>\r\n <text>Roundcube-libkolab-1.1 Libkolabxml-1.1</text>\r\n </prodid>\r\n <version>\r\n <text>2.0</text>\r\n </version>\r\n <x-kolab-version>\r\n <text>3.1.0</text>\r\n </x-kolab-version>\r\n </properties>\r\n <components>\r\n <vevent>\r\n <properties>\r\n <uid>\r\n <text>253E800C973E9FB99D174669001DB19B-FCBB6C4091F28CA0</text>\r\n </uid>\r\n <created>\r\n <date-time>2014-09-23T23:31:23Z</date-time>\r\n </created>\r\n <dtstamp>\r\n <date-time>2014-10-20T11:23:40Z</date-time>\r\n </dtstamp>\r\n <sequence>\r\n <integer>28</integer>\r\n </sequence>\r\n <class>\r\n <text>PUBLIC</text>\r\n </class>\r\n <dtstart>\r\n <parameters>\r\n <tzid>\r\n <text>/kolab.org/Europe/Berlin</text>\r\n </tzid>\r\n </parameters>\r\n <date-time>2014-10-20T14:00:00</date-time>\r\n </dtstart>\r\n <dtend>\r\n <parameters>\r\n <tzid>\r\n <text>/kolab.org/Europe/Berlin</text>\r\n </tzid>\r\n </parameters>\r\n <date-time>2014-10-20T16:00:00</date-time>\r\n </dtend>\r\n <summary>\r\n <text>Today</text>\r\n </summary>\r\n <description>\r\n <text>(new revision)</text>\r\n </description>\r\n <organizer>\r\n <parameters>\r\n <cn>\r\n <text>Br\u00fcederli, Thomas</text>\r\n </cn>\r\n </parameters>\r\n <cal-address>mailto:%3Cthomas.bruederli%40example.org%3E</cal-address>\r\n </organizer>\r\n </properties>\r\n </vevent>\r\n </components>\r\n </vcalendar>\r\n\r\n</icalendar>\r\n\r\n--=_46bc539ab7a6c0a8bd4d2ddbf553df00--\r\n" } } dealer = BonnieDealer() dealer.run(json.dumps(messageappend)) # query by subject (i.e. object UUID) events = self.query_log([('headers.Subject','=','253E800C973E9FB99D174669001DB19B-FCBB6C4091F28CA0')]) self.assertEqual(len(events), 1) event = events[0] self.assertIsInstance(event['headers'], dict) self.assertEqual(event['headers']['X-Kolab-Mime-Version'], '3.0') self.assertEqual(event['headers']['X-Kolab-Type'], 'application/x-vnd.kolab.event') self.assertTrue(event.has_key('user_id')) self.assertTrue(event.has_key('revision'))
def test_005_messagetrash(self): messagetrash = { "event": "MessageTrash", "messages": 2, "modseq": 104, "pid": 1248, "service": "imap", "timestamp": "2014-10-20T13:10:59.546+02:00", "uidnext": 38, "uidset": "36", "uri": "imap://[email protected]@kolab.example.org/Calendar;UIDVALIDITY=1411487702", "user": "******", "vnd.cmu.midset": [ "NIL" ], "vnd.cmu.sessionId": "kolab.example.org-1248-1413803459-1", "vnd.cmu.unseenMessages": 2, "messageHeaders": { "36": { "Content-Type": "multipart/mixed", "Date": "2014-10-20T11:23:40Z", "From": [ " <*****@*****.**>" ], "MIME-Version": "1.0", "Subject": "253E800C973E9FB99D174669001DB19B-FCBB6C4091F28CA0", "To": [ " <*****@*****.**>" ], "User-Agent": "Kolab 3.1/Roundcube 1.1-git", "X-Kolab-Mime-Version": "3.0", "X-Kolab-Type": "application/x-vnd.kolab.event" } } } dealer = BonnieDealer() dealer.run(json.dumps(messagetrash)) events = self.query_log([('event','=','MessageTrash')]) self.assertEqual(len(events), 1) event = events[0] self.assertTrue(event['headers']['Subject'] in messagetrash['messageHeaders']['36']['Subject']) self.assertEqual(len(event['message_id']), 0)
def test_mailboxcreate(self): dealer = BonnieDealer() notification = { 'event': 'MailboxCreate', 'user': '******', 'uri': 'imap://[email protected]@kolab.example.org/Calendar;UIDVALIDITY=12345' } dealer.run(json.dumps(notification)) events = self.query_log([('event','=','MailboxCreate')]) self.assertEqual(len(events), 1) event = events[0] self.assertTrue(event.has_key('folder_id')) self.assertTrue(event.has_key('folder_uniqueid')) self.assertTrue(event.has_key('user_id')) # check objects/folder entry folder = self.storage_get(event['folder_id'], index='objects', doctype='folder') self.assertIsInstance(folder, dict) self.assertEqual(folder['uniqueid'], event['folder_uniqueid']) self.assertEqual(folder['name'], 'Calendar') self.assertEqual(folder['type'], 'event') self.assertEqual(folder['owner'], '*****@*****.**') self.assertIsInstance(folder['metadata'], dict) self.assertIsInstance(folder['acl'], dict) self.assertTrue(folder['acl'].has_key(event['user_id'])) self.assertTrue(folder['acl'][event['user_id']].startswith('lrswi')) # check objects/user entry user = self.storage_get(event['user_id'], index='objects', doctype='user') self.assertIsInstance(user, dict) self.assertEqual(user['user'], notification['user']) self.assertEqual(user['cn'], 'John Doe')
def test_run(self): dealer = BonnieDealer() dealer.run(json.dumps({ 'event':'Login', 'user':'******' })) self.assertIn('Login', BonnieDealerOutput.output_calls) # don't trigger blacklisted events BonnieDealerOutput.output_calls = [] dealer.run(json.dumps({ 'event':'Login', 'user':'******' })) self.assertEqual(len(BonnieDealerOutput.output_calls), 0) dealer.run(json.dumps({ 'event':'MessageAppend', 'user':'******' })) self.assertEqual(len(BonnieDealerOutput.output_calls), 1) self.assertIn('MessageAppend', BonnieDealerOutput.output_calls)
def test_001_login(self): login = { 'event': 'Login', 'user': '******', 'vnd.cmu.sessionId': 'kolab-sess-test-12345', 'clientIP': '::1', 'serverDomain': 'example.org', } dealer = BonnieDealer() dealer.run(json.dumps(login)) events = self.query_log([('event','=','Login')]) self.assertEqual(len(events), 1) event = events[0] self.assertTrue(event.has_key('user_id')) self.assertTrue(event['session_id'], login['vnd.cmu.sessionId']) self.assertEqual(event['@version'], bonnie.API_VERSION) del dealer time.sleep(1) logout = { 'event': 'Logout', 'user': '******', 'vnd.cmu.sessionId': 'kolab-sess-test-12345', 'clientIP': '::1' } dealer = BonnieDealer() dealer.run(json.dumps(logout)) events = self.query_log([('event','=','Login'), ('logout_time','=','*')]) self.assertEqual(len(events), 1) event = events[0] self.assertTrue(event.has_key('logout_time')) self.assertTrue(event.has_key('duration')) # check objects/users entry user = self.storage_get(event['user_id'], index='objects', doctype='user') self.assertIsInstance(user, dict) self.assertEqual(user['user'], login['user']) self.assertEqual(user['cn'], 'John Doe')
def test_001_messagenew(self): # we assume "messageHeaders" and "messageContent" payload already being collected messagenew = { "event": "MessageNew", "messageSize": 976, "messages": 6, "modseq": 20, "pid": 2340, "service": "lmtpunix", "timestamp": "2014-10-20T13:34:14.966+02:00", "uidnext": 7, "uidset": "6", "uri": "imap://[email protected]@kolab.example.org/INBOX;UIDVALIDITY=1411487714/;UID=6", "user": "******", "vnd.cmu.midset": [ "<*****@*****.**>" ], "vnd.cmu.sessionId": "kolab.example.org-2340-1413804854-1", "vnd.cmu.unseenMessages": 3, "messageHeaders": { "6": { "Content-Transfer-Encoding": "7bit", "Content-Type": "text/plain", "Date": "2014-10-20T11:32:41Z", "From": [ "Br\u00fcederli, Thomas <*****@*****.**>" ], "MIME-Version": "1.0", "Message-ID": "<*****@*****.**>", "Received": "from kolab.example.org ([unix socket])\r\n\t by kolab.example.org (Cyrus git2.5+0-Kolab-2.5-67.el6.kolab_3.4) with LMTPA;\r\n\t Mon, 20 Oct 2014 13:34:14 +0200", "Return-Path": "<*****@*****.**>", "Subject": "MessageNew event test", "To": [ "Doe, John <*****@*****.**>" ], "X-Sender": "*****@*****.**", "X-Sieve": "CMU Sieve 2.4", "X-Spam-Flag": "NO", "X-Spam-Level": "", "X-Spam-Score": "-0.002", "X-Spam-Status": "No, score=-0.002 tagged_above=-10 required=6.2\r\n\ttests=[NO_RECEIVED=-0.001, NO_RELAYS=-0.001] autolearn=ham", "X-Virus-Scanned": "amavisd-new at example.org" } }, "messageContent": { "6": "Return-Path: <*****@*****.**>\r\nReceived: from kolab.example.org ([unix socket])\r\n\t by kolab.example.org (Cyrus git2.5+0-Kolab-2.5-67.el6.kolab_3.4) with LMTPA;\r\n\t Mon, 20 Oct 2014 13:34:14 +0200\r\nX-Sieve: CMU Sieve 2.4\r\nX-Virus-Scanned: amavisd-new at example.org\r\nX-Spam-Flag: NO\r\nX-Spam-Score: -0.002\r\nX-Spam-Level: \r\nX-Spam-Status: No, score=-0.002 tagged_above=-10 required=6.2\r\n\ttests=[NO_RECEIVED=-0.001, NO_RELAYS=-0.001] autolearn=ham\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; charset=US-ASCII;\r\n format=flowed\r\nContent-Transfer-Encoding: 7bit\r\nDate: Mon, 20 Oct 2014 13:32:41 +0200\r\nFrom: =?UTF-8?Q?Br=C3=BCederli=2C_Thomas?= <*****@*****.**>\r\nTo: \"Doe, John\" <*****@*****.**>\r\nSubject: MessageNew event test\r\nMessage-ID: <*****@*****.**>\r\nX-Sender: [email protected]\r\n\r\nThis message should trigger the MessageNew event for john.doe...\r\n...and MessageAppend to /Sent for the sender.\r\n" } } dealer = BonnieDealer() dealer.run(json.dumps(messagenew)) events = self.query_log([('event','=','MessageNew')]) self.assertEqual(len(events), 1) event = events[0] self.assertEqual(event['uidset'], '6') self.assertEqual(event['service'], 'lmtpunix') self.assertEqual(event['session_id'], messagenew['vnd.cmu.sessionId']) self.assertEqual(event['@timestamp'], '2014-10-20T11:34:14.966000Z') self.assertEqual(len(event['message_id']), 1) self.assertIsInstance(event['headers'], dict) self.assertTrue(event['headers']['Message-ID'] in event['message_id']) self.assertTrue(event['headers']['Subject'] in messagenew['messageHeaders']['6']['Subject']) # check if message payload is parsable message = message_from_string(event['message'].encode('utf8','replace')) self.assertEqual(message['Subject'], event['headers']['Subject']) # check objects/folder entry self.assertTrue(event.has_key('folder_id')) folder = self.storage_get(event['folder_id'], index='objects', doctype='folder') self.assertIsInstance(folder, dict) self.assertEqual(folder['uniqueid'], event['folder_uniqueid']) self.assertEqual(folder['name'], 'INBOX') self.assertEqual(folder['owner'], '*****@*****.**') # check objects/user entry self.assertTrue(event.has_key('user_id')) user = self.storage_get(event['user_id'], index='objects', doctype='user') self.assertIsInstance(user, dict) self.assertEqual(user['user'], messagenew['user'])
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # import json import os import sys from bonnie.dealer import BonnieDealer if __name__ == "__main__": notification = sys.stdin.read().strip() dealer = BonnieDealer() dealer.run(notification) # newpid = os.fork() # # if newpid == 0: # dealer = BonnieDealer() # dealer.run(notification)