def send(self, message): if time.time() - self.last_auth > self.refresh: self.authenticate() connection = db.connect() cursor = connection.cursor() try: cursor.execute( '''SELECT `destination` FROM `user_contact` WHERE `user_id` = (SELECT `id` FROM `user` WHERE `name` = %s) AND `mode_id` = (SELECT `id` FROM `contact_mode` WHERE `name` = 'rocketchat')''', message['user']) if cursor.rowcount == 0: raise ValueError('Rocketchat username not found for %s' % message['user']) target = cursor.fetchone()[0] finally: cursor.close() connection.close() re = requests.post(self.api_host + '/api/v1/chat.postMessage', json={ 'channel': '@%s' % target, 'text': ' -- '.join( [message['subject'], message['body']]) }, headers={ 'X-User-Id': self.user_id, 'X-Auth-Token': self.token }) if re.status_code != 200 or not re.json()['success']: raise ValueError('Failed to contact rocketchat')
def user_validator(config): subject = config['subject'] body = config['body'] sleep_time = config.get('interval', 86400) while 1: # Sleep first so bouncing notifier doesn't spam sleep(sleep_time) connection = db.connect() cursor = connection.cursor() cursor.execute('''SELECT `user`.`name` FROM `event` LEFT JOIN `user_contact` ON `event`.`user_id` = `user_contact`.`user_id` AND `user_contact`.`mode_id` = (SELECT `id` FROM `contact_mode` WHERE `name` = 'call') JOIN `user` ON `event`.`user_id` = `user`.`id` WHERE `event`.`start` > UNIX_TIMESTAMP() AND `user_contact`.`destination` IS NULL GROUP BY `event`.`user_id`;''') for row in cursor: message = { 'user': row[0], 'mode': 'email', 'subject': subject, 'body': body } messengers.send_message(message) connection.close() cursor.close()
def on_post(req, resp): login_info = uri.parse_query_string(req.context['body']) user = login_info.get('username') password = login_info.get('password') if user is None or password is None: raise HTTPBadRequest('Invalid login attempt', 'Missing user/password') if not auth_manager.authenticate(user, password): raise HTTPUnauthorized('Authentication failure', 'bad login credentials', '') connection = db.connect() cursor = connection.cursor(db.DictCursor) data = get_user_data(None, {'name': user}, dbinfo=(connection, cursor)) if not data: cursor.close() connection.close() raise HTTPNotFound() session = req.env['beaker.session'] session['user'] = user session.save() csrf_token = '%x' % SystemRandom().getrandbits(128) cursor.execute( 'INSERT INTO `session` (`id`, `csrf_token`) VALUES (%s, %s)', (req.env['beaker.session']['_id'], csrf_token)) connection.commit() cursor.close() connection.close() # TODO: purge out of date csrf token data[0]['csrf_token'] = csrf_token resp.body = dumps(data[0])
def main(): config = utils.read_config(sys.argv[1]) db.init(config['db']) cycle_time = config.get('scheduler_cycle_time', 3600) while 1: connection = db.connect() db_cursor = connection.cursor(db.DictCursor) start = time.time() # Iterate through all teams db_cursor.execute('SELECT id, name, scheduling_timezone FROM team WHERE active = TRUE') teams = db_cursor.fetchall() for team in teams: team_id = team['id'] # Get rosters for team db_cursor.execute('SELECT `id`, `name` FROM `roster` WHERE `team_id` = %s', team_id) rosters = db_cursor.fetchall() if db_cursor.rowcount == 0: continue logger.info('scheduling for team: %s', team['name']) events = [] for roster in rosters: roster_id = roster['id'] # Get schedules for each roster schedules = get_schedules({'team_id': team_id, 'roster_id': roster_id}) for schedule in schedules: if schedule['auto_populate_threshold'] <= 0: continue logger.info('\t\tschedule: %s', str(schedule['id'])) schedule['timezone'] = team['scheduling_timezone'] # Calculate events for schedule future_events, last_epoch = calculate_future_events(schedule, db_cursor) role_id = get_role_id(schedule['role'], db_cursor) for epoch in future_events: # Add (start_time, schedule_id, role_id, roster_id, epoch_events) to events events.append((min([ev['start'] for ev in epoch]), schedule['id'], role_id, roster_id, epoch)) set_last_epoch(schedule['id'], last_epoch, db_cursor) # Create events in the db, associating a user to them # Iterate through events in order of start time to properly assign users for event_info in sorted(events, key=lambda x: x[0]): _, schedule_id, role_id, roster_id, epoch = event_info user_id = find_least_active_available_user_id(team_id, role_id, roster_id, epoch, db_cursor) if not user_id: logger.info('Failed to find available user') continue logger.info('Found user: %s', user_id) create_events(team_id, schedule_id, user_id, epoch, role_id, db_cursor) connection.commit() # Sleep until next time sleep_time = cycle_time - (time.time() - start) if sleep_time > 0: logger.info('Sleeping for %s seconds' % sleep_time) time.sleep(cycle_time - (time.time() - start)) else: logger.info('Schedule loop took %s seconds, skipping sleep' % (time.time() - start)) db_cursor.close() connection.close()
def mark_message_as_unsent(msg_info): connection = db.connect() cursor = connection.cursor() cursor.execute( 'UPDATE `notification_queue` SET `active` = 0, `sent` = 0 WHERE `id` = %s', msg_info['id']) connection.commit() connection.close() cursor.close()
def link(self, ids): connection = db.connect() cursor = connection.cursor() link_id = uuid4().hex cursor.execute('UPDATE `event` SET `link_id` = %s WHERE `id` IN %s', (link_id, ids)) connection.commit() cursor.close() connection.close() return link_id
def ldap_auth(self, username, password): if self.cert_path: ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.cert_path) connection = ldap.initialize(self.ldap_url) connection.set_option(ldap.OPT_REFERRALS, 0) attrs = ['dn'] + self.attrs.values() ldap_contacts = {} if not password: return False auth_user = username + self.user_suffix try: if self.bind_user: # use search filter to find DN of username connection.simple_bind_s(self.bind_user, self.bind_password) sfilter = self.search_filter % username result = connection.search_s(self.base_dn, ldap.SCOPE_SUBTREE, sfilter, attrs) if len(result) < 1: return False auth_user = result[0][0] ldap_attrs = result[0][1] for key, val in self.attrs.iteritems(): if ldap_attrs.get(val): if type(ldap_attrs.get(val)) == list: ldap_contacts[key] = ldap_attrs.get(val)[0] else: ldap_contacts[key] = ldap_attrs.get(val) else: ldap_contacts[key] = val connection.simple_bind_s(auth_user, password) except ldap.INVALID_CREDENTIALS: return False except (ldap.SERVER_DOWN, ldap.INVALID_DN_SYNTAX) as err: logger.warn("%s", err) return None if self.import_user: connection = db.connect() cursor = connection.cursor(db.DictCursor) if user_exists(username, cursor): logger.info("user %s already exists, updating from ldap", username) update_user(username, ldap_contacts, cursor) else: logger.info("user %s does not exists. importing.", username) import_user(username, ldap_contacts, cursor) connection.commit() cursor.close() connection.close() return True
def get_audit_log(start, end): connection = db.connect() cursor = connection.cursor() cursor.execute( 'SELECT action_name FROM audit WHERE timestamp BETWEEN %s AND %s', (int(start), int(end) + 1)) ret = {row[0] for row in cursor} cursor.close() connection.close() return ret
def tearDown(self): connection = db.connect() cursor = connection.cursor() cursor.execute("DELETE FROM `team` WHERE `name` = %s", self.team_name) cursor.execute("DELETE FROM `user` WHERE `name` IN %s", ([self.user_name, self.admin_name], )) connection.commit() cursor.close() connection.close()
def get_notifications(usernames, type_name): connection = db.connect() cursor = connection.cursor(db.DictCursor) cursor.execute('''SELECT user.name AS user FROM notification_queue JOIN user ON user_id = user.id JOIN notification_type ON notification_queue.type_id = notification_type.id WHERE user_id IN (SELECT id FROM user WHERE name IN %s) AND notification_type.name = %s''', (usernames, type_name)) ret = cursor.fetchall() cursor.close() connection.close() return ret
def main(): config = utils.read_config(sys.argv[1]) db.init(config['db']) cycle_time = config.get('scheduler_cycle_time', 3600) schedulers = {} while 1: connection = db.connect() db_cursor = connection.cursor(db.DictCursor) start = time.time() # Load all schedulers db_cursor.execute('SELECT name FROM scheduler') schedulers = {} for row in db_cursor: try: scheduler_name = row['name'] if scheduler_name not in schedulers: schedulers[scheduler_name] = load_scheduler(scheduler_name) except (ImportError, AttributeError): logger.exception('Failed to load scheduler %s, skipping', row['name']) # Iterate through all teams db_cursor.execute( 'SELECT id, name, scheduling_timezone FROM team WHERE active = TRUE' ) teams = db_cursor.fetchall() for team in teams: logger.info('scheduling for team: %s', team['name']) schedule_map = defaultdict(list) for schedule in get_schedules({'team_id': team['id']}): schedule_map[schedule['scheduler']['name']].append(schedule) for scheduler_name, schedules in schedule_map.iteritems(): schedulers[scheduler_name].schedule(team, schedules, (connection, db_cursor)) # Sleep until next time sleep_time = cycle_time - (time.time() - start) if sleep_time > 0: logger.info('Sleeping for %s seconds' % sleep_time) time.sleep(cycle_time - (time.time() - start)) else: logger.info('Schedule loop took %s seconds, skipping sleep' % (time.time() - start)) db_cursor.close() connection.close()
def poll(): query = '''SELECT `user`.`name` AS `user`, `contact_mode`.`name` AS `mode`, `notification_queue`.`send_time`, `user`.`time_zone`,`notification_type`.`subject`, `notification_queue`.`context`, `notification_type`.`body`, `notification_queue`.`id` FROM `notification_queue` JOIN `user` ON `notification_queue`.`user_id` = `user`.`id` JOIN `contact_mode` ON `notification_queue`.`mode_id` = `contact_mode`.`id` JOIN `notification_type` ON `notification_queue`.`type_id` = `notification_type`.`id` WHERE `notification_queue`.`active` = 1 AND `notification_queue`.`send_time` <= UNIX_TIMESTAMP()''' logger.info('[-] start send task...') connection = db.connect() cursor = connection.cursor(db.DictCursor) cursor.execute(query) for row in cursor: send_queue.put(row) cursor.close() connection.close()
def setUp(self): super(TestLogin, self).setUp() login.auth_manager = self.DummyAuthenticator() api = falcon.API(middleware=[ ReqBodyMiddleware(), ]) api.req_options.auto_parse_form_urlencoded = False self.api = api self.api.add_route('/login', login) self.api.add_route('/logout', logout) self.api.add_route('/dummy/{user}', self.UserDummy()) self.api.add_route('/dummy2/{team}', self.TeamDummy()) self.api = SessionMiddleware(self.api, self.session_opts) self.user_name = 'test_login_user' self.admin_name = 'test_login_admin' self.team_name = 'test_login_team' connection = db.connect() cursor = connection.cursor() # Create users cursor.execute("INSERT INTO `user` (`name`, `active`) VALUES (%s, 1)", self.user_name) self.user_id = cursor.lastrowid cursor.execute("INSERT INTO `user` (`name`, `active`) VALUES (%s, 1)", self.admin_name) self.admin_id = cursor.lastrowid # Set up team cursor.execute("INSERT INTO `team` (`name`) VALUES (%s)", self.team_name) self.team_id = cursor.lastrowid cursor.execute("INSERT INTO `team_user` VALUES (%s, %s)", (self.team_id, self.user_id)) cursor.execute("INSERT INTO `team_user` VALUES (%s, %s)", (self.team_id, self.admin_id)) cursor.execute("INSERT INTO `team_admin` VALUES (%s, %s)", (self.team_id, self.admin_id)) connection.commit() cursor.close() connection.close()
def sync_action(slack_client): re = slack_client.api_call("users.list") if not re.get('ok'): logger.error('Failed to fetch user list from slack') return slack_members = re['members'] slack_users = {} for m in slack_members: if m['name'] == 'slackbot' or m['deleted']: continue user_profile = m['profile'] slack_users[m['name']] = { 'name': m['name'], 'full_name': user_profile['real_name'], 'photo_url': user_profile['image_512'], 'email': user_profile['email'], } if 'phone' in user_profile: slack_users[m['name']]['phone'] = normalize_phone_number( user_profile['phone']) connection = db.connect() # cache mode ids cursor = connection.cursor() cursor.execute('SELECT `id`, `name` FROM `contact_mode`') mode_ids = {row[1]: row[0] for row in cursor} cursor.close() slack_usernames = set(slack_users.keys()) oncall_usernames = set(fetch_oncall_usernames(connection)) users_to_insert = slack_usernames - oncall_usernames users_to_delete = oncall_usernames - slack_usernames logger.info('users to insert: %s', users_to_insert) logger.info('users to delete: %s', users_to_delete) insert_users(connection, slack_users, users_to_insert, mode_ids) delete_users(connection, users_to_delete) connection.close()
def __init__(self, prefix): self.prefix = prefix self.created = set() self.created_ids = set() self.connection = db.connect() self.cursor = self.connection.cursor()
def reminder(config): interval = config['polling_interval'] default_timezone = config['default_timezone'] connection = db.connect() cursor = connection.cursor() cursor.execute('SELECT `last_window_end` FROM `notifier_state`') if cursor.rowcount != 1: window_start = int(time.time() - interval) logger.warning( 'Corrupted/missing notifier state; unable to determine last window. Guessing %s', window_start) else: window_start = cursor.fetchone()[0] cursor.close() connection.close() query = ''' SELECT `user`.`name`, `user`.`id` AS `user_id`, `time_before`, `contact_mode`.`name` AS `mode`, `team`.`name` AS `team`, `event`.`start`, `event`.`id`, `role`.`name` AS `role`, `user`.`time_zone` FROM `user` JOIN `notification_setting` ON `notification_setting`.`user_id` = `user`.`id` AND `notification_setting`.`type_id` = (SELECT `id` FROM `notification_type` WHERE `name` = %s) JOIN `setting_role` ON `notification_setting`.`id` = `setting_role`.`setting_id` JOIN `event` ON `event`.`start` >= `time_before` + %s AND `event`.`start` < `time_before` + %s AND `event`.`user_id` = `user`.`id` AND `event`.`role_id` = `setting_role`.`role_id` AND `event`.`team_id` = `notification_setting`.`team_id` JOIN `contact_mode` ON `notification_setting`.`mode_id` = `contact_mode`.`id` JOIN `team` ON `event`.`team_id` = `team`.`id` JOIN `role` ON `event`.`role_id` = `role`.`id` LEFT JOIN `event` AS `e` ON `event`.`link_id` = `e`.`link_id` AND `e`.`start` < `event`.`start` WHERE `e`.`id` IS NULL AND `user`.`active` = 1 ''' while (1): logger.info('Reminder polling loop started') window_end = int(time.time()) connection = db.connect() cursor = connection.cursor(db.DictCursor) cursor.execute(query, (constants.ONCALL_REMINDER, window_start, window_end)) notifications = cursor.fetchall() for row in notifications: context = { 'team': row['team'], 'start_time': timestamp_to_human_str( row['start'], row['time_zone'] if row['time_zone'] else default_timezone), 'time_before': sec_to_human_str(row['time_before']), 'role': row['role'] } create_reminder(row['user_id'], row['mode'], row['start'] - row['time_before'], context, 'oncall_reminder', cursor) logger.info('Created reminder with context %s for %s', context, row['name']) cursor.execute('UPDATE `notifier_state` SET `last_window_end` = %s', window_end) connection.commit() logger.info('Created reminders for window [%s, %s), sleeping for %s s', window_start, window_end, interval) window_start = window_end cursor.close() connection.close() sleep(interval)