Beispiel #1
0
def sign_up():
    if current_user.role != current_user.SYSTEM_ADMIN:
        abort(403)
    if request.method == 'GET':
        return render_template('users/sign-up.html', hide_loc_nav=True)
    else:
        ar = AccountRequest()
        ar.organization_name = request.form['orgName']
        ar.email_address = request.form['email_address']
        ar.creation_timestamp = datetime.datetime.utcnow()
        ar.email_sent = True
        ar.email_failed = False
        ar.access_code = make_code(30)
        ar.attributes = '{}'
        sys_name = current_app.config['SYSTEM_NAME']
        subject = '%s account request' % sys_name
        message_body = '''Follow this link to create an account on %s:
%screate-account/%s

(If you did not request an account, you can ignore this email.)
''' % (sys_name, request.url_root, ar.access_code)
        try:
            send_email(ar.email_address, subject, message_body,
                       current_app.config)
        except:
            return Response('Error sending email.')
        db.session.add(ar)
        db.session.commit()
        return render_template('users/account-request-complete.html',
                               hide_loc_nav=True)
    def post(self, org_id):
        args = request.values

        # check that user is an org admin or system admin
        if current_user.role != current_user.SYSTEM_ADMIN:
            try:
                current_org_user = (
                    OrganizationUser.query
                    .filter(OrganizationUser.organization_id == org_id, OrganizationUser.user_id == current_user.id)
                    .one()
                )
                if not current_org_user.is_admin:
                    abort(403)
                current_org_user = None
            except NoResultFound:
                abort(403)

        # case 1: inviting a new user by email
        if 'email_address' in args:
            email_address = args['email_address']
            if not ('.' in email_address and '@' in email_address):  # fix(later): better validation
                abort(405)
            ar = AccountRequest()
            ar.organization_id = org_id
            ar.inviter_id = current_user.id
            ar.creation_timestamp = datetime.datetime.utcnow()
            ar.email_address = email_address
            ar.email_sent = True
            ar.email_failed = False
            ar.access_code = make_code(30)
            ar.attributes = '{}'
            db.session.add(ar)
            db.session.commit()

            # send an email to the user
            # fix(later): add error handling/retry
            sys_name = current_app.config['SYSTEM_NAME']
            org_full_name = json.loads(ar.organization.system_attributes)['full_name']
            subject = '%s invitation from %s' % (sys_name, org_full_name)
            message_body = '''You have been invited to join %s on %s.

Follow this link to create an account:
%screate-account/%s
''' % (org_full_name, sys_name, request.url_root, ar.access_code)
            try:
                send_email(email_address, subject, message_body, current_app.config)
            except SMTPException:
                return {'status': 'error'}
            return {'status': 'ok'}

        # case 2: assigning an existing user to be a member of this organization
        else:
            org_user = OrganizationUser()  # fix(later): prevent duplicates
            org_user.organization_id = org_id
            org_user.user_id = args['user_id']
            org_user.is_admin = bool(int(args['is_admin']))  # fix(later): make conversion safe
            db.session.add(org_user)
            db.session.commit()
            return {'status': 'ok'}
def controller_watchdog():
    server_config = load_server_config()
    worker_log('controller_watchdog', 'starting')
    last_log_time = None
    while True:
        watchdog_check_count = 0
        watchdog_expire_count = 0
        try:

            # get list of controllers
            controllers = Resource.query.filter(
                Resource.type == Resource.CONTROLLER_FOLDER,
                not_(Resource.deleted))
            for controller in controllers:
                system_attributes = json.loads(
                    controller.system_attributes
                ) if controller.system_attributes else {}

                # if watchdog notifications are enabled
                if system_attributes.get(
                        'watchdog_minutes',
                        0) > 0 and 'watchdog_recipients' in system_attributes:
                    watchdog_check_count += 1
                    try:

                        # check controller status; if stale watchdog timestamp, send message (if not done already);
                        # if no watchdog timestamp, don't send message (assume user is just setting on the controller for the first time)
                        controller_status = ControllerStatus.query.filter(
                            ControllerStatus.id == controller.id).one()
                        # fix(soon): safe int convert
                        time_thresh = datetime.datetime.utcnow(
                        ) - datetime.timedelta(
                            minutes=system_attributes['watchdog_minutes'])
                        if controller_status.last_watchdog_timestamp and controller_status.last_watchdog_timestamp < time_thresh:
                            watchdog_expire_count += 1
                            if controller_status.watchdog_notification_sent is False:

                                # send notifications
                                recipients = system_attributes[
                                    'watchdog_recipients']
                                worker_log(
                                    'controller_watchdog',
                                    'sending notification for %s to %s' %
                                    (controller.path(), recipients))
                                recipients = recipients.split(',')
                                message = '%s is offline' % controller.path()
                                if server_config[
                                        'PRODUCTION']:  # only send message in production; this is very important
                                    for recipient in recipients:
                                        if '@' in recipient:
                                            send_email(recipient, message,
                                                       message, server_config)
                                        else:
                                            send_text_message(
                                                recipient, message,
                                                server_config)
                                controller_status.watchdog_notification_sent = True
                                db.session.commit()
                        else:
                            if controller_status.watchdog_notification_sent:
                                controller_status.watchdog_notification_sent = False
                                db.session.commit()
                        db.session.expire(controller_status)
                    except NoResultFound:
                        worker_log(
                            'controller_watchdog',
                            'controller status not found (%d)' % controller.id)

        # handle all exceptions because we don't want an error in this code (e.g. sending email or bad status/controller data) stopping all
        # notifications
        # pylint: disable=broad-except
        except Exception as e:
            print('controller_watchdog error: %s' % str(e))
            worker_log('controller_watchdog', str(e))

        # once an hour, log current status
        if (last_log_time is None) or time.time() - last_log_time > 60 * 60:
            worker_log(
                'controller_watchdog',
                'checked %d controllers; %d are currently expired' %
                (watchdog_check_count, watchdog_expire_count))
            last_log_time = time.time()

        # wait one minute
        time.sleep(60)