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')
Beispiel #2
0
def get_jobs_events_from_sequence(user, sequence):
    """Get all the jobs events from a given sequence number."""

    args = check_and_get_args(flask.request.args.to_dict())

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

    query = sql.select([models.JOBS_EVENTS]). \
        select_from(models.JOBS_EVENTS.join(models.JOBS,
                    models.JOBS.c.id == models.JOBS_EVENTS.c.job_id)). \
        where(_TABLE.c.id >= sequence)
    sort_list = v1_utils.sort_query(args['sort'], _JOBS_EVENTS_COLUMNS,
                                    default='created_at')
    query = v1_utils.add_sort_to_query(query, sort_list)

    if args.get('limit', None):
        query = query.limit(args.get('limit'))
    if args.get('offset', None):
        query = query.offset(args.get('offset'))

    rows = flask.g.db_conn.execute(query).fetchall()

    query_nb_rows = sql.select([func.count(models.JOBS_EVENTS.c.id)])
    nb_rows = flask.g.db_conn.execute(query_nb_rows).scalar()

    return json.jsonify({'jobs_events': rows, '_meta': {'count': nb_rows}})
Beispiel #3
0
def delete_team_by_id(user, t_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)
    v1_utils.verify_existence_and_get(t_id, _TABLE)

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

    with flask.g.db_conn.begin():
        values = {'state': 'archived'}
        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.DCIDeleteConflict('Team', t_id)

        for model in [models.FILES, models.REMOTECIS,
                      models.USERS, models.JOBS]:
            query = model.update().where(model.c.team_id == t_id).values(
                **values
            )
            flask.g.db_conn.execute(query)

    return flask.Response(None, 204, content_type='application/json')
