Ejemplo n.º 1
0
def check_session(csrf_check):
    auth_token = flask.request.headers.get('Auth-Token', None)
    if auth_token:
        auth_timestamp = flask.request.headers.get('Auth-Timestamp', None)
        auth_nonce = flask.request.headers.get('Auth-Nonce', None)
        auth_signature = flask.request.headers.get('Auth-Signature', None)
        if not auth_token or not auth_timestamp or not auth_nonce or \
                not auth_signature:
            return False
        auth_nonce = auth_nonce[:32]

        try:
            if abs(int(auth_timestamp) - int(utils.time_now())) > \
                    settings.app.auth_time_window:
                return False
        except ValueError:
            return False

        administrator = find_user(token=auth_token)
        if not administrator:
            return False

        if not administrator.auth_api:
            return False

        auth_string = '&'.join([
            auth_token, auth_timestamp, auth_nonce, flask.request.method,
            flask.request.path])

        if len(auth_string) > AUTH_SIG_STRING_MAX_LEN or len(auth_nonce) < 8:
            return False

        if not administrator.secret or len(administrator.secret) < 8:
            return False

        auth_test_signature = base64.b64encode(hmac.new(
            administrator.secret.encode(), auth_string,
            hashlib.sha256).digest())
        if auth_signature != auth_test_signature:
            return False

        try:
            Administrator.nonces_collection.insert({
                'token': auth_token,
                'nonce': auth_nonce,
                'timestamp': utils.now(),
            })
        except pymongo.errors.DuplicateKeyError:
            return False
    else:
        if not flask.session:
            return False

        admin_id = utils.session_opt_str('admin_id')
        if not admin_id:
            return False
        admin_id = utils.ObjectId(admin_id)
        session_id = utils.session_opt_str('session_id')

        signature = utils.session_opt_str('signature')
        if not signature:
            return False

        if not utils.check_flask_sig():
            return False

        if csrf_check:
            csrf_token = flask.request.headers.get('Csrf-Token', None)
            if not validate_token(csrf_token):
                logger.error('CSRF token check failed', 'auth',
                    method=flask.request.method,
                    path=flask.request.path,
                )
                return False

        administrator = get_user(admin_id, session_id)
        if not administrator:
            return False

        if not settings.app.reverse_proxy and \
                not settings.app.allow_insecure_session and \
                not settings.app.server_ssl and \
                utils.session_opt_str('source') != utils.get_remote_addr():
            flask.session.clear()
            clear_session(admin_id, session_id)
            return False

        session_timeout = settings.app.session_timeout
        if session_timeout and int(utils.time_now()) - \
                utils.session_int('timestamp') > session_timeout:
            flask.session.clear()
            clear_session(admin_id, session_id)
            return False

        flask.session['timestamp'] = int(utils.time_now())
        utils.set_flask_sig()

    if administrator.disabled:
        return False

    flask.g.administrator = administrator
    return True
Ejemplo n.º 2
0
def check_session(csrf_check):
    auth_token = flask.request.headers.get('Auth-Token', None)
    if auth_token:
        auth_timestamp = flask.request.headers.get('Auth-Timestamp', None)
        auth_nonce = flask.request.headers.get('Auth-Nonce', None)
        auth_signature = flask.request.headers.get('Auth-Signature', None)
        if not auth_token or not auth_timestamp or not auth_nonce or \
                not auth_signature:
            return False
        auth_nonce = auth_nonce[:32]

        try:
            if abs(int(auth_timestamp) - int(utils.time_now())) > \
                    settings.app.auth_time_window:
                return False
        except ValueError:
            return False

        administrator = find_user(token=auth_token)
        if not administrator:
            return False

        if not administrator.auth_api:
            return False

        auth_string = '&'.join([
            auth_token, auth_timestamp, auth_nonce, flask.request.method,
            flask.request.path] +
            ([flask.request.data] if flask.request.data else []))

        if len(auth_string) > AUTH_SIG_STRING_MAX_LEN or len(auth_nonce) < 8:
            return False

        if not administrator.secret or len(administrator.secret) < 8:
            return False

        auth_test_signature = base64.b64encode(hmac.new(
            administrator.secret.encode(), auth_string,
            hashlib.sha256).digest())
        if auth_signature != auth_test_signature:
            return False

        try:
            Administrator.nonces_collection.insert({
                'token': auth_token,
                'nonce': auth_nonce,
                'timestamp': utils.now(),
            })
        except pymongo.errors.DuplicateKeyError:
            return False
    else:
        if not flask.session:
            return False

        admin_id = flask.session.get('admin_id')
        if not admin_id:
            return False
        admin_id = utils.ObjectId(admin_id)
        session_id = flask.session.get('session_id')

        signature = flask.session.get('signature')
        if not signature:
            return False

        if not utils.check_flask_sig():
            return False

        if csrf_check:
            csrf_token = flask.request.headers.get('Csrf-Token', None)
            if not validate_token(csrf_token):
                logger.error('CSRF token check failed', 'auth',
                    method=flask.request.method,
                    path=flask.request.path,
                )
                return False

        administrator = get_user(admin_id, session_id)
        if not administrator:
            return False

        if not settings.app.reverse_proxy and \
                not settings.app.allow_insecure_session and \
                not settings.app.server_ssl and \
                flask.session.get('source') != utils.get_remote_addr():
            flask.session.clear()
            clear_session(admin_id, session_id)
            return False

        session_timeout = settings.app.session_timeout
        if session_timeout and int(utils.time_now()) - \
                flask.session['timestamp'] > session_timeout:
            flask.session.clear()
            clear_session(admin_id, session_id)
            return False

        flask.session['timestamp'] = int(utils.time_now())
        utils.set_flask_sig()

    if administrator.disabled:
        return False

    flask.g.administrator = administrator
    return True