Exemple #1
0
    def getExportJSONObject(self):
        sessionsFolder = self.findSessionsFolder()
        items = list(Folder().childItems(sessionsFolder,
                                         filters={'name': 'json'}))
        if not len(items):
            raise RestException('doesn\'t contain a json item', code=404)
        jsonItem = items[0]
        # Next TODO: read, format, and stream back the json version of the export
        original_json_object = json.loads(jsonItem['description'])

        for scan in original_json_object['scans']:
            experiment = Folder().findOne({
                'name': scan['experiment_id'],
                'parentId': sessionsFolder['_id']
            })
            if not experiment:
                continue
            session = Folder().findOne({
                'name':
                '{0}_{1}'.format(scan['id'], scan['type']),
                'parentId':
                experiment['_id']
            })
            if not session:
                continue
            scan['decision'] = convertRatingToDecision(
                session.get('meta', {}).get('rating', None))
            scan['note'] = session.get('meta', {}).get('note', None)

        return original_json_object
 def path_from_id(object_id):
     if str(object_id).startswith("wtlocal:"):
         decoded = base64.b64decode(object_id[8:]).decode()
         path, root_id = decoded.split("|")
     else:
         root_folder = Folder().load(object_id, force=True) or {}
         path = root_folder.get("fsPath")  # only exists on virtual folders
         root_id = str(root_folder.get("_id"))
     if path:
         path = pathlib.Path(path)
     return path, root_id
Exemple #3
0
def _virtualChildItems(self, event):
    params = event.info['params']

    if 'folderId' not in params:
        return  # This is not a child listing request

    user = self.getCurrentUser()
    folder = Folder().load(params['folderId'],
                           user=user,
                           level=AccessType.READ)

    if not folder.get('isVirtual') or 'virtualItemsQuery' not in folder:
        return  # Parent is not a virtual folder, proceed as normal

    limit, offset, sort = self.getPagingParameters(params,
                                                   defaultSortField='name')
    q = json_util.loads(folder['virtualItemsQuery'])

    if 'virtualItemsSort' in folder:
        sort = json.loads(folder['virtualItemsSort'])

    item = Item()
    # These items may reside in folders that the user cannot read, so we must filter
    items = item.filterResultsByPermission(item.find(q, sort=sort),
                                           user,
                                           level=AccessType.READ,
                                           limit=limit,
                                           offset=offset)
    event.preventDefault().addResponse([item.filter(i, user) for i in items])
Exemple #4
0
 def _copyAnnotationsFromOtherItem(self, srcItemId, destItem):
     # Copy annotations from the original item to this one
     query = {'_active': {'$ne': False}, 'itemId': srcItemId}
     annotations = Annotation().find(query)
     total = annotations.count()
     if not total:
         return
     destItemId = destItem['_id']
     folder = Folder().load(destItem['folderId'], force=True)
     count = 0
     for annotation in annotations:
         logger.info('Copying annotation %d of %d from %s to %s',
                     count + 1, total, srcItemId, destItemId)
         # Make sure we have the elements
         annotation = Annotation().load(annotation['_id'], force=True)
         # This could happen, for instance, if the annotation were deleted
         # while we are copying other annotations.
         if annotation is None:
             continue
         annotation['itemId'] = destItemId
         del annotation['_id']
         # Remove existing permissionsi, then give it the same permissions
         # as the item's folder.
         annotation.pop('access', None)
         self.copyAccessPolicies(destItem, annotation, save=False)
         self.setPublic(annotation, folder.get('public'), save=False)
         Annotation().save(annotation)
         count += 1
     logger.info('Copied %d annotations from %s to %s ',
                 count, srcItemId, destItemId)
