diff --git a/src/oncall/api/v0/public_ical.py b/src/oncall/api/v0/public_ical.py index 39b2847..c2df899 100644 --- a/src/oncall/api/v0/public_ical.py +++ b/src/oncall/api/v0/public_ical.py @@ -16,18 +16,19 @@ def on_get(req, resp, key): information. Key can be requested at /api/v0/ical_key. """ + roles = req.get_param_as_list('roles') + name_and_type = get_name_and_type_from_key(key) if name_and_type is None: raise HTTPNotFound() name, type = name_and_type start = int(time.time()) + events = [] if type == 'user': - events = get_user_events(name, start) + events = get_user_events(name, start, roles=roles) elif type == 'team': - events = get_team_events(name, start, include_subscribed=True) - else: # should not happen - events = [] + events = get_team_events(name, start, roles=roles, include_subscribed=True) resp.body = ical.events_to_ical(events, name, contact=False) resp.set_header('Content-Type', 'text/calendar') diff --git a/src/oncall/api/v0/roles.py b/src/oncall/api/v0/roles.py index 91e0cee..11dbddb 100644 --- a/src/oncall/api/v0/roles.py +++ b/src/oncall/api/v0/roles.py @@ -31,6 +31,17 @@ constraints = { } +def get_role_ids(cursor, roles): + if not roles: + return [] + + role_query = 'SELECT DISTINCT `id` FROM `role` WHERE `name` IN ({0})'.format( + ','.join(['%s'] * len(roles))) + # we need prepared statements here because roles come from user input + cursor.execute(role_query, roles) + return [row['id'] for row in cursor] + + def on_get(req, resp): """ Role search. diff --git a/src/oncall/api/v0/team_ical.py b/src/oncall/api/v0/team_ical.py index 775906f..3407263 100644 --- a/src/oncall/api/v0/team_ical.py +++ b/src/oncall/api/v0/team_ical.py @@ -3,14 +3,20 @@ import time from . import ical - +from .roles import get_role_ids from ... import db -def get_team_events(team, start, include_subscribed=False): +def get_team_events(team, start, roles=None, include_subscribed=False): connection = db.connect() cursor = connection.cursor(db.DictCursor) + role_condition = '' + role_ids = get_role_ids(cursor, roles) + if role_ids: + role_condition = ' AND `event`.`role_id` IN ({0})'.format( + ','.join(map(str, role_ids))) + team_condition = "`team`.`name` = %s" if include_subscribed: cursor.execute( @@ -40,10 +46,9 @@ def get_team_events(team, start, include_subscribed=False): JOIN `role` ON `event`.`role_id` = `role`.`id` WHERE `event`.`end` > %s AND - ''' + team_condition + ''' + team_condition + role_condition - cursor.execute( - query, (start, team)) + cursor.execute(query, (start, team)) events = cursor.fetchall() cursor.close() @@ -73,10 +78,11 @@ def on_get(req, resp, team): contact = req.get_param_as_bool('contact') if contact is None: contact = True + roles = req.get_param_as_list('roles') include_sub = req.get_param_as_bool('include_subscribed') if include_sub is None: include_sub = True - events = get_team_events(team, start, include_subscribed=include_sub) + events = get_team_events(team, start, roles=roles, include_subscribed=include_sub) resp.body = ical.events_to_ical(events, team, contact) resp.set_header('Content-Type', 'text/calendar') diff --git a/src/oncall/api/v0/user_ical.py b/src/oncall/api/v0/user_ical.py index 51a7fce..5b3762f 100644 --- a/src/oncall/api/v0/user_ical.py +++ b/src/oncall/api/v0/user_ical.py @@ -3,15 +3,21 @@ import time from . import ical +from .roles import get_role_ids from ... import db -def get_user_events(user_name, start): +def get_user_events(user_name, start, roles=None): connection = db.connect() cursor = connection.cursor(db.DictCursor) - cursor.execute( - ''' + role_condition = '' + role_ids = get_role_ids(cursor, roles) + if role_ids: + role_condition = ' AND `event`.`role_id` IN ({0})'.format( + ','.join(map(str, role_ids))) + + query = ''' SELECT `event`.`id`, `team`.`name` AS team, @@ -26,8 +32,9 @@ def get_user_events(user_name, start): WHERE `event`.`end` > %s AND `user`.`name` = %s - ''', - (start, user_name)) + ''' + role_condition + + cursor.execute(query, (start, user_name)) events = cursor.fetchall() cursor.close() @@ -58,7 +65,8 @@ def on_get(req, resp, user_name): contact = req.get_param_as_bool('contact') if contact is None: contact = True + roles = req.get_param_as_list('roles') - events = get_user_events(user_name, start) + events = get_user_events(user_name, start, roles=roles) resp.body = ical.events_to_ical(events, user_name, contact) resp.set_header('Content-Type', 'text/calendar')