Beispiel #4
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')
Beispiel #5
0
def create_feeders(user):
    values = flask.request.json
    check_json_is_valid(create_feeder_schema, values)
    values.update(v1_utils.common_values_dict())

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

    values.update({
        # XXX(fc): this should be populated as a default value from the
        # model, but we don't return values from the database :(
        'api_secret': signature.gen_secret(),
        'data': values.get('data', {}),
    })

    query = _TABLE.insert().values(**values)

    try:
        flask.g.db_conn.execute(query)
    except sa_exc.IntegrityError:
        raise dci_exc.DCICreationConflict(_TABLE.name, 'name')

    return flask.Response(json.dumps({'feeder': values}),
                          201,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Beispiel #6
0
def put_api_secret_feeder(user, f_id):
    utils.check_and_get_etag(flask.request.headers)
    feeder = v1_utils.verify_existence_and_get(f_id, _TABLE)
    if not user.is_in_team(feeder['team_id']):
        raise dci_exc.Unauthorized()

    return base.refresh_api_secret(user, feeder, _TABLE)
Beispiel #7
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')
Beispiel #8
0
def create_topics(user):
    values = flask.request.json
    check_json_is_valid(create_topic_schema, values)
    values.update(v1_utils.common_values_dict())

    if user.is_not_super_admin() and user.is_not_epm() and user.is_not_feeder(
    ):  # noqa
        raise dci_exc.Unauthorized()

    # todo(yassine): enabled when client updated.
    # if values['component_types'] == []:
    #     raise dci_exc.DCIException('component_types should not be void')

    query = _TABLE.insert().values(**values)

    try:
        flask.g.db_conn.execute(query)
    except sa_exc.IntegrityError:
        raise dci_exc.DCICreationConflict(_TABLE.name, 'name')

    result = json.dumps({'topic': values})
    return flask.Response(result,
                          201,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Beispiel #9
0
def create_users(user):
    values = flask.request.json
    check_json_is_valid(create_user_schema, values)
    values.update(v1_utils.common_values_dict())

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

    values.update({
        'password': auth.hash_password(values.get('password')),
        'fullname': values.get('fullname', values['name']),
        'timezone': values.get('timezone', 'UTC'),
        'sso_username': None
    })

    query = _TABLE.insert().values(**values)

    try:
        flask.g.db_conn.execute(query)
    except sa_exc.IntegrityError:
        raise dci_exc.DCICreationConflict(_TABLE.name, 'name')

    # remove the password in the result for security reasons
    del values['password']

    return flask.Response(json.dumps({'user': values}),
                          201,
                          headers={'ETag': values['etag']},
                          content_type='application/json')
Beispiel #10
0
def delete_job_by_id(user, j_id):
    # get If-Match header
    if_match_etag = utils.check_and_get_etag(flask.request.headers)

    job = v1_utils.verify_existence_and_get(j_id, _TABLE)

    if ((user.is_not_in_team(job['team_id']) or user.is_read_only_user())
            and user.is_not_epm()):
        raise dci_exc.Unauthorized()

    with flask.g.db_conn.begin():
        values = {'state': 'archived'}
        where_clause = sql.and_(_TABLE.c.id == j_id,
                                _TABLE.c.etag == if_match_etag)
        query = _TABLE.update().where(where_clause).values(**values)

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

        if not result.rowcount:
            raise dci_exc.DCIDeleteConflict('Job', j_id)

        for model in [models.FILES]:
            query = model.update().where(model.c.job_id == j_id).values(
                **values)
            flask.g.db_conn.execute(query)

    return flask.Response(None, 204, content_type='application/json')
Beispiel #11
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')
Beispiel #12
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')
def upload_component_file(user, c_id):
    COMPONENT_FILES = models.COMPONENT_FILES

    component = v1_utils.verify_existence_and_get(c_id, _TABLE)
    if str(component['topic_id']) not in v1_utils.user_topic_ids(user):
        raise dci_exc.Unauthorized()

    store = dci_config.get_store('components')

    file_id = utils.gen_uuid()
    file_path = files_utils.build_file_path(component['topic_id'],
                                            c_id,
                                            file_id)
    content = files_utils.get_stream_or_content_from_request(flask.request)
    store.upload(file_path, content)
    s_file = store.head(file_path)

    values = dict.fromkeys(['md5', 'mime', 'component_id', 'name'])

    values.update({
        'id': file_id,
        'component_id': c_id,
        'name': file_id,
        'created_at': datetime.datetime.utcnow().isoformat(),
        'md5': s_file['etag'],
        'mime': s_file['content-type'],
        'size': s_file['content-length']
    })

    query = COMPONENT_FILES.insert().values(**values)

    flask.g.db_conn.execute(query)
    result = json.dumps({'component_file': values})
    return flask.Response(result, 201, content_type='application/json')
def verify_access_to_topic(user, topic):
    """Verify that the user can access to a topic, raise an unauthorized
       exception if not."""
    if (user.is_not_super_admin() and user.is_not_read_only_user()
            and user.is_not_epm() and user.is_not_feeder()
            and not has_access_to_topic(user, topic)):
        raise dci_exc.Unauthorized()
def add_user_to_team(user, team_id, user_id):
    if (team_id == flask.g.team_admin_id or team_id == flask.g.team_redhat_id
            or team_id == flask.g.team_epm_id) and user.is_not_super_admin():
        raise dci_exc.Unauthorized()

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

    query = models.JOIN_USERS_TEAMS.insert().values(user_id=user_id,
                                                    team_id=team_id)

    try:
        flask.g.db_conn.execute(query)
    except sa_exc.IntegrityError as e:
        raise dci_exc.DCIException('Adding user to team failed: %s' % str(e))

    return flask.Response(None, 201, content_type='application/json')
Beispiel #16
0
def put_api_secret(user, r_id):
    utils.check_and_get_etag(flask.request.headers)
    remoteci = v1_utils.verify_existence_and_get(r_id, _TABLE)

    if user.is_not_in_team(remoteci['team_id']) and user.is_not_epm():
        raise dci_exc.Unauthorized()

    return base.refresh_api_secret(user, remoteci, _TABLE)
Beispiel #17
0
def purge_jobs_events_from_sequence(user, sequence):
    if user.is_not_super_admin():
        raise dci_exc.Unauthorized()
    query = _TABLE.delete(). \
        where(_TABLE.c.id >= sequence)
    flask.g.db_conn.execute(query)

    return flask.Response(None, 204, content_type='application/json')
Beispiel #18
0
def verify_team_in_topic(user, topic_id):
    """Verify that the user's team does belongs to the given topic. If
    the user is an admin or read only user then it belongs to all topics.
    """
    if user.is_super_admin() or user.is_read_only_user() or user.is_epm():
        return
    if str(topic_id) not in user_topic_ids(user):
        raise dci_exc.Unauthorized()
Beispiel #19
0
def user_by_id(user, user_id):
    if user.id != user_id and user.is_not_super_admin() and user.is_not_epm():
        raise dci_exc.Unauthorized()
    user_res = v1_utils.verify_existence_and_get(user_id, _TABLE)
    return base.get_resource_by_id(user,
                                   user_res,
                                   _TABLE,
                                   _EMBED_MANY,
                                   ignore_columns=['password'])
Beispiel #20
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')
Beispiel #21
0
def get_file_content(user, file_id):
    file = get_file_object(file_id)
    if (user.is_not_in_team(file['team_id']) and user.is_not_read_only_user()
            and user.is_not_epm()):
        raise dci_exc.Unauthorized()
    file_descriptor = get_file_descriptor(file)
    return flask.send_file(file_descriptor,
                           mimetype=file['mime'] or 'text/plain',
                           as_attachment=True,
                           attachment_filename=file['name'].replace(' ', '_'))
Beispiel #22
0
def get_subscribed_remotecis(identity, user_id):
    if (identity.is_not_super_admin() and identity.id != str(user_id)
            and identity.is_not_epm()):
        raise dci_exc.Unauthorized()
    remotecis = flask.g.db_conn.execute(
        sql.select([models.REMOTECIS]).select_from(
            models.JOIN_USER_REMOTECIS.join(models.REMOTECIS)).where(
                models.JOIN_USER_REMOTECIS.c.user_id == identity.id))
    return flask.Response(json.dumps({"remotecis": remotecis}),
                          200,
                          content_type="application/json")
Beispiel #23
0
def purge_archived_resources(user, table):
    """Remove the entries to be purged from the database. """

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

    where_clause = sql.and_(table.c.state == 'archived')
    query = table.delete().where(where_clause)
    flask.g.db_conn.execute(query)

    return flask.Response(None, 204, content_type='application/json')
def remove_user_from_team(user, team_id, user_id):

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

    _JUTR = models.JOIN_USERS_TEAMS
    query = _JUTR.delete().where(
        sql.and_(_JUTR.c.user_id == user_id, _JUTR.c.team_id == team_id))
    flask.g.db_conn.execute(query)

    return flask.Response(None, 204, content_type='application/json')
Beispiel #25
0
def get_topic_by_id(user, topic_id):
    args = check_and_get_args(flask.request.args.to_dict())
    topic = v1_utils.verify_existence_and_get(topic_id, _TABLE)

    if user.is_not_super_admin() and user.is_not_epm() and user.is_not_feeder(
    ):  # noqa
        if not user.is_read_only_user():
            v1_utils.verify_team_in_topic(user, topic_id)
        if 'teams' in args['embed']:
            raise dci_exc.Unauthorized()

    return base.get_resource_by_id(user, topic, _TABLE, _EMBED_MANY)
Beispiel #26
0
def verify_team_in_product(user, product_id):
    """Verify that the user's team is associated to the given product. If
    the user is an admin, read only user or epm then it belongs to all topics.
    """
    if user.is_super_admin() or user.is_read_only_user() or user.is_epm():
        return
    query = sql.select([models.JOIN_PRODUCTS_TEAMS]).where(
        sql.and_(models.JOIN_PRODUCTS_TEAMS.c.product_id == product_id,
                 models.JOIN_PRODUCTS_TEAMS.c.team_id.in_(user.teams_ids)))
    res = flask.g.db_conn.execute(query).fetchone()
    if not res:
        raise dci_exc.Unauthorized()
Beispiel #27
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')
Beispiel #28
0
def get_all_teams_from_topic(user, topic_id):
    topic = v1_utils.verify_existence_and_get(topic_id, _TABLE)

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

    # Get all teams which belongs to a given topic
    JTT = models.JOINS_TOPICS_TEAMS
    query = (sql.select([models.TEAMS]).select_from(JTT.join(
        models.TEAMS)).where(JTT.c.topic_id == topic['id']))
    rows = flask.g.db_conn.execute(query)

    return flask.jsonify({'teams': rows, '_meta': {'count': rows.rowcount}})
Beispiel #29
0
def get_file_testscases(user, file_id):
    file = get_file_object(file_id)
    if (user.is_not_in_team(file['team_id']) and user.is_not_read_only_user()
            and user.is_not_epm()):
        raise dci_exc.Unauthorized()
    file_descriptor = get_file_descriptor(file)
    jsonunit = tsfm.junit2dict(file_descriptor)
    job = v1_utils.verify_existence_and_get(file['job_id'], models.JOBS)
    previous_jsonunit = _get_previous_jsonunit(job, file['name'])
    jsonunit = _compute_regressions_successfix(jsonunit, previous_jsonunit)
    return flask.Response(json.dumps({"testscases": jsonunit["testscases"]}),
                          200,
                          content_type='application/json')
Beispiel #30
0
def get_tags_from_job(user, job_id):
    """Retrieve all tags attached 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_read_only_user()
            and user.is_not_epm()):
        raise dci_exc.Unauthorized()

    JTT = models.JOIN_JOBS_TAGS
    query = (sql.select([models.TAGS]).select_from(JTT.join(
        models.TAGS)).where(JTT.c.job_id == job_id))
    rows = flask.g.db_conn.execute(query)

    return flask.jsonify({'tags': rows, '_meta': {'count': rows.rowcount}})