Skip to content

Commit

Permalink
ensure deprecation warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Jul 25, 2022
1 parent b65e858 commit 197ac04
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 63 deletions.
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ Unreleased
- Revert change to `expand_login_view` that attempted to preserve a
dynamic subdomain value. Such values should be handled using
`app.url_value_preprocessor` and `app.url_defaults`. #691
- Ensure deprecation warnings are present for deprecated features that
will be removed in the next feature release.
- Use `request_loader` instead of `header_loader`.
- Use `user_loaded_from_request` instead of `user_loaded_from_header`.
- Use `app.config["LOGIN_DISABLED"]` instead of `_login_disabled`.
- Use `init_app` instead of `setup_app`.

Version 0.6.1
-------------
Expand Down
4 changes: 2 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ Configuring Login

.. autoclass:: LoginManager

.. automethod:: setup_app
.. automethod:: init_app

.. automethod:: unauthorized

Expand All @@ -553,7 +553,7 @@ Configuring Login

.. automethod:: user_loader

.. automethod:: header_loader
.. automethod:: request_loader

.. attribute:: anonymous_user

Expand Down
19 changes: 17 additions & 2 deletions src/flask_login/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from .signals import session_protected
from .signals import user_accessed
from .signals import user_loaded_from_cookie
from .signals import user_loaded_from_header
from .signals import user_loaded_from_request
from .signals import user_logged_in
from .signals import user_logged_out
Expand Down Expand Up @@ -55,7 +54,6 @@
"session_protected",
"user_accessed",
"user_loaded_from_cookie",
"user_loaded_from_header",
"user_loaded_from_request",
"user_logged_in",
"user_logged_out",
Expand All @@ -77,3 +75,20 @@
"make_next_param",
"set_login_view",
]


def __getattr__(name):
if name == "user_loaded_from_header":
import warnings
from .signals import _user_loaded_from_header

warnings.warn(
"'user_loaded_from_header' is deprecated and will be"
" removed in Flask-Login 0.7. Use"
" 'user_loaded_from_request' instead.",
DeprecationWarning,
stacklevel=2,
)
return _user_loaded_from_header

raise AttributeError(name)
43 changes: 36 additions & 7 deletions src/flask_login/login_manager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import warnings
from datetime import datetime
from datetime import timedelta

