Esempio n. 1
0
def put_topic(user, topic_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    values = schemas.topic.put(flask.request.json)

    if not auth.is_admin(user):
        raise auth.UNAUTHORIZED

    def _verify_team_in_topic(user, topic_id):
        topic_id = v1_utils.verify_existence_and_get(topic_id,
                                                     _TABLE,
                                                     get_id=True)
        # verify user's team in the topic
        v1_utils.verify_team_in_topic(user, topic_id)
        return topic_id

    topic_id = _verify_team_in_topic(user, topic_id)

    if 'next_topic' in values and values['next_topic']:
        _verify_team_in_topic(user, values['next_topic'])

    values['etag'] = utils.gen_etag()
    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.id == topic_id)
    query = _TABLE.update().where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)
    if not result.rowcount:
        raise dci_exc.DCIConflict('Topic', topic_id)

    return flask.Response(None,
                          204,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 2
0
def update_remoteci_keys(user, r_id):
    _CAKEY = dci_config.CONFIG['CA_KEY']
    _CACERT = dci_config.CONFIG['CA_CERT']

    etag = utils.check_and_get_etag(flask.request.headers)
    remoteci = v1_utils.verify_existence_and_get(r_id, _TABLE)

    key, cert = v1_utils.get_key_and_cert_signed(_CAKEY, _CACERT)

    values = {}
    keys = {
        'key': crypto.dump_privatekey(crypto.FILETYPE_PEM,
                                      key).decode('utf-8'),
        'cert': crypto.dump_certificate(crypto.FILETYPE_PEM,
                                        cert).decode('utf-8')
    }
    where_clause = sql.and_(_TABLE.c.etag == etag,
                            _TABLE.c.state != 'archived',
                            _TABLE.c.id == remoteci['id'])

    values['etag'] = utils.gen_etag()
    values['cert_fp'] = re.sub(':', '',
                               cert.digest('sha1').decode('utf-8')).lower()

    query = (_TABLE.update().where(where_clause).values(**values))

    flask.g.db_conn.execute(query)

    return flask.Response(json.dumps({'keys': keys}),
                          201,
                          content_type='application/json')
Esempio n. 3
0
def put_feeder(user, f_id):
    if_match_etag = utils.check_and_get_etag(flask.request.headers)
    values = flask.request.json
    check_json_is_valid(update_feeder_schema, values)
    feeder = v1_utils.verify_existence_and_get(f_id, _TABLE)

    if not user.is_in_team(feeder['team_id']):
        raise dci_exc.Unauthorized()

    values['etag'] = utils.gen_etag()
    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.state != 'archived', _TABLE.c.id == f_id)

    query = (_TABLE.update().returning(
        *_TABLE.columns).where(where_clause).values(**values))

    result = flask.g.db_conn.execute(query)
    if not result.rowcount:
        raise dci_exc.DCIConflict('Feeder', f_id)

    _result = dict(result.fetchone())
    del _result['api_secret']

    return flask.Response(json.dumps({'feeder': _result}),
                          200,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 4
0
def put_user(user, user_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)
    values = schemas.user.put(flask.request.json)

    # to update a user the caller must be either the admin of its team
    # or a super admin
    puser = dict(_verify_existence_and_get_user(user_id))
    if puser['id'] != str(user_id) and not user.is_in_team(puser['team_id']):
        raise auth.UNAUTHORIZED

    # if the caller wants to update the team_id then it must be done by a super
    # admin
    if 'team_id' in values and not user.is_super_admin() and \
       not user.is_team_product_owner(values['team_id']):
        raise auth.UNAUTHORIZED

    values['etag'] = utils.gen_etag()

    if 'password' in values:
        values['password'] = auth.hash_password(values.get('password'))

    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.id == user_id)
    query = _TABLE.update().where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)

    if not result.rowcount:
        raise dci_exc.DCIConflict('User', user_id)

    return flask.Response(None,
                          204,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 5
0
def put_user(user, user_id):
    values = flask.request.json
    check_json_is_valid(update_user_schema, values)
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    # to update a user the caller must be a super admin
    if user.is_not_super_admin():
        raise dci_exc.Unauthorized()

    values['etag'] = utils.gen_etag()

    if 'password' in values:
        values['password'] = auth.hash_password(values.get('password'))

    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.id == user_id)
    query = _TABLE.update().returning(*_TABLE.columns).\
        where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)
    if not result.rowcount:
        raise dci_exc.DCIConflict('User', user_id)

    _result = dict(result.fetchone())
    del _result['password']

    return flask.Response(json.dumps({'user': _result}),
                          200,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 6
0
def test_get_results_by_job_id(user, job_user_id):
    with mock.patch(SWIFT, spec=Swift) as mock_swift:
        mockito = mock.MagicMock()
        head_result = {
            'etag': utils.gen_etag(),
            'content-type': "stream",
            'content-length': 1
        }

        def get(a):
            return [True, six.StringIO(JUNIT)]

        mockito.head.return_value = head_result
        mockito.get = get
        mock_swift.return_value = mockito
        headers = {
            'DCI-JOB-ID': job_user_id,
            'Content-Type': 'application/junit',
            'DCI-MIME': 'application/junit',
            'DCI-NAME': 'res_junit.xml'
        }

        user.post('/api/v1/files', headers=headers, data=JUNIT)

        # get file from job
        file_from_job = user.get('/api/v1/jobs/%s/results' % job_user_id)
        assert file_from_job.status_code == 200
        assert file_from_job.data['_meta']['count'] == 1
        assert file_from_job.data['results'][0]['total'] == 6
Esempio n. 7
0
def test_components_export_control_true(user, epm, team_user_id,
                                        topic_user_id, components_user_ids):
    topic = epm.get('/api/v1/topics/%s' % topic_user_id).data['topic']
    res = epm.post('/api/v1/products/%s/teams' % topic['product_id'],
                   data={'team_id': team_user_id})
    assert res.status_code == 201
    epm.put('/api/v1/topics/%s' % topic_user_id,
            data={'export_control': True},
            headers={'If-match': topic['etag']})
    topic = epm.get('/api/v1/topics/%s' % topic_user_id).data['topic']
    assert topic['export_control'] is True

    with mock.patch(SWIFT, spec=Swift) as mock_swift:

        mockito = mock.MagicMock()
        mockito.get.return_value = ["test", six.StringIO("lollollel")]
        head_result = {
            'etag': utils.gen_etag(),
            'content-type': "stream",
            'content-length': 1
        }
        mockito.head.return_value = head_result
        mock_swift.return_value = mockito

        url = '/api/v1/components/%s/files' % components_user_ids[0]
        c_file = epm.post(url, data='lol')
        c_file_1_id = c_file.data['component_file']['id']
        # team_user_id is not subscribing to topic_user_id but it's
        # associated to the product thus it can access the topic's components
        assert user.get('/api/v1/components/%s' % components_user_ids[0]).status_code == 200  # noqa
        assert user.get('/api/v1/components/%s/files' % components_user_ids[0]).status_code == 200  # noqa
        assert user.get('/api/v1/components/%s/files/%s' % (components_user_ids[0], c_file_1_id)).status_code == 200  # noqa
        assert user.get('/api/v1/components/%s/files/%s/content' % (components_user_ids[0], c_file_1_id)).status_code == 200  # noqa
Esempio n. 8
0
def put_team(user, t_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    values = schemas.team.put(flask.request.json)

    if not (auth.is_admin(user) or auth.is_admin_user(user, t_id)):
        raise auth.UNAUTHORIZED

    v1_utils.verify_existence_and_get(t_id, _TABLE)

    values['etag'] = utils.gen_etag()
    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.id == t_id)
    query = _TABLE.update().where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)

    if not result.rowcount:
        raise dci_exc.DCIConflict('Team', t_id)

    return flask.Response(None,
                          204,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 9
0
def _validate_input(values, user):
    topic_id = values.pop('topic_id')
    remoteci_id = values.get('remoteci_id')

    values.update({
        'id': utils.gen_uuid(),
        'created_at': datetime.datetime.utcnow().isoformat(),
        'updated_at': datetime.datetime.utcnow().isoformat(),
        'etag': utils.gen_etag(),
        'status': 'new'
    })

    remoteci = v1_utils.verify_existence_and_get(remoteci_id, models.REMOTECIS)
    v1_utils.verify_existence_and_get(topic_id, models.TOPICS)

    # let's kill existing running jobs for the remoteci
    where_clause = sql.expression.and_(
        _TABLE.c.remoteci_id == remoteci_id,
        _TABLE.c.status.in_(('new', 'pre-run', 'running', 'post-run'))
    )
    kill_query = _TABLE .update().where(where_clause).values(status='killed')
    flask.g.db_conn.execute(kill_query)

    if remoteci['state'] != 'active':
        message = 'RemoteCI "%s" is disabled.' % remoteci_id
        raise dci_exc.DCIException(message, status_code=412)

    # The user belongs to the topic then we can start the scheduling
    v1_utils.verify_team_in_topic(user, topic_id)
    return topic_id, remoteci
Esempio n. 10
0
def put_meta(job_id, meta_id):
    """Modify a meta."""

    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    values = schemas.meta.put(flask.request.json)

    meta_retrieved = v1_utils.verify_existence_and_get(meta_id, _TABLE)

    if meta_retrieved['job_id'] != job_id:
        raise dci_exc.DCIException(
            "Meta '%s' is not associated to job '%s'." % (meta_id, job_id))

    values['etag'] = utils.gen_etag()
    where_clause = sql.and_(
        _TABLE.c.etag == if_match_etag,
        _TABLE.c.id == meta_id
    )
    query = _TABLE.update().where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)

    if not result.rowcount:
        raise dci_exc.DCIConflict('Meta', meta_id)

    return flask.Response(None, 204, headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 11
0
def put_remoteci(user, r_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    values = schemas.remoteci.put(flask.request.json)

    remoteci = v1_utils.verify_existence_and_get(r_id, _TABLE)

    if not user.is_in_team(remoteci['team_id']):
        raise auth.UNAUTHORIZED

    values['etag'] = utils.gen_etag()
    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.state != 'archived',
                            _TABLE.c.id == r_id)

    query = (_TABLE
             .update()
             .where(where_clause)
             .values(**values))

    result = flask.g.db_conn.execute(query)

    if not result.rowcount:
        raise dci_exc.DCIConflict('RemoteCI', r_id)

    return flask.Response(None, 204, headers={'ETag': values['etag']},
                          content_type='application/json')
def test_download_file_from_component(admin, topic_id):
    with mock.patch(SWIFT, spec=Swift) as mock_swift:

        mockito = mock.MagicMock()

        mockito.get.return_value = ["test", "lol lol lel".split(" ")]
        mockito.get_object.return_value = "lollollel"
        head_result = {
            'etag': utils.gen_etag(),
            'content-type': "stream",
            'content-length': 3
        }
        mockito.head.return_value = head_result

        mock_swift.return_value = mockito

        data = {'name': "pname1", 'title': 'aaa',
                'type': 'gerrit_review',
                'topic_id': topic_id,
                'export_control': True}
        ct_1 = admin.post('/api/v1/components', data=data).data['component']

        url = '/api/v1/components/%s/files' % ct_1['id']
        data = "lol"
        c_file = admin.post(url, data=data).data['component_file']

        url = '/api/v1/components/%s/files/%s/content' % (ct_1['id'],
                                                          c_file['id'])
        d_file = admin.get(url)
        assert d_file.status_code == 200
        assert d_file.data == "lollollel"
def test_files(m_datetime, admin, user_sso_rh_employee, app, engine,
               jobstate_user_id, job_user_id):
    user_sso = user_sso_rh_employee
    m_utcnow = mock.MagicMock()
    m_utcnow.utctimetuple.return_value = datetime.datetime. \
        fromtimestamp(1518653629).timetuple()
    m_datetime.utcnow.return_value = m_utcnow
    with app.app_context():
        flask.g.db_conn = engine.connect()
        # get all files
        files = user_sso.get('/api/v1/jobs/%s/files' % job_user_id)
        assert files.status_code == 200
        # get file content
        with mock.patch(SWIFT, spec=Swift) as mock_swift:

            mockito = mock.MagicMock()

            head_result = {
                'etag': utils.gen_etag(),
                'content-type': "stream",
                'content-length': 7
            }

            mockito.head.return_value = head_result
            mockito.get.return_value = [
                head_result, six.StringIO("azertyuiop1234567890")]
            mock_swift.return_value = mockito
            content = "azertyuiop1234567890"
            file_id = t_utils.post_file(admin, jobstate_user_id,
                                        FileDesc('foo', content))

            get_file = user_sso.get('/api/v1/files/%s' % file_id)

            assert get_file.status_code == 200
Esempio n. 14
0
def update_product(user, product_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)
    values = flask.request.json
    check_json_is_valid(update_product_schema, values)

    if user.is_not_super_admin():
        raise dci_exc.Unauthorized()

    v1_utils.verify_existence_and_get(product_id, _TABLE)

    values['etag'] = utils.gen_etag()
    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.id == product_id)
    query = _TABLE.update().returning(*_TABLE.columns).\
        where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)
    if not result.rowcount:
        raise dci_exc.DCIConflict('Product update error', product_id)

    return flask.Response(json.dumps({'product': result.fetchone()}),
                          200,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 15
0
def test_delete_job_archive_dependencies(admin, job_user_id):
    with mock.patch(SWIFT, spec=Swift) as mock_swift:

        mockito = mock.MagicMock()

        head_result = {
            'etag': utils.gen_etag(),
            'content-type': "stream",
            'content-length': 7
        }

        mockito.head.return_value = head_result
        mock_swift.return_value = mockito

        headers = {
            'DCI-JOB-ID': job_user_id,
            'DCI-NAME': 'afile.txt',
            'Content-Type': 'text/plain'
        }

        file = admin.post('/api/v1/files', headers=headers, data='content')
        assert file.status_code == 201

        url = '/api/v1/jobs/%s' % job_user_id
        job = admin.get(url)
        etag = job.data['job']['etag']
        assert job.status_code == 200

        deleted_job = admin.delete(url, headers={'If-match': etag})
        assert deleted_job.status_code == 204

        url = '/api/v1/files/%s' % file.data['file']['id']
        file = admin.get(url)
        assert file.status_code == 404
Esempio n. 16
0
def put_topic(user, topic_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)
    values = schemas.topic.put(flask.request.json)
    topic = v1_utils.verify_existence_and_get(topic_id, _TABLE)

    if not user.is_super_admin() and \
       not ((user.is_product_owner() or user.is_feeder()) and
            user.product_id == topic['product_id']):
        raise auth.UNAUTHORIZED

    n_topic = None
    if 'next_topic' in values and values['next_topic']:
        n_topic = v1_utils.verify_existence_and_get(values['next_topic'],
                                                    _TABLE)

    if user.is_product_owner() and \
       (user.product_id != topic['product_id'] or
       (n_topic and user.product_id != n_topic['product_id'])):
            raise auth.UNAUTHORIZED

    values['etag'] = utils.gen_etag()
    where_clause = sql.and_(
        _TABLE.c.etag == if_match_etag,
        _TABLE.c.id == topic_id
    )
    query = _TABLE.update().where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)
    if not result.rowcount:
        raise dci_exc.DCIConflict('Topic', topic_id)

    return flask.Response(None, 204, headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 17
0
def test_create_file_for_job_id(user, remoteci_context, components_user_ids,
                                topic_user_id):
    with mock.patch(SWIFT, spec=Swift) as mock_swift:

        mockito = mock.MagicMock()
        head_result = {
            'etag': utils.gen_etag(),
            'content-type': "stream",
            'content-length': 7
        }
        mockito.head.return_value = head_result
        mock_swift.return_value = mockito
        # create a job
        job = remoteci_context.post('/api/v1/jobs',
                                    data={
                                        'components': components_user_ids,
                                        'topic_id': topic_user_id
                                    })
        job_id = job.data['job']['id']
        assert job.status_code == 201

        # create a file
        headers = {'DCI-JOB-ID': job_id, 'DCI-NAME': 'foobar'}
        file = user.post('/api/v1/files', headers=headers)
        file_id = file.data['file']['id']
        file = user.get('/api/v1/files/%s' % file_id).data
        assert file['file']['name'] == 'foobar'
Esempio n. 18
0
def put_current_user(user):
    if_match_etag = utils.check_and_get_etag(flask.request.headers)
    values = schemas.current_user.put(flask.request.json)

    current_password = values['current_password']
    encrypted_password = user['password']
    if not auth.check_passwords_equal(current_password, encrypted_password):
        raise dci_exc.DCIException('current_password invalid')

    new_password = values.get('new_password')
    if new_password:
        encrypted_password = auth.hash_password(new_password)

    etag = utils.gen_etag()

    query = _TABLE.update().where(
        sql.and_(_TABLE.c.etag == if_match_etag,
                 _TABLE.c.id == user['id'])).values({
                     'etag':
                     etag,
                     'fullname':
                     values.get('fullname') or user['fullname'],
                     'email':
                     values.get('email') or user['email'],
                     'timezone':
                     values.get('timezone') or user['timezone'],
                     'password':
                     encrypted_password,
                 })

    flask.g.db_conn.execute(query)
    return flask.Response(None,
                          204,
                          headers={'ETag': etag},
                          content_type='application/json')
Esempio n. 19
0
def update_job_by_id(user, job_id):
    """Update a job
    """
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    # get the diverse parameters
    values = schemas.job.put(flask.request.json)

    job = v1_utils.verify_existence_and_get(job_id, _TABLE)

    if not user.is_in_team(job['team_id']):
        raise auth.UNAUTHORIZED

    # Update jobstate if needed
    status = values.get('status')
    if status and job.status != status:
        jobstates.insert_jobstate(user, {
            'status': status,
            'job_id': job_id
        })

    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.id == job_id)

    values['etag'] = utils.gen_etag()
    query = _TABLE.update().where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)

    if not result.rowcount:
        raise dci_exc.DCIConflict('Job', job_id)

    return flask.Response(None, 204, headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 20
0
def test_get_jobstates_by_job_id_with_embed(admin, job_user_id,
                                            jobstate_user_id):  # noqa
    with mock.patch(SWIFT, spec=Swift) as mock_swift:
        mockito = mock.MagicMock()

        head_result = {
            'etag': utils.gen_etag(),
            'content-type': "stream",
            'content-length': 7
        }

        mockito.head.return_value = head_result
        mock_swift.return_value = mockito
        headers = {'DCI-JOBSTATE-ID': jobstate_user_id, 'DCI-NAME': 'name1'}
        pfile = admin.post('/api/v1/files', headers=headers,
                           data='kikoolol').data
        file1_id = pfile['file']['id']
        headers = {'DCI-JOBSTATE-ID': jobstate_user_id, 'DCI-NAME': 'name2'}
        pfile = admin.post('/api/v1/files', headers=headers,
                           data='kikoolol').data
        file2_id = pfile['file']['id']
        jobstates = admin.get('/api/v1/jobs/%s/jobstates'
                              '?embed=files&sort=files.name' %
                              job_user_id)  # noqa
        jobstate = jobstates.data['jobstates'][0]
        assert jobstate['files'][0]['id'] == file1_id
        assert jobstate['files'][1]['id'] == file2_id

        jobstates = admin.get('/api/v1/jobs/%s/jobstates'
                              '?embed=files&sort=-files.name' %
                              job_user_id)  # noqa
        jobstate = jobstates.data['jobstates'][0]
        assert jobstate['files'][0]['id'] == file2_id
        assert jobstate['files'][1]['id'] == file1_id
Esempio n. 21
0
def test_delete_file_from_component(admin, topic_id):
    with mock.patch(SWIFT, spec=Swift) as mock_swift:

        mockito = mock.MagicMock()

        head_result = {
            'etag': utils.gen_etag(),
            'content-type': "stream",
            'content-length': 1
        }

        mockito.head.return_value = head_result
        mock_swift.return_value = mockito

        data = {'name': "pname1", 'title': 'aaa',
                'type': 'gerrit_review',
                'topic_id': topic_id,
                'export_control': True}
        ct_1 = admin.post('/api/v1/components', data=data).data['component']

        url = '/api/v1/components/%s/files' % ct_1['id']
        data = "lol"
        c_file = admin.post(url, data=data).data['component_file']
        url = '/api/v1/components/%s/files' % ct_1['id']
        g_file = admin.get(url)
        assert g_file.data['_meta']['count'] == 1

        url = '/api/v1/components/%s/files/%s' % (ct_1['id'], c_file['id'])
        d_file = admin.delete(url)
        assert d_file.status_code == 204

        url = '/api/v1/components/%s/files' % ct_1['id']
        g_file = admin.get(url)
        assert g_file.data['_meta']['count'] == 0
Esempio n. 22
0
def add_tag_to_job(user, job_id):
    """Add a tag to a job."""

    job = v1_utils.verify_existence_and_get(job_id, _TABLE)
    if user.is_not_in_team(job['team_id']) and user.is_not_epm():
        raise dci_exc.Unauthorized()

    values = {'job_id': job_id}

    with flask.g.db_conn.begin():
        job_tagged = tags.add_tag_to_resource(values, models.JOIN_JOBS_TAGS)
        # update the job tag field
        job_values = {}
        job_values['etag'] = utils.gen_etag()
        tag_name = flask.request.json.get('name')
        tag_name = [tag_name] if tag_name else []
        job_values['tag'] = job['tag'] + tag_name
        query = _TABLE.update().where(_TABLE.c.id == job_id).values(
            **job_values)

        result = flask.g.db_conn.execute(query)
        if not result.rowcount:
            raise dci_exc.DCIConflict('Job', job_id)

    return flask.Response(json.dumps(job_tagged),
                          201,
                          content_type='application/json')
Esempio n. 23
0
def put_api_secret(user, r_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    remoteci = v1_utils.verify_existence_and_get(r_id, _TABLE)

    if not (auth.is_admin(user) or auth.is_in_team(user, remoteci['team_id'])):
        raise auth.UNAUTHORIZED

    where_clause = sql.and_(
        _TABLE.c.etag == if_match_etag,
        _TABLE.c.id == r_id,
    )
    values = {'api_secret': signature.gen_secret(), 'etag': utils.gen_etag()}

    query = (_TABLE.update().where(where_clause).values(**values))

    result = flask.g.db_conn.execute(query)

    if not result.rowcount:
        raise dci_exc.DCIConflict('RemoteCI', r_id)

    res = flask.jsonify(({
        'id': r_id,
        'etag': values['etag'],
        'api_secret': values['api_secret']
    }))
    res.headers.add_header('ETag', values['etag'])
    return res
Esempio n. 24
0
def delete_tag_from_job(user, job_id, tag_id):
    """Delete a tag from a job."""

    _JJT = models.JOIN_JOBS_TAGS
    job = v1_utils.verify_existence_and_get(job_id, _TABLE)
    if user.is_not_in_team(job['team_id']) and user.is_not_epm():
        raise dci_exc.Unauthorized()
    tag = v1_utils.verify_existence_and_get(tag_id, models.TAGS)
    tag_name = tag['name']

    with flask.g.db_conn.begin():
        query = _JJT.delete().where(
            sql.and_(_JJT.c.tag_id == tag_id, _JJT.c.job_id == job_id))
        try:
            flask.g.db_conn.execute(query)
        except sa_exc.IntegrityError:
            raise dci_exc.DCICreationConflict('tag', 'tag_id')
            # update the job tag field
        job_values = {}
        job_values['etag'] = utils.gen_etag()
        tag_name = [tag_name] if tag_name else []
        job_values['tag'] = list(set(job['tag']) - set(tag_name))
        query = _TABLE.update().where(_TABLE.c.id == job_id).values(
            **job_values)

        result = flask.g.db_conn.execute(query)
        if not result.rowcount:
            raise dci_exc.DCIConflict('Job', job_id)

    return flask.Response(None, 204, content_type='application/json')
Esempio n. 25
0
def put_user(user, user_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)
    values = schemas.user.put(flask.request.json)

    puser = dict(_verify_existence_and_get_user(user_id))

    if puser['id'] != str(user_id):
        if not (auth.is_admin(user)
                or auth.is_admin_user(user, puser['team_id'])):
            raise auth.UNAUTHORIZED

    # TODO(yassine): if the user wants to change the team, then check its done
    # by a super admin. ie. team_name='admin'

    values['etag'] = utils.gen_etag()

    if 'password' in values:
        values['password'] = auth.hash_password(values.get('password'))

    where_clause = sql.and_(_TABLE.c.etag == if_match_etag,
                            _TABLE.c.id == user_id)
    query = _TABLE.update().where(where_clause).values(**values)

    result = flask.g.db_conn.execute(query)

    if not result.rowcount:
        raise dci_exc.DCIConflict('User', user_id)

    return flask.Response(None,
                          204,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 26
0
def refresh_api_secret(user, resource, table):
    """Refresh the resource API Secret. """

    resource_name = table.name[0:-1]

    where_clause = sql.and_(
        table.c.etag == resource['etag'],
        table.c.id == resource['id'],
    )

    values = {
        'api_secret': signature.gen_secret(),
        'etag': utils.gen_etag()
    }

    query = table.update().where(where_clause).values(**values)
    result = flask.g.db_conn.execute(query)

    if not result.rowcount:
        raise dci_exc.DCIConflict(resource_name, resource['id'])

    res = flask.jsonify(({'id': resource['id'], 'etag': resource['etag'],
                          'api_secret': values['api_secret']}))
    res.headers.add_header('ETag', values['etag'])
    return res
Esempio n. 27
0
def update_components(user, c_id):
    component = v1_utils.verify_existence_and_get(c_id, _TABLE)
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    topic = v1_utils.verify_existence_and_get(component['topic_id'],
                                              models.TOPICS)
    export_control.verify_access_to_topic(user, topic)

    values = flask.request.json
    check_json_is_valid(update_component_schema, values)
    values['etag'] = utils.gen_etag()

    where_clause = sql.and_(
        _TABLE.c.etag == if_match_etag,
        _TABLE.c.id == c_id
    )

    query = _TABLE.update().returning(*_TABLE.columns).where(where_clause).\
        values(**values)

    result = flask.g.db_conn.execute(query)
    if not result.rowcount:
        raise dci_exc.DCIConflict('Component', c_id)

    return flask.Response(
        json.dumps({'component': result.fetchone()}), 200,
        headers={'ETag': values['etag']}, content_type='application/json'
    )
Esempio n. 28
0
def create_new_upgrade_job_from_an_existing_job(user):
    """Create a new job in the 'next topic' of the topic of
    the provided job_id."""
    values = flask.request.json
    check_json_is_valid(upgrade_job_schema, values)

    values.update({
        'id': utils.gen_uuid(),
        'created_at': get_utc_now().isoformat(),
        'updated_at': get_utc_now().isoformat(),
        'etag': utils.gen_etag(),
        'status': 'new'
    })

    original_job_id = values.pop('job_id')
    original_job = v1_utils.verify_existence_and_get(original_job_id,
                                                     models.JOBS)
    if user.is_not_in_team(original_job['team_id']) and user.is_not_epm():
        raise dci_exc.Unauthorized()

    # get the remoteci
    remoteci_id = str(original_job['remoteci_id'])
    remoteci = v1_utils.verify_existence_and_get(remoteci_id, models.REMOTECIS)
    values.update({'remoteci_id': remoteci_id})

    # get the associated topic
    topic_id = str(original_job['topic_id'])
    topic = v1_utils.verify_existence_and_get(topic_id, models.TOPICS)

    values.update({
        'user_agent':
        flask.request.environ.get('HTTP_USER_AGENT'),
        'client_version':
        flask.request.environ.get('HTTP_CLIENT_VERSION'),
    })

    next_topic_id = topic['next_topic_id']

    if not next_topic_id:
        raise dci_exc.DCIException("topic %s does not contains a next topic" %
                                   topic_id)
    topic = v1_utils.verify_existence_and_get(next_topic_id, models.TOPICS)
    product_id = topic['product_id']

    # instantiate a new job in the next_topic_id
    # todo(yassine): make possible the upgrade to choose specific components
    values = _build_job(product_id,
                        next_topic_id,
                        remoteci, [],
                        values,
                        previous_job_id=original_job_id)

    return flask.Response(json.dumps({'job': values}),
                          201,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Esempio n. 29
0
def create_files(user):
    file_info = get_file_info_from_headers(dict(flask.request.headers))
    values = dict.fromkeys(
        ['md5', 'mime', 'jobstate_id', 'job_id', 'name', 'test_id'])
    values.update(file_info)

    if values.get('jobstate_id') is None and values.get('job_id') is None:
        raise dci_exc.DCIException('HTTP headers DCI-JOBSTATE-ID or '
                                   'DCI-JOB-ID must be specified')
    if values.get('name') is None:
        raise dci_exc.DCIException('HTTP header DCI-NAME must be specified')

    if values.get('jobstate_id') and values.get('job_id') is None:
        jobstate = v1_utils.verify_existence_and_get(values.get('jobstate_id'),
                                                     models.JOBSTATES)
        values['job_id'] = jobstate['job_id']

    job = v1_utils.verify_existence_and_get(values.get('job_id'), models.JOBS)
    if (user.is_not_in_team(job['team_id']) and user.is_read_only_user()
            and user.is_not_epm()):
        raise dci_exc.Unauthorized()

    file_id = utils.gen_uuid()
    file_path = files_utils.build_file_path(job['team_id'], values['job_id'],
                                            file_id)

    content = files_utils.get_stream_or_content_from_request(flask.request)
    store = dci_config.get_store('files')
    store.upload(file_path, content)
    s_file = store.head(file_path)

    etag = utils.gen_etag()
    values.update({
        'id': file_id,
        'created_at': datetime.datetime.utcnow().isoformat(),
        'updated_at': datetime.datetime.utcnow().isoformat(),
        'team_id': job['team_id'],
        'md5': None,
        'size': s_file['content-length'],
        'state': 'active',
        'etag': etag,
    })

    with flask.g.db_conn.begin():
        q_insert_file = _TABLE.insert().values(**values)
        flask.g.db_conn.execute(q_insert_file)
        result = json.dumps({'file': values})

        if values['mime'] == 'application/junit':
            _, junit_file = store.get(file_path)
            _process_junit_file(values, junit_file, job)

    return flask.Response(result, 201, content_type='application/json')
Esempio n. 30
0
def test_add_file_to_component(admin, topic_id):
    with mock.patch(SWIFT, spec=Swift) as mock_swift:

        mockito = mock.MagicMock()

        head_result = {
            'etag': utils.gen_etag(),
            'content-type': "stream",
            'content-length': 1
        }

        mockito.head.return_value = head_result
        mock_swift.return_value = mockito

        def create_ct(name):
            data = {'name': name, 'title': 'aaa',
                    'type': 'gerrit_review',
                    'topic_id': topic_id,
                    'export_control': True}
            return admin.post(
                '/api/v1/components',
                data=data).data['component']

        ct_1 = create_ct('pname1')
        ct_2 = create_ct('pname2')

        cts = admin.get(
            '/api/v1/components/%s?embed=files' % ct_1['id']).data
        assert len(cts['component']['files']) == 0

        url = '/api/v1/components/%s/files' % ct_1['id']
        c_file = admin.post(url, data='lol')
        c_file_1_id = c_file.data['component_file']['id']
        url = '/api/v1/components/%s/files' % ct_2['id']
        c_file = admin.post(url, data='lol2')
        c_file_2_id = c_file.data['component_file']['id']

        assert c_file.status_code == 201
        l_file = admin.get(url)
        assert l_file.status_code == 200
        assert l_file.data['_meta']['count'] == 1
        assert l_file.data['component_files'][0]['component_id'] == ct_2['id']
        cts = admin.get(
            '/api/v1/components/%s?embed=files' % ct_1['id']).data
        assert len(cts['component']['files']) == 1
        assert cts['component']['files'][0]['size'] == 1

        cts = admin.get('/api/v1/components/%s/files' % ct_1['id']).data
        assert cts['component_files'][0]['id'] == c_file_1_id

        cts = admin.get('/api/v1/components/%s/files' % ct_2['id']).data
        assert cts['component_files'][0]['id'] == c_file_2_id