Beispiel #1
0
    def _to_python(self, itemId, state):
        itemType = self.itemType if self.itemType else 'item'
        if not itemId or not itemId[0]:
            raise MissingParam('%s-id' % (itemType), itemId, state)
        itemId = itemId[0]

        columns = set(['meta']).update(self.columns)
        item = yield db.get_slice(itemId, "items", columns)
        if not item:
            raise InvalidItem(itemType, itemId, state)

        item = utils.supercolumnsToDict(item)
        meta = item["meta"]

        if self.itemType and meta["type"] != self.itemType:
            raise InvalidItem(itemType, itemId, state)

        parentId = meta.get("parent", None)
        if parentId:
            parent = yield db.get_slice(parentId, "items", ["meta"])
            parent = utils.supercolumnsToDict(parent)
        else:
            parent = item
        acl = parent["meta"]["acl"]
        owner = parent["meta"]["owner"]
        #parent is deleted
        deleted = parent['meta'].get('state', None) == 'deleted'
        #item is deleted
        deleted = deleted or meta.get('state', None) == 'deleted'

        if deleted:
            raise InvalidItem(itemType, itemId, state)

        if self.source != 'api':
            request = state.request
            authInfo = request.getSession(IAuthInfo)
            myId = authInfo.username
            orgId = authInfo.organization
            isOrgAdmin = authInfo.isAdmin

        isOrgAdmin = self.checkAdmin and isOrgAdmin
        relation = Relation(myId, [])
        yield relation.initGroupsList()
        if not utils.checkAcl(myId, orgId, isOrgAdmin, relation, parent['meta']):
            raise ItemAccessDenied(itemType, itemId, state)
        defer.returnValue((itemId, item))
Beispiel #2
0
    def _getKeywordMatches(self, request, keyword, start='', count=10):
        args = {}
        authinfo = request.getSession(IAuthInfo)
        myId = authinfo.username
        orgId = authinfo.organization

        items = {}
        itemIds = []
        itemIdKeyMap = {}
        allFetchedItems = set()
        deleted = set()

        fetchStart = utils.decodeKey(start)
        fetchCount = count + 2
        while len(itemIds) < count:
            fetchedItemIds = []
            toFetchItems = set()

            results = yield db.get_slice(orgId + ":" + keyword, "keywordItems",
                                         count=fetchCount, start=fetchStart,
                                         reverse=True)
            for col in results:
                fetchStart = col.column.name
                itemAndParentIds = col.column.value.split(':')
                itemIdKeyMap[itemAndParentIds[0]] = fetchStart
                fetchedItemIds.append(itemAndParentIds[0])
                for itemId in itemAndParentIds:
                    if itemId not in allFetchedItems:
                        toFetchItems.add(itemId)
                        allFetchedItems.add(itemId)

            if toFetchItems:
                fetchedItems = yield db.multiget_slice(toFetchItems, "items",
                                                       ["meta", "attachments"])
                fetchedItems = utils.multiSuperColumnsToDict(fetchedItems)
                items.update(fetchedItems)

            for itemId in fetchedItemIds:
                item = items[itemId]
                if not 'meta' in item:
                    continue

                state = item['meta'].get('state', 'published')
                if state == 'deleted':
                    deleted.add(itemIdKeyMap[itemId])
                elif utils.checkAcl(myId, orgId, True, None, item['meta']):
                    itemIds.append(itemId)

            if len(results) < fetchCount:
                break

        if len(itemIds) > count:
            nextPageStart = utils.encodeKey(itemIdKeyMap[itemIds[-1]])
            itemIds = itemIds[:-1]
        else:
            nextPageStart = None

        dd = db.batch_remove({'keywordItems': [orgId + ':' + keyword]},
                             names=deleted) if deleted else defer.succeed([])

        args.update({'items': items, 'myId': myId})
        toFetchEntities = set()
        extraDataDeferreds = []
        for itemId in itemIds:
            item = items[itemId]
            itemMeta = item['meta']
            toFetchEntities.add(itemMeta['owner'])
            if 'target' in itemMeta:
                toFetchEntities.update(itemMeta['target'].split(','))
            if 'parent' in itemMeta:
                parentId = itemMeta['parent']
                if parentId in items:
                    toFetchEntities.add(items[parentId]['meta']['owner'])

            itemType = itemMeta.get('type', 'status')
            if itemType in plugins:
                d = plugins[itemType].fetchData(args, itemId)
                extraDataDeferreds.append(d)

        result = yield defer.DeferredList(extraDataDeferreds)
        for success, ret in result:
            if success:
                toFetchEntities.update(ret)

        fetchedEntities = {}
        if toFetchEntities:
            fetchedEntities = base.EntitySet(toFetchEntities)
            yield fetchedEntities.fetchData()

        yield dd
        args.update({'entities': fetchedEntities,
                     'matches': itemIds, 'nextPageStart': nextPageStart})
        defer.returnValue(args)