Expand Down Expand Up @@ -28,7 +27,6 @@
from .signals import session_protected
from .signals import user_accessed
from .signals import user_loaded_from_cookie
from .signals import user_loaded_from_header
from .signals import user_loaded_from_request
from .signals import user_needs_refresh
from .signals import user_unauthorized
Expand Down Expand Up @@ -113,8 +111,13 @@ def setup_app(self, app, add_context_processor=True): # pragma: no cover
This method has been deprecated. Please use
:meth:`LoginManager.init_app` instead.
"""
import warnings

warnings.warn(
"Warning setup_app is deprecated. Please use init_app.", DeprecationWarning
"'setup_app' is deprecated and will be removed in"
" Flask-Login 0.7. Use 'init_app' instead.",
DeprecationWarning,
stacklevel=2,
)
self.init_app(app, add_context_processor)

Expand Down Expand Up @@ -318,9 +321,13 @@ def header_loader(self, callback):
:param callback: The callback for retrieving a user object.
:type callback: callable
"""
print(
"LoginManager.header_loader is deprecated. Use"
" LoginManager.request_loader instead."
import warnings

warnings.warn(
"'header_loader' is deprecated and will be removed in"
" Flask-Login 0.7. Use 'request_loader' instead.",
DeprecationWarning,
stacklevel=2,
)
self._header_callback = callback
return callback
Expand Down Expand Up @@ -422,7 +429,10 @@ def _load_user_from_header(self, header):
user = self._header_callback(header)
if user is not None:
app = current_app._get_current_object()
user_loaded_from_header.send(app, user=user)

from .signals import _user_loaded_from_header

_user_loaded_from_header.send(app, user=user)
return user
return None

Expand Down Expand Up @@ -504,11 +514,30 @@ def _clear_cookie(self, response):
@property
def _login_disabled(self):
"""Legacy property, use app.config['LOGIN_DISABLED'] instead."""
import warnings

warnings.warn(
"'_login_disabled' is deprecated and will be removed in"
" Flask-Login 0.7. Use 'LOGIN_DISABLED' in 'app.config'"
" instead.",
DeprecationWarning,
stacklevel=2,
)

if has_app_context():
return current_app.config.get("LOGIN_DISABLED", False)
return False

@_login_disabled.setter
def _login_disabled(self, newvalue):
"""Legacy property setter, use app.config['LOGIN_DISABLED'] instead."""
import warnings

warnings.warn(
"'_login_disabled' is deprecated and will be removed in"
" Flask-Login 0.7. Use 'LOGIN_DISABLED' in 'app.config'"
" instead.",
DeprecationWarning,
stacklevel=2,
)
current_app.config["LOGIN_DISABLED"] = newvalue
18 changes: 17 additions & 1 deletion src/flask_login/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#: Sent when the user is loaded from the header. In addition to the app (which
#: is the #: sender), it is passed `user`, which is the user being reloaded.
user_loaded_from_header = _signals.signal("loaded-from-header")
_user_loaded_from_header = _signals.signal("loaded-from-header")

#: Sent when the user is loaded from the request. In addition to the app (which
#: is the #: sender), it is passed `user`, which is the user being reloaded.
Expand All @@ -43,3 +43,19 @@
#: marked non-fresh or deleted. It receives no additional arguments besides
#: the app.
session_protected = _signals.signal("session-protected")


def __getattr__(name):
if name == "user_loaded_from_header":
import warnings

warnings.warn(
"'user_loaded_from_header' is deprecated and will be"
" removed in Flask-Login 0.7. Use"
" 'user_loaded_from_request' instead.",
DeprecationWarning,
stacklevel=2,
)
return _user_loaded_from_header

raise AttributeError(name)
51 changes: 0 additions & 51 deletions tests/test_login.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import base64
import sys
import unittest
from collections.abc import Hashable
Expand Down Expand Up @@ -34,7 +33,6 @@
from flask_login import set_login_view
from flask_login import user_accessed
from flask_login import user_loaded_from_cookie
from flask_login import user_loaded_from_header
from flask_login import user_loaded_from_request
from flask_login import user_logged_in
from flask_login import user_logged_out
Expand Down Expand Up @@ -207,13 +205,6 @@ def test_class_init(self):

self.assertIsInstance(login_manager, LoginManager)

def test_login_disabled_is_set(self):
login_manager = LoginManager(self.app, add_context_processor=True)
self.assertFalse(login_manager._login_disabled)
with self.app.app_context():
login_manager._login_disabled = True
self.assertTrue(login_manager._login_disabled)

def test_no_user_loader_raises(self):
login_manager = LoginManager(self.app, add_context_processor=True)
with self.app.test_request_context():
Expand Down Expand Up @@ -324,16 +315,6 @@ def logout():
def load_user(user_id):
return USERS[int(user_id)]

@self.login_manager.header_loader
def load_user_from_header(header_value):
if header_value.startswith("Basic "):
header_value = header_value.replace("Basic ", "", 1)
try:
user_id = base64.b64decode(header_value)
except TypeError:
pass
return USERS.get(int(user_id))

@self.login_manager.request_loader
def load_user_from_request(request):
user_id = request.args.get("user_id")
Expand Down Expand Up @@ -408,26 +389,6 @@ def test_login_inactive_user_forced(self):
login_user(creeper, force=True)
self.assertEqual(current_user.name, "Creeper")

def test_login_user_with_header(self):
user_id = 2
user_name = USERS[user_id].name
self.login_manager._request_callback = None
with self.app.test_client() as c:
decoded = base64.b64encode(str(user_id).encode()).decode()
headers = [("Authorization", f"Basic {decoded}")]
result = c.get("/username", headers=headers)
self.assertEqual(user_name, result.data.decode("utf-8"))

def test_login_invalid_user_with_header(self):
user_id = 9000
user_name = "Anonymous"
self.login_manager._request_callback = None
with self.app.test_client() as c:
decoded = base64.b64encode(str(user_id).encode()).decode()
headers = [("Authorization", f"Basic {decoded}")]
result = c.get("/username", headers=headers)
self.assertEqual(user_name, result.data.decode("utf-8"))

def test_login_user_with_request(self):
user_id = 2
user_name = USERS[user_id].name
Expand Down Expand Up @@ -914,18 +875,6 @@ def test_user_loaded_from_cookie_fired(self):
c.get("/username")
listener.assert_heard_one(self.app, user=notch)

def test_user_loaded_from_header_fired(self):
user_id = 1
user_name = USERS[user_id].name
self.login_manager._request_callback = None
with self.app.test_client() as c:
with listen_to(user_loaded_from_header) as listener:
decoded = base64.b64encode(str(user_id).encode()).decode()
headers = [("Authorization", f"Basic {decoded}")]
result = c.get("/username", headers=headers)
self.assertEqual(user_name, result.data.decode("utf-8"))
listener.assert_heard_one(self.app, user=USERS[user_id])

def test_user_loaded_from_request_fired(self):
user_id = 1
user_name = USERS[user_id].name
Expand Down

0 comments on commit 197ac04

Please sign in to comment.