Example #1
0
 def ImportMessageChange(self, props, flags):
     if self.skip:
         raise MAPIError(SYNC_E_IGNORE)
     try:
         entryid = PpropFindProp(props, PR_ENTRYID)
         if self.importer.store:
             mapistore = self.importer.store.mapiobj
         else:
             store_entryid = PpropFindProp(props, PR_STORE_ENTRYID).Value
             store_entryid = WrapStoreEntryID(0, b'zarafa6client.dll', store_entryid[:-4]) + self.server.pseudo_url + b'\x00'
             mapistore = self.server._store2(store_entryid)
         item = _item.Item()
         item.server = self.server
         item.store = _store.Store(mapiobj=mapistore, server=self.server)
         try:
             item.mapiobj = _utils.openentry_raw(mapistore, entryid.Value, 0)
             props = item.mapiobj.GetProps([PR_EC_HIERARCHYID, PR_EC_PARENT_HIERARCHYID, PR_STORE_RECORD_KEY], 0) # XXX properties don't exist?
             item.docid = props[0].Value
             item.storeid = _benc(props[2].Value)
             if hasattr(self.importer, 'update'):
                 self.importer.update(item, flags)
         except (MAPIErrorNotFound, MAPIErrorNoAccess): # XXX, mail already deleted, can we do this in a cleaner way?
             self.log.debug('received change for entryid %s, but it could not be opened', _benc(entryid.Value))
     except Exception:
         self.log.error('could not process change for entryid %s (%r):', _benc(entryid.Value), props)
         self.log.error(traceback.format_exc())
         if self.stats:
             self.stats['errors'] += 1
     raise MAPIError(SYNC_E_IGNORE)
Example #2
0
 def create_store(self):
     try:
         storeid_rootid = self.server.sa.CreateStore(
             ECSTORE_TYPE_PRIVATE, self._ecuser.UserID)
     except MAPIErrorCollision:
         raise DuplicateError("user '%s' already has store" % self.name)
     store_entryid = WrapStoreEntryID(
         0, b'zarafa6client.dll',
         storeid_rootid[0][:-4]) + self.server.pseudo_url + b'\x00'
     return Store(entryid=_benc(store_entryid), server=self.server)
Example #3
0
    def create_public_store(self):
        """Create company public :class:`store <Store>`."""
        if self._name == u'Default':
            try:
                storeid_rootid = self.server.sa.CreateStore(ECSTORE_TYPE_PUBLIC, EID_EVERYONE)
            except MAPIErrorCollision:
                raise DuplicateError("public store already exists")
        else:
            try:
                storeid_rootid = self.server.sa.CreateStore(ECSTORE_TYPE_PUBLIC, self._eccompany.CompanyID)
            except MAPIErrorCollision:
                raise DuplicateError("public store already exists for company '%s'" % self.name)

        store_entryid = WrapStoreEntryID(0, b'zarafa6client.dll', storeid_rootid[0][:-4]) + self.server.pseudo_url + b'\x00'

        self._public_store = _store.Store(entryid=_hex(store_entryid), server=self.server)
        return self._public_store
Example #4
0
    def create_store(self, user, _msr=False):
        # TODO detect homeserver override
        storetype = ECSTORE_TYPE_PRIVATE
        # TODO configurable storetype

        if _msr:
            try:
                storeid, rootid = self.sa.CreateEmptyStore(
                    storetype, _bdec(user.userid), EC_OVERRIDE_HOMESERVER,
                    None, None)
            except MAPIErrorCollision:
                raise DuplicateError(
                    "user '%s' already has an associated store (unhook first?)"
                    % user.name)
            store_entryid = WrapStoreEntryID(
                0, b'zarafa6client.dll',
                storeid[:-4]) + b'https://' + codecs.encode(
                    self.name, 'utf-8') + b':237\x00'
            store_entryid = store_entryid[:66] + b'\x10' + store_entryid[
                67:]  # multi-server flag
            store = self.store(entryid=_benc(store_entryid))

            # TODO add EC_OVERRIDE_HOMESERVER flag to CreateStore instead? or how does the old MSR do this?

            # TODO language

            # system folders
            root = store.root

            store.findroot = root.create_folder('FINDER_ROOT')
            store.findroot.permission(self.group('Everyone'),
                                      create=True).rights = [
                                          'read_items', 'create_subfolders',
                                          'edit_own', 'delete_own',
                                          'folder_visible'
                                      ]

            store.views = root.create_folder('IPM_VIEWS')
            store.common_views = root.create_folder('IPM_COMMON_VIEWS')

            root.create_folder('Freebusy Data')
            root.create_folder('Schedule')
            root.create_folder('Shortcut')

            # special folders
            subtree = store.subtree = root.folder('IPM_SUBTREE', create=True)

            store.calendar = subtree.create_folder('Calendar')
            store.contacts = subtree.create_folder('Contacts')
            # TODO Conversation Action Settings?
            store.wastebasket = subtree.create_folder('Deleted Items')
            store.drafts = subtree.create_folder('Drafts')
            store.inbox = subtree.create_folder('Inbox')
            store.journal = subtree.create_folder('Journal')
            store.junk = subtree.create_folder('Junk E-mail')
            store.notes = subtree.create_folder('Notes')
            store.outbox = subtree.create_folder('Outbox')
            # TODO Quick Step Settings?
            # TODO RSS Feeds?
            store.sentmail = subtree.create_folder('Sent Items')
            # TODO Suggested Contacts?
            store.tasks = subtree.create_folder('Tasks')

            # freebusy message TODO create dynamically instead?
            fbmsg = root.create_item(
                subject='LocalFreebusy',
                message_class='IPM.Microsoft.ScheduleData.FreeBusy')
            root[PR_FREEBUSY_ENTRYIDS] = [b'', _bdec(fbmsg.entryid), b'', b'']

        else:
            store = user.create_store()
        return store