Exemple #5
0
 def validate(self, tale):
     if 'iframe' not in tale:
         tale['iframe'] = False
     if tale.get('format', 0) < 2:
         dataFolder = getOrCreateRootFolder(DATADIRS_NAME)
         try:
             origFolder = Folder().load(tale['folderId'],
                                        force=True,
                                        exc=True)
         except ValidationException:
             raise GirderException(
                 ('Tale ({_id}) references folder ({folderId}) '
                  'that does not exist').format(**tale))
         if origFolder.get('creatorId'):
             creator = User().load(origFolder['creatorId'], force=True)
         else:
             creator = None
         tale['involatileData'] = [{
             'type': 'folder',
             'id': tale.pop('folderId')
         }]
         newFolder = Folder().copyFolder(origFolder,
                                         parent=dataFolder,
                                         name=str(tale['_id']),
                                         creator=creator,
                                         progress=False)
         tale['folderId'] = newFolder['_id']
     tale['format'] = _currentTaleFormat
     return tale
Exemple #6
0
def _virtualChildItemsFind(self, params):
    if not params.get('folderId'):
        return  # This is not a child listing request

    user = self.getCurrentUser()
    folder = Folder().load(params['folderId'],
                           user=user,
                           level=AccessType.READ)

    if not folder or not folder.get(
            'isVirtual') or 'virtualItemsQuery' not in folder:
        return  # Parent is not a virtual folder, proceed as normal

    limit, offset, sort = self.getPagingParameters(params,
                                                   defaultSortField='name')
    q = json_util.loads(folder['virtualItemsQuery'])
    if 'virtualItemsSort' in folder:
        sort = json.loads(folder['virtualItemsSort'])

    # Add other parameter options with $and to ensure they don't clobber the
    # virtual items query.
    if params.get('text'):
        q = {'$and': [q, {'$text': {'$search': params['text']}}]}
    if params.get('name'):
        q = {'$and': [q, {'name': params['name']}]}
    return q, sort, user, limit, offset
Exemple #7
0
def _virtualChildItems(self, event):
    params = event.info['params']

    if not params.get('folderId'):
        return  # This is not a child listing request

    user = self.getCurrentUser()
    folder = Folder().load(params['folderId'], user=user, level=AccessType.READ)

    if not folder or not folder.get('isVirtual') or 'virtualItemsQuery' not in folder:
        return  # Parent is not a virtual folder, proceed as normal

    limit, offset, sort = self.getPagingParameters(params, defaultSortField='name')
    q = json_util.loads(folder['virtualItemsQuery'])
    # Add other parameter options with $and to ensure they don't clobber the
    # virtual items query.
    if params.get('text'):
        q = {'$and': [q, {'$text': {'$search': params['text']}}]}
    if params.get('name'):
        q = {'$and': [q, {'name': params['name']}]}

    if 'virtualItemsSort' in folder:
        sort = json.loads(folder['virtualItemsSort'])

    item = Item()
    # These items may reside in folders that the user cannot read, so we must
    # find with permissions
    items = item.findWithPermissions(
        q, sort=sort, user=user, level=AccessType.READ, limit=limit, offset=offset)
    # We have to add this here, as we can't use filtermodel since we return the
    # results in addResponse.
    if callable(getattr(items, 'count', None)):
        cherrypy.response.headers['Girder-Total-Count'] = items.count()
    items = [item.filter(i, user) for i in items]
    event.preventDefault().addResponse(items)
Exemple #8
0
    def createAnnotation(self, item, creator, annotation, public=None):
        now = datetime.datetime.utcnow()
        doc = {
            'itemId': item['_id'],
            'creatorId': creator['_id'],
            'created': now,
            'updatedId': creator['_id'],
            'updated': now,
            'annotation': annotation,
        }

        # copy access control from the folder containing the image
        folder = Folder().load(item['folderId'], force=True)
        self.copyAccessPolicies(src=folder, dest=doc, save=False)

        if public is None:
            public = folder.get('public', False)
        self.setPublic(doc, public, save=False)

        # give the current user admin access
        self.setUserAccess(doc,
                           user=creator,
                           level=AccessType.ADMIN,
                           save=False)

        return self.save(doc)
