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')
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')
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' )
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')
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')
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 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
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')
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')
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')
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')
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 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')
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
def create_meta(user, job_id): """Create a meta information associated to a specific job.""" v1_utils.verify_existence_and_get(job_id, models.JOBS) values = v1_utils.common_values_dict(user) values.update(schemas.meta.post(flask.request.json)) values.update({ 'job_id': job_id }) with flask.g.db_conn.begin(): where_clause = sql.and_( _TABLE.c.name == values['name'], _TABLE.c.job_id == values['job_id']) query = sql.select([_TABLE.c.id]).where(where_clause) if flask.g.db_conn.execute(query).fetchone(): raise dci_exc.DCIConflict('Meta already exists', values['name']) # create the label/value row query = _TABLE.insert().values(**values) flask.g.db_conn.execute(query) result = json.dumps({'meta': values}) return flask.Response(result, 201, headers={'ETag': values['etag']}, content_type='application/json')
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')
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')
def delete_test_from_remoteci(user, r_id, t_id): v1_utils.verify_existence_and_get(r_id, _TABLE) JDC = models.JOIN_REMOTECIS_TESTS where_clause = sql.and_(JDC.c.remoteci_id == r_id, JDC.c.test_id == t_id) query = JDC.delete().where(where_clause) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('Test', t_id) return flask.Response(None, 204, content_type='application/json')
def delete_test_from_jobdefinition(user, jd_id, t_id): v1_utils.verify_existence_and_get(jd_id, _TABLE) JDC = models.JOIN_JOBDEFINITIONS_TESTS where_clause = sql.and_(JDC.c.jobdefinition_id == jd_id, JDC.c.test_id == t_id) query = JDC.delete().where(where_clause) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('Test', t_id) return flask.Response(None, 204, content_type='application/json')
def delete_permission_from_role(user, role_id, permission_id): v1_utils.verify_existence_and_get(role_id, _TABLE) JRP = models.JOIN_ROLES_PERMISSIONS where_clause = sql.and_(JRP.c.role_id == role_id, JRP.c.permission_id == permission_id) query = JRP.delete().where(where_clause) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('Role', role_id) return flask.Response(None, 204, content_type='application/json')
def delete_user_from_remoteci(user, r_id, u_id): v1_utils.verify_existence_and_get(r_id, _TABLE) if str(u_id) != user.id and user.is_not_epm(): raise dci_exc.Unauthorized() JUR = models.JOIN_USER_REMOTECIS where_clause = sql.and_(JUR.c.remoteci_id == r_id, JUR.c.user_id == u_id) query = JUR.delete().where(where_clause) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('User', u_id) return flask.Response(None, 204, content_type='application/json')
def delete_test_from_topic(user, t_id, test_id): if not auth.is_admin(user): v1_utils.verify_team_in_topic(user, t_id) v1_utils.verify_existence_and_get(test_id, models.TESTS) JTT = models.JOIN_TOPICS_TESTS where_clause = sql.and_(JTT.c.topic_id == t_id, JTT.c.test_id == test_id) query = JTT.delete().where(where_clause) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('Test', test_id) return flask.Response(None, 204, content_type='application/json')
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 it's an admin or belongs to the same team if not(auth.is_admin(user) or auth.is_in_team(user, 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) if values.get('status') == "failure": _TEAMS = models.TEAMS where_clause = sql.expression.and_( _TEAMS.c.id == job['team_id'] ) query = (sql.select([_TEAMS]).where(where_clause)) team_info = flask.g.db_conn.execute(query).fetchone() if team_info['notification'] is True: if team_info['email'] is not None: msg = {'event': 'notification', 'email': team_info['email'], 'job_id': str(job['id'])} flask.g.sender.send_json(msg) return flask.Response(None, 204, headers={'ETag': values['etag']}, content_type='application/json')
def delete_meta(job_id, meta_id): """Delete a meta from a specific job.""" meta_retrieved = v1_utils.verify_existence_and_get(meta_id, _TABLE) if meta_retrieved['job_id'] != job_id: raise dci_exc.DCIDeleteConflict( "Meta '%s' is not associated to job '%s'." % (meta_id, job_id)) query = _TABLE.delete().where(_TABLE.c.id == meta_id) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('Meta deletion conflict', meta_id) return flask.Response(None, 204, content_type='application/json')
def delete_permission_by_id(user, permission_id): # get If-Match header if_match_etag = utils.check_and_get_etag(flask.request.headers) v1_utils.verify_existence_and_get(permission_id, _TABLE) values = {'state': 'archived'} where_clause = sql.and_(_TABLE.c.etag == if_match_etag, _TABLE.c.id == permission_id) query = _TABLE.update().where(where_clause).values(**values) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('Permission deletion error', permission_id) return flask.Response(None, 204, content_type='application/json')
def delete_team_from_topic(user, topic_id, team_id): if not auth.is_admin(user): raise auth.UNAUTHORIZED topic_id = v1_utils.verify_existence_and_get(topic_id, _TABLE, get_id=True) team_id = v1_utils.verify_existence_and_get(team_id, models.TEAMS, get_id=True) JTT = models.JOINS_TOPICS_TEAMS where_clause = sql.and_(JTT.c.topic_id == topic_id, JTT.c.team_id == team_id) query = JTT.delete().where(where_clause) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('Topics_teams', team_id) return flask.Response(None, 204, content_type='application/json')
def delete_user_from_remoteci(user, r_id, u_id): remoteci = v1_utils.verify_existence_and_get(r_id, _TABLE) if u_id != user['id'] and \ not user.is_in_team(remoteci['team_id']) and \ user.is_regular_user(): raise auth.UNAUTHORIZED JUR = models.JOIN_USER_REMOTECIS where_clause = sql.and_(JUR.c.remoteci_id == r_id, JUR.c.user_id == u_id) query = JUR.delete().where(where_clause) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('User', u_id) return flask.Response(None, 204, content_type='application/json')
def delete_team_from_topic(user, topic_id, team_id): topic = v1_utils.verify_existence_and_get(topic_id, _TABLE) team_id = v1_utils.verify_existence_and_get(team_id, models.TEAMS, get_id=True) if user.is_not_super_admin() and user.is_not_epm(): raise dci_exc.Unauthorized() JTT = models.JOINS_TOPICS_TEAMS where_clause = sql.and_(JTT.c.topic_id == topic['id'], JTT.c.team_id == team_id) query = JTT.delete().where(where_clause) result = flask.g.db_conn.execute(query) if not result.rowcount: raise dci_exc.DCIConflict('Topics_teams', team_id) return flask.Response(None, 204, content_type='application/json')
def put_current_sequence(user): if user.is_not_super_admin(): raise dci_exc.Unauthorized() # get If-Match header if_match_etag = utils.check_and_get_etag(flask.request.headers) values = flask.request.json check_json_is_valid(counter_schema, values) etag = utils.gen_etag() q_update = models.COUNTER.update().\ where(sql.and_(models.COUNTER.c.name == 'jobs_events', models.COUNTER.c.etag == if_match_etag)).\ values(sequence=values['sequence'], etag=etag) result = flask.g.db_conn.execute(q_update) if not result.rowcount: raise dci_exc.DCIConflict('jobs_events', 'sequence') return flask.Response(None, 204, content_type='application/json')
def create_jobstates(user): created_at, _ = utils.get_dates(user) values = schemas.jobstate.post(flask.request.json) insert_jobstate(user, values, created_at) # Update job status job_id = values.get('job_id') query_update_job = (models.JOBS.update().where( models.JOBS.c.id == job_id).values(status=values.get('status'))) result = flask.g.db_conn.execute(query_update_job) if not result.rowcount: raise dci_exc.DCIConflict('Job', job_id) result = json.dumps({'jobstate': values}) return flask.Response(result, 201, content_type='application/json')