def test_check_artifact_access(self):
        # "Study" artifact
        a = Artifact(1)
        # The user has access
        u = User('*****@*****.**')
        check_artifact_access(u, a)

        # Admin has access to everything
        admin = User('*****@*****.**')
        check_artifact_access(admin, a)

        # Demo user doesn't have access
        demo_u = User('*****@*****.**')
        with self.assertRaises(HTTPError):
            check_artifact_access(demo_u, a)

        # "Analysis" artifact
        a = Artifact(8)
        a.visibility = 'private'
        check_artifact_access(u, a)
        check_artifact_access(admin, a)
        with self.assertRaises(HTTPError):
            check_artifact_access(demo_u, a)
        check_artifact_access(User('*****@*****.**'), a)
        a.visibility = 'public'
        check_artifact_access(demo_u, a)
Exemple #2
0
    def test_check_artifact_access(self):
        # "Study" artifact
        a = Artifact(1)
        # The user has access
        u = User('*****@*****.**')
        check_artifact_access(u, a)

        # Admin has access to everything
        admin = User('*****@*****.**')
        check_artifact_access(admin, a)

        # Demo user doesn't have access
        demo_u = User('*****@*****.**')
        with self.assertRaises(HTTPError):
            check_artifact_access(demo_u, a)

        # "Analysis" artifact
        a = Artifact(8)
        a.visibility = 'private'
        check_artifact_access(u, a)
        check_artifact_access(admin, a)
        with self.assertRaises(HTTPError):
            check_artifact_access(demo_u, a)
        check_artifact_access(User('*****@*****.**'), a)
        a.visibility = 'public'
        check_artifact_access(demo_u, a)
Exemple #3
0
def artifact_status_put_req(artifact_id, user_id, visibility):
    """Set the status of the artifact given

    Parameters
    ----------
    artifact_id : int
        Artifact being acted on
    user_id : str
        The user requesting the action
    visibility : {'sandbox', 'awaiting_approval', 'private', 'public'}
        What to change the visibility to

    Returns
    -------
    dict
        Status of action, in the form {'status': status, 'message': msg}
        status: status of the action, either success or error
        message: Human readable message for status
    """
    if visibility not in get_visibilities():
        return {'status': 'error',
                'message': 'Unknown visibility value: %s' % visibility}

    pd = Artifact(int(artifact_id))
    sid = pd.study.id
    access_error = check_access(sid, user_id)
    if access_error:
        return access_error
    user = User(str(user_id))
    status = 'success'
    msg = 'Artifact visibility changed to %s' % visibility
    # Set the approval to private if needs approval and admin
    if visibility == 'private':
        if not qiita_config.require_approval:
            pd.visibility = 'private'
        # Set the approval to private if approval not required
        elif user.level == 'admin':
            pd.visibility = 'private'
        # Trying to set approval without admin privileges
        else:
            status = 'error'
            msg = 'User does not have permissions to approve change'
    else:
        pd.visibility = visibility

    LogEntry.create('Warning', '%s changed artifact %s (study %d) to %s' % (
        user_id, artifact_id, sid, visibility))

    return {'status': status,
            'message': msg}
    def approve_study(self, study, user, callback):
        """Approves the current study if and only if the current user is admin

        Parameters
        ----------
        study : Study
            The current study object
        user : User
            The current user object
        callback : function
            The callback function to call with the results once the processing
            is done
        """
        if _approve(user.level):
            pd_id = int(self.get_argument('pd_id'))
            pd = Artifact(pd_id)
            pd.visibility = 'private'
            _propagate_visibility(pd)
            msg = "Processed data approved"
            msg_level = "success"
        else:
            msg = ("The current user does not have permission to approve "
                   "the processed data")
            msg_level = "danger"
        callback((msg, msg_level, "processed_data_tab", pd_id, None))
    def approve_study(self, study, user, callback):
        """Approves the current study if and only if the current user is admin

        Parameters
        ----------
        study : Study
            The current study object
        user : User
            The current user object
        callback : function
            The callback function to call with the results once the processing
            is done
        """
        if _approve(user.level):
            pd_id = int(self.get_argument('pd_id'))
            pd = Artifact(pd_id)
            pd.visibility = 'private'
            _propagate_visibility(pd)
            msg = "Processed data approved"
            msg_level = "success"
        else:
            msg = ("The current user does not have permission to approve "
                   "the processed data")
            msg_level = "danger"
        callback((msg, msg_level, "processed_data_tab", pd_id, None))
Exemple #6
0
def artifact_status_put_req(artifact_id, user_id, visibility):
    """Set the status of the artifact given

    Parameters
    ----------
    artifact_id : int
        Artifact being acted on
    user_id : str
        The user requesting the action
    visibility : {'sandbox', 'awaiting_approval', 'private', 'public'}
        What to change the visibility to

    Returns
    -------
    dict
        Status of action, in the form {'status': status, 'message': msg}
        status: status of the action, either success or error
        message: Human readable message for status
    """
    if visibility not in get_visibilities():
        return {'status': 'error',
                'message': 'Unknown visiblity value: %s' % visibility}

    pd = Artifact(int(artifact_id))
    access_error = check_access(pd.study.id, user_id)
    if access_error:
        return access_error
    user = User(str(user_id))
    status = 'success'
    msg = 'Artifact visibility changed to %s' % visibility
    # Set the approval to private if needs approval and admin
    if visibility == 'private':
        if not qiita_config.require_approval:
            pd.visibility = 'private'
        # Set the approval to private if approval not required
        elif user.level == 'admin':
            pd.visibility = 'private'
        # Trying to set approval without admin privileges
        else:
            status = 'error'
            msg = 'User does not have permissions to approve change'
    else:
        pd.visibility = visibility

    return {'status': status,
            'message': msg}
    def test_propagate_visibility(self):
        a = Artifact(4)
        a.visibility = 'public'
        _propagate_visibility(a)
        self.assertEqual(Artifact(1).visibility, 'public')
        self.assertEqual(Artifact(2).visibility, 'public')
        self.assertEqual(Artifact(4).visibility, 'public')

        a.visibility = 'private'
        _propagate_visibility(a)
        self.assertEqual(Artifact(1).visibility, 'private')
        self.assertEqual(Artifact(2).visibility, 'private')
        self.assertEqual(Artifact(4).visibility, 'private')

        a = Artifact(2)
        a.visibility = 'public'
        _propagate_visibility(a)
        self.assertEqual(Artifact(1).visibility, 'private')
        self.assertEqual(Artifact(2).visibility, 'private')
        self.assertEqual(Artifact(4).visibility, 'private')
    def test_propagate_visibility(self):
        a = Artifact(4)
        a.visibility = 'public'
        _propagate_visibility(a)
        self.assertEqual(Artifact(1).visibility, 'public')
        self.assertEqual(Artifact(2).visibility, 'public')
        self.assertEqual(Artifact(4).visibility, 'public')

        a.visibility = 'private'
        _propagate_visibility(a)
        self.assertEqual(Artifact(1).visibility, 'private')
        self.assertEqual(Artifact(2).visibility, 'private')
        self.assertEqual(Artifact(4).visibility, 'private')

        a = Artifact(2)
        a.visibility = 'public'
        _propagate_visibility(a)
        self.assertEqual(Artifact(1).visibility, 'private')
        self.assertEqual(Artifact(2).visibility, 'private')
        self.assertEqual(Artifact(4).visibility, 'private')
    def make_public(self, study, user, callback):
        """Makes the current study public

        Parameters
        ----------
        study : Study
            The current study object
        user : User
            The current user object
        callback : function
            The callback function to call with the results once the processing
            is done
        """
        pd_id = int(self.get_argument('pd_id'))
        pd = Artifact(pd_id)
        pd.visibility = 'public'
        _propagate_visibility(pd)
        msg = "Processed data set to public"
        msg_level = "success"
        callback((msg, msg_level, "processed_data_tab", pd_id, None))
    def make_sandbox(self, study, user, callback):
        """Reverts the current study to the 'sandbox' status

        Parameters
        ----------
        study : Study
            The current study object
        user : User
            The current user object
        callback : function
            The callback function to call with the results once the processing
            is done
        """
        pd_id = int(self.get_argument('pd_id'))
        pd = Artifact(pd_id)
        pd.visibility = 'sandbox'
        _propagate_visibility(pd)
        msg = "Processed data reverted to sandbox"
        msg_level = "success"
        callback((msg, msg_level, "processed_data_tab", pd_id, None))
    def request_approval(self, study, user, callback):
        """Changes the status of the current study to "awaiting_approval"

        Parameters
        ----------
        study : Study
            The current study object
        user : User
            The current user object
        callback : function
            The callback function to call with the results once the processing
            is done
        """
        pd_id = int(self.get_argument('pd_id'))
        pd = Artifact(pd_id)
        pd.visibility = 'awaiting_approval'
        _propagate_visibility(pd)
        msg = "Processed data sent to admin for approval"
        msg_level = "success"
        callback((msg, msg_level, "processed_data_tab", pd_id, None))
    def make_sandbox(self, study, user, callback):
        """Reverts the current study to the 'sandbox' status

        Parameters
        ----------
        study : Study
            The current study object
        user : User
            The current user object
        callback : function
            The callback function to call with the results once the processing
            is done
        """
        pd_id = int(self.get_argument('pd_id'))
        pd = Artifact(pd_id)
        pd.visibility = 'sandbox'
        _propagate_visibility(pd)
        msg = "Processed data reverted to sandbox"
        msg_level = "success"
        callback((msg, msg_level, "processed_data_tab", pd_id, None))
    def request_approval(self, study, user, callback):
        """Changes the status of the current study to "awaiting_approval"

        Parameters
        ----------
        study : Study
            The current study object
        user : User
            The current user object
        callback : function
            The callback function to call with the results once the processing
            is done
        """
        pd_id = int(self.get_argument('pd_id'))
        pd = Artifact(pd_id)
        pd.visibility = 'awaiting_approval'
        _propagate_visibility(pd)
        msg = "Processed data sent to admin for approval"
        msg_level = "success"
        callback((msg, msg_level, "processed_data_tab", pd_id, None))
    def make_public(self, study, user, callback):
        """Makes the current study public

        Parameters
        ----------
        study : Study
            The current study object
        user : User
            The current user object
        callback : function
            The callback function to call with the results once the processing
            is done
        """
        pd_id = int(self.get_argument('pd_id'))
        pd = Artifact(pd_id)
        pd.visibility = 'public'
        _propagate_visibility(pd)
        msg = "Processed data set to public"
        msg_level = "success"
        callback((msg, msg_level, "processed_data_tab", pd_id, None))