Beispiel #3
0
    def _invite(self, request, convId=None):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        myOrgId = args['orgId']
        convId, conv = yield utils.getValidItemId(request, "id", columns=["invitees"])

        # Parse invitees from the tag edit plugin values
        arg_keys = request.args.keys()
        invitees, new_invitees = [], []
        for arg in arg_keys:
            if arg.startswith("invitee[") and arg.endswith("-a]"):
                rcpt = arg.replace("invitee[", "").replace("-a]", "")
                if rcpt != "":
                    invitees.append(rcpt)

        if myId not in conv["invitees"].keys():
            raise errors.invalidRequest(_("Only those who are invited can invite others"))

        res = base.EntitySet(invitees)
        yield res.fetchData()
        invitees = [x for x in res.keys() if res[x].basic["org"] == myOrgId]
        invitees = [x for x in invitees if x not in conv["invitees"].keys()]
        relation = Relation(myId, [])

        updateConv = {"meta":{}, "invitees":{}}
        if myId == conv["meta"]["owner"]:
            #If invited by owner, add the invitees to the ACL
            acl = conv["meta"]["acl"]
            acl = pickle.loads(acl)
            acl.setdefault("accept", {}).setdefault("users", [])
            acl["accept"]["users"].extend(invitees)
            updateConv["meta"]["acl"] = pickle.dumps(acl)
            new_invitees.extend(invitees)
        else:
            for invitee in invitees:
                relation = Relation(invitee, [])
                yield relation.initGroupsList()
                withinAcl = utils.checkAcl(invitee, myOrgId, False,
                                           relation, conv["meta"])
                if withinAcl:
                    new_invitees.append(invitee)

        if new_invitees:
            convMeta = conv["meta"]
            starttime = int(convMeta["event_startTime"])
            starttimeUUID = utils.uuid1(timestamp=starttime)
            starttimeUUID = starttimeUUID.bytes

            endtime = int(convMeta["event_endTime"])
            endtimeUUID = utils.uuid1(timestamp=endtime)
            endtimeUUID = endtimeUUID.bytes

            updateConv["invitees"] = dict([(x, myId) for x in new_invitees])
            d = yield db.batch_insert(convId, "items", updateConv)

            yield event.inviteUsers(request, starttimeUUID, endtimeUUID,
                                    convId, conv["meta"], myId,
                                    myOrgId, new_invitees)
            request.write("""$$.alerts.info('%s');""" \
                            %("%d people invited to this event" %len(new_invitees)))
        else:
            if not invitees:
                request.write("""$$.alerts.info('%s');""" \
                                %("Invited persons are already on the invitation list"))
            else:
                request.write("""$$.alerts.info('%s');""" \
                                %("Invited persons do not have access to this event"))

        request.write("$('#item-subactions .tagedit-listelement-old').remove();")
Beispiel #4
0
def userFiles(myId, entityId, myOrgId, start='', end='', fromFeed=True):
    allItems = {}
    hasPrevPage = False     # Do we have another page before the current one.
    nextPageStart = ''      # Start item for the next page
    accessibleFiles = []
    accessibleItems = []
    toFetchEntities = set()

    count = constants.FILES_PER_PAGE
    toFetchCount = count + 1

    relation = Relation(myId, [])
    yield relation.initGroupsList()

    # Fetching files owned by entityId or files that were part of entityId's feed.
    cf = 'entityFeed_files' if fromFeed else 'user_files'

    # End is actually the start item of next page.
    # If @end is set, we have to display @count items before @end.  For that
    # we fetch @count + 2 items before (and including) @end. Of the extra items
    # fetched, one item helps us determine if there is another page before this
    # and the other one is the start of next page.
    if end:
        start = end
        reverse = False
        toFetchCount += 1
    else:
        reverse = True

    while 1:
        files = yield db.get_slice(entityId, cf, count=toFetchCount, start=start, reverse=reverse)
        files = utils.columnsToDict(files, True)
        toFetchItems = []
        for tuuid in files:
            if len(files[tuuid].split(':')) == 4:
                fid, name, itemId, attachmentId = files[tuuid].split(':')
                toFetchItems.append(itemId)

        toFetchItems = [itemId for itemId in toFetchItems if itemId not in accessibleItems]
        if toFetchItems:
            items = yield db.multiget_slice(toFetchItems, "items", ["meta"])
            items = utils.multiSuperColumnsToDict(items)
            toFetchConvIds = [items[itemId]['meta']['parent'] for itemId in items if 'parent' in items[itemId]['meta'] and items[itemId]['meta']['parent'] not in allItems]
            if toFetchConvIds:
                convs = yield db.multiget_slice(toFetchConvIds, "items", ["meta"])
                convs = utils.multiSuperColumnsToDict(convs)
                allItems.update(convs)
            allItems.update(items)
            for itemId in items:
                if 'parent' in items[itemId]['meta']:
                    convId = items[itemId]['meta']['parent']
                    acl = allItems[convId]['meta']['acl']
                else:
                    acl = items[itemId]['meta']['acl']
                    convId = itemId
                if utils.checkAcl(myId, myOrgId, False, relation, allItems[convId]['meta']):
                    accessibleItems.append(itemId)

        for tuuid in files:
            if len(files[tuuid].split(':')) == 4:
                fid, name, itemId, ownerId = files[tuuid].split(':')
                if itemId in accessibleItems:
                    accessibleFiles.append((tuuid,
                                            (fid, urlsafe_b64decode(name),
                                             itemId, ownerId, allItems[itemId])))
                    toFetchEntities.add(ownerId)

        if len(files) < toFetchCount or len(accessibleFiles) > count:
            break
        else:
            start = files.keys()[-1]

    if end:
        # We have enough items to have another page before this.
        if len(accessibleFiles) > count + 1:
            hasPrevPage = True
            accessibleFiles = accessibleFiles[:count + 1]

        # Revert the list to get most recent items first.
        accessibleFiles.reverse()

        # The last item is actually the first item of next page.
        nextPageStart = accessibleFiles[-1][0]
        accessibleFiles = accessibleFiles[:-1]

    elif start:
        hasPrevPage = True  # XXX: may not always be true, but the edge case is OK

    if len(accessibleFiles) > count:
        nextPageStart = accessibleFiles[count][0]
        accessibleFiles = accessibleFiles[:count]

    defer.returnValue((accessibleFiles, hasPrevPage, nextPageStart, toFetchEntities))