Exemple #9
0
    def getExportCSV(self):
        def convertRatingToDecision(rating):
            return {
                None: 0,
                'questionable': 0,
                'good': 1,
                'usableExtra': 2,
                'bad': -1
            }[rating]

        sessionsFolder = self.findSessionsFolder()
        items = list(Folder().childItems(sessionsFolder,
                                         filters={'name': 'csv'}))
        if not len(items):
            raise RestException('doesn\'t contain a csv item', code=404)
        csvItem = items[0]
        reader = csv.DictReader(io.StringIO(csvItem['description']))
        output = io.StringIO()
        writer = csv.DictWriter(output, fieldnames=reader.fieldnames)
        writer.writeheader()
        for row in reader:
            experience = Folder().findOne({
                'name': row['xnat_experiment_id'],
                'parentId': sessionsFolder['_id']
            })
            if not experience:
                continue
            session = Folder().findOne({
                'name':
                row['scan_id'] + '_' + row['scan_type'],
                'parentId':
                experience['_id']
            })
            if not session:
                continue
            row['decision'] = convertRatingToDecision(
                session.get('meta', {}).get('rating', None))
            row['scan_note'] = session.get('meta', {}).get('note', None)
            writer.writerow(row)
        return output
Exemple #10
0
 def tryGetExistingSessionMeta(self, sessionsFolder, experimentId, scan):
     experimentFolder = Folder().findOne({
         'name': experimentId,
         'parentId': sessionsFolder['_id']
     })
     if not experimentFolder:
         return None
     sessionFolder = Folder().findOne({
         'name': scan,
         'parentId': experimentFolder['_id']
     })
     if not sessionFolder:
         return None
     return sessionFolder.get('meta', {})
Exemple #11
0
def _virtualFolderDetails(self, event):
    folderId = event.info['id']
    user = self.getCurrentUser()
    folder = Folder().load(folderId, user=user, level=AccessType.READ)

    if not folder or not folder.get('isVirtual') or 'virtualItemsQuery' not in folder:
        return  # Parent is not a virtual folder, proceed as normal

    q = json_util.loads(folder['virtualItemsQuery'])
    item = Item()
    # Virtual folders can't contain subfolders
    result = {
        'nFolders': 0,
        'nItems': item.findWithPermissions(q, user=user, level=AccessType.READ).count()
    }
    event.preventDefault().addResponse(result)
Exemple #12
0
    def _migrateACL(self, annotation):
        """
        Add access control information to an annotation model.

        Originally annotation models were not access controlled.  This function
        performs the migration for annotations created before this change was
        made.  The access object is copied from the folder containing the image
        the annotation is attached to.   In addition, the creator is given
        admin access.
        """
        if annotation is None or 'access' in annotation:
            return annotation

        item = Item().load(annotation['itemId'], force=True)
        if item is None:
            logger.warning(
                'Could not generate annotation ACL due to missing item %s',
                annotation['_id'])
            return annotation

        folder = Folder().load(item['folderId'], force=True)
        if folder is None:
            logger.warning(
                'Could not generate annotation ACL due to missing folder %s',
                annotation['_id'])
            return annotation

        user = User().load(annotation['creatorId'], force=True)
        if user is None:
            logger.warning(
                'Could not generate annotation ACL %s due to missing user %s',
                annotation['_id'])
            return annotation

        self.copyAccessPolicies(item, annotation, save=False)
        self.setUserAccess(annotation,
                           user,
                           AccessType.ADMIN,
                           force=True,
                           save=False)
        self.setPublic(annotation, folder.get('public'), save=False)

        # call the super class save method to avoid messing with elements
        super().save(annotation)
        logger.info('Generated annotation ACL for %s', annotation['_id'])
        return annotation