Exemple #15
0
    def test_artifact_summary_get_request(self):
        # Artifact w/o summary
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp_p_jobs = [[
            '063e553b-327c-4818-ab4a-adfe58e49860', 'Split libraries FASTQ',
            'queued', None, None
        ],
                      [
                          'bcc7ebcd-39c1-43e4-af2d-822e3589f14d',
                          'Split libraries', 'running', 'demultiplexing', None
                      ]]
        exp_files = [
            (1L, '1_s_G1_L001_sequences.fastq.gz (raw forward seqs)'),
            (2L, '1_s_G1_L001_sequences_barcodes.fastq.gz (raw barcodes)')
        ]
        exp = {
            'status':
            'success',
            'message':
            '',
            'name':
            'Raw data 1',
            'summary':
            None,
            'job':
            None,
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': [],
            'visibility':
            'private',
            'buttons':
            '<button onclick="if (confirm(\'Are you sure you '
            'want to make public artifact id: 1?\')) { '
            'set_artifact_visibility(\'public\', 1) }" '
            'class="btn btn-primary btn-sm">Make public</button>'
            ' <button onclick="if (confirm(\'Are you sure you '
            'want to revert to sandbox artifact id: 1?\')) '
            '{ set_artifact_visibility(\'sandbox\', 1) }" '
            'class="btn btn-primary btn-sm">Revert to '
            'sandbox</button>',
            'files':
            exp_files,
            'editable':
            True,
            'prep_id':
            1,
            'study_id':
            1
        }
        self.assertEqual(obs, exp)

        # Artifact with summary being generated
        job = ProcessingJob.create(
            User('*****@*****.**'),
            Parameters.load(Command(7), values_dict={'input_data': 1}))
        job._set_status('queued')
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {
            'status':
            'success',
            'message':
            '',
            'name':
            'Raw data 1',
            'summary':
            None,
            'job': [job.id, 'queued', None],
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': [],
            'visibility':
            'private',
            'buttons':
            '<button onclick="if (confirm(\'Are you sure you '
            'want to make public artifact id: 1?\')) { '
            'set_artifact_visibility(\'public\', 1) }" '
            'class="btn btn-primary btn-sm">Make public</button>'
            ' <button onclick="if (confirm(\'Are you sure you '
            'want to revert to sandbox artifact id: 1?\')) { '
            'set_artifact_visibility(\'sandbox\', 1) }" '
            'class="btn btn-primary btn-sm">Revert to '
            'sandbox</button>',
            'files':
            exp_files,
            'editable':
            True,
            'prep_id':
            1,
            'study_id':
            1
        }
        self.assertEqual(obs, exp)

        # Artifact with summary
        fd, fp = mkstemp(suffix=".html")
        close(fd)
        with open(fp, 'w') as f:
            f.write('<b>HTML TEST - not important</b>\n')
        a = Artifact(1)
        a.html_summary_fp = fp
        self._files_to_remove.extend([fp, a.html_summary_fp[1]])
        exp_files.append(
            (a.html_summary_fp[0],
             '%s (html summary)' % basename(a.html_summary_fp[1])))
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {
            'status':
            'success',
            'message':
            '',
            'name':
            'Raw data 1',
            'summary':
            '<b>HTML TEST - not important</b>\n',
            'job':
            None,
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': [],
            'visibility':
            'private',
            'buttons':
            '<button onclick="if (confirm(\'Are you sure you '
            'want to make public artifact id: 1?\')) { '
            'set_artifact_visibility(\'public\', 1) }" '
            'class="btn btn-primary btn-sm">Make public</button>'
            ' <button onclick="if (confirm(\'Are you sure you '
            'want to revert to sandbox artifact id: 1?\')) { '
            'set_artifact_visibility(\'sandbox\', 1) }" '
            'class="btn btn-primary btn-sm">Revert to '
            'sandbox</button>',
            'files':
            exp_files,
            'editable':
            True,
            'prep_id':
            1,
            'study_id':
            1
        }
        self.assertEqual(obs, exp)

        # No access
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {
            'status': 'error',
            'message': 'User does not have access to study'
        }
        self.assertEqual(obs, exp)

        # A non-owner/share user can't see the files
        a.visibility = 'public'
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {
            'status': 'success',
            'message': '',
            'name': 'Raw data 1',
            'summary': '<b>HTML TEST - not important</b>\n',
            'job': None,
            'processing_jobs': exp_p_jobs,
            'errored_jobs': [],
            'visibility': 'public',
            'buttons': '',
            'files': [],
            'editable': False,
            'prep_id': 1,
            'study_id': 1
        }
        self.assertEqual(obs, exp)
