Beispiel #1
0
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
Beispiel #2
0
    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
Beispiel #3
0
    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')
Beispiel #4
0
    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)
Beispiel #5
0
 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)
Beispiel #6
0
 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)
Beispiel #7
0
    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)
Beispiel #8
0
    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
                    }]
                })
Beispiel #9
0
    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
Beispiel #10
0
    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
Beispiel #11
0
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'))