Exemple #13
0
def _validateFolder(event):
    doc = event.info

    if 'isVirtual' in doc and not isinstance(doc['isVirtual'], bool):
        raise ValidationException('The isVirtual field must be boolean.',
                                  field='isVirtual')

    if doc.get('isVirtual'):
        # Make sure it doesn't have children
        if list(Folder().childItems(doc, limit=1)):
            raise ValidationException(
                'Virtual folders may not contain child items.',
                field='isVirtual')
        if list(Folder().find(
            {
                'parentId': doc['_id'],
                'parentCollection': 'folder'
            }, limit=1)):
            raise ValidationException(
                'Virtual folders may not contain child folders.',
                field='isVirtual')
    if doc['parentCollection'] == 'folder':
        parent = Folder().load(event.info['parentId'], force=True, exc=True)
        if parent.get('isVirtual'):
            raise ValidationException(
                'You may not place folders under a virtual folder.',
                field='folderId')

    if 'virtualItemsQuery' in doc:
        try:
            json.loads(doc['virtualItemsQuery'])
        except (TypeError, ValueError):
            raise ValidationException(
                'The virtual items query must be valid JSON.',
                field='virtualItemsQuery')

    if 'virtualItemsSort' in doc:
        try:
            json.loads(doc['virtualItemsSort'])
        except (TypeError, ValueError):
            raise ValidationException(
                'The virtual items sort must be valid JSON.',
                field='virtualItemsSort')
Exemple #14
0
    def updateFolderAccess(self, phase, submissions):
        """
        Synchronize access control between the phase and submission folders for
        the phase. Phase admins should have read access on the submission
        folders.
        """
        # Get phase admin users
        phaseAcl = Phase().getFullAccessList(phase)
        phaseAdminUserIds = set([user['id']
                                 for user in phaseAcl.get('users')
                                 if user['level'] >= AccessType.WRITE])
        phaseAdminUsers = [User().load(userId, force=True, exc=True)
                           for userId in phaseAdminUserIds]

        # Update submission folder ACL for current phase admins
        try:
            for sub in submissions:
                folder = Folder().load(sub['folderId'], force=True)
                if not folder:
                    continue
                folderAcl = Folder().getFullAccessList(folder)

                # Revoke access to users who are not phase admins; ignore folder
                # owner
                usersToRemove = [User().load(user['id'], force=True,
                                             exc=True)
                                 for user in folderAcl.get('users')
                                 if (user['id'] not in phaseAdminUserIds and
                                     user['id'] != folder['creatorId'])]
                for user in usersToRemove:
                    Folder().setUserAccess(folder, user, None)

                # Add access to phase admins; ignore folder owner
                usersToAdd = [user for user in phaseAdminUsers
                              if user['_id'] != folder['creatorId']]
                for user in usersToAdd:
                    Folder().setUserAccess(folder, user, AccessType.READ)

                # Save folder if access changed
                if usersToRemove or usersToAdd:
                    Folder().save(folder, validate=False)
        except TypeError:
            raise ValidationException('A list of submissions is required.')
Exemple #15
0
def _virtualChildItems(self, event):
    params = event.info['params']

    if 'folderId' not in params:
        return  # This is not a child listing request

    user = self.getCurrentUser()
    folder = Folder().load(params['folderId'], user=user, level=AccessType.READ)

    if not folder.get('isVirtual') or 'virtualItemsQuery' not in folder:
        return  # Parent is not a virtual folder, proceed as normal

    limit, offset, sort = self.getPagingParameters(params, defaultSortField='name')
    q = json_util.loads(folder['virtualItemsQuery'])

    if 'virtualItemsSort' in folder:
        sort = json.loads(folder['virtualItemsSort'])

    item = Item()
    # These items may reside in folders that the user cannot read, so we must filter
    items = item.filterResultsByPermission(
        item.find(q, sort=sort), user, level=AccessType.READ, limit=limit, offset=offset)
    event.preventDefault().addResponse([item.filter(i, user) for i in items])