Exemple #16
0
    def test_artifact_summary_get_request(self):
        user = User('*****@*****.**')
        # Artifact w/o summary
        obs = artifact_summary_get_request(user, 1)
        exp_p_jobs = [[
            '063e553b-327c-4818-ab4a-adfe58e49860', 'Split libraries FASTQ',
            'queued', None, None
        ],
                      [
                          'bcc7ebcd-39c1-43e4-af2d-822e3589f14d',
                          'Split libraries', 'running', 'demultiplexing', None
                      ]]
        exp_files = [
            (1L, '1_s_G1_L001_sequences.fastq.gz (raw forward seqs)'),
            (2L, '1_s_G1_L001_sequences_barcodes.fastq.gz (raw barcodes)')
        ]
        exp = {
            'name':
            'Raw data 1',
            'artifact_id':
            1,
            'visibility':
            'private',
            'editable':
            True,
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 1?\')) { '
                        'set_artifact_visibility(\'public\', 1) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button>'),
            'processing_parameters': {},
            'files':
            exp_files,
            'summary':
            None,
            'job':
            None,
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': []
        }
        self.assertEqual(obs, exp)

        # Artifact with summary being generated
        job = ProcessingJob.create(
            User('*****@*****.**'),
            Parameters.load(Command(7), values_dict={'input_data': 1}))
        job._set_status('queued')
        obs = artifact_summary_get_request(user, 1)
        exp = {
            'name':
            'Raw data 1',
            'artifact_id':
            1,
            'visibility':
            'private',
            'editable':
            True,
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 1?\')) { '
                        'set_artifact_visibility(\'public\', 1) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button>'),
            'processing_parameters': {},
            'files':
            exp_files,
            'summary':
            None,
            'job': [job.id, 'queued', None],
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': []
        }
        self.assertEqual(obs, exp)

        # Artifact with summary
        fd, fp = mkstemp(suffix=".html")
        close(fd)
        with open(fp, 'w') as f:
            f.write('<b>HTML TEST - not important</b>\n')
        a = Artifact(1)
        a.set_html_summary(fp)
        self._files_to_remove.extend([fp, a.html_summary_fp[1]])
        exp_files.append(
            (a.html_summary_fp[0],
             '%s (html summary)' % basename(a.html_summary_fp[1])))
        exp_summary_path = relpath(a.html_summary_fp[1],
                                   qiita_config.base_data_dir)
        obs = artifact_summary_get_request(user, 1)
        exp = {
            'name':
            'Raw data 1',
            'artifact_id':
            1,
            'visibility':
            'private',
            'editable':
            True,
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 1?\')) { '
                        'set_artifact_visibility(\'public\', 1) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button>'),
            'processing_parameters': {},
            'files':
            exp_files,
            'summary':
            exp_summary_path,
            'job':
            None,
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': []
        }
        self.assertEqual(obs, exp)

        # No access
        demo_u = User('*****@*****.**')
        with self.assertRaises(QiitaHTTPError):
            obs = artifact_summary_get_request(demo_u, 1)

        # A non-owner/share user can't see the files
        a.visibility = 'public'
        obs = artifact_summary_get_request(demo_u, 1)
        exp = {
            'name': 'Raw data 1',
            'artifact_id': 1,
            'visibility': 'public',
            'editable': False,
            'buttons': '',
            'processing_parameters': {},
            'files': [],
            'summary': exp_summary_path,
            'job': None,
            'processing_jobs': exp_p_jobs,
            'errored_jobs': []
        }
        self.assertEqual(obs, exp)

        # returnig to private
        a.visibility = 'private'

        # admin gets buttons
        obs = artifact_summary_get_request(User('*****@*****.**'), 2)
        exp_p_jobs = [[
            'd19f76ee-274e-4c1b-b3a2-a12d73507c55',
            'Pick closed-reference OTUs', 'error', 'generating demux file',
            'Error message'
        ]]
        exp_files = [(3L, '1_seqs.fna (preprocessed fasta)'),
                     (4L, '1_seqs.qual (preprocessed fastq)'),
                     (5L, '1_seqs.demux (preprocessed demux)')]
        exp = {
            'name':
            'Demultiplexed 1',
            'artifact_id':
            2,
            'visibility':
            'private',
            'editable':
            True,
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 2?\')) { '
                        'set_artifact_visibility(\'public\', 2) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '2?\')) { set_artifact_visibility(\'sandbox\', 2) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button> <a class="btn btn-primary '
                        'btn-sm" href="/ebi_submission/2"><span '
                        'class="glyphicon glyphicon-export"></span> '
                        'Submit to EBI</a> <a class="btn btn-primary '
                        'btn-sm" href="/vamps/2"><span class="glyphicon '
                        'glyphicon-export"></span> Submit to VAMPS</a>'),
            'processing_parameters': {
                'max_barcode_errors': 1.5,
                'sequence_max_n': 0,
                'max_bad_run_length': 3,
                'phred_offset': u'auto',
                'rev_comp': False,
                'phred_quality_threshold': 3,
                'input_data': 1,
                'rev_comp_barcode': False,
                'rev_comp_mapping_barcodes': False,
                'min_per_read_length_fraction': 0.75,
                'barcode_type': u'golay_12'
            },
            'files':
            exp_files,
            'summary':
            None,
            'job':
            None,
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': []
        }
        self.assertEqual(obs, exp)

        # analysis artifact
        obs = artifact_summary_get_request(user, 8)
        exp = {
            'name': 'noname',
            'artifact_id': 8,
            'visibility': 'sandbox',
            'editable': True,
            'buttons': '',
            'processing_parameters': {},
            'files': [(27, 'biom_table.biom (biom)')],
            'summary': None,
            'job': None,
            'processing_jobs': [],
            'errored_jobs': []
        }
        self.assertEqual(obs, exp)
Exemple #17
0
def artifact_patch_request(user,
                           artifact_id,
                           req_op,
                           req_path,
                           req_value=None,
                           req_from=None):
    """Modifies an attribute of the artifact

    Parameters
    ----------
    user : qiita_db.user.User
        The user performing the patch operation
    artifact_id : int
        Id of the artifact in which the patch operation is being performed
    req_op : str
        The operation to perform on the artifact
    req_path : str
        The prep information and attribute to patch
    req_value : str, optional
        The value that needs to be modified
    req_from : str, optional
        The original path of the element

    Raises
    ------
    QiitaHTTPError
        If `req_op` != 'replace'
        If the path parameter is incorrect
        If missing req_value
        If the attribute to replace is not known
    """
    if req_op == 'replace':
        req_path = [v for v in req_path.split('/') if v]
        if len(req_path) != 1:
            raise QiitaHTTPError(404, 'Incorrect path parameter')

        attribute = req_path[0]

        # Check if the user actually has access to the artifact
        artifact = Artifact(artifact_id)
        check_artifact_access(user, artifact)

        if not req_value:
            raise QiitaHTTPError(404, 'Missing value to replace')

        if attribute == 'name':
            artifact.name = req_value
            return
        elif attribute == 'visibility':
            if req_value not in get_visibilities():
                raise QiitaHTTPError(
                    400, 'Unknown visibility value: %s' % req_value)
            # Set the approval to private if needs approval and admin
            if req_value == 'private':
                if not qiita_config.require_approval:
                    artifact.visibility = 'private'
                # Set the approval to private if approval not required
                elif user.level == 'admin':
                    artifact.visibility = 'private'
                # Trying to set approval without admin privileges
                else:
                    raise QiitaHTTPError(
                        403, 'User does not have permissions '
                        'to approve change')
            else:
                artifact.visibility = req_value
        else:
            # We don't understand the attribute so return an error
            raise QiitaHTTPError(
                404, 'Attribute "%s" not found. Please, '
                'check the path parameter' % attribute)
    else:
        raise QiitaHTTPError(
            400, 'Operation "%s" not supported. Current '
            'supported operations: replace' % req_op)
