Beispiel #1
0
    def _listPresetTags(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        orgId = args["orgId"]
        landing = not self._ajax

        args['title'] = 'Preset Tags'
        args['menuId'] = 'tags'
        args["viewType"] = "tags"

        if script and landing:
            t.render(request, "admin.mako", **args)

        if script and appchange:
            t.renderScriptBlock(request, "admin.mako", "layout",
                                    landing, "#mainbar", "set", **args)

        presetTags = yield db.get_slice(orgId, "orgPresetTags", count=100)
        presetTags = utils.columnsToDict(presetTags, ordered=True).values()
        if presetTags:
            tags_ = yield db.get_slice(orgId, "orgTags", presetTags)
            tags_ = utils.supercolumnsToDict(tags_)
        else:
            tags_ = {}

        args['tagsList'] = presetTags
        args['tags'] = tags_
        if script:
            t.renderScriptBlock(request, "admin.mako", "list_tags",
                                    landing, "#content", "set", **args)

        if not script:
            t.render(request, "admin.mako", **args)
Beispiel #2
0
def getLatestCounts(request, asJSON=True):
    authinfo = yield defer.maybeDeferred(request.getSession, IAuthInfo)
    myId = authinfo.username
    myOrgId = authinfo.organization

    latest = yield db.get_slice(myId, "latest")
    latest = supercolumnsToDict(latest)
    counts = dict([(key, len(latest[key])) for key in latest])

    # Default keys for which counts should be set
    defaultKeys = ["notifications", "messages", "groups", "tags"]
    for key in defaultKeys:
        counts[key] = counts[key] if key in counts else 0

    groups = yield db.get_slice(myId, "entities", ["adminOfGroups"])
    groups = supercolumnsToDict(groups).get("adminOfGroups", {}).keys()
    if groups:
        counts.setdefault("groups", 0)
        cols = yield db.multiget_slice(groups, "latest")
        cols = multiSuperColumnsToDict(cols)
        for groupId in cols:
            for key in cols[groupId]:
                counts["groups"] += len(cols[groupId][key])
    if asJSON:
        defer.returnValue(json.dumps(counts))
    else:
        defer.returnValue(counts)
Beispiel #3
0
    def _addPresetTag(self, request):
        orgId = request.getSession(IAuthInfo).organization
        tagNames = utils.getRequestArg(request, 'tag')
        if not tagNames:
            return

        invalidTags = []
        tagNames = [x.strip().decode('utf-8', 'replace') for x in tagNames.split(',')]
        for tagName in tagNames:
            if len(tagName) < 50 and regex.match('^[\w-]*$', tagName):
                yield tags.ensureTag(request, tagName, orgId, True)
            else:
                invalidTags.append(tagName)

        presetTags = yield db.get_slice(orgId, "orgPresetTags")
        presetTags = utils.columnsToDict(presetTags, ordered=True).values()

        tags_ = yield db.get_slice(orgId, "orgTags", presetTags)
        tags_ = utils.supercolumnsToDict(tags_)
        args = {'tags': tags_, 'tagsList': presetTags}

        handlers = {}
        if invalidTags:
            if len(invalidTags) == 1:
                message = " %s is invalid tag." % (invalidTags[0])
            else:
                message = " %s are invalid tags. " % (",".join(invalidTags))
            errorMsg = "%s <br/>Tag can contain alpha-numeric characters or hyphen only. It cannot be more than 50 characters" % (message)
            handlers = {'onload': "$$.alerts.error('%s')" % (errorMsg)}

        t.renderScriptBlock(request, "admin.mako", "list_tags",
                            False, "#content", "set", True,
                            handlers=handlers, **args)
Beispiel #4
0
def deleteFileInfo(myId, orgId, itemId, item, conv=None):

    if 'parent' in item['meta']:
        if not conv:
            conv = yield db.get_slice(item['meta']['parent'], 'items', ['meta'])
            conv = utils.supercolumnsToDict(conv)
        convId = item['meta']['parent']
    else:
        conv = item
        convId = itemId
    acl = pickle.loads(conv['meta']['acl'])

    allowedGroups = acl.get('accept', {}).get('groups', [])
    deniedGroups = acl.get('deny', {}).get('groups', [])
    groups = [x for x in allowedGroups if x not in deniedGroups]
    allowedOrgs = acl.get('accept', {}).get('orgs', [])
    ownerId = conv['meta']['owner']

    entityIds = [myId]
    entityIds.extend(groups)
    entityIds.extend(allowedOrgs)
    entityIds_ = yield utils.expandAcl(myId, orgId, conv['meta']['acl'], convId, ownerId, True)
    entityIds.extend(entityIds_)
    deferreds = []

    for attachmentId in item.get('attachments', {}):
        col = yield db.get_slice(attachmentId, 'attachmentVersions', count=1)
        tuuid = col[0].column.name
        deferreds.append(db.remove(myId, "user_files", tuuid))
        #TODO: use batch remove/batch mutate
        for entityId in entityIds:
            deferreds.append(db.remove(entityId, "entityFeed_files", tuuid))
    if deferreds:
        yield defer.DeferredList(deferreds)
Beispiel #5
0
    def _deletePresetTag(self, request):
        orgId = request.getSession(IAuthInfo).organization
        tagId = utils.getRequestArg(request, 'id')
        if not tagId:
            return

        try:
            tag = yield db.get(orgId, 'orgTags', super_column=tagId)
            tag = utils.supercolumnsToDict([tag])
            tagName = tag[tagId]['title']
            if 'isPreset' in tag[tagId]:
                yield db.remove(orgId, "orgTags", 'isPreset', tagId)
                yield db.remove(orgId, 'orgPresetTags', tagName)
            presetTags = yield db.get_slice(orgId, "orgPresetTags")
            presetTags = utils.columnsToDict(presetTags, ordered=True).values()
            if presetTags:
                tags_ = yield db.get_slice(orgId, "orgTags", presetTags)
                tags_ = utils.supercolumnsToDict(tags)
            else:
                tags_ = {}
            args = {'tagsList': presetTags, 'tags': tags_}
            request.write('$("#tag-%s").remove()' % (tagId))

        except ttypes.NotFoundException:
            return
Beispiel #6
0
def pushfileinfo(myId, orgId, itemId, item, conv=None):
    if 'parent' in item['meta']:
        if not conv:
            conv = yield db.get_slice(item['meta']['parent'], "items", ["meta"])
            conv = utils.supercolumnsToDict(conv)
        convId = item['meta']['parent']
    else:
        convId = itemId
        conv = item
    acl = pickle.loads(conv['meta']['acl'])

    allowedGroups = acl.get('accept', {}).get('groups', [])
    deniedGroups = acl.get('deny', {}).get('groups', [])
    groups = [x for x in allowedGroups if x not in deniedGroups]
    allowedOrgs = acl.get('accept', {}).get('orgs', [])
    ownerId = conv['meta']['owner']

    entityIds = [myId]
    entityIds.extend(groups)
    entityIds.extend(allowedOrgs)
    entityIds_ = yield utils.expandAcl(myId, orgId, conv['meta']['acl'], convId, ownerId, True)
    entityIds.extend(entityIds_)

    for attachmentId in item.get('attachments', {}):
        name, size, ftype = item['attachments'][attachmentId].split(':')
        cols = yield db.get_slice(attachmentId, "attachmentVersions", count=1)
        tuuid = cols[0].column.name
        value = '%s:%s:%s:%s' % (attachmentId, name, itemId, ownerId)
        #TODO: use batch remove/batch mutate
        yield db.insert(myId, "user_files", value, tuuid)
        for entityId in entityIds:
            yield db.insert(entityId, "entityFeed_files", value, tuuid)
Beispiel #7
0
def getPendingRequests(group, me, start='', count=PEOPLE_PER_PAGE):
    """get the list of users who want to join the group.
    Only admin can view pending group requests.

    Keyword params:
    @me:
    @group: group object
    @start: start fetching from @start
    @count: no.of pending requests to fetch.
    """
    toFetchCount = count + 1
    nextPageStart = None
    prevPageStart = None

    if me.id not in group.admins:
        raise errors.PermissionDenied('Access Denied')

    cols = yield db.get_slice(group.id, "pendingConnections",
                              start=start, count=toFetchCount)
    userIds = [x.column.name.split(':')[1] for x in cols if len(x.column.name.split(':')) == 2]
    if len(userIds) == toFetchCount:
        nextPageStart = userIds[-1]
        userIds = userIds[0:count]
    entities = base.EntitySet(userIds)
    yield entities.fetchData()
    if start:
        cols = yield db.get_slice(group.id, "pendingConnections",
                                  start=start, count=toFetchCount,
                                  reverse=True)
        if len(cols) > 1:
            prevPageStart = cols[-1].column.name
    data = {'userIds': userIds, "entities": entities,
            "prevPageStart": prevPageStart,  "nextPageStart": nextPageStart}
    defer.returnValue(data)
Beispiel #8
0
    def _getPresence(self, request):
        authInfo = request.getSession(IAuthInfo)
        orgId = authInfo.organization
        myId = authInfo.username
        data = []

        cols = yield db.get_slice(orgId, "presence")
        cols = utils.supercolumnsToDict(cols)
        if myId not in cols:
            myPresence = yield db.get_slice(orgId, "presence", super_column=myId)
            cols[myId] = utils.columnsToDict(myPresence)

        presence = {}
        for userId in cols:
            presence[userId] = getMostAvailablePresence(cols[userId].values())

        if presence[myId] == PresenceStates.OFFLINE:
            request.write(json.dumps(data))
            return

        userIds = cols.keys()
        entities = base.EntitySet(userIds)
        yield entities.fetchData()
        for entityId in entities.keys():
            entity = entities[entityId]
            _data = {"userId": entityId, "name": entity.basic['name'],
                     "status": presence.get(entityId, PresenceStates.OFFLINE),
                     "title": entity.basic["jobTitle"],
                     "avatar": utils.userAvatar(entityId,  entity, 's')}
            data.append(_data)

        request.write(json.dumps(data))
Beispiel #9
0
    def fetchData(self, args, convId=None, userId=None, columns=[]):
        convId = convId or args["convId"]
        myId = userId or args.get("myId", None)

        conv = yield db.get_slice(convId, "items",
                                  ['options', 'counts'].extend(columns))
        conv = utils.supercolumnsToDict(conv, True)
        conv.update(args.get("items", {}).get(convId, {}))

        options = conv["options"] if "options" in conv else None
        if not options:
            raise errors.InvalidRequest("The poll does not have any options")

        myVote = yield db.get_slice(myId, "userVotes", [convId])
        myVote = myVote[0].column.value if myVote else None

        startTime = conv['meta'].get('start', None)
        endTime = conv['meta'].get('end', None)
        showResults = conv['meta'].get('showResults', 'True') == True

        if not showResults:
            # FIX: endTime is String. convert to time
            if not endTime or time.gmtime() > endTime:
                showResults = "True"

        args.setdefault("items", {})[convId] = conv
        args.setdefault("myVotes", {})[convId] = myVote
        args.setdefault("showResults", {})[convId] = showResults

        defer.returnValue(set())
Beispiel #10
0
    def _tags(self, request, term):
        if len(term) < 2:
            request.write("[]")
            return
        orgId = request.getSession(IAuthInfo).organization
        finish = _getFinishTerm(term)
        itemId = utils.getRequestArg(request, "itemId")
        if not itemId:
            request.write("[]")
            return

        toFetchTags = set()

        d1 = db.get_slice(orgId, "orgTagsByName", start=term, finish=finish, count=10)
        tags = []
        matchedTags = yield d1
        matchedTags = [match.column.value for match in matchedTags]
        if matchedTags:
            matchedTags = yield db.get_slice(orgId, "orgTags", matchedTags)
            matchedTags = utils.supercolumnsToDict(matchedTags)
            for tagId in matchedTags:
                tags.append({"title": matchedTags[tagId]["title"], "id": tagId})
        tags.sort(key=itemgetter("title"))

        output = []
        template = self._singleLineTemplate
        for tag in tags:
            data = {"title": tag["title"], "meta": ""}
            output.append({"value": tag["title"], "label": template % data, "href": "/tags?id=%s" % tag["id"]})

        request.write(json.dumps(output))
Beispiel #11
0
    def _revoke(self, request):
        authinfo = request.getSession(IAuthInfo)
        myId = authinfo.username
        myOrgId = authinfo.organization
        clientId = utils.getRequestArg(request, "id", sanitize=False)

        client = yield db.get_slice(clientId, "apps")
        client = utils.supercolumnsToDict(client)
        if not client:
            raise errors.InvalidApp(clientId)

        me = yield db.get_slice(myId, "entities", ["apikeys", "apps"])
        me = utils.supercolumnsToDict(me)

        # Remove the client in case of API Key
        if client["meta"]["category"] == "apikey":
            if client["meta"]["author"] != myId:
                raise errors.AppAccessDenied(clientId)

            d1 = db.remove(clientId, "apps")
            d2 = db.remove(myId, "appsByOwner", clientId)
            d3 = db.remove(myId, "entities", clientId, "apikeys")
            d4 = db.remove(myOrgId, "appsByOwner", clientId)
            yield defer.DeferredList([d1, d2, d3, d4])

        # Remove the refresh token
        # XXX: Valid access tokens could still exist
        else:
            authorization = me["apps"][clientId]
            d1 = db.remove(myId, "entities", clientId, "apps")
            d2 = db.remove(authorization, "oAuthData")
            yield defer.DeferredList([d1, d2])
Beispiel #12
0
    def _myCollection(self, request, term):
        authInfo = request.getSession(IAuthInfo)
        myId = authInfo.username
        orgId = authInfo.organization
        finish = _getFinishTerm(term)

        # Fetch list of tags and names that match the given term
        d2 = db.get_slice(orgId, "nameIndex", start=term, finish=finish, count=10)

        toFetchEntities = set()
        users = []

        # List of users that match the given term
        matchedUsers = yield d2
        for user in matchedUsers:
            name, uid = user.column.name.rsplit(":")
            if uid not in toFetchEntities:
                users.append(uid)
                toFetchEntities.add(uid)

        # Fetch the required entities
        entities = {}
        if toFetchEntities:
            entities = base.EntitySet(toFetchEntities)
            yield entities.fetchData()

        output = []
        template = self._dlgLinetemplate
        avatar = utils.userAvatar

        for uid in users:
            if uid in entities:
                name = entities[uid].basic["name"]
                data = {
                    "icon": avatar(uid, entities[uid], "s"),
                    "title": name,
                    "meta": entities[uid].basic.get("jobTitle", ""),
                }
                output.append({"label": template % data, "type": "user", "value": uid})

        cols = yield db.get_slice(myId, "entityGroupsMap", start=term.lower(), finish=finish.lower(), count=10)
        groupIds = [x.column.name.split(":", 1)[1] for x in cols]
        avatar = utils.groupAvatar
        groups = {}

        if groupIds:
            groups = base.EntitySet(groupIds)
            yield groups.fetchData()

        for groupId in groupIds:
            data = {
                "icon": avatar(groupId, groups[groupId], "s"),
                "title": groups[groupId].basic["name"],
                "meta": groups[groupId].basic.get("desc", "&nbsp;"),
            }
            obj = {"value": groupId, "label": template % data, "type": "group"}
            output.append(obj)

        request.write(json.dumps(output))
Beispiel #13
0
    def _unlike(self, request, data=None):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        orgId = args['orgId']

        itemId, item = data['id']
        item = yield Item.unlike(itemId, item, myId, orgId)
        if not item:
            return

        args["items"] = {itemId: item}
        args["myLikes"] = {itemId: []}
        likesCount = int(item["meta"]["likesCount"])
        convId = item["meta"].get('parent', itemId)

        if itemId != convId:
            t.renderScriptBlock(request, "item.mako", "item_footer", False,
                                 "#item-footer-%s" % (itemId), "set",
                                 args=[itemId], **args)
        else:
            relation = Relation(myId, [])
            yield relation.initSubscriptionsList()

            toFetchEntities = set()
            likes = []
            subscriptions = list(relation.subscriptions)
            if subscriptions:
                likes = yield db.get_slice(convId, "itemLikes", subscriptions)
                likes = [x.column.name for x in likes]
                toFetchEntities = set(likes)

            feedItems = yield db.get_slice(myId, "feedItems", [convId])
            feedItems = utils.supercolumnsToDict(feedItems)
            isFeed = (utils.getRequestArg(request, "_pg") != "/item")
            hasComments = False
            if not isFeed:
                hasComments = True
            else:
                feedItems = yield db.get_slice(myId, "feedItems", [convId])
                feedItems = utils.supercolumnsToDict(feedItems)
                for tuuid in feedItems.get(convId, {}):
                    val = feedItems[convId][tuuid]
                    rtype = val.split(":")[0]
                    if rtype == "C":
                        hasComments = True

            entities = base.EntitySet(toFetchEntities)
            if toFetchEntities:
                yield entities.fetchData()

            args["entities"] = entities

            handler = {"onload": "(function(){$$.convs.showHideComponent('%s', 'likes', false)})();" % (convId)} if not likes else None
            t.renderScriptBlock(request, "item.mako", "conv_footer", False,
                                "#item-footer-%s" % (itemId), "set",
                                args=[itemId, hasComments, likes], **args)
            t.renderScriptBlock(request, "item.mako", 'conv_likes', False,
                                '#conv-likes-wrapper-%s' % convId, 'set', True,
                                args=[itemId, likesCount, False, likes], handlers=handler, **args)
Beispiel #14
0
 def fetchData(self, columns=None):
     if columns == None:
         columns = ['basic']
     if columns == []:
         data = yield db.get_slice(self.id, "entities")
     else:
         data = yield db.get_slice(self.id, "entities", columns)
     data = utils.supercolumnsToDict(data)
     self._data = data
Beispiel #15
0
    def _getFileInfo(self, request):
        """Fetch the meta info on a file that is being requested to be
        downloaded. Returns the meta info of the file in question.

        Keyword Arguments:
        itemId: id of the conversation on which this file is attached.
        attachmentId: id of the file on the amazon S3 that is to be served.
        version: version of the file on the amazon S3 that the user is
            requesting.

        """
        authinfo = request.getSession(IAuthInfo)
        myId = authinfo.username
        myOrgId = authinfo.organization
        itemId = utils.getRequestArg(request, "id", sanitize=False)
        attachmentId = utils.getRequestArg(request, "fid", sanitize=False)
        version = utils.getRequestArg(request, "ver", sanitize=False) or ''
        columns = ["meta", "attachments", "participants"]

        if not (itemId and attachmentId):
            raise errors.MissingParams([])

        item = yield db.get_slice(itemId, "mConversations", columns)
        item = utils.supercolumnsToDict(item)
        if not item:
            raise errors.InvalidMessage(itemId)
        if myId not in item.get('participants', {}):
            raise errors.MessageAccessDenied(itemId)

        # Check if the attachmentId belong to item
        if attachmentId not in item['attachments'].keys():
            raise errors.InvalidAttachment(itemId, attachmentId, version)

        fileId, filetype, name = None, 'text/plain', 'file'
        if version:
            version = utils.decodeKey(version)
            try:
                cols = yield db.get(attachmentId, "attachmentVersions", version)
            except ttypes.NotFoundException:
                raise errors.InvalidAttachment(itemId, attachmentId, version)
            except ttypes.InvalidRequestException:
                raise errors.InvalidAttachment(itemId, attachmentId, version)
            cols = utils.columnsToDict([cols])
        else:
            cols = yield db.get_slice(attachmentId, "attachmentVersions", count=1, reverse=True)
            cols = utils.columnsToDict(cols)
            version = cols.keys()[0]


        fileId, name, size, filetype = cols[version].split(':')

        files = yield db.get_slice(fileId, "files", ["meta"])
        files = utils.supercolumnsToDict(files)

        url = files['meta']['uri']
        owner = files["meta"]["owner"]
        defer.returnValue([owner, url, filetype, size, name])
Beispiel #16
0
    def delete(self, myId, convId, conv):
        log.debug("plugin:delete", convId)
        user_tuids = {}

        # Get the list of every user who responded to this event
        res = yield db.get_slice(convId, "eventResponses")
        attendees = [x.column.name.split(":", 1)[1] for x in res]

        # Add all the invited people of the item
        res = yield db.get_slice(convId, "items", ['invitees'])
        res = utils.supercolumnsToDict(res)
        attendees.extend(res["invitees"].keys())
        invitedPeople = res["invitees"].keys()

        log.debug("Maps", ["%s:%s"%(uId, convId) for \
                                       uId in attendees])

        # Get the Org and GroupIds if any.
        convMeta = conv["meta"]
        groupIds = convMeta["target"].split(",") if "target" in convMeta else []
        attendees.extend(groupIds+[convMeta["org"]])

        log.debug("Attendees", attendees)

        # Get the timeuuids that were inserted for this user
        res = yield db.multiget_slice(["%s:%s"%(uId, convId) for \
                                       uId in attendees], "userAgendaMap")
        res = utils.multiColumnsToDict(res)

        for k, v in res.iteritems():
            uid = k.split(":", 1)[0]
            tuids = v.keys()
            if tuids:
                user_tuids[uid] = tuids

        log.debug("userAgenda Removal", user_tuids)
        # Delete their entries in the user's list of event entries
        for attendee in user_tuids:
            yield db.batch_remove({'userAgenda': [attendee]},
                                    names=user_tuids[attendee])

        # Delete invitation entries for invited people
        invited_tuids = dict([[x, user_tuids[x]] for x in invitedPeople])
        log.debug("userAgenda Invitation Removal", invited_tuids)
        for attendee in invited_tuids:
            yield db.batch_remove({'userAgenda': ['%s:%s' %(attendee, 'I')]},
                                    names=invited_tuids[attendee])

        log.debug("eventResponses Removal", convId)
        # Delete the event's entry in eventResponses
        yield db.remove(convId, "eventResponses")

        log.debug("userAgendaMap Removal", user_tuids)
        # Delete their entries in userAgendaMap
        for attendee in user_tuids:
            yield db.batch_remove({'userAgendaMap': ["%s:%s"%(attendee, convId)]},
                                    names=user_tuids[attendee])
Beispiel #17
0
def getGroups(me, entity, start='', count=PEOPLE_PER_PAGE):
    """get the groups of entity. (either groups of an organization
    or groups of an user)

    keyword params:
    @me:
    @entity: org/user
    start: fetch group from @start
    count: no.of groups to fetch.
    """
    toFetchCount = count + 1
    groups = {}
    groupIds = []
    myGroupsIds = []
    groupFollowers = {}
    pendingConnections = {}
    toFetchGroups = set()
    nextPageStart = ''
    prevPageStart = ''

    #TODO: list the groups in sorted order.
    cols = yield db.get_slice(entity.id, 'entityGroupsMap',
                              start=start, count=toFetchCount)
    groupIds = [x.column.name for x in cols]
    if len(groupIds) > count:
        nextPageStart = utils.encodeKey(groupIds[-1])
        groupIds = groupIds[0:count]
    toFetchGroups.update(set([y.split(':', 1)[1] for y in groupIds]))
    if entity.id == me.id:
        myGroupsIds = [x.split(':', 1)[1] for x in groupIds]
    elif groupIds:
        cols = yield db.get_slice(me.id, "entityGroupsMap", groupIds)
        myGroupsIds = [x.column.name.split(':', 1)[1] for x in cols]
    groupIds = [x.split(':', 1)[1] for x in groupIds]

    if start:
        cols = yield db.get_slice(entity.id, 'entityGroupsMap', start=start,
                                  count=toFetchCount, reverse=True)
        if len(cols) > 1:
            prevPageStart = utils.encodeKey(cols[-1].column.name)

    if toFetchGroups:
        groups = base.EntitySet(toFetchGroups)
        yield groups.fetchData()
        groupFollowers = yield db.multiget_slice(toFetchGroups, "followers",
                                                 names=[me.id])
        groupFollowers = utils.multiColumnsToDict(groupFollowers)
        columns = reduce(lambda x, y: x + y, [["GO:%s" % (x), "GI:%s" % (x)] for x in toFetchGroups])
        cols = yield db.get_slice(me.id, 'pendingConnections', columns)
        pendingConnections = utils.columnsToDict(cols)

    data = {"entities": groups, "groupIds": groupIds,
            "pendingConnections": pendingConnections,
            "myGroups": myGroupsIds, "groupFollowers": groupFollowers,
            "nextPageStart": nextPageStart, "prevPageStart": prevPageStart}
    defer.returnValue(data)
Beispiel #18
0
def edit(me, group, name, access, desc, displayPic):
    """update group meta info.
    Only group-admin can edit group meta info.

    Keyword params:
    @me:
    @group:
    @name: name of the group.
    @access: group access type (open/closed).
    @desc: description of the group.
    @displayPic: profile pic of the group.

    """
    if me.id not in group.admins:
        raise errors.PermissionDenied('Only administrator can edit group meta data')
    if name:
        start = name.lower() + ':'
        cols = yield db.get_slice(me.basic['org'], "entityGroupsMap",
                                  start=start, count=1)
        for col in cols:
            name_, groupId_ = col.column.name.split(':')
            if name_ == name.lower() and groupId_ != group.id:
                raise errors.InvalidGroupName(name)

    meta = {'basic': {}}
    if name and name != group.basic['name']:
        meta['basic']['name'] = name
    if desc and desc != group.basic.get('desc', ''):
        meta['basic']['desc'] = desc
    if access in ['closed', 'open'] and access != group.basic['access']:
        meta['basic']['access'] = access
    if displayPic:
        avatar = yield saveAvatarItem(group.id, me.basic['org'], displayPic)
        meta['basic']['avatar'] = avatar
    if name and name != group.basic["name"]:
        members = yield db.get_slice(group.id, "groupMembers")
        members = utils.columnsToDict(members).keys()
        entities = members + [me.basic['org']]
        oldColName = "%s:%s" % (group.basic["name"].lower(), group.id)
        colname = '%s:%s' % (name.lower(), group.id)
        mutations = {}
        for entity in entities:
            mutations[entity] = {'entityGroupsMap': {colname: '',
                                                     oldColName: None}}
        #XXX:notify group-members about the change in name
        yield db.batch_mutate(mutations)

    if meta['basic']:
        yield db.batch_insert(group.id, 'entities', meta)
    if not desc and group.basic.get('desc', ''):
        yield db.remove(group.id, "entities", 'desc', 'basic')
    if (not desc and group.basic.get('desc', '')) or meta['basic']:
        defer.returnValue(True)
Beispiel #19
0
def getManagedGroups(me, start, count=PEOPLE_PER_PAGE):
    """get all groups managed by me

    Keyword params:
    @me:
    @start: get groups from @start.
    @count: no.of groups to be fetched.
    """
    groups = {}
    groupIds = []
    myGroupsIds = []
    nextPageStart = ''
    prevPageStart = ''
    toFetchCount = count + 1
    toFetchGroups = set()
    groupFollowers = {}
    pendingConnections = {}

    try:
        cols = yield db.get_slice(me.id, "entities",
                                  super_column='adminOfGroups',
                                  start=start, count=toFetchCount)
        groupIds = [x.column.name for x in cols]
        toFetchGroups.update(set(groupIds))
        myGroupsIds = groupIds
        if len(groupIds) > count:
            nextPageStart = utils.encodeKey(groupIds[-1])
            groupIds = groupIds[0:count]
    except ttypes.NotFoundException:
        pass

    if start:
        cols = yield db.get_slice(me.id, "entities",
                                  super_column='adminOfGroups', start=start,
                                 count=toFetchCount, reverse=True)
        if len(cols) > 1:
            prevPageStart = utils.encodeKey(cols[-1].column.name)

    if toFetchGroups:
        groups = base.EntitySet(toFetchGroups)
        yield groups.fetchData()
        groupFollowers = yield db.multiget_slice(toFetchGroups, "followers", names=[me.id])
        groupFollowers = utils.multiColumnsToDict(groupFollowers)
        columns = reduce(lambda x, y: x + y, [["GO:%s" % (x), "GI:%s" % (x)] for x in toFetchGroups])
        cols = yield db.get_slice(me.id, 'pendingConnections', columns)
        pendingConnections = utils.columnsToDict(cols)

    data = {"entities": groups, "groupIds": groupIds,
            "pendingConnections": pendingConnections,
            "myGroups": myGroupsIds, "groupFollowers": groupFollowers,
            "nextPageStart": nextPageStart, "prevPageStart": prevPageStart}
    defer.returnValue(data)
Beispiel #20
0
    def _listBlockedUsers(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        orgId = args["orgId"]
        landing = not self._ajax
        start = utils.getRequestArg(request, 'start') or ''
        start = utils.decodeKey(start)
        count = PEOPLE_PER_PAGE
        toFetchCount = count + 1
        nextPageStart = ''
        prevPageStart = ''
        args["title"] = "Manage Users"
        args["menuId"] = "users"
        args["viewType"] = "blocked"

        if script and landing:
            t.render(request, "admin.mako", **args)

        if script and appchange:
            t.renderScriptBlock(request, "admin.mako", "layout",
                                    landing, "#mainbar", "set", **args)

        args["heading"] = "Admin Console - Blocked Users"
        cols = yield db.get_slice(orgId, "blockedUsers",
                                  start=start, count=toFetchCount)
        blockedUsers = [col.column.name for col in cols]
        if len(blockedUsers) > count:
            nextPageStart = utils.encodeKey(blockedUsers[-1])
            blockedUsers = blockedUsers[:count]
        if start:
            cols = yield db.get_slice(orgId, "blockedUsers", start=start,
                                      count=toFetchCount, reverse=True)
            if len(cols) > 1:
                prevPageStart = utils.decodeKey(cols[-1].column.name)

        entities = base.EntitySet(blockedUsers)
        yield entities.fetchData()

        args["entities"] = entities
        args['nextPageStart'] = nextPageStart
        args['prevPageStart'] = prevPageStart

        if script:
            t.renderScriptBlock(request, "admin.mako", "viewOptions",
                                landing, "#users-view", "set", **args)
            t.renderScriptBlock(request, "admin.mako", "list_users",
                                    landing, "#content", "set", **args)

        if script and landing:
            request.write("</body></html>")
        if not script:
            t.render(request, "admin.mako", **args)
Beispiel #21
0
def untag(itemId, item, tagId, tag, myId, orgId):
    if "parent" in item:
        raise errors.InvalidRequest(_("Tags cannot be applied or removed from comments"))

    if tagId not in item.get("tags", {}):
        raise errors.InvalidRequest(_("No such tag on the item"))  # No such tag on item

    d1 = db.remove(itemId, "items", tagId, "tags")
    d2 = db.remove(tagId, "tagItems", item["meta"]["uuid"])
    d3 = db.get_slice(tagId, "tagFollowers")

    try:
        itemsCountCol = yield db.get(orgId, "orgTags", "itemsCount", tagId)
        tagItemsCount = int(itemsCountCol.column.value) - 1
        if tagItemsCount % 10 == 7:
            tagItemsCount = yield db.get_count(tagId, "tagItems")
            tagItemsCount = tagItemsCount - 1
        db.insert(orgId, "orgTags", "%s" % tagItemsCount, "itemsCount", tagId)
    except ttypes.NotFoundException:
        pass
    result = yield defer.DeferredList([d1, d2, d3])
    followers = utils.columnsToDict(result[2][1]).keys()


    feedUpdateVal = "T:%s:%s::%s" % (myId, itemId, tagId)
    yield Feed.unpush(myId, orgId, itemId, item,
                      feedUpdateVal, followers + [myId])
Beispiel #22
0
    def _vote(self, request):
        convId, conv = yield utils.getValidItemId(request, 'id', 'poll', ['options'])
        vote = utils.getRequestArg(request, 'option')
        if not vote or vote not in conv.get("options", {}):
            raise errors.MissingParams(["Option"])

        optionCounts = {}
        myId = request.getSession(IAuthInfo).username

        prevVote = yield db.get_slice(myId, "userVotes", [convId])
        prevVote = prevVote[0].column.value if prevVote else False
        if prevVote == vote:
            yield self._results(request)
            return

        if prevVote:
            yield db.remove(convId, "votes", myId, prevVote)
            prevOptionCount = yield db.get_count(convId, "votes", prevVote)
            optionCounts[prevVote] = str(prevOptionCount)

        yield db.insert(myId, "userVotes", vote, convId)
        yield db.insert(convId, "votes",  '', myId, vote)

        voteCount = yield db.get_count(convId, "votes", vote)
        optionCounts[vote] = str(voteCount)

        yield db.batch_insert(convId, "items", {"counts": optionCounts})
        yield self._results(request)
Beispiel #23
0
def updateAndPublishStatus(userId, orgId, sessionId, status, user=None):
    # Check if there is a change in the online status
    results = yield db.get_slice(orgId, 'presence', super_column=userId)
    results = utils.columnsToDict(results)
    oldPublishedStatus = getMostAvailablePresence(results.values())

    # Update the online status
    if status != 'offline':
        yield db.insert(orgId, 'presence', status, sessionId, userId)
    else:
        yield db.remove(orgId, 'presence', sessionId, userId)

    # If status changed broadcast the change
    # XXX: Currently everyone on the network will get the presence update.
    #      This will not scale well with big networks
    results[sessionId] = status
    newPublishedStatus = getMostAvailablePresence(results.values())

    if oldPublishedStatus != newPublishedStatus:
        if not user:
            user = base.Entity(userId)
            yield user.fetchData()
        data = {"userId": userId, 'status': newPublishedStatus,
                'name': user.basic['name'],
                'title': user.basic['jobTitle'],
                'avatar': utils.userAvatar(userId, user, 's')}
        yield comet.publish('/presence/' + orgId, data)
Beispiel #24
0
def clearChannels(userId, sessionId):
    key = "%s:%s" % (userId, sessionId)
    cols = yield db.get_slice(key, "sessionChannelsMap")
    channels = utils.columnsToDict(cols).keys()
    for channelId in channels:
        yield db.remove(channelId, "channelSubscribers", key)
    yield db.remove(key, "sessionChannelsMap")
Beispiel #25
0
    def render_POST(self, request):
        try:
            username = request.args['u'][0]
            password = request.args['p'][0]
            remember = request.args['r'][0] if 'r' in request.args else None
            if not username or not password:
                raise KeyError
        except KeyError:
            self._renderSigninForm(request, self.MISSING_FIELDS)
            return server.NOT_DONE_YET

        d = db.get_slice(username, "userAuth")
        def callback(result):
            cols = utils.columnsToDict(result)
            if not utils.checkpass(password, cols.get("passwordHash", "XXX")):
                return self._renderSigninForm(request, self.AUTHENTICATION_FAILED)
            if cols.has_key("isBlocked"):
                return self._renderSigninForm(request, self.USER_BLOCKED)
            if cols.has_key("isFlagged"):
                return self._renderSigninForm(request, self.USER_FLAGGED)
            self._saveSessionAndRedirect(request, cols, remember)
        def errback(error):
            return self._renderSigninForm(request, self.UNKNOWN_ERROR)
        d.addCallback(callback)
        d.addErrback(errback)

        return server.NOT_DONE_YET
Beispiel #26
0
    def _attendance(self, request):
        itemId, item = yield utils.getValidItemId(request, "id",
                                                  columns=["invitees"])
        list_type = utils.getRequestArg(request, 'type') or "yes"
        user_list = []

        if itemId and list_type in ["yes", "no", "maybe"]:
            cols = yield db.get_slice(itemId, "eventResponses")
            res = utils.columnsToDict(cols)
            for rsvp in res.keys():
                resp = rsvp.split(":")[0]
                uid = rsvp.split(":")[1]
                if resp == list_type:
                    if uid in item["invitees"] and \
                      item["invitees"][uid] == list_type:
                        user_list.insert(0, uid)
                    else:
                        user_list.append(uid)

            invited = user_list
            owner = item["meta"].get("owner")

            entities = base.EntitySet(invited+[owner])
            yield entities.fetchData()

            args = {"users": invited, "entities": entities}
            args['title'] = {"yes":_("People attending this event"),
                             "no": _("People not attending this event"),
                             "maybe": _("People who may attend this event")
                             }[list_type]

            t.renderScriptBlock(request, "item.mako", "userListDialog", False,
                                    "#invitee-dlg-%s"%(itemId), "set", **args)
Beispiel #27
0
    def _removeTempFile(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        myOrgId = args["orgId"]

        SKey = config.get('CloudFiles', 'SecretKey')
        AKey = config.get('CloudFiles', 'AccessKey')
        bucket = config.get('CloudFiles', 'Bucket')
        creds = AWSCredentials(AKey, SKey)

        client = s3Client.S3Client(creds)
        fileId = utils.getRequestArg(request, "id")
        key = "%s/%s/%s" % (myOrgId, myId, fileId)

        #Check if the file is not in the "files" CF. In other words, it is not
        # attached to an existing item. Also check if I am the owner of the
        # file. Finally clear the existing entry in the "temp_files" CF
        res = yield db.get_slice(fileId, "tmp_files", ["fileId"])
        if len(res) == 1:
            try:
                res = yield db.get(fileId, "files", super_column="meta")
            except ttypes.NotFoundException:
                file_info = yield client.head_object(bucket, key)
                owner = file_info['x-amz-meta-uid'][0]
                if owner == myId:
                    yield client.delete_object(bucket, key)
                    yield db.remove(fileId, "tmp_files")
                else:
                    raise errors.EntityAccessDenied("attachment", fileId)
            else:
                raise errors.InvalidRequest()
Beispiel #28
0
def getValidEntityId(request, arg, type="user", columns=None):
    entityId = getRequestArg(request, arg, sanitize=False)
    if not entityId:
        raise errors.MissingParams([_("%s id") % _(type).capitalize()])

    if not columns:
        columns = []
    columns.extend(["basic"])

    entity = yield db.get_slice(entityId, "entities", columns)
    if not entity:
        raise errors.InvalidEntity(type, entityId)

    entity = supercolumnsToDict(entity)
    basic = entity["basic"]

    if type != basic["type"]:
        raise errors.InvalidEntity(type, entityId)

    authinfo = request.getSession(IAuthInfo)
    myOrgId = authinfo.organization
    org = basic["org"] if basic["type"] != "org" else entityId
    if myOrgId != org:
        raise errors.EntityAccessDenied(type, entityId)
    defer.returnValue((entityId, entity))
Beispiel #29
0
def delete(itemId, item, myId, orgId):
    convId = item["meta"].get("parent", itemId)
    itemOwnerId = item["meta"]["owner"]

    if itemId == convId:
        conv = item
        convOwnerId = itemOwnerId
    else:
        conv = yield db.get_slice(convId, "items", ["meta", "tags"])
        conv = utils.supercolumnsToDict(conv)
        if not conv:
            raise errors.InvalidRequest(_('Conversation does not exist!'))

        convOwnerId = conv["meta"]["owner"]

    # TODO: Admin actions.
    # Do I have permission to delete the comment
    if (itemOwnerId != myId and convOwnerId != myId):
        raise errors.PermissionDenied(_("You must either own the comment or the conversation to delete this comment"))

    deferreds = []
    convType = conv["meta"].get('type', 'status')
    convACL = conv["meta"]["acl"]
    timestamp = str(int(time.time()))
    itemUUID = item["meta"]["uuid"]

    # The conversation is lazy deleted.
    # If it is the comment being deleted, rollback all feed updates
    # that were made due to this comment and likes on this comment.
    d = deleteItem(itemId, myId, orgId, item, conv)
    deferreds.append(d)

    yield defer.DeferredList(deferreds)
    defer.returnValue(conv)
Beispiel #30
0
def tag(itemId, item, tagName, myId, orgId):
    if "parent" in item["meta"]:
        raise errors.InvalidRequest(_("Tag cannot be applied on a comment"))

    (tagId, tag) = yield tags._ensureTag(tagName, myId, orgId)
    if tagId in item.get("tags", {}):
        raise errors.InvalidRequest(_("Tag already exists on the choosen item"))

    d1 = db.insert(itemId, "items", myId, tagId, "tags")
    d2 = db.insert(tagId, "tagItems", itemId, item["meta"]["uuid"])
    d3 = db.get_slice(tagId, "tagFollowers")

    tagItemsCount = int(tag.get("itemsCount", "0")) + 1
    if tagItemsCount % 10 == 7:
        tagItemsCount = yield db.get_count(tagId, "tagItems")
        tagItemsCount += 1
    db.insert(orgId, "orgTags", "%s" % tagItemsCount, "itemsCount", tagId)

    result = yield defer.DeferredList([d1, d2, d3])
    followers = utils.columnsToDict(result[2][1]).keys()

    if followers:
        timeUUID = uuid.uuid1().bytes
        feedUpdateVal = "T:%s:%s::%s" % (myId, itemId, tagId)
        yield Feed.push(myId, orgId, itemId, item, timeUUID,
                        feedUpdateVal, feeds=followers)

    defer.returnValue((tagId, tag))