Exemple #16
0
    def updateRunStatus(self, event):
        """
        Event handler that updates the run status based on the recorded_run task.
        """
        job = event.info['job']
        if job['title'] == 'Recorded Run' and job.get('status') is not None:
            status = int(job['status'])
            rfolder = Folder().load(job['args'][0], force=True)

            # Store the previous status, if present.
            previousStatus = rfolder.get(FIELD_STATUS_CODE, -1)

            if status == JobStatus.SUCCESS:
                rfolder[FIELD_STATUS_CODE] = RunStatus.COMPLETED.code
            elif status == JobStatus.ERROR:
                rfolder[FIELD_STATUS_CODE] = RunStatus.FAILED.code
            elif status in (JobStatus.QUEUED, JobStatus.RUNNING):
                rfolder[FIELD_STATUS_CODE] = RunStatus.RUNNING.code

            # If the status changed, save the object
            if FIELD_STATUS_CODE in rfolder and rfolder[
                    FIELD_STATUS_CODE] != previousStatus:
                Folder().save(rfolder)
Exemple #17
0
def _validateFolder(event):
    doc = event.info

    if 'isVirtual' in doc and not isinstance(doc['isVirtual'], bool):
        raise ValidationException('The isVirtual field must be boolean.', field='isVirtual')

    if doc.get('isVirtual'):
        # Make sure it doesn't have children
        if list(Folder().childItems(doc, limit=1)):
            raise ValidationException(
                'Virtual folders may not contain child items.', field='isVirtual')
        if list(Folder().find({
            'parentId': doc['_id'],
            'parentCollection': 'folder'
        }, limit=1)):
            raise ValidationException(
                'Virtual folders may not contain child folders.', field='isVirtual')
    if doc['parentCollection'] == 'folder':
        parent = Folder().load(event.info['parentId'], force=True, exc=True)
        if parent.get('isVirtual'):
            raise ValidationException(
                'You may not place folders under a virtual folder.', field='folderId')

    if 'virtualItemsQuery' in doc:
        try:
            json.loads(doc['virtualItemsQuery'])
        except (TypeError, ValueError):
            raise ValidationException(
                'The virtual items query must be valid JSON.', field='virtualItemsQuery')

    if 'virtualItemsSort' in doc:
        try:
            json.loads(doc['virtualItemsSort'])
        except (TypeError, ValueError):
            raise ValidationException(
                'The virtual items sort must be valid JSON.', field='virtualItemsSort')