Exemple #18
0
    def test_artifact_summary_get_request(self):
        # Artifact w/o summary
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp_p_jobs = [[
            '063e553b-327c-4818-ab4a-adfe58e49860', 'Split libraries FASTQ',
            'queued', None, None
        ],
                      [
                          'bcc7ebcd-39c1-43e4-af2d-822e3589f14d',
                          'Split libraries', 'running', 'demultiplexing', None
                      ]]
        exp_files = [
            (1L, '1_s_G1_L001_sequences.fastq.gz (raw forward seqs)'),
            (2L, '1_s_G1_L001_sequences_barcodes.fastq.gz (raw barcodes)')
        ]
        exp = {
            'status':
            'success',
            'message':
            '',
            'name':
            'Raw data 1',
            'summary':
            None,
            'job':
            None,
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': [],
            'visibility':
            'private',
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 1?\')) { '
                        'set_artifact_visibility(\'public\', 1) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button>'),
            'files':
            exp_files,
            'editable':
            True,
            'prep_id':
            1,
            'study_id':
            1
        }
        self.assertEqual(obs, exp)

        # Artifact with summary being generated
        job = ProcessingJob.create(
            User('*****@*****.**'),
            Parameters.load(Command(7), values_dict={'input_data': 1}))
        job._set_status('queued')
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {
            'status':
            'success',
            'message':
            '',
            'name':
            'Raw data 1',
            'summary':
            None,
            'job': [job.id, 'queued', None],
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': [],
            'visibility':
            'private',
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 1?\')) { '
                        'set_artifact_visibility(\'public\', 1) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button>'),
            'files':
            exp_files,
            'editable':
            True,
            'prep_id':
            1,
            'study_id':
            1
        }
        self.assertEqual(obs, exp)

        # Artifact with summary
        fd, fp = mkstemp(suffix=".html")
        close(fd)
        with open(fp, 'w') as f:
            f.write('<b>HTML TEST - not important</b>\n')
        a = Artifact(1)
        a.html_summary_fp = fp
        self._files_to_remove.extend([fp, a.html_summary_fp[1]])
        exp_files.append(
            (a.html_summary_fp[0],
             '%s (html summary)' % basename(a.html_summary_fp[1])))
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {
            'status':
            'success',
            'message':
            '',
            'name':
            'Raw data 1',
            'summary':
            '<b>HTML TEST - not important</b>\n',
            'job':
            None,
            'processing_jobs':
            exp_p_jobs,
            'errored_jobs': [],
            'visibility':
            'private',
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 1?\')) { '
                        'set_artifact_visibility(\'public\', 1) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button>'),
            'files':
            exp_files,
            'editable':
            True,
            'prep_id':
            1,
            'study_id':
            1
        }
        self.assertEqual(obs, exp)

        # No access
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {
            'status': 'error',
            'message': 'User does not have access to study'
        }
        self.assertEqual(obs, exp)

        # A non-owner/share user can't see the files
        a.visibility = 'public'
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {
            'status': 'success',
            'message': '',
            'name': 'Raw data 1',
            'summary': '<b>HTML TEST - not important</b>\n',
            'job': None,
            'processing_jobs': exp_p_jobs,
            'errored_jobs': [],
            'visibility': 'public',
            'buttons': '',
            'files': [],
            'editable': False,
            'prep_id': 1,
            'study_id': 1
        }
        self.assertEqual(obs, exp)

        # returnig to private
        a.visibility = 'sandbox'

        # admin gets buttons
        obs = artifact_summary_get_request('*****@*****.**', 2)
        exp_p_jobs = [[
            'd19f76ee-274e-4c1b-b3a2-a12d73507c55',
            'Pick closed-reference OTUs', 'error', 'generating demux file',
            'Error message'
        ]]
        exp_files = [(3L, '1_seqs.fna (preprocessed fasta)'),
                     (4L, '1_seqs.qual (preprocessed fastq)'),
                     (5L, '1_seqs.demux (preprocessed demux)')]
        exp = {
            'status':
            'success',
            'files':
            exp_files,
            'errored_jobs': [],
            'editable':
            True,
            'visibility':
            'private',
            'job':
            None,
            'message':
            '',
            'name':
            'Demultiplexed 1',
            'processing_jobs':
            exp_p_jobs,
            'summary':
            None,
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 2?\')) { '
                        'set_artifact_visibility(\'public\', 2) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '2?\')) { set_artifact_visibility(\'sandbox\', 2) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button> <a class="btn btn-primary '
                        'btn-sm" href="/vamps/2"><span class="glyphicon '
                        'glyphicon-export"></span> Submit to VAMPS</a>'),
            'study_id':
            1,
            'prep_id':
            1
        }
        self.assertEqual(obs, exp)
Exemple #19
0
    def test_artifact_summary_get_request(self):
        # Artifact w/o summary
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp_p_jobs = [
            ['063e553b-327c-4818-ab4a-adfe58e49860', 'Split libraries FASTQ',
             'queued', None, None],
            ['bcc7ebcd-39c1-43e4-af2d-822e3589f14d', 'Split libraries',
             'running', 'demultiplexing', None]]
        exp_files = [
            (1L, '1_s_G1_L001_sequences.fastq.gz (raw forward seqs)'),
            (2L, '1_s_G1_L001_sequences_barcodes.fastq.gz (raw barcodes)')]
        exp = {'status': 'success',
               'message': '',
               'name': 'Raw data 1',
               'processing_parameters': {},
               'summary': None,
               'job': None,
               'processing_jobs': exp_p_jobs,
               'errored_jobs': [],
               'visibility': 'private',
               'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                           'want to make public artifact id: 1?\')) { '
                           'set_artifact_visibility(\'public\', 1) }" '
                           'class="btn btn-primary btn-sm">Make public'
                           '</button> <button onclick="if (confirm(\'Are you '
                           'sure you want to revert to sandbox artifact id: '
                           '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                           '}" class="btn btn-primary btn-sm">Revert to '
                           'sandbox</button>'),
               'files': exp_files,
               'editable': True,
               'prep_id': 1,
               'study_id': 1}
        self.assertEqual(obs, exp)

        # Artifact with summary being generated
        job = ProcessingJob.create(
            User('*****@*****.**'),
            Parameters.load(Command(7), values_dict={'input_data': 1})
        )
        job._set_status('queued')
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {'status': 'success',
               'message': '',
               'name': 'Raw data 1',
               'processing_parameters': {},
               'summary': None,
               'job': [job.id, 'queued', None],
               'processing_jobs': exp_p_jobs,
               'errored_jobs': [],
               'visibility': 'private',
               'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                           'want to make public artifact id: 1?\')) { '
                           'set_artifact_visibility(\'public\', 1) }" '
                           'class="btn btn-primary btn-sm">Make public'
                           '</button> <button onclick="if (confirm(\'Are you '
                           'sure you want to revert to sandbox artifact id: '
                           '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                           '}" class="btn btn-primary btn-sm">Revert to '
                           'sandbox</button>'),
               'files': exp_files,
               'editable': True,
               'prep_id': 1,
               'study_id': 1}
        self.assertEqual(obs, exp)

        # Artifact with summary
        fd, fp = mkstemp(suffix=".html")
        close(fd)
        with open(fp, 'w') as f:
            f.write('<b>HTML TEST - not important</b>\n')
        a = Artifact(1)
        a.html_summary_fp = fp
        self._files_to_remove.extend([fp, a.html_summary_fp[1]])
        exp_files.append(
            (a.html_summary_fp[0],
             '%s (html summary)' % basename(a.html_summary_fp[1])))
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {'status': 'success',
               'message': '',
               'name': 'Raw data 1',
               'processing_parameters': {},
               'summary': '<b>HTML TEST - not important</b>\n',
               'job': None,
               'processing_jobs': exp_p_jobs,
               'errored_jobs': [],
               'visibility': 'private',
               'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                           'want to make public artifact id: 1?\')) { '
                           'set_artifact_visibility(\'public\', 1) }" '
                           'class="btn btn-primary btn-sm">Make public'
                           '</button> <button onclick="if (confirm(\'Are you '
                           'sure you want to revert to sandbox artifact id: '
                           '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                           '}" class="btn btn-primary btn-sm">Revert to '
                           'sandbox</button>'),
               'files': exp_files,
               'editable': True,
               'prep_id': 1,
               'study_id': 1}
        self.assertEqual(obs, exp)

        # No access
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {'status': 'error',
               'message': 'User does not have access to study'}
        self.assertEqual(obs, exp)

        # A non-owner/share user can't see the files
        a.visibility = 'public'
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {'status': 'success',
               'message': '',
               'name': 'Raw data 1',
               'processing_parameters': {},
               'summary': '<b>HTML TEST - not important</b>\n',
               'job': None,
               'processing_jobs': exp_p_jobs,
               'errored_jobs': [],
               'visibility': 'public',
               'buttons': '',
               'files': [],
               'editable': False,
               'prep_id': 1,
               'study_id': 1}
        self.assertEqual(obs, exp)

        # returnig to private
        a.visibility = 'sandbox'

        # admin gets buttons
        obs = artifact_summary_get_request('*****@*****.**', 2)
        exp_p_jobs = [
            ['d19f76ee-274e-4c1b-b3a2-a12d73507c55',
             'Pick closed-reference OTUs', 'error', 'generating demux file',
             'Error message']]
        exp_files = [
            (3L, '1_seqs.fna (preprocessed fasta)'),
            (4L, '1_seqs.qual (preprocessed fastq)'),
            (5L, '1_seqs.demux (preprocessed demux)')]
        exp = {'status': 'success',
               'files': exp_files,
               'errored_jobs': [],
               'editable': True,
               'visibility': 'private',
               'job': None,
               'message': '',
               'name': 'Demultiplexed 1',
               'processing_jobs': exp_p_jobs,
               'processing_parameters': {
                   'max_barcode_errors': 1.5, 'sequence_max_n': 0,
                   'max_bad_run_length': 3, 'phred_offset': u'auto',
                   'rev_comp': False, 'phred_quality_threshold': 3,
                   'input_data': 1, 'rev_comp_barcode': False,
                   'rev_comp_mapping_barcodes': False,
                   'min_per_read_length_fraction': 0.75,
                   'barcode_type': u'golay_12'},
               'summary': None,
               'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                           'want to make public artifact id: 2?\')) { '
                           'set_artifact_visibility(\'public\', 2) }" '
                           'class="btn btn-primary btn-sm">Make public'
                           '</button> <button onclick="if (confirm(\'Are you '
                           'sure you want to revert to sandbox artifact id: '
                           '2?\')) { set_artifact_visibility(\'sandbox\', 2) '
                           '}" class="btn btn-primary btn-sm">Revert to '
                           'sandbox</button> <a class="btn btn-primary '
                           'btn-sm" href="/vamps/2"><span class="glyphicon '
                           'glyphicon-export"></span> Submit to VAMPS</a>'),
               'study_id': 1,
               'prep_id': 1}
        self.assertEqual(obs, exp)
