def validate_auth(role): """ Check if admin / supervisor credentials are valid :param role: a list of authorized roles :returns: admin database entry or None if validation failed """ auth_token = request.headers.get('JanuaAuthToken') if auth_token: data = deserialize_token(auth_token) if not data: return None admin = jdb.admin.get_by_id(data['id']) if not admin: return None if get_role(admin) not in role: return None if admin.web_auth_token == data['token']: return admin auth = request.authorization if auth: username = auth.username password = auth.password admin = authenticate_admin(username, password) if not admin: return None if get_role(admin) in role: return admin return None
def get_admin_month_stats(self, admin): """ Get SMS month statistics usage for an admin :param admin: admin object :returns: a list containing dictionary with month/value keys representing number of SMS sent corresponding month """ data = [] if get_role(admin) == 'admin': admin_filter = '' else: admin_filter = 'AND admin_id = %s' % admin.id res = self.db.engine.execute(""" SELECT strftime('%m', date_time) as yr_mon, TOTAL(number_of_slices) as sms FROM SMS WHERE status <= 2 AND strftime('%Y', date_time) = '{0}' {1} GROUP BY yr_mon ORDER BY yr_mon""".format((datetime.datetime.now().year), admin_filter)) last_month = 0 for month_id in xrange(1, 13): data.append({'month': calendar.month_abbr[month_id], 'value': 0}) for row in res.fetchall(): month_id = int(row[0]) data[month_id - 1]['value'] = int(row[1]) return data
def del_admin(self): admins = jdb.admin.get_all() if len(admins) == 1: return console_success('No supervisor in database') print 'Select an admin to delete:' idx = 0 for admin in admins: if get_role(admin) == 'supervisor': print '%d. %s %s' % (idx, admin.firstname, admin.name) idx += 1 admin_id = prompt('Enter a number (or ENTER to quit)') if admin_id.isdigit(): response = prompt('Are you sure ? (type \'yes\')') if response == 'yes': admin_id = int(admin_id) admin = admins[admin_id] entry = '%s %s' % (admin.firstname, admin.name) if jdb.del_entry(admin) == False: return console_error('failed to delete entry %s' % entry) else: return console_success('entry %s has been deleted' % entry) else: return console_success('operation has been canceled') else: return console_success('operation has been canceled')
def get_single_preprocessor(admin, instance_id=None, **kw): """Accepts a single argument, `instance_id`, the primary key of the instance of the model to get. """ if get_role(admin) != 'admin': if instance_id and int(instance_id) not in get_action_ids(admin): raise ProcessingException(description='', code=404)
def web(self): admin = jdb.admin.get_by_phone(self.phone_number) data = {'success': True, 'params': [], 'num_params': 0} reached, numsms = jdb.sms.is_admin_quota_reached(admin) quota = admin.sms_quota data = {'sent': int(numsms), 'quota': quota} if get_role(admin) == 'admin': data.update({'global': int(jdb.sms.month_usage())}) return jsonify(smsusage=data)
def web(self): admin = jdb.admin.get_by_phone(self.phone_number) authorized_actions = [] filtered = False if get_role(admin) == 'supervisor': filtered = True actions = jdb.action.get_by_authorized_supervisor_id(admin.id) authorized_actions = [action.name for action in actions] jsonactions = get_custom_action_repr('web', filtered, authorized_actions) return jsonify(**jsonactions)
def patch_single_preprocessor(admin, instance_id=None, data=None, **kw): """Accepts two arguments, `instance_id`, the primary key of the instance of the model to patch, and `data`, the dictionary of fields to change on the instance. """ if get_role(admin) == 'admin': if 'admin_id' not in data: raise ProcessingException(description='', code=400) else: keys = [key for key in data] for key in keys: if key != 'admin_id': data.pop(key, None) else: raise ProcessingException(description='', code=405)
def get_many_preprocessor(admin, search_params=None, **kw): """Accepts a single argument, `search_params`, which is a dictionary containing the search parameters for the request. """ if get_role(admin) != 'admin': if 'filters' in search_params: search_params['filters'].append({ u'name': u'admin_id', u'op': u'eq', u'val': admin.id }) else: search_params.update({ 'filters': [{ u'name': u'admin_id', u'op': u'eq', u'val': admin.id }] })
def authorized(self, sms): action = sms['action'] phone_number = sms['address'] admin = jdb.admin.get_by_phone(phone_number) log.debug('Check sender authorization') if not action.keyword: if action.get_id() == 0: log.debug('Config action triggered by %s' % phone_number) if admin: sms['admin'] = admin log.debug('Supervisor authorized to trigger config action') return True log.info('Phone number %s asked for sms config' % phone_number) return False log.debug('Custom action %s triggered by %s' % (action.get_name(), phone_number)) dbactions = jdb.action.get_all() dbactions_id = [ act.janua_id for act in dbactions if act.enabled == True and act.authentication == True ] if action.get_id() not in dbactions_id: log.debug('Action id unknown') return False if admin: sms['admin'] = admin if get_role(admin) == 'supervisor': authorized_actions = jdb.action.get_by_authorized_supervisor_id( admin.id) if authorized_actions: log.debug('Supervisor authorized to trigger action') return True log.debug('Supervisor not authorized to trigger action') else: log.debug('Super admin authorized to trigger action') return True elif action.keyword: log.debug('Custom keyword action %s triggered by %s' % (action.keyword, phone_number)) if admin: sms['admin'] = admin if action.filtered == False: log.debug('Non filtered action') return True if get_role(admin) == 'admin': log.debug('Super admin authorized to trigger action') return True authorized_actions = jdb.action.get_by_authorized_supervisor_id( admin.id) if action.get_id() in [ dbaction.janua_id for dbaction in authorized_actions ]: log.debug('Supervisor authorized to trigger action') return True db_action = jdb.action.get_by_janua_id(action.get_id()) if not db_action: log.debug('Action keyword not in database') return False if not action.filtered: contact = jdb.contact.get_by_phone(phone_number) if contact: sms['contact'] = contact log.debug('Action not filtered') return True contacts = jdb.contact.get_by_action_id(db_action.id) try: contact = filter(lambda x: x.phone_number == phone_number, contacts)[0] except (IndexError, ValueError): log.debug('Contact is not authorized to trigger action') return False if contact: sms['contact'] = contact log.debug('Contact is authorized to trigger action') return True return False
def process_notify(self): """ Process notify message pool """ phone_numbers = set() mail_to = set() flags = NotifyFlags for notify_args in self.notify.pool: notify_flags, arg = notify_args db_action = jdb.action.get_by_janua_id(self.get_id()) if self.running_context == 'sms': if not db_action and self.get_id() > 0: return 'No action corresponding to janua_id %d was found in database' % self.get_id( ) if notify_flags & flags.sender: log.debug('Notify sender') phone_numbers.add(self.phone_number) if self.email: mail_to.add(self.email) elif (notify_flags & flags.manager) and db_action: log.debug('Notify manager') entry = jdb.admin.get_by_id(db_action.admin_id) phone_numbers.add(entry.phone_number) mail_to.add(entry.email) elif notify_flags & flags.admin: log.debug('Notify admin') entry = jdb.admin.get_super_admin() phone_numbers.add(entry.phone_number) mail_to.add(entry.email) elif notify_flags & flags.supervisors: log.debug('Notify supervisors') for entry in jdb.admin.get_all(): if get_role(entry) == 'supervisor': phone_numbers.add(entry.phone_number) mail_to.add(entry.email) elif (notify_flags & flags.contacts) and db_action: log.debug('Notify contacts') contacts = jdb.contact.get_by_action_id(db_action.id) try: contact = filter( lambda x: x.phone_number == self.phone_number, contacts)[0] except (IndexError, ValueError): return 'No contact associated with %s' % self.phone_number group_ids = [ group.id for group in jdb.group.get_by_contact_id(contact.id) ] contact_ids = [ cn.contact_id for cn in jdb.contact_notify.get_by_action_id(db_action.id) if cn.group_id in group_ids ] for contact_id in contact_ids: if contact_id != contact.id: contact_notify = jdb.contact.get_by_id(contact_id) phone_numbers.add(contact_notify.phone_number) mail_to.add(contact_notify.email) if notify_flags & flags.sms: message = arg data = None if message: data = message log.info('Action notify: %s' % message) if message: success, message = self.send_sms(data, ','.join(phone_numbers), False) if not success: return message else: return 'SMS message is empty' if notify_flags & flags.mail: if isinstance(arg, MailObj): return 'Mail notify argument is not a MailObj instance' kwargs = { 'subject': arg.subject, 'message': arg.message, 'to': ','.join(mail_to), 'template': arg.template, 'template_args': arg.template_args, 'filtered': False } success, message = self.send_email(**kwargs) if not success: return message
def login(): """ Get an authentication session Sample request to authenticate: .. code-block:: javascript POST /login HTTP/1.1 Host: janua.mydomain.com Content-Type: application/json { "username": "******", "password": "******", "language": "EN", } Sample response: .. code-block:: javascript HTTP/1.1 200 { "success": true, "message": "Successful authentication", "JanuaAuthToken": "abcdef123456789", } """ if not request.json: return make_response(json_error('Request format is not json')) if 'username' not in request.json: return make_response(json_error('Username is missing')) if 'password' not in request.json: return make_response(json_error('Password is missing')) if 'language' not in request.json: return make_response(json_error('Language is missing')) username = request.json['username'] password = request.json['password'] language = request.json['language'] admin = authenticate_admin(username, password) if admin: admin_token = serialize_token(admin.id, token_serializer) if not admin_token: return make_response(json_error('Failed to generate token')) session_lifetime = timedelta(hours=config.web.session_lifetime) expire = datetime.utcnow() + session_lifetime response = make_response( json_success('Authentication ok', JanuaAuthToken=admin_token)) response.set_cookie('role', get_role(admin), expires=expire) response.set_cookie('admin_id', str(admin.id), expires=expire) response.set_cookie('auth_token', admin_token, expires=expire) return response return make_response(json_error('Authentication failure'))