Exemple #18
0
    def testCuration(self):
        admin, user = self.users

        # create a collection and a folder
        c1 = Collection().createCollection('c1', admin, public=True)
        f1 = Folder().createFolder(c1,
                                   'f1',
                                   parentType='collection',
                                   public=False)
        f2 = Folder().createFolder(c1,
                                   'f2',
                                   parentType='collection',
                                   public=False)
        Folder().setUserAccess(f2, user, AccessType.WRITE, True)

        # test initial curation values
        path = '/folder/%s/curation' % f1.get('_id')
        resp = self.request(path=path, user=admin)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['enabled'], False)
        self.assertEqual(resp.json['timeline'], [])

        # test non-admin access to private folder
        path = '/folder/%s/curation' % f1.get('_id')
        resp = self.request(path=path, user=user)
        self.assertStatus(resp, 403)

        # test non-admin access to folder with permissions
        path = '/folder/%s/curation' % f2.get('_id')
        resp = self.request(path=path, user=user)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['enabled'], False)
        self.assertEqual(resp.json['timeline'], [])

        # test non-admin unable to enable curation
        path = '/folder/%s/curation' % f2.get('_id')
        params = dict(enabled='true')
        resp = self.request(path=path, user=user, method='PUT', params=params)
        self.assertStatus(resp, 403)

        # test admin able to enable curation
        path = '/folder/%s/curation' % f2.get('_id')
        params = dict(enabled='true')
        resp = self.request(path=path, user=admin, method='PUT', params=params)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['enabled'], True)
        self.assertEqual(resp.json['status'], 'construction')

        # test non-admin unable to disable curation
        path = '/folder/%s/curation' % f2.get('_id')
        params = dict(enabled='false')
        resp = self.request(path=path, user=user, method='PUT', params=params)
        self.assertStatus(resp, 403)

        # test non-admin able to request approval
        path = '/folder/%s/curation' % f2.get('_id')
        params = dict(status='requested')
        resp = self.request(path=path, user=user, method='PUT', params=params)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['enabled'], True)
        self.assertEqual(resp.json['status'], 'requested')

        # test non-admin unable to change status
        path = '/folder/%s/curation' % f2.get('_id')
        params = dict(status='approved')
        resp = self.request(path=path, user=user, method='PUT', params=params)
        self.assertStatus(resp, 403)

        path = '/folder/%s/curation' % f2.get('_id')
        params = dict(status='construction')
        resp = self.request(path=path, user=user, method='PUT', params=params)
        self.assertStatus(resp, 403)

        # test admin able to approve
        path = '/folder/%s/curation' % f2.get('_id')
        params = dict(status='approved')
        resp = self.request(path=path, user=admin, method='PUT', params=params)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['enabled'], True)
        self.assertEqual(resp.json['status'], 'approved')

        # test timeline is correct
        path = '/folder/%s/curation' % f2.get('_id')
        resp = self.request(path=path, user=user)
        self.assertStatusOk(resp)
        self.assertEqual(len(resp.json['timeline']), 3)
        self.assertEqual(resp.json['timeline'][0]['oldEnabled'], False)
        self.assertEqual(resp.json['timeline'][0]['enabled'], True)
        self.assertEqual(resp.json['timeline'][0]['oldStatus'], 'construction')
        self.assertEqual(resp.json['timeline'][0]['status'], 'construction')
        self.assertEqual(resp.json['timeline'][1]['oldEnabled'], True)
        self.assertEqual(resp.json['timeline'][1]['enabled'], True)
        self.assertEqual(resp.json['timeline'][1]['oldStatus'], 'construction')
        self.assertEqual(resp.json['timeline'][1]['status'], 'requested')
        self.assertEqual(resp.json['timeline'][2]['oldEnabled'], True)
        self.assertEqual(resp.json['timeline'][2]['enabled'], True)
        self.assertEqual(resp.json['timeline'][2]['oldStatus'], 'requested')
        self.assertEqual(resp.json['timeline'][2]['status'], 'approved')
Exemple #19
0
def _validateItem(event):
    parent = Folder().load(event.info['folderId'], force=True, exc=True)
    if parent.get('isVirtual'):
        raise ValidationException(
            'You may not place items under a virtual folder.', field='folderId')
Exemple #20
0
    def testFolderAccessAndDetails(self):
        # create a folder to work with
        folder = Folder().createFolder(
            parent=self.admin, parentType='user', creator=self.admin,
            name='Folder')

        resp = self.request(
            path='/folder/%s/access' % folder['_id'], method='GET',
            user=self.admin)
        self.assertStatusOk(resp)
        access = resp.json
        self.assertEqual(access, {
            'users': [{
                'login': self.admin['login'],
                'level': AccessType.ADMIN,
                'id': str(self.admin['_id']),
                'flags': [],
                'name': '%s %s' % (
                    self.admin['firstName'], self.admin['lastName'])}],
            'groups': []
        })
        self.assertTrue(not folder.get('public'))
        # Setting the access list with bad json should throw an error
        resp = self.request(
            path='/folder/%s/access' % folder['_id'], method='PUT',
            user=self.admin, params={'access': 'badJSON'})
        self.assertStatus(resp, 400)
        # Change the access to public
        resp = self.request(
            path='/folder/%s/access' % folder['_id'], method='PUT',
            user=self.admin,
            params={'access': json.dumps(access), 'public': True})
        self.assertStatusOk(resp)
        resp = self.request(
            path='/folder/%s' % folder['_id'], method='GET',
            user=self.admin)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['public'], True)

        # Create an item in the folder
        Item().createItem(folder=folder, creator=self.admin, name='Item')
        # Create a public and private folder within the folder
        Folder().createFolder(
            parent=folder, parentType='folder', creator=self.admin,
            name='Public', public=True)
        Folder().createFolder(
            parent=folder, parentType='folder', creator=self.admin,
            name='Private', public=False)

        # Test folder details as anonymous
        resp = self.request(
            path='/folder/%s/details' % str(folder['_id']))
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['nItems'], 1)
        self.assertEqual(resp.json['nFolders'], 1)

        # Test folder details as admin
        resp = self.request(
            path='/folder/%s/details' % str(folder['_id']), user=self.admin)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['nItems'], 1)
        self.assertEqual(resp.json['nFolders'], 2)