Exemple #20
0
    def test_artifact_summary_get_request(self):
        user = User('*****@*****.**')
        main_buttons = (
            '<button onclick="if (confirm('
            "\'Are you sure you want to make "
            "public artifact id: 1?')) { set_artifact_visibility('public', 1) "
            '}" class="btn btn-primary btn-sm">Make public</button> <button '
            'onclick="if (confirm('
            "'Are you sure you want to revert to "
            "sandbox artifact id: 1?')) { set_artifact_visibility('sandbox', 1"
            ') }" class="btn btn-primary btn-sm">Revert to sandbox</button> ')
        private_download_button = (
            '<button class="btn btn-primary btn-sm" type="button" '
            'aria-expanded="false" aria-controls="privateDownloadLink" '
            'onclick="generate_private_download_link(%s)">Generate Download '
            'Link</button><div class="collapse" id="privateDownloadLink"><div '
            'class="card card-body" id="privateDownloadText">Generating '
            'Download Link...</div></div>')
        # Artifact w/o summary
        obs = artifact_summary_get_request(user, 1)
        exp_files = [
            (1, '1_s_G1_L001_sequences.fastq.gz (raw forward seqs)',
             '2125826711', '58 Bytes'),
            (2, '1_s_G1_L001_sequences_barcodes.fastq.gz (raw barcodes)',
             '2125826711', '58 Bytes')
        ]
        exp = {
            'name': 'Raw data 1',
            'artifact_id': 1,
            'artifact_type': 'FASTQ',
            'artifact_timestamp': '2012-10-01 09:10',
            'visibility': 'private',
            'editable': True,
            'buttons': main_buttons + private_download_button % 1,
            'processing_info': {},
            'files': exp_files,
            'is_from_analysis': False,
            'summary': None,
            'job': None,
            'errored_summary_jobs': []
        }
        self.assertEqual(obs, exp)

        # Artifact with summary being generated
        job = ProcessingJob.create(
            User('*****@*****.**'),
            Parameters.load(Command(7), values_dict={'input_data': 1}))
        job._set_status('queued')
        obs = artifact_summary_get_request(user, 1)
        exp = {
            'name': 'Raw data 1',
            'artifact_id': 1,
            'artifact_type': 'FASTQ',
            'artifact_timestamp': '2012-10-01 09:10',
            'visibility': 'private',
            'editable': True,
            'buttons': main_buttons + private_download_button % 1,
            'processing_info': {},
            'files': exp_files,
            'is_from_analysis': False,
            'summary': None,
            'job': [job.id, 'queued', None],
            'errored_summary_jobs': []
        }
        self.assertEqual(obs, exp)

        # Artifact with summary
        fd, fp = mkstemp(suffix=".html")
        close(fd)
        with open(fp, 'w') as f:
            f.write('<b>HTML TEST - not important</b>\n')
        a = Artifact(1)
        a.set_html_summary(fp)
        self._files_to_remove.extend([fp, a.html_summary_fp[1]])
        exp_files.append((a.html_summary_fp[0],
                          '%s (html summary)' % basename(a.html_summary_fp[1]),
                          '1642196267', '33 Bytes'))
        exp_summary_path = relpath(a.html_summary_fp[1],
                                   qiita_config.base_data_dir)
        obs = artifact_summary_get_request(user, 1)
        exp = {
            'name': 'Raw data 1',
            'artifact_id': 1,
            'artifact_type': 'FASTQ',
            'artifact_timestamp': '2012-10-01 09:10',
            'visibility': 'private',
            'editable': True,
            'buttons': main_buttons + private_download_button % 1,
            'processing_info': {},
            'files': exp_files,
            'is_from_analysis': False,
            'summary': exp_summary_path,
            'job': None,
            'errored_summary_jobs': []
        }
        self.assertEqual(obs, exp)

        # No access
        demo_u = User('*****@*****.**')
        with self.assertRaises(QiitaHTTPError):
            obs = artifact_summary_get_request(demo_u, 1)

        # A non-owner/share user can't see the files
        a.visibility = 'public'
        obs = artifact_summary_get_request(demo_u, 1)
        exp = {
            'name': 'Raw data 1',
            'artifact_id': 1,
            'artifact_type': 'FASTQ',
            'artifact_timestamp': '2012-10-01 09:10',
            'visibility': 'public',
            'editable': False,
            'buttons': '',
            'processing_info': {},
            'files': [],
            'is_from_analysis': False,
            'summary': exp_summary_path,
            'job': None,
            'errored_summary_jobs': []
        }
        self.assertEqual(obs, exp)

        # testing sandbox
        a.visibility = 'sandbox'
        obs = artifact_summary_get_request(user, 1)
        exp = {
            'name': 'Raw data 1',
            'artifact_id': 1,
            'artifact_type': 'FASTQ',
            'artifact_timestamp': '2012-10-01 09:10',
            'visibility': 'sandbox',
            'editable': True,
            'buttons': private_download_button % 1,
            'processing_info': {},
            'files': exp_files,
            'is_from_analysis': False,
            'summary': exp_summary_path,
            'job': None,
            'errored_summary_jobs': []
        }
        self.assertEqual(obs, exp)

        # returnig to private
        a.visibility = 'private'

        # admin gets buttons
        obs = artifact_summary_get_request(User('*****@*****.**'), 2)
        exp_files = [(3, '1_seqs.fna (preprocessed fasta)', '', '0 Bytes'),
                     (4, '1_seqs.qual (preprocessed fastq)', '', '0 Bytes'),
                     (5, '1_seqs.demux (preprocessed demux)', '', '0 Bytes')]
        exp = {
            'name':
            'Demultiplexed 1',
            'artifact_id':
            2,
            'artifact_type':
            'Demultiplexed',
            'artifact_timestamp':
            '2012-10-01 10:10',
            'visibility':
            'private',
            'editable':
            True,
            'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                        'want to make public artifact id: 2?\')) { '
                        'set_artifact_visibility(\'public\', 2) }" '
                        'class="btn btn-primary btn-sm">Make public'
                        '</button> <button onclick="if (confirm(\'Are you '
                        'sure you want to revert to sandbox artifact id: '
                        '2?\')) { set_artifact_visibility(\'sandbox\', 2) '
                        '}" class="btn btn-primary btn-sm">Revert to '
                        'sandbox</button> <a class="btn btn-primary '
                        'btn-sm" href="/ebi_submission/2"><span '
                        'class="glyphicon glyphicon-export"></span> '
                        'Submit to EBI</a> <a class="btn btn-primary '
                        'btn-sm" href="/vamps/2"><span class="glyphicon '
                        'glyphicon-export"></span> Submit to VAMPS</a> ' +
                        private_download_button % 2),
            'processing_info': {
                'command_active': True,
                'software_deprecated': False,
                'command': 'Split libraries FASTQ',
                'processing_parameters': {
                    'max_barcode_errors': '1.5',
                    'sequence_max_n': '0',
                    'max_bad_run_length': '3',
                    'phred_offset': 'auto',
                    'rev_comp': 'False',
                    'phred_quality_threshold': '3',
                    'input_data': '1',
                    'rev_comp_barcode': 'False',
                    'rev_comp_mapping_barcodes': 'False',
                    'min_per_read_length_fraction': '0.75',
                    'barcode_type': 'golay_12'
                },
                'software_version': '1.9.1',
                'software': 'QIIME'
            },
            'files':
            exp_files,
            'is_from_analysis':
            False,
            'summary':
            None,
            'job':
            None,
            'errored_summary_jobs': []
        }
        self.assertEqual(obs, exp)

        # analysis artifact
        obs = artifact_summary_get_request(user, 8)
        exp = {
            'name': 'noname',
            'artifact_id': 8,
            'artifact_type': 'BIOM',
            # this value changes on build so copy from obs
            'artifact_timestamp': obs['artifact_timestamp'],
            'visibility': 'sandbox',
            'editable': True,
            'buttons': private_download_button % 8,
            'processing_info': {},
            'files': [(22, 'biom_table.biom (biom)', '1756512010', '1.1 MB')],
            'is_from_analysis': True,
            'summary': None,
            'job': None,
            'errored_summary_jobs': []
        }
        self.assertEqual(obs, exp)
