Skip to main content

Decorators

View decorators for protecting views and requiring specific identity blocks.

@sva_oauth_required

Require SVA OAuth authentication. Redirects unauthenticated users to the login page.

Usage

from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims

@sva_oauth_required
def my_view(request):
"""This view requires authentication"""
claims = get_sva_claims(request)
return render(request, 'template.html', {'claims': claims})

Behavior

  • Checks if user has a valid access token in session
  • If not authenticated, redirects to SVA_OAUTH_LOGIN_URL (default: /oauth/login/)
  • Displays an info message prompting the user to sign in
  • If authenticated, continues to the view

Class-Based Views

from django.views import View
from django.utils.decorators import method_decorator
from sva_oauth_client.decorators import sva_oauth_required

@method_decorator(sva_oauth_required, name='dispatch')
class ProtectedView(View):
def get(self, request):
# User is authenticated
return render(request, 'template.html')

@sva_blocks_required

Require specific identity blocks (claims) to be present in the data token.

Usage

from sva_oauth_client.decorators import sva_blocks_required
from sva_oauth_client.utils import get_sva_claims

@sva_blocks_required('email', 'name', 'phone')
def profile_view(request):
"""Requires email, name, and phone blocks"""
claims = get_sva_claims(request)

# These are guaranteed to exist
email = claims['email']
name = claims['name']
phone = claims['phone']

return render(request, 'profile.html', {
'email': email,
'name': name,
'phone': phone,
})

Parameters

  • *blocks: Variable number of block names that must be present

Behavior

  1. First checks if user is authenticated (same as @sva_oauth_required)
  2. Verifies that the data token is valid and not expired
  3. Checks that all required blocks are present in the data token
  4. If any block is missing, redirects to login with an error message
  5. If the token is invalid or expired, triggers logout and redirects to login

Error Handling

Automatically handles SVATokenError exceptions:

  • Expired tokens → Logout and redirect to login
  • Invalid tokens → Logout and redirect to login
  • Missing blocks → Redirect to login with error message

Class-Based Views

from django.views import View
from django.utils.decorators import method_decorator
from sva_oauth_client.decorators import sva_blocks_required

@method_decorator(sva_blocks_required('email', 'name'), name='dispatch')
class ProfileView(View):
def get(self, request):
claims = get_sva_claims(request)
# email and name are guaranteed to exist
return render(request, 'profile.html', {'claims': claims})

Combining Decorators

You can combine decorators, but order matters:

from django.contrib.auth.decorators import login_required
from sva_oauth_client.decorators import sva_oauth_required

@sva_oauth_required
@login_required # This runs after sva_oauth_required
def my_view(request):
# Both decorators must pass
pass

Custom Error Handling

You can catch exceptions in your views:

from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims
from sva_oauth_client.client import SVATokenError
from django.shortcuts import redirect

@sva_oauth_required
def my_view(request):
try:
claims = get_sva_claims(request)
# Process claims...
except SVATokenError:
# Token expired or invalid
# Decorator will handle logout, but you can add custom logic
messages.error(request, 'Your session has expired.')
return redirect('sva_oauth_client:login')

Examples

Basic Protected View

@sva_oauth_required
def dashboard(request):
claims = get_sva_claims(request)
return render(request, 'dashboard.html', {'claims': claims})

Requiring Email

@sva_blocks_required('email')
def email_required_view(request):
claims = get_sva_claims(request)
email = claims['email'] # Guaranteed to exist
return render(request, 'template.html', {'email': email})

Requiring Multiple Blocks

@sva_blocks_required('email', 'name', 'phone', 'address')
def complete_profile_view(request):
claims = get_sva_claims(request)
# All blocks are guaranteed to exist
return render(request, 'profile.html', {'claims': claims})

Next Steps