Exemple #21
0
    def setCuration(self, folder, params):
        user = self.getCurrentUser()
        if CURATION not in folder:
            folder[CURATION] = dict(DEFAULTS)
        curation = folder[CURATION]
        oldCuration = dict(curation)

        # update enabled
        oldEnabled = curation.get(ENABLED, False)
        if ENABLED in params:
            self.requireAdmin(user)
            curation[ENABLED] = self.boolParam(ENABLED, params)
        enabled = curation.get(ENABLED, False)

        # update status
        oldStatus = curation.get(STATUS)
        if STATUS in params:
            # verify valid status
            if params[STATUS] not in [CONSTRUCTION, REQUESTED, APPROVED]:
                raise RestException('Invalid status parameter')
            # regular users can only do construction -> requested transition
            if curation.get(STATUS) != CONSTRUCTION or \
               params[STATUS] != REQUESTED:
                self.requireAdmin(user)
            curation[STATUS] = params[STATUS]
        status = curation.get(STATUS)

        # admin enabling curation
        if enabled and not oldEnabled:
            # TODO: check if writers exist?
            # TODO: email writers?
            with self._progressContext(folder, TITLE_PRIVATE) as pc:
                self._setPublic(folder, False, pc)
            curation[ENABLE_USER_ID] = user.get('_id')
            self._addTimeline(oldCuration, curation, 'enabled curation')

        # admin reopening folder
        if enabled and oldStatus == APPROVED and status == CONSTRUCTION:
            with self._progressContext(folder, TITLE_PRIVATE) as pc:
                self._setPublic(folder, False, pc)
            curation[ENABLE_USER_ID] = user.get('_id')
            with self._progressContext(folder, TITLE_WRITEABLE) as pc:
                self._makeWriteable(folder, pc)
            self._addTimeline(oldCuration, curation, 'reopened folder')

        # admin disabling curation
        if not enabled and oldEnabled:
            self._addTimeline(oldCuration, curation, 'disabled curation')

        # user requesting approval
        if enabled and oldStatus == CONSTRUCTION and status == REQUESTED:
            curation[REQUEST_USER_ID] = user.get('_id')
            with self._progressContext(folder, TITLE_READ_ONLY) as pc:
                self._makeReadOnly(folder, pc)
            self._addTimeline(oldCuration, curation, 'requested approval')
            # send email to admin requesting approval
            self._sendMail(
                folder, curation.get(ENABLE_USER_ID),
                'REQUEST FOR APPROVAL: ' + folder['name'],
                'curation.requested.mako')

        # admin approving request
        if enabled and oldStatus == REQUESTED and status == APPROVED:
            with self._progressContext(folder, TITLE_PUBLIC) as pc:
                self._setPublic(folder, True, pc)
            curation[REVIEW_USER_ID] = user.get('_id')
            self._addTimeline(oldCuration, curation, 'approved request')
            # send approval notification to requestor
            self._sendMail(
                folder, curation.get(REQUEST_USER_ID),
                'APPROVED: ' + folder['name'],
                'curation.approved.mako')

        # admin rejecting request
        if enabled and oldStatus == REQUESTED and status == CONSTRUCTION:
            curation[REVIEW_USER_ID] = user.get('_id')
            with self._progressContext(folder, TITLE_WRITEABLE) as pc:
                self._makeWriteable(folder, pc)
            self._addTimeline(oldCuration, curation, 'rejected request')
            # send rejection notification to requestor
            self._sendMail(
                folder, curation.get(REQUEST_USER_ID),
                'REJECTED: ' + folder['name'],
                'curation.rejected.mako')

        folder = Folder().save(folder)
        curation['public'] = folder.get('public')
        return curation