Exemple #21
0
def artifact_patch_request(user,
                           artifact_id,
                           req_op,
                           req_path,
                           req_value=None,
                           req_from=None):
    """Modifies an attribute of the artifact

    Parameters
    ----------
    user : qiita_db.user.User
        The user performing the patch operation
    artifact_id : int
        Id of the artifact in which the patch operation is being performed
    req_op : str
        The operation to perform on the artifact
    req_path : str
        The prep information and attribute to patch
    req_value : str, optional
        The value that needs to be modified
    req_from : str, optional
        The original path of the element

    Raises
    ------
    QiitaHTTPError
        If `req_op` != 'replace'
        If the path parameter is incorrect
        If missing req_value
        If the attribute to replace is not known
    """
    if req_op == 'replace':
        req_path = [v for v in req_path.split('/') if v]
        if len(req_path) != 1:
            raise QiitaHTTPError(404, 'Incorrect path parameter')

        attribute = req_path[0]

        # Check if the user actually has access to the artifact
        artifact = Artifact(artifact_id)
        check_artifact_access(user, artifact)

        if not req_value:
            raise QiitaHTTPError(404, 'Missing value to replace')

        if attribute == 'name':
            artifact.name = req_value
            return
        elif attribute == 'visibility':
            if req_value not in get_visibilities():
                raise QiitaHTTPError(
                    400, 'Unknown visibility value: %s' % req_value)

            if (req_value == 'private' and qiita_config.require_approval
                    and not user.level == 'admin'):
                raise QiitaHTTPError(
                    403, 'User does not have permissions '
                    'to approve change')

            try:
                artifact.visibility = req_value
            except Exception as e:
                raise QiitaHTTPError(403, str(e).replace('\n', '<br/>'))

            sid = artifact.study.id
            if artifact.visibility == 'awaiting_approval':
                email_to = '*****@*****.**'
                subject = ('QIITA: Artifact %s awaiting_approval. Study %d, '
                           'Prep %d' %
                           (artifact_id, sid, artifact.prep_templates[0].id))
                message = ('%s requested approval. <a '
                           'href="https://qiita.ucsd.edu/study/description/'
                           '%d">Study %d</a>.' % (user.email, sid, sid))
                try:
                    send_email(email_to, subject, message)
                except Exception:
                    msg = ("Couldn't send email to admins, please email us "
                           "directly to <a href='mailto:{0}'>{0}</a>.".format(
                               email_to))
                    raise QiitaHTTPError(400, msg)
            else:
                msg = '%s changed artifact %s (study %d) to %s' % (
                    user.email, artifact_id, sid, req_value)
                LogEntry.create('Warning', msg)
        else:
            # We don't understand the attribute so return an error
            raise QiitaHTTPError(
                404, 'Attribute "%s" not found. Please, '
                'check the path parameter' % attribute)
    else:
        raise QiitaHTTPError(
            400, 'Operation "%s" not supported. Current '
            'supported operations: replace' % req_op)
    def test_artifact_summary_get_request(self):
        user = User('*****@*****.**')
        # Artifact w/o summary
        obs = artifact_summary_get_request(user, 1)
        exp_files = [
            (1L, '1_s_G1_L001_sequences.fastq.gz (raw forward seqs)'),
            (2L, '1_s_G1_L001_sequences_barcodes.fastq.gz (raw barcodes)')]
        exp = {'name': 'Raw data 1',
               'artifact_id': 1,
               'artifact_type': 'FASTQ',
               'artifact_timestamp': '2012-10-01 09:10',
               'visibility': 'private',
               'editable': True,
               'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                           'want to make public artifact id: 1?\')) { '
                           'set_artifact_visibility(\'public\', 1) }" '
                           'class="btn btn-primary btn-sm">Make public'
                           '</button> <button onclick="if (confirm(\'Are you '
                           'sure you want to revert to sandbox artifact id: '
                           '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                           '}" class="btn btn-primary btn-sm">Revert to '
                           'sandbox</button>'),
               'processing_info': {},
               'files': exp_files,
               'is_from_analysis': False,
               'summary': None,
               'job': None,
               'errored_summary_jobs': []}
        self.assertEqual(obs, exp)

        # Artifact with summary being generated
        job = ProcessingJob.create(
            User('*****@*****.**'),
            Parameters.load(Command(7), values_dict={'input_data': 1})
        )
        job._set_status('queued')
        obs = artifact_summary_get_request(user, 1)
        exp = {'name': 'Raw data 1',
               'artifact_id': 1,
               'artifact_type': 'FASTQ',
               'artifact_timestamp': '2012-10-01 09:10',
               'visibility': 'private',
               'editable': True,
               'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                           'want to make public artifact id: 1?\')) { '
                           'set_artifact_visibility(\'public\', 1) }" '
                           'class="btn btn-primary btn-sm">Make public'
                           '</button> <button onclick="if (confirm(\'Are you '
                           'sure you want to revert to sandbox artifact id: '
                           '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                           '}" class="btn btn-primary btn-sm">Revert to '
                           'sandbox</button>'),
               'processing_info': {},
               'files': exp_files,
               'is_from_analysis': False,
               'summary': None,
               'job': [job.id, 'queued', None],
               'errored_summary_jobs': []}
        self.assertEqual(obs, exp)

        # Artifact with summary
        fd, fp = mkstemp(suffix=".html")
        close(fd)
        with open(fp, 'w') as f:
            f.write('<b>HTML TEST - not important</b>\n')
        a = Artifact(1)
        a.set_html_summary(fp)
        self._files_to_remove.extend([fp, a.html_summary_fp[1]])
        exp_files.append(
            (a.html_summary_fp[0],
             '%s (html summary)' % basename(a.html_summary_fp[1])))
        exp_summary_path = relpath(
            a.html_summary_fp[1], qiita_config.base_data_dir)
        obs = artifact_summary_get_request(user, 1)
        exp = {'name': 'Raw data 1',
               'artifact_id': 1,
               'artifact_type': 'FASTQ',
               'artifact_timestamp': '2012-10-01 09:10',
               'visibility': 'private',
               'editable': True,
               'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                           'want to make public artifact id: 1?\')) { '
                           'set_artifact_visibility(\'public\', 1) }" '
                           'class="btn btn-primary btn-sm">Make public'
                           '</button> <button onclick="if (confirm(\'Are you '
                           'sure you want to revert to sandbox artifact id: '
                           '1?\')) { set_artifact_visibility(\'sandbox\', 1) '
                           '}" class="btn btn-primary btn-sm">Revert to '
                           'sandbox</button>'),
               'processing_info': {},
               'files': exp_files,
               'is_from_analysis': False,
               'summary': exp_summary_path,
               'job': None,
               'errored_summary_jobs': []}
        self.assertEqual(obs, exp)

        # No access
        demo_u = User('*****@*****.**')
        with self.assertRaises(QiitaHTTPError):
            obs = artifact_summary_get_request(demo_u, 1)

        # A non-owner/share user can't see the files
        a.visibility = 'public'
        obs = artifact_summary_get_request(demo_u, 1)
        exp = {'name': 'Raw data 1',
               'artifact_id': 1,
               'artifact_type': 'FASTQ',
               'artifact_timestamp': '2012-10-01 09:10',
               'visibility': 'public',
               'editable': False,
               'buttons': '',
               'processing_info': {},
               'files': [],
               'is_from_analysis': False,
               'summary': exp_summary_path,
               'job': None,
               'errored_summary_jobs': []}
        self.assertEqual(obs, exp)

        # returnig to private
        a.visibility = 'private'

        # admin gets buttons
        obs = artifact_summary_get_request(User('*****@*****.**'), 2)
        exp_files = [
            (3L, '1_seqs.fna (preprocessed fasta)'),
            (4L, '1_seqs.qual (preprocessed fastq)'),
            (5L, '1_seqs.demux (preprocessed demux)')]
        exp = {'name': 'Demultiplexed 1',
               'artifact_id': 2,
               'artifact_type': 'Demultiplexed',
               'artifact_timestamp': '2012-10-01 10:10',
               'visibility': 'private',
               'editable': True,
               'buttons': ('<button onclick="if (confirm(\'Are you sure you '
                           'want to make public artifact id: 2?\')) { '
                           'set_artifact_visibility(\'public\', 2) }" '
                           'class="btn btn-primary btn-sm">Make public'
                           '</button> <button onclick="if (confirm(\'Are you '
                           'sure you want to revert to sandbox artifact id: '
                           '2?\')) { set_artifact_visibility(\'sandbox\', 2) '
                           '}" class="btn btn-primary btn-sm">Revert to '
                           'sandbox</button> <a class="btn btn-primary '
                           'btn-sm" href="/ebi_submission/2"><span '
                           'class="glyphicon glyphicon-export"></span> '
                           'Submit to EBI</a> <a class="btn btn-primary '
                           'btn-sm" href="/vamps/2"><span class="glyphicon '
                           'glyphicon-export"></span> Submit to VAMPS</a>'),
               'processing_info': {
                    'command': 'Split libraries FASTQ',
                    'software': 'QIIME',
                    'software_version': '1.9.1',
                    'processing_parameters': {
                        'max_barcode_errors': '1.5', 'sequence_max_n': '0',
                        'max_bad_run_length': '3', 'phred_offset': u'auto',
                        'rev_comp': 'False', 'phred_quality_threshold': '3',
                        'input_data': '1', 'rev_comp_barcode': 'False',
                        'rev_comp_mapping_barcodes': 'False',
                        'min_per_read_length_fraction': '0.75',
                        'barcode_type': u'golay_12'}},
               'files': exp_files,
               'is_from_analysis': False,
               'summary': None,
               'job': None,
               'errored_summary_jobs': []}
        self.assertEqual(obs, exp)

        # analysis artifact
        obs = artifact_summary_get_request(user, 8)
        exp = {'name': 'noname',
               'artifact_id': 8,
               'artifact_type': 'BIOM',
               # this value changes on build so copy from obs
               'artifact_timestamp': obs['artifact_timestamp'],
               'visibility': 'sandbox',
               'editable': True,
               'buttons': '',
               'processing_info': {},
               'files': [(27, 'biom_table.biom (biom)')],
               'is_from_analysis': True,
               'summary': None,
               'job': None,
               'errored_summary_jobs': []}
        self.assertEqual(obs, exp)
