예제 #1
0
    def load(self,
             user,
             level=AccessType.ADMIN,
             reviewer=None,
             force=False,
             applet=None,
             subject=None):
        """
        We override load in order to ensure the folder has certain fields
        within it, and if not, we add them lazily at read time.

        :param user: The user for whom to get the ResponseFolder.
        :type id: dict
        :param reviewer: The user to check access against.
        :type user: dict or None
        :param level: The required access type for the object.
        :type level: AccessType
        :param reviewer: The user trying to see the data.
        :type reviewer: dict
        :param applet: ID of Applet to which we are loading responses.
                       "Responses" Folder containing all such Folders if None.
        :type applet: str or None
        :param subject: Applet-specific ID for response subject if getting
                        responses about a specific subject.
        :type subject: str or None
        :returns: Folder or list of Folders
        """
        responseFolder = Folder().load(id=Folder().createFolder(
            parent=user,
            parentType='user',
            name='Responses',
            creator=user,
            reuseExisting=True,
            public=False).get('_id'),
                                       user=reviewer,
                                       level=AccessType.READ)
        accessList = Folder().getFullAccessList(responseFolder)
        accessList = {
            k: [{
                "id":
                i.get('id'),
                "level":
                AccessType.ADMIN
                if i.get('id') == str(user.get('_id')) else i.get('level')
            } for i in accessList[k]]
            for k in accessList
        }
        if str(user.get('_id')) not in [
                u.get('id') for u in accessList.get('users', [])
        ]:
            accessList.get('users', {}).append({
                "id": str(user.get('_id')),
                "level": AccessType.ADMIN
            })
        Folder().setAccessList(responseFolder, accessList)
        if applet:
            responseFolders = []
            allResponseFolders = list(Folder().childFolders(
                parent=responseFolder, parentType='folder', user=reviewer))
            subjectResponseFolders = list(
                itertools.chain.from_iterable([
                    list(Folder().childFolders(parent=appletResponsesFolder,
                                               parentType='folder',
                                               user=reviewer))
                    for appletResponsesFolder in allResponseFolders
                ]))
            if subject:
                assignments = Assignment().findAssignments(applet.get('_id'))
                subjectFilter = [
                    getUserCipher(appletAssignment, subject)
                    for appletAssignment in assignments
                ]
                subjectResponseFolders = [
                    sRF for sRF in subjectResponseFolders
                    if sRF.get('name') in subjectFilter
                    or srf.get('subject', {}).get('@id') in subjectFilter
                ]
            responseFolders += list(Folder().find({
                '$and': [{
                    '$or': [{
                        'meta.applet.@id': str(applet)
                    }, {
                        'meta.applet.url': str(applet)
                    }]
                }, {
                    '$or': [{
                        'parentId': parent['_id']
                    } for parent in subjectResponseFolders]
                }]
            }))
            if len(responseFolders) == 1:
                return (responseFolders[0])
            else:
                return (responseFolders)
        return (responseFolder)
예제 #2
0
def _invite(applet, user, role, rsvp, subject):
    """
    Helper function to invite a user to an applet.

    :param applet: Applet to invite user to
    :type applet: AppletModel
    :param user: ID (canonical or applet-specific) or email address of user to
                 invite
    :type user: string
    :param role: Role to invite user to
    :type role: string
    :param rsvp: Require user acceptance?
    :type rsvp: boolean
    :param subject: Subject about 'user' role can inform or about which
                    'reviewer' role can review
    :type subject: string or literal
    :returns: New assignment (dictionary)
    """
    if role not in USER_ROLE_KEYS:
        raise ValidationException('Invalid role.', 'role')
    thisUser = Applet().getCurrentUser()
    user = user if user else str(thisUser['_id'])

    if mail_utils.validateEmailAddress(user):
        user = UserModel().hash(user)

    if bool(rsvp):
        groupName = {'title': '{} {}s'.format(str(applet.get('_id')), role)}
        groupName['lower'] = groupName.get('title', '').lower()
        group = GroupModel().findOne(query={'lowerName': groupName['lower']})
        if not group or group is None:
            group = GroupModel().createGroup(
                name=groupName['title'],
                creator=thisUser,
                public=bool(role in ['manager', 'reviewer']))
    try:
        assignments = CollectionModel().createCollection(name="Assignments",
                                                         public=True,
                                                         reuseExisting=True)
        assignmentType = 'collection'
    except AccessException:
        assignments, assignmentType = selfAssignment()
    appletAssignment = list(FolderModel().childFolders(
        parent=assignments,
        parentType=assignmentType,
        user=thisUser,
        filters={
            'meta.applet.@id': str(applet['_id']) if '_id' in applet else None
        }))
    appletAssignment = appletAssignment[0] if len(
        appletAssignment) else FolderModel().setMetadata(
            FolderModel().createFolder(
                parent=assignments,
                name=FolderModel().preferredName(applet),
                parentType=assignmentType,
                public=False,
                creator=thisUser,
                allowRename=True,
                reuseExisting=False), {
                    'applet': {
                        '@id': str(applet['_id']) if '_id' in applet else None
                    }
                })
    meta = appletAssignment.get('meta', {})
    members = meta.get('members',
                       []) if meta.get('members') is not None else []
    cUser = getUserCipher(appletAssignment, user)
    subject = subject.upper() if subject is not None and subject.upper(
    ) in SPECIAL_SUBJECTS else getUserCipher(
        appletAssignment,
        str(thisUser['_id']) if subject is None else subject)
    thisAppletAssignment = {
        '@id': str(cUser),
        'roles': {
            role: True if role not in ['reviewer', 'user'] else [subject]
        }
    }
    for i, u in enumerate(members):
        if '@id' in u and u["@id"] == str(cUser):
            thisAppletAssignment = members.pop(i)
            if 'roles' not in thisAppletAssignment:
                thisAppletAssignment['roles'] = {}
            thisAppletAssignment['roles'][role] = True if role not in [
                'reviewer', 'user'
            ] else [subject] if (subject in SPECIAL_SUBJECTS) or (
                'reviewer' not in thisAppletAssignment['roles']) else list(
                    set(thisAppletAssignment['roles']['reviewer'] +
                        [subject]).difference(set(SPECIAL_SUBJECTS))
                ) if "ALL" not in thisAppletAssignment['roles'][
                    'reviewer'] else ["ALL"]
    members.append(thisAppletAssignment)
    meta['members'] = members
    appletAssignment = FolderModel().setMetadata(appletAssignment, meta)
    authorizeReviewers(appletAssignment)
    return (appletAssignment)