Exemple #22
0
def _validateItem(event):
    parent = Folder().load(event.info['folderId'], force=True, exc=True)
    if parent.get('isVirtual'):
        raise ValidationException(
            'You may not place items under a virtual folder.',
            field='folderId')
Exemple #23
0
    def setCuration(self, folder, params):
        user = self.getCurrentUser()
        if CURATION not in folder:
            folder[CURATION] = dict(DEFAULTS)
        curation = folder[CURATION]
        oldCuration = dict(curation)

        # update enabled
        oldEnabled = curation.get(ENABLED, False)
        if ENABLED in params:
            self.requireAdmin(user)
            curation[ENABLED] = self.boolParam(ENABLED, params)
        enabled = curation.get(ENABLED, False)

        # update status
        oldStatus = curation.get(STATUS)
        if STATUS in params:
            # verify valid status
            if params[STATUS] not in [CONSTRUCTION, REQUESTED, APPROVED]:
                raise RestException('Invalid status parameter')
            # regular users can only do construction -> requested transition
            if curation.get(STATUS) != CONSTRUCTION or \
               params[STATUS] != REQUESTED:
                self.requireAdmin(user)
            curation[STATUS] = params[STATUS]
        status = curation.get(STATUS)

        # admin enabling curation
        if enabled and not oldEnabled:
            # TODO: check if writers exist?
            # TODO: email writers?
            with self._progressContext(folder, TITLE_PRIVATE) as pc:
                self._setPublic(folder, False, pc)
            curation[ENABLE_USER_ID] = user.get('_id')
            self._addTimeline(oldCuration, curation, 'enabled curation')

        # admin reopening folder
        if enabled and oldStatus == APPROVED and status == CONSTRUCTION:
            with self._progressContext(folder, TITLE_PRIVATE) as pc:
                self._setPublic(folder, False, pc)
            curation[ENABLE_USER_ID] = user.get('_id')
            with self._progressContext(folder, TITLE_WRITEABLE) as pc:
                self._makeWriteable(folder, pc)
            self._addTimeline(oldCuration, curation, 'reopened folder')

        # admin disabling curation
        if not enabled and oldEnabled:
            self._addTimeline(oldCuration, curation, 'disabled curation')

        # user requesting approval
        if enabled and oldStatus == CONSTRUCTION and status == REQUESTED:
            curation[REQUEST_USER_ID] = user.get('_id')
            with self._progressContext(folder, TITLE_READ_ONLY) as pc:
                self._makeReadOnly(folder, pc)
            self._addTimeline(oldCuration, curation, 'requested approval')
            # send email to admin requesting approval
            self._sendMail(folder, curation.get(ENABLE_USER_ID),
                           'REQUEST FOR APPROVAL: ' + folder['name'],
                           'curation.requested.mako')

        # admin approving request
        if enabled and oldStatus == REQUESTED and status == APPROVED:
            with self._progressContext(folder, TITLE_PUBLIC) as pc:
                self._setPublic(folder, True, pc)
            curation[REVIEW_USER_ID] = user.get('_id')
            self._addTimeline(oldCuration, curation, 'approved request')
            # send approval notification to requestor
            self._sendMail(folder, curation.get(REQUEST_USER_ID),
                           'APPROVED: ' + folder['name'],
                           'curation.approved.mako')

        # admin rejecting request
        if enabled and oldStatus == REQUESTED and status == CONSTRUCTION:
            curation[REVIEW_USER_ID] = user.get('_id')
            with self._progressContext(folder, TITLE_WRITEABLE) as pc:
                self._makeWriteable(folder, pc)
            self._addTimeline(oldCuration, curation, 'rejected request')
            # send rejection notification to requestor
            self._sendMail(folder, curation.get(REQUEST_USER_ID),
                           'REJECTED: ' + folder['name'],
                           'curation.rejected.mako')

        folder = Folder().save(folder)
        curation['public'] = folder.get('public')
        return curation