Exemple #23
0
def artifact_patch_request(user, artifact_id, req_op, req_path, req_value=None,
                           req_from=None):
    """Modifies an attribute of the artifact

    Parameters
    ----------
    user : qiita_db.user.User
        The user performing the patch operation
    artifact_id : int
        Id of the artifact in which the patch operation is being performed
    req_op : str
        The operation to perform on the artifact
    req_path : str
        The prep information and attribute to patch
    req_value : str, optional
        The value that needs to be modified
    req_from : str, optional
        The original path of the element

    Raises
    ------
    QiitaHTTPError
        If `req_op` != 'replace'
        If the path parameter is incorrect
        If missing req_value
        If the attribute to replace is not known
    """
    if req_op == 'replace':
        req_path = [v for v in req_path.split('/') if v]
        if len(req_path) != 1:
            raise QiitaHTTPError(404, 'Incorrect path parameter')

        attribute = req_path[0]

        # Check if the user actually has access to the artifact
        artifact = Artifact(artifact_id)
        check_artifact_access(user, artifact)

        if not req_value:
            raise QiitaHTTPError(404, 'Missing value to replace')

        if attribute == 'name':
            artifact.name = req_value
            return
        elif attribute == 'visibility':
            if req_value not in get_visibilities():
                raise QiitaHTTPError(400, 'Unknown visibility value: %s'
                                          % req_value)

            if (req_value == 'private' and qiita_config.require_approval
                    and not user.level == 'admin'):
                raise QiitaHTTPError(403, 'User does not have permissions '
                                          'to approve change')

            try:
                artifact.visibility = req_value
            except Exception as e:
                raise QiitaHTTPError(403, str(e).replace('\n', '<br/>'))

            if artifact.visibility == 'awaiting_approval':
                email_to = '*****@*****.**'
                sid = artifact.study.id
                subject = ('QIITA: Artifact %s awaiting_approval. Study %d, '
                           'Prep %d' % (artifact_id, sid,
                                        artifact.prep_templates[0].id))
                message = ('%s requested approval. <a '
                           'href="https://qiita.ucsd.edu/study/description/'
                           '%d">Study %d</a>.' % (user.email, sid, sid))
                try:
                    send_email(email_to, subject, message)
                except Exception:
                    msg = ("Couldn't send email to admins, please email us "
                           "directly to <a href='mailto:{0}'>{0}</a>.".format(
                               email_to))
                    raise QiitaHTTPError(400, msg)
        else:
            # We don't understand the attribute so return an error
            raise QiitaHTTPError(404, 'Attribute "%s" not found. Please, '
                                      'check the path parameter' % attribute)
    else:
        raise QiitaHTTPError(400, 'Operation "%s" not supported. Current '
                                  'supported operations: replace' % req_op)