Example #5
0
    def create_store(self, user, _msr=False):
        """Create store for :class:`User`.

        :param user: User
        """
        # TODO detect homeserver override
        storetype = ECSTORE_TYPE_PRIVATE
        # TODO configurable storetype

        if _msr:
            try:
                storeid, rootid = self.sa.CreateEmptyStore(storetype,
                    _bdec(user.userid), EC_OVERRIDE_HOMESERVER, None, None)
            except MAPIErrorCollision:
                raise DuplicateError("user '%s' already has an associated \
store (unhook first?)" % user.name)
            # Parse the server, fallback to 237 for now
            server_port = self._get_server_port()
            if not server_port:
                # TODO: raise exception?
                server_port = 237

            store_entryid = \
                WrapStoreEntryID(0, b'zarafa6client.dll',storeid[:-4]) + \
                b'https://' + \
                codecs.encode(self.name, 'utf-8') + \
                b':' + str(server_port).encode('utf-8') + b'\x00'
            # multi-server flag
            store_entryid = \
                store_entryid[:66] + \
                b'\x10' + \
                store_entryid[67:]
            store = self.store(entryid=_benc(store_entryid))

            # TODO add EC_OVERRIDE_HOMESERVER flag to CreateStore instead?
            # or how does the old MSR do this?

            # TODO language

            # system folders
            root = store.root

            store.findroot = root.create_folder('FINDER_ROOT')
            store.findroot.permission(
                self.group('Everyone'), create=True).rights = \
                ['read_items', 'create_subfolders', 'edit_own', 'delete_own',
                 'folder_visible']

            store.views = root.create_folder('IPM_VIEWS')
            store.common_views = root.create_folder('IPM_COMMON_VIEWS')

            freebusydata = root.create_folder('Freebusy Data')
            root.create_folder('Schedule')
            root.create_folder('Shortcut')

            # special folders
            subtree = store.subtree = root.folder('IPM_SUBTREE', create=True)

            calendar = subtree.create_folder('Calendar')
            store.calendar = calendar
            store.contacts = subtree.create_folder('Contacts')
            # TODO Conversation Action Settings?
            store.wastebasket = subtree.create_folder('Deleted Items')
            store.drafts = subtree.create_folder('Drafts')
            store.inbox = subtree.create_folder('Inbox')
            store.journal = subtree.create_folder('Journal')
            store.junk = subtree.create_folder('Junk E-mail')
            store.notes = subtree.create_folder('Notes')
            store.outbox = subtree.create_folder('Outbox')
            # TODO Quick Step Settings?
            # TODO RSS Feeds?
            store.sentmail = subtree.create_folder('Sent Items')
            # TODO Suggested Contacts?
            store.tasks = subtree.create_folder('Tasks')

            # freebusy message TODO create dynamically instead?
            fbmsg = root.create_item(
                subject='LocalFreebusy',
                message_class='IPM.Microsoft.ScheduleData.FreeBusy'
            )

            calendar_fbmsg = calendar.create_item(
                subject='LocalFreebusy',
                message_class='IPM.Microsoft.ScheduleData.FreeBusy',
                associated=True
            )

            # PR_FREEBUSY_ENTRYIDS[0] gives associated freebusy iten in calendar
            # PR_FREEBUSY_ENTRYIDS[1] Localfreebusy (used for delegate properties) message
            # PR_FREEBUSY_ENTRYIDS[2] global Freebusydata in public store (empty in Kopano)
            # PR_FREEBUSY_ENTRYIDS[3] Freebusydata in IPM_SUBTREE
            root[PR_FREEBUSY_ENTRYIDS] = [_bdec(calendar_fbmsg.entryid), _bdec(fbmsg.entryid), b'', _bdec(freebusydata.entryid)]

        else:
            store = user.create_store()
        return store