Ejemplo n.º 1
0
    def _registerClient(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        myOrgId = args["orgId"]

        name = utils.getRequestArg(request, "name")
        desc = utils.getRequestArg(request, "desc")
        scope = utils.getRequestArg(request, "scope", multiValued=True)
        category = utils.getRequestArg(request, "category")
        redirect = utils.getRequestArg(request, "redirect", sanitize=False)

        if not name:
            raise errors.MissingParams(["Name"])

        if not scope:
            raise errors.MissingParams(["Permissions"])

        if category != "apikey" and not redirect:
            raise errors.MissingParams(["Redirect URL"])

        knownScopes = globals().get("scopes")
        unknownScopes = [x for x in scope if x not in knownScopes.keys()]
        if category not in ["webapp", "native", "apikey"] or unknownScopes:
            raise errors.BaseError("Invalid value sent for Type/Permissions")

        clientId = utils.getUniqueKey()
        clientSecret = utils.getRandomKey()

        meta = {
            "author": myId,
            "name": name,
            "org": myOrgId,
            "secret": utils.hashpass(clientSecret),
            "scope": " ".join(scope),
            "category": category,
        }

        if category != "apikey":
            meta["redirect"] = b64encode(redirect)
            meta["desc"] = desc
            yield db.batch_insert(clientId, "apps", {"meta": meta})
            yield db.insert(myId, "appsByOwner", "", clientId)
            yield db.insert(myOrgId, "appsByOwner", "", clientId)
        else:
            yield db.batch_insert(clientId, "apps", {"meta": meta})
            yield db.insert(myId, "entities", "", clientId, "apikeys")

        self.setTitle(request, name)

        args["clientId"] = clientId
        args["client"] = meta
        args["client"]["secret"] = clientSecret
        t.renderScriptBlock(request, "apps.mako", "registrationResults", landing, "#apps-contents", "set", **args)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
def addUser(emailId, displayName, passwd, orgId, jobTitle=None, timezone=None):
    userId = getUniqueKey()

    userInfo = {"basic": {"name": displayName, "org": orgId, "type": "user", "emailId": emailId}}
    userAuthInfo = {"passwordHash": hashpass(passwd), "org": orgId, "user": userId}

    if jobTitle:
        userInfo["basic"]["jobTitle"] = jobTitle
    if timezone:
        userInfo["basic"]["timezone"] = timezone

    yield db.insert(orgId, "orgUsers", "", userId)
    yield db.batch_insert(userId, "entities", userInfo)
    yield db.batch_insert(emailId, "userAuth", userAuthInfo)
    yield updateDisplayNameIndex(userId, [orgId], displayName, None)
    yield updateNameIndex(userId, [orgId], displayName, None)
    yield updateNameIndex(userId, [orgId], emailId, None)

    defer.returnValue(userId)
Ejemplo n.º 4
0
    def _addMembers(self, request):
        """This method add a new user to this conversation.

        Keyword Arguments:
        newMembers: A list of members who will be added to this conversation.
        convId: The id of the conversation to which these new members will be
            added as participants.

        CF Changes:
        mConversations

        """
        myId = request.getSession(IAuthInfo).username
        orgId = request.getSession(IAuthInfo).organization
        newMembers, body, subject, convId = self._parseComposerArgs(request)

        if not (convId and newMembers):
            raise errors.MissingParams(['Recipient'])

        conv = yield db.get_slice(convId, "mConversations")
        conv = utils.supercolumnsToDict(conv)
        subject = conv['meta'].get('subject', None)
        participants = set(conv.get('participants', {}).keys())
        if not conv:
            raise errors.InvalidMessage(convId)
        if myId not in participants:
            raise errors.MessageAccessDenied(convId)

        #cols = yield db.multiget_slice(newMembers, "entities", ['basic'])
        #people = utils.multiSuperColumnsToDict(cols)
        people = base.EntitySet(newMembers)
        yield people.fetchData()
        newMembers = set([userId for userId in people.keys() \
                            if people[userId].basic and \
                               people[userId].basic["org"] == orgId])
        newMembers = newMembers - participants

        mailNotificants = participants - set([myId])
        toFetchEntities = mailNotificants.union([myId, orgId]).union(newMembers)
        entities = base.EntitySet(toFetchEntities)
        yield entities.fetchData()
        data = {"entities": entities}
        data["orgId"] = orgId
        data["convId"] = convId
        data["subject"] = subject
        data["_fromName"] = entities[myId].basic['name']
        if newMembers:
            data["message"] = conv["meta"]["snippet"]
            newMembers = dict([(userId, '') for userId in newMembers])
            yield db.batch_insert(convId, "mConversations", {'participants': newMembers})
            yield self._deliverMessage(convId, newMembers, conv['meta']['uuid'], conv['meta']['owner'])
            yield notifications.notify(newMembers, ":NM", myId, **data)
        if mailNotificants and newMembers:
            data["addedMembers"] = newMembers
            yield notifications.notify(mailNotificants, ":MA", myId, **data)
Ejemplo n.º 5
0
def updateData():

    convIds = set()
    rows = yield db.get_range_slice('item_files', count=1000)

    for row in rows:
        convId = row.key
        convIds.add(convId)
        attachments = utils.supercolumnsToDict(row.columns)
        for attachmentId in attachments:
            for timeuuid in attachments[attachmentId]:
                encodedTimeUUID, aid, name, size, ftype = attachments[attachmentId][timeuuid].split(':')
                yield db.insert(attachmentId, "attachmentVersions", "%s:%s:%s:%s" %(aid, name, size, ftype), timeuuid)

    rows = yield db.get_range_slice('items', count=10000)
    for row in rows:
        itemId = row.key
        item = utils.supercolumnsToDict(row.columns)
        attachments = {}
        for attachmentId in item.get('attachments', {}):
            if len(item['attachments'][attachmentId].split(':')) == 4:
                x,name, size, ftype = item['attachments'][attachmentId].split(':')
                attachments[attachmentId] = "%s:%s:%s" %(name, size, ftype)
        if attachments:
            yield db.remove(itemId, 'items', super_column='attachments')
            yield db.batch_insert(itemId, "items", {"attachments": attachments})


    rows = yield db.get_range_slice('mConversations', count=10000)
    for row in rows:
        messageId = row.key
        message = utils.supercolumnsToDict(row.columns)
        attachments = {}
        print messageId
        for attachmentId in message.get('attachments', {}):
            if len(message['attachments'][attachmentId].split(':')) == 4:
                x,name, size, ftype = message['attachments'][attachmentId].split(':')
                attachments[attachmentId] = "%s:%s:%s" %(name, size, ftype)
        if attachments:
            yield db.remove(messageId, 'mConversations', super_column='attachments')
            yield db.batch_insert(messageId, "mConversations", {"attachments": attachments})
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
def unsubscribe(request, group, user):
    """Unsubscribe @user from @group.
    Remove the user from group-followers, group from user-groups,
    create a group-leave activity item and push item to group-followers
    and group feed. Remove the group from user display name indices.

    Raises an error if user is not member of group or when
    user is the only administrator of the group.

    keyword params:
    @user: entity object of user
    @group: entity object of the group
    @request:

    """
    try:
        yield db.get(group.id, "groupMembers", user.id)
    except ttypes.NotFoundException:
        raise errors.InvalidRequest(_("You are not a member of the group"))

    if len(getattr(group, 'admins', {}).keys()) == 1 \
       and user.id in group.admins:
        raise errors.InvalidRequest(_("You are the only administrator of this group"))

    colname = _entityGroupMapColName(group)
    itemType = "activity"
    responseType = "I"

    itemId = utils.getUniqueKey()
    acl = {"accept": {"groups": [group.id]}}
    _acl = pickle.dumps(acl)
    item = yield utils.createNewItem(request, itemType, user,
                                     acl, "groupLeave")
    item["meta"]["target"] = group.id

    d1 = db.remove(group.id, "followers", user.id)
    d2 = db.remove(user.id, "entityGroupsMap", colname)
    d3 = db.batch_insert(itemId, 'items', item)
    d4 = db.remove(group.id, "groupMembers", user.id)
    d5 = feed.pushToOthersFeed(user.id, user.basic['org'],
                               item["meta"]["uuid"], itemId, itemId, _acl,
                               responseType, itemType, user.id,
                               promoteActor=False)
    d6 = utils.updateDisplayNameIndex(user.id, [group.id], None,
                                      user.basic['name'])
    deferreds = [d1, d2, d3, d4, d5, d6]
    if user.id in group.admins:
        d7 = db.remove(group.id, "entities", user.id, "admins")
        d8 = db.remove(user.id, "entities", group.id, "adminOfGroups")
        deferreds.extend([d7, d8])

    yield defer.DeferredList(deferreds)
Ejemplo n.º 8
0
    def _newConversation(self, ownerId, participants, meta, attachments):
        """Commit the meta information about a new conversation. Returns
        the conversation id of the newly created conversation.

        CF Changes:
        mConversations

        """
        participants = dict([(userId, '') for userId in participants])
        convId = utils.getUniqueKey()
        attach_meta = self._formatAttachMeta(attachments)
        yield db.batch_insert(convId, "mConversations", {"meta": meta,
                                                "participants": participants,
                                                "attachments": attach_meta})
        defer.returnValue(convId)
Ejemplo n.º 9
0
def _upload_files(owner, tmp_fileIds):
    attachments = {}
    if tmp_fileIds:
        cols = yield db.multiget_slice(tmp_fileIds, "tmp_files", ["fileId"])
        cols = multiColumnsToDict(cols)
        for tmpFileId in cols:
            attachmentId = getUniqueKey()
            timeuuid = uuid.uuid1().bytes
            val = cols[tmpFileId]["fileId"]
            fileId, name, size, ftype = val.split(":")
            meta = {"meta": {"uri": tmpFileId, "name": name, "fileType": ftype, "owner": owner}}
            yield db.batch_insert(tmpFileId, "files", meta)
            yield db.remove(tmpFileId, "tmp_files")
            yield db.insert(attachmentId, "attachmentVersions", val, timeuuid)
            attachments[attachmentId] = (fileId, name, size, ftype)
    defer.returnValue(attachments)
Ejemplo n.º 10
0
    def _newMessage(self, ownerId, timeUUID, body, epoch):
        """Commit the meta information of a message. A message is a reply to a
        an existing conversation or the first message of a new conversation.

        CF Changes:
        messages

        """
        messageId = utils.getUniqueKey()
        meta = {"owner": ownerId,
                "timestamp": str(int(time.time())),
                'date_epoch': str(epoch),
                "body": body,
                "uuid": timeUUID}
        yield db.batch_insert(messageId, "messages", {'meta': meta})
        defer.returnValue(messageId)
Ejemplo n.º 11
0
def createUser(emailId, displayName, jobTitle, timezone, passwd):
    localpart, domain = emailId.split("@")

    existingUser = yield db.get_count(emailId, "userAuth")
    if not existingUser:
        orgId = yield getOrgKey(domain)
        if not orgId:
            orgId = utils.getUniqueKey()
            domains = {domain:''}
            basic = {"name":domain, "type":"org"}
            yield db.batch_insert(orgId, "entities", {"basic":basic,"domains":domains})
            yield db.insert(domain, "domainOrgMap", '', orgId)

        userId = yield utils.addUser(emailId, displayName, passwd,
                                     orgId, jobTitle, timezone)
    else:
        raise Exception("User already exists for " + emailId)
Ejemplo n.º 12
0
    def _editWorkInfo(self, request):
        # Contact information at work.
        myId = request.getSession(IAuthInfo).username
        orgId = request.getSession(IAuthInfo).organization

        me = base.Entity(myId)
        yield me.fetchData([])
        data = {}
        to_remove = []

        for field in ["phone", "mobile"]:
            val = utils.getRequestArg(request, field)
            if val:
                data[field] = val
            else:
                to_remove.append(field)

        if 'phone' in data and not re.match('^\+?[0-9x\- ]{5,20}$', data['phone']):
            raise errors.InvalidRequest(_('Phone numbers can only have numerals, hyphens, spaces and a plus sign'))

        if 'mobile' in data and not re.match('^\+?[0-9x\- ]{5,20}$', data['mobile']):
            raise errors.InvalidRequest(_('Phone numbers can only have numerals, hyphens, spaces and a plus sign'))

        if data:
            yield db.batch_insert(myId, "entities", {"contact": data})
        if to_remove:
            yield db.batch_remove({"entities":[myId]}, names=to_remove, supercolumn='contact')

        contactInfo = me.get('contact', {})
        if any([contactInfo.get(x, None) != data.get(x, None) for x in ["phone", "mobile"]]):
            request.write('$$.alerts.info("%s");' % _('Profile updated'))

        args = {"detail": "", "me": me}
        suggestedSections = yield self._checkProfileCompleteness(request, myId, args)
        tmp_suggested_sections = {}
        for section, items in suggestedSections.iteritems():
            if len(suggestedSections[section]) > 0:
                tmp_suggested_sections[section] = items
        args.update({'suggested_sections':tmp_suggested_sections})

        t.renderScriptBlock(request, "settings.mako", "right",
                            False, ".right-contents", "set", **args)
        me.update({'contact':data})
        yield search.solr.updatePeopleIndex(myId, me, orgId)
Ejemplo n.º 13
0
def _addMember(request, group, user):
    """Add a new member to the group.
    Add user to group followers, create a group-join activity item and push
    item to group, group-followers feed. Update user groups with new group.

    Keyword params:
    @group: entity object of the group
    @user: entity object of the user
    @request:

    """
    deferreds = []
    itemType = "activity"
    relation = Relation(user.id, [])
    if not getattr(user, 'basic', []):
        yield user.fetchData(['basic'])

    responseType = "I"
    acl = {"accept": {"groups": [group.id]}}
    _acl = pickle.dumps(acl)

    itemId = utils.getUniqueKey()
    colname = _entityGroupMapColName(group)
    yield db.insert(user.id, "entityGroupsMap", "", colname)
    yield db.insert(group.id, "groupMembers", itemId, user.id)
    item = yield utils.createNewItem(request, "activity", user,
                                     acl, "groupJoin")
    item["meta"]["target"] = group.id

    d1 = db.insert(group.id, "followers", "", user.id)
    d2 = db.batch_insert(itemId, 'items', item)
    d3 = feed.pushToFeed(group.id, item["meta"]["uuid"], itemId,
                         itemId, responseType, itemType, user.id)
    d4 = feed.pushToOthersFeed(user.id, user.basic['org'],
                                item["meta"]["uuid"], itemId,
                                itemId, _acl, responseType,
                                itemType, user.id, promoteActor=False)

    d5 = utils.updateDisplayNameIndex(user.id, [group.id],
                                      user.basic['name'], None)

    deferreds = [d1, d2, d3, d4, d5]
    yield defer.DeferredList(deferreds)
Ejemplo n.º 14
0
def makeAdmin(request, group, user, me):
    """make user admin of the group.
    Only an group-administrator can make an group-member and administrator.

    Keyword params:
    @request:
    @me:
    @user: user object
    @group: group object
    """
    if me.id not in group.admins:
        raise errors.PermissionDenied(_('You are not an administrator of the group'))

    cols = yield db.get_slice(group.id, "groupMembers", [user.id])
    if not cols:
        raise errors.InvalidRequest(_('Only group member can become administrator'))

    if user.id in group.admins:
        defer.returnValue(None)

    yield db.insert(group.id, "entities", '', user.id, 'admins')
    yield db.insert(user.id, "entities", group.basic['name'],
                    group.id, "adminOfGroups")

    itemType = "activity"
    responseType = "I"
    acl = {"accept": {"groups": [group.id]}}
    _acl = pickle.dumps(acl)

    itemId = utils.getUniqueKey()
    item = yield utils.createNewItem(request, "activity", user,
                                     acl, "groupAdmin")
    item["meta"]["target"] = group.id

    d1 = db.batch_insert(itemId, 'items', item)
    d2 = feed.pushToFeed(group.id, item["meta"]["uuid"], itemId,
                         itemId, responseType, itemType, user.id)
    d3 = feed.pushToOthersFeed(user.id, user.basic['org'],
                                item["meta"]["uuid"], itemId, itemId,
                                _acl, responseType, itemType,
                                user.id, promoteActor=False)

    yield defer.DeferredList([d1, d2, d3])
Ejemplo n.º 15
0
    def _updateOrgInfo(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        orgId = args["orgId"]
        org = args['org']

        name = utils.getRequestArg(request, "name")
        dp = utils.getRequestArg(request, "dp", sanitize=False)

        orgInfo, orgDetails = {}, {}
        if dp:
            avatar = yield saveAvatarItem(orgId, orgId, dp, isLogo=True)
            orgInfo["basic"] = {}
            orgInfo["basic"]["logo"] = avatar
            org.basic['logo'] = avatar
            orgDetails["logo"] = utils.companyLogo(org)
        if name:
            if "basic" not in orgInfo:
                orgInfo["basic"] = {}
            orgInfo["basic"]["name"] = name
            args['org'].basic['name'] = name
            orgDetails["name"] = name
        if orgInfo:
            yield db.batch_insert(orgId, "entities", orgInfo)

        response = """
                    <script>
                        var data = %s;
                        if (data.logo){
                          var imageUrl = data.logo;
                          parent.$('#sitelogo-img').attr('src', imageUrl);
                        }
                        if (data.name){
                          parent.$('#sitelogo-link').attr('title', data.name);
                          parent.$('#sitelogo-img').attr('alt', data.name);
                        }
                        parent.$$.alerts.info("%s");
                    </script>
                    """ % (json.dumps(orgDetails),
                            _("Company details updated"))
        request.write(response)
Ejemplo n.º 16
0
def saveAvatarItem(entityId, orgId, data, isLogo=False):
    imageFormat = _getImageFileFormat(data)
    if imageFormat not in constants.SUPPORTED_IMAGE_TYPES:
        raise errors.InvalidFileFormat("The image format is not supported")

    try:
        original = PythonMagick.Blob(data)
        image = PythonMagick.Image(original)
    except Exception as e:
        raise errors.InvalidFileFormat("Invalid image format")

    medium = PythonMagick.Blob()
    small = PythonMagick.Blob()
    large = PythonMagick.Blob()
    largesize = constants.LOGO_SIZE_LARGE if isLogo else constants.AVATAR_SIZE_LARGE
    mediumsize = constants.LOGO_SIZE_MEDIUM if isLogo else constants.AVATAR_SIZE_MEDIUM
    smallsize = constants.LOGO_SIZE_SMALL if isLogo else constants.AVATAR_SIZE_SMALL

    image.scale(largesize)
    image.write(large)
    image.scale(mediumsize)
    image.write(medium)
    image.scale(smallsize)
    image.write(small)

    itemId = utils.getUniqueKey()
    acl = pickle.dumps({"accept":{"orgs":[orgId]}})
    item = {
        "meta": {"owner": entityId, "acl": acl, "type": "image"},
        "avatar": {
            "format": imageFormat,
            "small": small.data, "medium": medium.data,
            "large": large.data, "original": original.data
        }}
    yield db.batch_insert(itemId, "items", item)
    #delete older image if any;
    yield deleteAvatarItem(entityId, isLogo)

    defer.returnValue("%s:%s" % (imageFormat, itemId))
Ejemplo n.º 17
0
    def _receiveUserAccess(self, request):
        authinfo = request.getSession(IAuthInfo)
        myId = authinfo.username
        myOrgId = authinfo.organization

        allow = utils.getRequestArg(request, 'allow') == "true"
        state = utils.getRequestArg(request, 'state')
        scopes = utils.getRequestArg(request, 'scope')
        clientId = utils.getRequestArg(request, 'client_id')
        redirectUri = utils.getRequestArg(request, 'redirect_uri', sanitize=False)
        signature = utils.getRequestArg(request, 'signature')

        # Check if signature is valid
        message = "%s:%s:%s:%s:%s" % \
                  (myId, clientId, scopes, redirectUri, state)
        checksum = hmac.new(myOrgId, message, hashlib.sha256)
        if signature != checksum.hexdigest():
            self._error(request, self.SIGNATURE_MISMATCH)
            return

        client = yield db.get_slice(clientId, "apps")
        client = utils.supercolumnsToDict(client)
        if not client:
            self._error(request, self.CLIENT_GONE)
            return

        if allow:
            # Authcode must expire shortly after it is issued
            # We expire the authcode in 5 minutes?
            authCode = utils.getRandomKey()
            authMap = {"user_id": myId, "org_id": myOrgId,
                       "client_id": clientId,
                       "redirect_uri": b64encode(redirectUri),
                       "scope": scopes, "type": "auth"}
            yield db.batch_insert(authCode, "oAuthData", authMap, ttl=120)
            yield db.insert(myId, "entities", authCode, clientId, "apps", ttl=120)
            self._redirectOnSuccess(request, redirectUri, authCode, state)
        else:
            self._redirectOnError(request, redirectUri, "access_denied", state)
Ejemplo n.º 18
0
    def _tokenForClientCredentials(self, request):
        clientId = utils.getRequestArg(request, 'client_id')
        clientSecret = utils.getRequestArg(request, 'client_secret')

        client = yield db.get_slice(clientId, "apps")
        client = utils.supercolumnsToDict(client)
        if not client or not utils.checkpass(clientSecret, client['meta']['secret']):
            self._error(request, "invalid_client")
            return

        # The client is valid.  Issue auth token.
        # We don't issue a refresh token and everytime the client will have
        # to authenticate using it's credentials
        scopes = client["meta"]["scope"].split(' ')
        userId = client["meta"]["author"]
        orgId  = client["meta"]["org"]
        accessToken = utils.getRandomKey()
        accessTokenData = {"user_id": userId, "type": "access", "org_id": orgId,
                           "client_id": clientId, "scope": " ".join(scopes)}
        yield db.batch_insert(accessToken, "oAuthData",
                              accessTokenData, ttl=self._accessTokenExpiry)
        self._success(request, accessToken)
Ejemplo n.º 19
0
def _ensureTag(tagName, myId, orgId, presetTag=False):
    try:
        tagName = tagName.lower()
        c = yield db.get(orgId, "orgTagsByName", tagName)
        tagId = c.column.value
        c = yield db.get_slice(orgId, "orgTags", super_column=tagId)
        tag = utils.columnsToDict(c)
        if presetTag and not tag.get('isPreset', '') == 'True':
            yield db.insert(orgId, "orgPresetTags", tagId, tagName)

            yield db.insert(orgId, "orgTags", 'True', 'isPreset', tagId)
            tag['isPreset'] = 'True'
    except ttypes.NotFoundException:
        tagId = utils.getUniqueKey()
        tag = {"title": tagName, 'createdBy': myId}
        if presetTag:
            tag['isPreset'] = 'True'
        tagName = tagName.lower()
        yield db.batch_insert(orgId, "orgTags", {tagId: tag})
        yield db.insert(orgId, "orgTagsByName", tagId, tagName)
        if presetTag:
            yield db.insert(orgId, "orgPresetTags", tagId, tagName)

    defer.returnValue((tagId, tag))
Ejemplo n.º 20
0
 def save(self):
     yield db.batch_insert(self.id, 'entities', self._data)
Ejemplo n.º 21
0
    def _reply(self, request):
        """Commit a new message in reply to an existing conversation. Creates
        a new message, uploads any attachments, updates the conversation meta
        info and finally renders the message for the user.

        Keyword Arguments:
        convId: conversation id to which this user is replying to.
        body: The content of the reply.

        CF Changes:
        mConversations
        mConvMessages
        attachmentVersions

        """
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        myOrgId = args['orgId']

        convId = utils.getRequestArg(request, 'id')
        recipients, body, subject, convId = self._parseComposerArgs(request)
        epoch = int(time.time())

        if not convId:
            raise errors.MissingParams([])

        cols = yield db.get_slice(convId, "mConversations", ['meta', 'participants'])
        cols = utils.supercolumnsToDict(cols)
        subject = cols['meta'].get('subject', None)
        participants = cols.get('participants', {}).keys()
        if not cols:
            raise errors.InvalidMessage(convId)
        if myId not in participants:
            raise errors.MessageAccessDenied(convId)

        timeUUID = uuid.uuid1().bytes
        snippet = self._fetchSnippet(body)
        meta = {'uuid': timeUUID, 'date_epoch': str(epoch), "snippet": snippet}

        attachments = yield self._handleAttachments(request)
        attach_meta = self._formatAttachMeta(attachments)

        messageId = yield self._newMessage(myId, timeUUID, body, epoch)
        yield self._deliverMessage(convId, participants, timeUUID, myId)
        yield db.insert(convId, "mConvMessages", messageId, timeUUID)
        yield db.batch_insert(convId, "mConversations",
                              {'meta': meta, 'attachments': attach_meta})

        # Currently, we don't support searching for private messages
        # self._indexMessage(convId, messageId, myOrgId, meta, attachments, body)

        #XXX:We currently only fetch the message we inserted. Later we may fetch
        # all messages delivered since we last rendered the conversation
        cols = yield db.get_slice(convId, "mConversations")
        conv = utils.supercolumnsToDict(cols)
        participants = set(conv['participants'])
        mids = [messageId]
        messages = yield db.multiget_slice(mids, "messages", ["meta"])
        messages = utils.multiSuperColumnsToDict(messages)
        participants.update([messages[mid]['meta']['owner'] for mid in messages])

        people = base.EntitySet(participants)
        yield people.fetchData()

        value = myId
        data = {"entities": people}
        data["entities"].update({args['orgId']: args["org"]})
        data["orgId"] = args["orgId"]
        data["convId"] = convId
        data["message"] = body
        data["subject"] = subject
        data["_fromName"] = people[value].basic['name']

        users = participants - set([myId])
        if users:
            yield notifications.notify(users, ":MR", value, timeUUID, **data)

        args.update({"people": people})
        args.update({"messageIds": mids})
        args.update({'messages': messages})
        if script:
            onload = """
                        $('.conversation-reply').attr('value', '');
                        $('#msgreply-attach-uploaded').empty();
                     """
            t.renderScriptBlock(request, "message.mako",
                                "render_conversation_messages", landing,
                                ".conversation-messages-wrapper", "append", True,
                                handlers={"onload": onload}, **args)

        #Update the right side bar with any attachments the user uploaded
        args.update({"conv": conv})
        people = base.EntitySet(set(conv['participants']))
        yield people.fetchData()

        args.update({"people": people})
        args.update({"conv": conv})
        args.update({"id": convId})
        args.update({"view": "message"})
        if script:
            onload = """
                     $('#conversation_add_member').autocomplete({
                           source: '/auto/users',
                           minLength: 2,
                           select: function( event, ui ) {
                               $('#conversation_recipients').attr('value', ui.item.uid)
                           }
                      });
                     """
            t.renderScriptBlock(request, "message.mako", "right",
                                landing, ".right-contents", "set", True,
                                handlers={"onload": onload}, **args)

        else:
            request.redirect('/messages')
            request.finish()
Ejemplo n.º 22
0
def new(request, authInfo, convType, richText=False):
    if convType not in plugins:
        raise errors.BaseError('Unsupported item type', 400)
    myId = authInfo.username
    orgId = authInfo.organization
    entities = base.EntitySet([myId, orgId])
    yield entities.fetchData(['basic', 'admins'])

    plugin = plugins[convType]
    convId = utils.getUniqueKey()
    conv = yield plugin.create(request, entities[myId], convId, richText)
    orgAdminIds = entities[orgId].admins.keys()
    if orgAdminIds:
        text = ''
        monitoredFields = getattr(plugin, 'monitoredFields', {})
        for superColumnName in monitoredFields:
            for columnName in monitoredFields[superColumnName]:
                if columnName in conv[superColumnName]:
                    text = " ".join([text, conv[superColumnName][columnName]])
        matchedKeywords = yield utils.watchForKeywords(orgId, text)

        if matchedKeywords:
            reviewOK = utils.getRequestArg(request, "_review") == "1"
            if reviewOK:
                # Add conv to list of items that matched this keyword
                # and notify the administrators about it.
                orgAdmins = base.EntitySet(orgAdminIds)
                yield orgAdmins.fetchData()
                entities.update(orgAdmins)
                for keyword in matchedKeywords:
                    yield db.insert(orgId + ":" + keyword, "keywordItems",
                                    convId, conv['meta']['uuid'])
                    yield notifications.notify(orgAdminIds, ':KW:' + keyword,
                                               myId, entities=entities)
            else:
                # This item contains a few keywords that are being monitored
                # by the admin and cannot be posted unless reviewOK is set.
                defer.returnValue((None, None, matchedKeywords))

    #
    # Save the new item to database and index it.
    #
    yield db.batch_insert(convId, "items", conv)
    yield files.pushfileinfo(myId, orgId, convId, conv)
    search.solr.updateItemIndex(convId, conv, orgId)

    #
    # Push item to feeds and userItems
    #
    timeUUID = conv["meta"]["uuid"]
    convACL = conv["meta"]["acl"]
    deferreds = []
    responseType = 'I'

    # Push to feeds
    feedUpdateVal = "I:%s:%s" % (myId, convId)
    d = Feed.push(myId, orgId, convId, conv, timeUUID,
                  feedUpdateVal, promoteActor=True)
    deferreds.append(d)

    # Save in user items.
    userItemValue = ":".join([responseType, convId, convId, convType, myId, ''])
    d = db.insert(myId, "userItems", userItemValue, timeUUID)
    deferreds.append(d)
    if plugins[convType].hasIndex:
        d = db.insert(myId, "userItems_%s" % (convType), userItemValue, timeUUID)
        deferreds.append(d)

    yield defer.DeferredList(deferreds)
    defer.returnValue((convId, conv, None))
Ejemplo n.º 23
0
def removeUser(request, userId, orgAdminId, user=None, orgAdminInfo=None):
    import base

    if not user:
        user = base.Entity(userId)
        yield user.fetchData()
    if not orgAdminInfo:
        orgAdmin = base.Entity(orgAdminId)
        yield orgAdmin.fetchData()

    emailId = user.basic.get("emailId", None)
    displayName = user.basic.get("name", None)
    firstname = user.basic.get("firstname", None)
    lastname = user.basic.get("lastname", None)
    orgId = user.basic["org"]
    org = base.Entity(orgId)
    yield org.fetchData()

    cols = yield db.get_slice(userId, "entities", ["apikeys", "apps"])
    apps_apiKeys = supercolumnsToDict(cols)
    apiKeys = apps_apiKeys.get("apikeys", {})
    apps = apps_apiKeys.get("apps", {})
    for clientId in apiKeys:
        yield db.remove(clientId, "apps")
    yield db.remove(userId, "entities", super_column="apikeys")

    for clientId in apps:
        yield db.remove(apps[clientId], "oAuthData")

    cols = yield db.get_slice(userId, "appsByOwner")
    cols = columnsToDict(cols)
    for clientId in cols:
        yield db.remove(orgId, "appsByOwner", clientId)
    yield db.remove(userId, "appsByOwner")
    yield db.remove(userId, "entities", super_column="apps")

    sessionIds = yield db.get_slice(userId, "userSessionsMap")
    sessionIds = columnsToDict(sessionIds)
    for sessionId in sessionIds:
        yield db.remove(sessionId, "sessions")
        yield cleanupChat(sessionId, userId, orgId)
    yield db.remove(userId, "userSessionsMap")

    groups = yield db.get_slice(userId, "entityGroupsMap")
    groupIds = [x.column.name.split(":")[1] for x in groups]
    groupAdmins = yield db.multiget_slice(groupIds, "entities", ["admins"])
    groupAdmins = multiSuperColumnsToDict(groupAdmins)
    for group in groups:
        name, groupId = group.column.name.split(":")
        yield db.remove(groupId, "followers", userId)
        yield db.remove(groupId, "groupMembers", userId)
        if len(groupAdmins[groupId].get("admins", {})) == 1 and userId in groupAdmins[groupId]["admins"]:
            yield db.insert(groupId, "entities", "", orgAdminId, "admins")
            cols = yield db.get_slice(groupId, "groupMembers", [orgAdminId])
            if not cols:
                itemId = getUniqueKey()
                acl = {"accept": {"groups": [groupId]}}
                yield db.insert(orgAdminId, "entityGroupsMap", "", group.column.name)
                yield db.insert(groupId, "groupMembers", itemId, orgAdminId)
                # only group members can post to a group so, item should be
                # created only after adding orgAdmin to the group.
                item = yield createNewItem(request, "activity", orgAdmin, acl, "groupJoin")
                item["meta"]["target"] = groupId
                yield db.batch_insert(itemId, "items", item)
                yield db.insert(groupId, "followers", "", orgAdminId)
                yield db.insert(orgAdminId, "entities", name, groupId, "adminOfGroups")
                yield updateDisplayNameIndex(orgAdminId, [groupId], org.basic["name"], None)
                # TODO: push to group-feed
                # XXX: call Group.addMember ?

        yield db.remove(groupId, "entities", userId, "admins")

    yield updateDisplayNameIndex(userId, groupIds, None, displayName)
    yield db.remove(userId, "entityGroupsMap")
    yield db.remove(userId, "entities", super_column="adminOfGroups")

    yield db.remove(emailId, "userAuth")
    yield db.remove(orgId, "orgUsers", userId)
    yield db.remove(orgId, "blockedUsers", userId)
    yield db.insert(userId, "entities", "", "deleted", "basic")
    yield db.insert(orgId, "deletedUsers", "", userId)
    yield updateDisplayNameIndex(userId, [orgId], None, displayName)
    yield updateNameIndex(userId, [orgId], None, displayName)
    yield updateNameIndex(userId, [orgId], None, emailId)
    if firstname:
        yield updateNameIndex(userId, [orgId], None, firstname)
    if lastname:
        yield updateNameIndex(userId, [orgId], None, lastname)
Ejemplo n.º 24
0
    def _deliverMessage(self, convId, recipients, timeUUID, owner):
        """To each participant in a conversation, add the conversation
        to the list of unread conversations.

        CF Changes:
        mConversations
        mConvFolders
        messages
        mAllConversations
        mDeletedConversations
        mArchivedConversations
        latest

        """
        convFolderMap = {}
        userFolderMap = {}
        toNotify = {}
        toRemove = {'latest': []}
        conv = yield db.get_slice(convId, "mConversations", ['meta'])
        conv = utils.supercolumnsToDict(conv)

        oldTimeUUID = conv['meta']['uuid']
        unread = "u:%s" % (convId)
        read = "r:%s" % (convId)

        cols = yield db.get_slice(convId, 'mConvFolders', recipients)
        cols = utils.supercolumnsToDict(cols)
        for recipient in recipients:
            deliverToInbox = True
            # for a new message, mConvFolders will be empty
            # so recipient may not necessarily be present in cols
            if recipient != owner:
                toNotify[recipient] = {'latest': {'messages': {timeUUID: convId}}}
            toRemove['latest'].append(recipient)

            for folder in cols.get(recipient, []):
                cf = self._folders[folder] if folder in self._folders else folder
                yield db.remove(recipient, cf, oldTimeUUID)
                if cf == 'mDeletedConversations':
                    #don't add to recipient's inbox if the conv is deleted.
                    deliverToInbox = False
                else:
                    yield db.remove(convId, 'mConvFolders', folder, recipient)
            if deliverToInbox:
                val = unread if recipient != owner else read
                convFolderMap[recipient] = {'mAllConversations': {timeUUID: val}}
                userFolderMap[recipient] = {'mAllConversations': ''}
                if recipient != owner:
                    convFolderMap[recipient]['mUnreadConversations'] = {timeUUID: unread}
                    userFolderMap[recipient]['mUnreadConversations'] = ''

            else:
                val = unread if recipient != owner else read
                convFolderMap[recipient] = {'mDeletedConversations': {timeUUID: val}}

        yield db.batch_mutate(convFolderMap)
        yield db.batch_insert(convId, "mConvFolders", userFolderMap)
        if toRemove['latest'] and oldTimeUUID != timeUUID:
            yield db.batch_remove(toRemove, names=[oldTimeUUID], supercolumn="messages")
        if toNotify:
            yield db.batch_mutate(toNotify)
Ejemplo n.º 25
0
    def postFeedback(self, request):
        """creates a feedback item with feedback, feedback-{mood} tags.
        Push item to feeback, feedback-{mood} tag followers.
        Note: Item is owned by feedback-domain/synovel.com, not user sending
        the feedback. Only users of feedback-domain/synovel.com can access
        the item.
        """
        comment = utils.getRequestArg(request, 'comment')
        mood = utils.getRequestArg(request, 'mood')
        if not mood or not comment:
            raise errors.MissingParams([_("Feedback")])

        authInfo = request.getSession(IAuthInfo)
        myId = authInfo.username
        orgId = authInfo.organization

        tagName = 'feedback'
        moodTagName = 'feedback-' + mood

        feedbackDomain = config.get('Feedback', 'Domain') or 'synovel.com'
        cols = yield db.get_slice(feedbackDomain, 'domainOrgMap')
        if not cols:
            raise errors.ConfigurationError("feedbackDomain is invalid!")

        # Only one org exists per domain
        synovelOrgId = cols[0].column.name

        tagId, tag = yield tags.ensureTag(request, tagName, synovelOrgId)
        moodTagId, moodTag = yield tags.ensureTag(request, moodTagName,
                                                  synovelOrgId)

        # Anyone in synovel can receive feedback.
        acl = {'accept': {'orgs': [synovelOrgId]}}
        acl = json.dumps(acl)
        synovelOrg = base.Entity(synovelOrgId)
        yield synovelOrg.fetchData()
        # createNewItem expects an entity object with has org in basic info.
        # organizations wont have 'org' set.
        synovelOrg.basic['org'] = synovelOrgId

        item = yield utils.createNewItem(request, 'feedback', synovelOrg,
                                         acl, subType=mood)
        item['meta']['org'] = synovelOrgId
        item['meta']['userId'] = myId
        item['meta']['userOrgId'] = orgId
        item['meta']['comment'] = comment
        item['tags'] = {tagId: synovelOrgId, moodTagId: synovelOrgId}

        itemId = utils.getUniqueKey()

        tagItemCount = int(tag['itemsCount'])
        moodTagItemCount = int(moodTag['itemsCount'])
        if tagItemCount % 10 == 7:
            tagItemCount = yield db.get_count(tagId, "tagItems")
        if moodTagItemCount % 10 == 7:
            moodTagItemCount = yield db.get_count(moodTagId, "tagItems")

        tagItemCount += 1
        moodTagItemCount += 1

        # Finally save the feedback
        yield db.batch_insert(itemId, "items", item)
        yield db.insert(tagId, "tagItems", itemId, item["meta"]["uuid"])
        yield db.insert(moodTagId, "tagItems", itemId, item["meta"]["uuid"])
        yield db.insert(synovelOrgId, "orgTags", str(tagItemCount),
                        "itemsCount", tagId)
        yield db.insert(synovelOrgId, "orgTags", str(moodTagItemCount),
                        "itemsCount", moodTagId)

        cols = yield db.multiget_slice([tagId, moodTagId], "tagFollowers")
        followers = utils.multiColumnsToDict(cols)
        followers = set(followers[tagId].keys() + followers[moodTagId].keys())

        value = {"feed": {item['meta']['uuid']: itemId}}
        muts = dict([(x, value) for x in followers])
        if muts:
            yield db.batch_mutate(muts)
Ejemplo n.º 26
0
    def _tokenForAuthCode(self, request, refresh=False):
        clientId = utils.getRequestArg(request, 'client_id')
        clientSecret = utils.getRequestArg(request, 'client_secret')
        redirectUri = utils.getRequestArg(request, 'redirect_uri', sanitize=False)
        scopes = utils.getRequestArg(request, 'scope')

        if refresh:
            authCode = utils.getRequestArg(request, 'refresh_token')
        else:
            authCode = utils.getRequestArg(request, 'code')

        # XXX: We should be checking for HTTP authentication before
        #      throwing an error in case of missing clientId and clientSecret.
        if not all([redirectUri, clientId, clientSecret, authCode]):
            self._error(request, "invalid_request")
            return

        grant = yield db.get_slice(authCode, "oAuthData")
        grant = utils.columnsToDict(grant)
        if not grant or grant['client_id'] != clientId or\
           grant['redirect_uri'] != b64encode(redirectUri) or\
           not (grant['type'] == 'auth' and not refresh or\
                grant['type'] == 'refresh' and refresh):
            self._error(request, "invalid_grant")
            return

        grantedScopes = grant['scope'].split(' ')
        if scopes:
            scopes = scopes.split(' ')
            if [x for x in scopes if x not in grantedScopes]:
                self._error(request, "invalid_scope")
                return
        else:
            scopes = grantedScopes

        client = yield db.get_slice(clientId, "apps")
        client = utils.supercolumnsToDict(client)
        if not client or not utils.checkpass(clientSecret, client['meta']['secret']):
            self._error(request, "invalid_client")
            return

        userId = grant["user_id"]
        orgId  = grant["org_id"]
        accessToken = utils.getRandomKey()
        accessTokenData = {"user_id": userId, "org_id": orgId,
                           "type": "access", "client_id": clientId,
                           "auth_code": authCode, "scope": " ".join(scopes)}
        yield db.batch_insert(accessToken, "oAuthData",
                              accessTokenData, ttl=self._accessTokenExpiry)

        refreshToken = utils.getRandomKey()
        refreshTokenData = {"user_id": userId, "org_id": orgId,
                            "type": "refresh", "client_id": clientId,
                            "redirect_uri": grant["redirect_uri"],
                            "auth_code": authCode, "scope": grant["scope"]}
        yield db.batch_insert(refreshToken, "oAuthData",
                              refreshTokenData, ttl=self._refreshTokenExpiry)
        yield db.insert(userId, "entities", refreshToken, clientId,
                        "apps", ttl=self._refreshTokenExpiry)

        yield db.remove(authCode, "oAuthData")
        self._success(request, accessToken, refreshToken)
Ejemplo n.º 27
0
def _comment(convId, conv, comment, snippet, myId, orgId, richText, reviewed, fids=None):
    convType = conv["meta"].get("type", "status")

    # 1. Create the new item
    timeUUID = uuid.uuid1().bytes
    meta = {"owner": myId, "parent": convId, "comment": comment,
            "timestamp": str(int(time.time())), "org": orgId,
            "uuid": timeUUID, "richText": str(richText)}
    item = {'meta':meta}
    followers = {myId: ''}
    itemId = utils.getUniqueKey()
    if snippet:
        meta['snippet'] = snippet

    # 1.5. Check if the comment matches any of the keywords
    entities = base.EntitySet([myId, orgId])
    yield entities.fetchData(['basic', 'admins'])
    orgAdmins = entities[orgId].admins.keys()
    if orgAdmins:
        matchedKeywords = yield utils.watchForKeywords(orgId, comment)
        if matchedKeywords:
            if reviewed:
                # Add item to list of items that matched this keyword
                # and notify the administrators about it.
                for keyword in matchedKeywords:
                    yield db.insert(orgId + ":" + keyword, "keywordItems",
                                    itemId + ":" + convId, timeUUID)
                    yield notifications.notify(orgAdmins, ':KW:' + keyword,
                                               myId, entities=entities)

            else:
                # This item contains a few keywords that are being monitored
                # by the admin and cannot be posted unless reviewOK is set.
                defer.returnValue((None, convId, {convId: conv}, matchedKeywords))

    # 1.9. Actually store the item
    if fids:
        attachments = yield utils._upload_files(myId, fids)
        if attachments:
            item['attachments'] = {}
        for attachmentId in attachments:
            fileId, name, size, ftype = attachments[attachmentId]
            item["attachments"][attachmentId] = "%s:%s:%s" % (name, size, ftype)

    yield db.batch_insert(itemId, "items", item)
    yield files.pushfileinfo(myId, orgId, itemId, item, conv)

    # 2. Update response count and add myself to the followers of conv
    convOwnerId = conv["meta"]["owner"]
    convType = conv["meta"]["type"]
    responseCount = int(conv["meta"].get("responseCount", "0"))
    if responseCount % 5 == 3:
        responseCount = yield db.get_count(convId, "itemResponses")

    responseCount += 1
    conv['meta']['responseCount'] = responseCount
    convUpdates = {"responseCount": str(responseCount)}
    yield db.batch_insert(convId, "items", {"meta": convUpdates,
                                            "followers": followers})

    # 3. Add item as response to parent
    yield db.insert(convId, "itemResponses",
                    "%s:%s" % (myId, itemId), timeUUID)

    # 4. Update userItems and userItems_*
    responseType = "Q" if convType == "question" else 'C'
    commentSnippet = utils.toSnippet(comment, 35, richText)
    userItemValue = ":".join([responseType, itemId, convId, convType,
                              convOwnerId, commentSnippet])
    yield db.insert(myId, "userItems", userItemValue, timeUUID)
    if convType in plugins and plugins[convType].hasIndex:
        yield db.insert(myId, "userItems_" + convType, userItemValue, timeUUID)

    # 5. Update my feed.
    feedItemVal = "%s:%s:%s" % (responseType, myId, itemId)
    yield Feed.push(myId, orgId, convId, conv, timeUUID, feedItemVal)

    yield _notify("C", convId, timeUUID, convType=convType,
                  convOwnerId=convOwnerId, myId=myId, me=entities[myId],
                  comment=comment, richText=richText)
    search.solr.updateItemIndex(itemId, {'meta': meta}, orgId, conv=conv)
    items = {itemId: item, convId: conv}
    defer.returnValue((itemId, convId, items, None))
Ejemplo n.º 28
0
    def _addUser(self, request):
        emailId = utils.getRequestArg(request, 'email')
        existingUser = db.get_count(emailId, "userAuth")

        localpart, domain = emailId.split("@")
        displayName = utils.getRequestArg(request, 'name')
        jobTitle = utils.getRequestArg(request, 'jobTitle')
        timezone = utils.getRequestArg(request, 'timezone')
        passwd = utils.getRequestArg(request, 'password', sanitize=False)
        pwdrepeat = utils.getRequestArg(request, 'pwdrepeat', sanitize=False)
        if not displayName or not jobTitle or not timezone or not passwd:
            raise errors.MissingParams([_("All fields are required to create the user")])

        if passwd != pwdrepeat:
            raise PasswordsNoMatch()

        args = {'emailId': emailId, 'view': 'invite'}

        existingUser = yield existingUser
        if not existingUser:
            authinfo = yield defer.maybeDeferred(request.getSession, IAuthInfo)
            orgId = yield getOrgId(domain)
            if not orgId:
                orgId = utils.getUniqueKey()
                domains = {domain: ''}
                basic = {"name": domain, "type": "org"}
                yield db.batch_insert(orgId, "entities", {"basic": basic,
                                                          "domains": domains})
                yield db.insert(domain, "domainOrgMap", '', orgId)

            userId = yield utils.addUser(emailId, displayName, passwd,
                                         orgId, jobTitle, timezone)
            authinfo.username = userId
            authinfo.organization = orgId
            authinfo.isAdmin = False
            yield request._saveSessionToDB()

            cols = yield db.get_slice(domain, "invitations", [emailId])
            cols = utils.supercolumnsToDict(cols)

            userIds = cols.get(emailId, {}).values()
            if userIds:
                db.batch_remove({'invitationsSent': userIds}, names=[emailId])

            yield db.remove(domain, "invitations", super_column=emailId)
            t.render(request, "signup.mako", **args)

            # Notify all invitees about this user.
            token = utils.getRequestArg(request, "token")
            acceptedInvitationSender = cols.get(emailId, {}).get(token)
            otherInvitees = [x for x in userIds
                             if x not in (acceptedInvitationSender, emailId)]

            entities = base.EntitySet(userIds + [orgId, userId])
            yield entities.fetchData()
            data = {"entities": entities, 'orgId': orgId}

            yield notifications.notify([acceptedInvitationSender], ":IA", userId, **data)
            yield notifications.notify(otherInvitees, ":NU", userId, **data)
        else:
            raise InvalidRegistration("A user with this e-mail already exists! Already registered?")
Ejemplo n.º 29
0
def updateData():
    yield db.truncate('user_files')
    try:
        yield db.get('asdf', 'entityFeed_files', uuid.uuid1().bytes)
    except ttypes.InvalidRequestException as exception:
        log.msg(exception)
        raise Exception('entityFeed_files CF missing, create the CF')
    except ttypes.NotFoundException:
        pass
    entities = {}
    items = {}

    rows = yield db.get_range_slice('items', count=10000, reverse=True)
    for row in rows:
        itemId = row.key
        item = utils.supercolumnsToDict(row.columns)
        items[itemId]=item

    for itemId in items:
        item =  items[itemId]
        log.msg(itemId)
        if 'meta' not in item:
            continue

        # Add org to all items
        try:
            owner = item['meta']['owner']
            col = yield db.get(owner, "entities", 'org', 'basic')
            ownerOrgId = col.column.value
            yield db.insert(itemId, 'items', ownerOrgId, 'org', 'meta')
        except Exception as e:
            if item['meta'].get('type', '') == 'feedback':
                yield db.insert(itemId, 'items', owner, 'org', 'meta')

        # Fix ACLs
        if 'parent' not in item['meta']:
            acl = item['meta']['acl']
            convOwner = item['meta']['owner']
            convId = itemId

            if acl == 'company':
                col = yield db.get(convOwner, "entities", "org", "basic")
                ownerOrgId = col.column.value
                acl = pickle.dumps({"accept":{"orgs":[ownerOrgId]}})
                yield db.insert(convId, 'items', acl, 'acl', 'meta')
            else:
                try:
                    acl = pickle.loads(acl)
                    if 'accept' in acl and 'friends' in acl['accept'] and isinstance(acl['accept']['friends'], bool):
                        del acl['accept']['friends']
                        acl = pickle.dumps(acl)
                        yield db.insert(convId, 'items', acl, 'acl', 'meta')
                except :
                    log.msg('cannot unpack acl', acl)

        # Migrate files
        #    truncate user_files
        #    update user_files and entityFeed_files
        if 'owner' in item['meta'] and 'attachments' in item:
            ownerId = item['meta']['owner']
            if ownerId not in entities:
                cols = yield db.get_slice(ownerId, 'entities', ['basic'])
                entities.update({ownerId: utils.supercolumnsToDict(cols)})
            for attachmentId in item['attachments']:
                orgId = entities[ownerId]['basic']['org']
                timeuuid, name = item['attachments'][attachmentId].split(':')[:2]
                timeuuid = utils.decodeKey(timeuuid)
                val = '%s:%s:%s:%s' % (attachmentId, name, itemId, ownerId)
                yield db.insert(ownerId, "user_files", val, timeuuid)
                if 'parent' not in item['meta'] and item['meta'].get('acl', ''):
                    _entities = yield utils.expandAcl(ownerId, orgId, item['meta']['acl'],
                                                      itemId, ownerId, True)
                    for entityId in _entities:
                        yield db.insert(entityId, "entityFeed_files", val, timeuuid)

        # Migrate items
        # Meta fields in "link", "event" and "poll"
        if item['meta'].get('type', None) in ['link', 'poll', 'event']:
            itemMeta = item['meta']
            itemType = itemMeta['type']
            updated = {}

            if itemType == "link":
                if 'url' in itemMeta:
                    updated['link_url'] = itemMeta['url']
                if 'title' in itemMeta:
                    updated['link_title'] = itemMeta['title']
                if 'summary' in itemMeta:
                    updated['link_summary'] = itemMeta['summary']
                if 'imgSrc' in itemMeta:
                    updated['link_imgSrc'] = itemMeta['imgSrc']
                if 'embedType' in itemMeta:
                    updated['link_embedType'] = itemMeta['embedType']
                if 'embedSrc' in itemMeta:
                    updated['link_embedSrc'] = itemMeta['embedSrc']
                if 'embedHeight' in itemMeta:
                    updated['link_embedHeight'] = itemMeta['embedHeight']
                if 'embedWidth' in itemMeta:
                    updated['link_embedWidth'] = itemMeta['embedWidth']
            elif itemType == 'poll':
                if 'question' in itemMeta:
                    updated['comment'] = itemMeta['question']
            else:
                print 'Found an event:', itemId

            if updated:
                yield db.batch_insert(itemId, 'items', {'meta': updated})


    #
    # Create poll indexes for feed and userItems
    #
    rows = yield db.get_range_slice('entities', count=10000, reverse=True)
    mutations = {}
    for row in rows:
        entityId = row.key
        entity = utils.supercolumnsToDict(row.columns)

        if entity['basic']['type'] != 'user':
            continue

        d1 = db.get_slice(entityId, 'feed', count=10000)
        d2 = db.get_slice(entityId, 'userItems', count=10000)

        results = yield d1
        for col in results:
            value = col.column.value
            if value in items:
                if items.get(value, {}).get('meta', {}).get('type', '') == 'poll':
                    mutations.setdefault(entityId, {}).setdefault('feed_poll', {}).update({col.column.name: value})

        results = yield d2
        for col in results:
            value = col.column.value
            responseType, itemId, convId, convType, others = value.split(':', 4)
            if convType == 'poll':
                mutations.setdefault(entityId, {}).setdefault('userItems_poll', {}).update({col.column.name: value})
    yield db.batch_mutate(mutations)

    #Group type changed from public-private to open-closed.
    rows = yield db.get_range_slice('entityGroupsMap', count=1000)
    groupIds = set()
    for row in rows:
        for col in row.columns:
            name_, groupId = col.column.name.split(':')
            groupIds.add(groupId)

    cols = yield db.multiget_slice(groupIds, "entities")
    groups = utils.multiSuperColumnsToDict(cols)
    for groupId in groups:
        access = groups[groupId]['basic']['access'].lower()
        if access == 'public':
            yield db.insert(groupId, 'entities', 'open', 'access', 'basic')
        elif access.lower() == 'private':
            yield db.insert(groupId, 'entities', 'closed', 'access', 'basic')

    #Fix entityGroupsMap
    rows = yield db.get_range_slice('entityGroupsMap', count=1000)
    for row in rows:
        entityId = row.key
        for col in row.columns:
            name_, groupId = col.column.name.split(':')
            if col.column.name != '%s:%s'%(groups[groupId]['basic']['name'].lower(), groupId):
                yield db.remove(entityId, 'entityGroupsMap', col.column.name)
                yield db.insert(entityId, 'entityGroupsMap', '', '%s:%s' %(groups[groupId]['basic']['name'].lower(), groupId))
Ejemplo n.º 30
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();")