plain.auth
Add users to your app and define which views they can access.
To log a user in, you'll want to pair this package with:
plain-passwords
plain-oauth
plain-passkeys
(TBD)plain-passlinks
(TBD)
Installation
# app/settings.py
INSTALLED_PACKAGES = [
# ...
"plain.auth",
"plain.sessions",
"plain.passwords",
]
MIDDLEWARE = [
"plain.middleware.security.SecurityMiddleware",
"plain.sessions.middleware.SessionMiddleware", # <--
"plain.middleware.common.CommonMiddleware",
"plain.csrf.middleware.CsrfViewMiddleware",
"plain.auth.middleware.AuthenticationMiddleware", # <--
]
AUTH_USER_MODEL = "users.User"
AUTH_LOGIN_URL = "login"
Create your own user model (plain create users
).
# app/users/models.py
from plain import models
from plain.passwords.models import PasswordField
class User(models.Model):
email = models.EmailField(unique=True)
password = PasswordField()
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.email
Define your URL/view where users can log in.
# app/urls.py
from plain.auth.views import LoginView, LogoutView
from plain.urls import include, path
from plain.passwords.views import PasswordLoginView
class LoginView(PasswordLoginView):
template_name = "login.html"
urlpatterns = [
path("logout/", LogoutView, name="logout"),
path("login/", LoginView, name="login"),
]
Checking if a user is logged in
A request.user
will either be None
or point to an instance of a your AUTH_USER_MODEL
.
So in templates you can do:
{% if request.user %}
<p>Hello, {{ request.user.email }}!</p>
{% else %}
<p>You are not logged in.</p>
{% endif %}
Or in Python:
if request.user:
print(f"Hello, {request.user.email}!")
else:
print("You are not logged in.")
Restricting views
Use the AuthViewMixin
to restrict views to logged in users, staff users, or custom logic.
from plain.auth.views import AuthViewMixin
from plain.exceptions import PermissionDenied
from plain.views import View
class LoggedInView(AuthViewMixin, View):
login_required = True
class StaffOnlyView(AuthViewMixin, View):
login_required = True
staff_required = True
class CustomPermissionView(AuthViewMixin, View):
def check_auth(self):
super().check_auth()
if not self.request.user.is_special:
raise PermissionDenied("You're not special!")
1from plain import auth
2from plain.exceptions import ImproperlyConfigured
3from plain.utils.functional import SimpleLazyObject
4
5
6def get_user(request):
7 if not hasattr(request, "_cached_user"):
8 request._cached_user = auth.get_user(request)
9 return request._cached_user
10
11
12class AuthenticationMiddleware:
13 def __init__(self, get_response):
14 self.get_response = get_response
15
16 def __call__(self, request):
17 if not hasattr(request, "session"):
18 raise ImproperlyConfigured(
19 "The Plain authentication middleware requires session "
20 "middleware to be installed. Edit your MIDDLEWARE setting to "
21 "insert "
22 "'plain.sessions.middleware.SessionMiddleware' before "
23 "'plain.auth.middleware.AuthenticationMiddleware'."
24 )
25 request.user = SimpleLazyObject(lambda: get_user(request))
26 response = self.get_response(request)
27 return response