Exemple #24
0
    def test_artifact_summary_get_request(self):
        # Artifact w/o summary
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp_p_jobs = [
            ['063e553b-327c-4818-ab4a-adfe58e49860', 'Split libraries FASTQ',
             'queued', None, None],
            ['bcc7ebcd-39c1-43e4-af2d-822e3589f14d', 'Split libraries',
             'running', 'demultiplexing', None]]
        exp_files = [
            (1L, '1_s_G1_L001_sequences.fastq.gz (raw forward seqs)'),
            (2L, '1_s_G1_L001_sequences_barcodes.fastq.gz (raw barcodes)')]
        exp = {'status': 'success',
               'message': '',
               'name': 'Raw data 1',
               'summary': None,
               'job': None,
               'processing_jobs': exp_p_jobs,
               'errored_jobs': [],
               'visibility': 'private',
               'buttons': '<button onclick="if (confirm(\'Are you sure you '
                          'want to make public artifact id: 1?\')) { '
                          'set_artifact_visibility(\'public\', 1) }" '
                          'class="btn btn-primary btn-sm">Make public</button>'
                          ' <button onclick="if (confirm(\'Are you sure you '
                          'want to revert to sandbox artifact id: 1?\')) '
                          '{ set_artifact_visibility(\'sandbox\', 1) }" '
                          'class="btn btn-primary btn-sm">Revert to '
                          'sandbox</button>',
               'files': exp_files,
               'editable': True}
        self.assertEqual(obs, exp)

        # Artifact with summary being generated
        job = ProcessingJob.create(
            User('*****@*****.**'),
            Parameters.load(Command(7), values_dict={'input_data': 1})
        )
        job._set_status('queued')
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {'status': 'success',
               'message': '',
               'name': 'Raw data 1',
               'summary': None,
               'job': [job.id, 'queued', None],
               'processing_jobs': exp_p_jobs,
               'errored_jobs': [],
               'visibility': 'private',
               'buttons': '<button onclick="if (confirm(\'Are you sure you '
                          'want to make public artifact id: 1?\')) { '
                          'set_artifact_visibility(\'public\', 1) }" '
                          'class="btn btn-primary btn-sm">Make public</button>'
                          ' <button onclick="if (confirm(\'Are you sure you '
                          'want to revert to sandbox artifact id: 1?\')) { '
                          'set_artifact_visibility(\'sandbox\', 1) }" '
                          'class="btn btn-primary btn-sm">Revert to '
                          'sandbox</button>',
               'files': exp_files,
               'editable': True}
        self.assertEqual(obs, exp)

        # Artifact with summary
        fd, fp = mkstemp(suffix=".html")
        close(fd)
        with open(fp, 'w') as f:
            f.write('<b>HTML TEST - not important</b>\n')
        a = Artifact(1)
        a.html_summary_fp = fp
        self._files_to_remove.extend([fp, a.html_summary_fp[1]])
        exp_files.append(
            (a.html_summary_fp[0],
             '%s (html summary)' % basename(a.html_summary_fp[1])))
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {'status': 'success',
               'message': '',
               'name': 'Raw data 1',
               'summary': '<b>HTML TEST - not important</b>\n',
               'job': None,
               'processing_jobs': exp_p_jobs,
               'errored_jobs': [],
               'visibility': 'private',
               'buttons': '<button onclick="if (confirm(\'Are you sure you '
                          'want to make public artifact id: 1?\')) { '
                          'set_artifact_visibility(\'public\', 1) }" '
                          'class="btn btn-primary btn-sm">Make public</button>'
                          ' <button onclick="if (confirm(\'Are you sure you '
                          'want to revert to sandbox artifact id: 1?\')) { '
                          'set_artifact_visibility(\'sandbox\', 1) }" '
                          'class="btn btn-primary btn-sm">Revert to '
                          'sandbox</button>',
               'files': exp_files,
               'editable': True}
        self.assertEqual(obs, exp)

        # No access
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {'status': 'error',
               'message': 'User does not have access to study'}
        self.assertEqual(obs, exp)

        # A non-owner/share user can't see the files
        a.visibility = 'public'
        obs = artifact_summary_get_request('*****@*****.**', 1)
        exp = {'status': 'success',
               'message': '',
               'name': 'Raw data 1',
               'summary': '<b>HTML TEST - not important</b>\n',
               'job': None,
               'processing_jobs': exp_p_jobs,
               'errored_jobs': [],
               'visibility': 'public',
               'buttons': '',
               'files': [],
               'editable': False}
        self.assertEqual(obs, exp)
Exemple #25
0
def artifact_patch_request(user, artifact_id, req_op, req_path, req_value=None,
                           req_from=None):
    """Modifies an attribute of the artifact

    Parameters
    ----------
    user : qiita_db.user.User
        The user performing the patch operation
    artifact_id : int
        Id of the artifact in which the patch operation is being performed
    req_op : str
        The operation to perform on the artifact
    req_path : str
        The prep information and attribute to patch
    req_value : str, optional
        The value that needs to be modified
    req_from : str, optional
        The original path of the element

    Raises
    ------
    QiitaHTTPError
        If `req_op` != 'replace'
        If the path parameter is incorrect
        If missing req_value
        If the attribute to replace is not known
    """
    if req_op == 'replace':
        req_path = [v for v in req_path.split('/') if v]
        if len(req_path) != 1:
            raise QiitaHTTPError(404, 'Incorrect path parameter')

        attribute = req_path[0]

        # Check if the user actually has access to the artifact
        artifact = Artifact(artifact_id)
        check_artifact_access(user, artifact)

        if not req_value:
            raise QiitaHTTPError(404, 'Missing value to replace')

        if attribute == 'name':
            artifact.name = req_value
            return
        elif attribute == 'visibility':
            if req_value not in get_visibilities():
                raise QiitaHTTPError(400, 'Unknown visibility value: %s'
                                          % req_value)
            # Set the approval to private if needs approval and admin
            if req_value == 'private':
                if not qiita_config.require_approval:
                    artifact.visibility = 'private'
                # Set the approval to private if approval not required
                elif user.level == 'admin':
                    artifact.visibility = 'private'
                # Trying to set approval without admin privileges
                else:
                    raise QiitaHTTPError(403, 'User does not have permissions '
                                              'to approve change')
            else:
                artifact.visibility = req_value
        else:
            # We don't understand the attribute so return an error
            raise QiitaHTTPError(404, 'Attribute "%s" not found. Please, '
                                      'check the path parameter' % attribute)
    else:
        raise QiitaHTTPError(400, 'Operation "%s" not supported. Current '
                                  'supported operations: replace' % req_op)