0
# Management Views
1
2
Django OAuth Toolkit provides comprehensive web interface views for managing OAuth2 applications and user-authorized tokens. These class-based views integrate with Django's admin system and provide complete CRUD operations.
3
4
## Capabilities
5
6
### Application Management Views
7
8
Web interface for OAuth2 client application management with full CRUD operations.
9
10
```python { .api }
11
class ApplicationList(ListView):
12
"""
13
List view for OAuth2 applications.
14
URL: /o/applications/
15
16
Shows paginated list of applications owned by the current user.
17
Requires user authentication.
18
19
Template: oauth2_provider/application_list.html
20
Context: applications (queryset of Application objects)
21
"""
22
23
model = Application
24
template_name = "oauth2_provider/application_list.html"
25
context_object_name = "applications"
26
27
class ApplicationDetail(DetailView):
28
"""
29
Detail view for OAuth2 application.
30
URL: /o/applications/{pk}/
31
32
Shows detailed information about a specific application.
33
Only accessible to application owner.
34
35
Template: oauth2_provider/application_detail.html
36
Context: application (Application object)
37
"""
38
39
model = Application
40
template_name = "oauth2_provider/application_detail.html"
41
context_object_name = "application"
42
43
class ApplicationRegistration(CreateView):
44
"""
45
Create view for registering new OAuth2 applications.
46
URL: /o/applications/register/
47
48
Form for creating new OAuth2 client applications.
49
Automatically assigns current user as application owner.
50
51
Template: oauth2_provider/application_registration_form.html
52
Form: ApplicationForm
53
"""
54
55
model = Application
56
template_name = "oauth2_provider/application_registration_form.html"
57
form_class = ApplicationForm
58
59
class ApplicationUpdate(UpdateView):
60
"""
61
Update view for OAuth2 applications.
62
URL: /o/applications/{pk}/update/
63
64
Form for updating existing OAuth2 applications.
65
Only accessible to application owner.
66
67
Template: oauth2_provider/application_form.html
68
Form: ApplicationForm
69
"""
70
71
model = Application
72
template_name = "oauth2_provider/application_form.html"
73
form_class = ApplicationForm
74
75
class ApplicationDelete(DeleteView):
76
"""
77
Delete view for OAuth2 applications.
78
URL: /o/applications/{pk}/delete/
79
80
Confirmation form for deleting OAuth2 applications.
81
Only accessible to application owner.
82
83
Template: oauth2_provider/application_confirm_delete.html
84
Context: application (Application object)
85
"""
86
87
model = Application
88
template_name = "oauth2_provider/application_confirm_delete.html"
89
success_url = reverse_lazy("oauth2_provider:list")
90
```
91
92
### Token Management Views
93
94
Web interface for users to manage their authorized OAuth2 tokens.
95
96
```python { .api }
97
class AuthorizedTokensListView(ListView):
98
"""
99
List view for user's authorized OAuth2 tokens.
100
URL: /o/authorized_tokens/
101
102
Shows paginated list of access tokens authorized by current user.
103
Groups tokens by application and shows token details.
104
105
Template: oauth2_provider/authorized-tokens.html
106
Context: authorized_tokens (queryset of AccessToken objects)
107
"""
108
109
template_name = "oauth2_provider/authorized-tokens.html"
110
context_object_name = "authorized_tokens"
111
112
def get_queryset(self):
113
"""Get access tokens for current user"""
114
115
class AuthorizedTokenDeleteView(DeleteView):
116
"""
117
Delete view for revoking authorized tokens.
118
URL: /o/authorized_tokens/{pk}/delete/
119
120
Allows users to revoke their authorized tokens.
121
Revokes both access and refresh tokens.
122
123
Template: oauth2_provider/authorized-token-delete.html
124
Context: authorized_token (AccessToken object)
125
"""
126
127
template_name = "oauth2_provider/authorized-token-delete.html"
128
context_object_name = "authorized_token"
129
success_url = reverse_lazy("oauth2_provider:authorized-token-list")
130
```
131
132
### Management URL Patterns
133
134
URL patterns for application and token management views.
135
136
```python { .api }
137
management_urlpatterns = [
138
# Application management views
139
path("applications/", views.ApplicationList.as_view(), name="list"),
140
path("applications/register/", views.ApplicationRegistration.as_view(), name="register"),
141
path("applications/<slug:pk>/", views.ApplicationDetail.as_view(), name="detail"),
142
path("applications/<slug:pk>/delete/", views.ApplicationDelete.as_view(), name="delete"),
143
path("applications/<slug:pk>/update/", views.ApplicationUpdate.as_view(), name="update"),
144
# Token management views
145
path("authorized_tokens/", views.AuthorizedTokensListView.as_view(), name="authorized-token-list"),
146
path(
147
"authorized_tokens/<slug:pk>/delete/",
148
views.AuthorizedTokenDeleteView.as_view(),
149
name="authorized-token-delete",
150
),
151
]
152
```
153
154
## Usage Examples
155
156
### URL Configuration
157
158
```python
159
# urls.py
160
from django.urls import path, include
161
162
urlpatterns = [
163
# Include OAuth2 management URLs
164
path('o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
165
]
166
167
# This provides these management URLs:
168
# /o/applications/ - List applications
169
# /o/applications/register/ - Register new application
170
# /o/applications/{id}/ - View application details
171
# /o/applications/{id}/update/ - Update application
172
# /o/applications/{id}/delete/ - Delete application
173
# /o/authorized_tokens/ - List authorized tokens
174
# /o/authorized_tokens/{id}/delete/ - Revoke token
175
```
176
177
### Custom Application Management
178
179
```python
180
from oauth2_provider.views.application import ApplicationRegistration
181
from oauth2_provider.forms import ApplicationForm
182
from django import forms
183
184
class CustomApplicationForm(ApplicationForm):
185
"""Custom form with additional fields"""
186
187
description = forms.CharField(
188
max_length=500,
189
required=False,
190
widget=forms.Textarea,
191
help_text="Describe your application"
192
)
193
194
class Meta(ApplicationForm.Meta):
195
fields = ApplicationForm.Meta.fields + ['description']
196
197
class CustomApplicationRegistration(ApplicationRegistration):
198
"""Custom registration view with additional fields"""
199
200
form_class = CustomApplicationForm
201
template_name = "myapp/custom_application_form.html"
202
203
def form_valid(self, form):
204
"""Add custom processing before saving"""
205
# Custom logic here
206
return super().form_valid(form)
207
208
# URL configuration
209
# path('custom/register/', CustomApplicationRegistration.as_view(), name='custom_register')
210
```
211
212
### Template Customization
213
214
```html
215
<!-- templates/oauth2_provider/application_list.html -->
216
{% extends "base.html" %}
217
218
{% block content %}
219
<h1>My OAuth2 Applications</h1>
220
221
<a href="{% url 'oauth2_provider:register' %}" class="btn btn-primary">
222
Register New Application
223
</a>
224
225
<div class="applications">
226
{% for application in applications %}
227
<div class="application-card">
228
<h3>{{ application.name }}</h3>
229
<p><strong>Client ID:</strong> {{ application.client_id }}</p>
230
<p><strong>Type:</strong> {{ application.get_client_type_display }}</p>
231
<p><strong>Grant Type:</strong> {{ application.get_authorization_grant_type_display }}</p>
232
233
<div class="actions">
234
<a href="{% url 'oauth2_provider:detail' application.pk %}">View</a>
235
<a href="{% url 'oauth2_provider:update' application.pk %}">Edit</a>
236
<a href="{% url 'oauth2_provider:delete' application.pk %}">Delete</a>
237
</div>
238
</div>
239
{% empty %}
240
<p>No applications registered yet.</p>
241
{% endfor %}
242
</div>
243
{% endblock %}
244
```
245
246
### Access Control
247
248
```python
249
from oauth2_provider.views.application import ApplicationDetail
250
from django.contrib.auth.mixins import LoginRequiredMixin
251
from django.core.exceptions import PermissionDenied
252
253
class SecureApplicationDetail(LoginRequiredMixin, ApplicationDetail):
254
"""Application detail view with enhanced security"""
255
256
def get_object(self, queryset=None):
257
"""Ensure user can only access their own applications"""
258
obj = super().get_object(queryset)
259
if obj.user != self.request.user:
260
raise PermissionDenied("You can only view your own applications")
261
return obj
262
263
class AdminApplicationList(ApplicationList):
264
"""Admin view to see all applications (requires staff permission)"""
265
266
def get_queryset(self):
267
"""Show all applications for staff users"""
268
if not self.request.user.is_staff:
269
raise PermissionDenied("Staff access required")
270
return Application.objects.all()
271
```
272
273
### Token Management Integration
274
275
```python
276
from oauth2_provider.views.token import AuthorizedTokensListView
277
from django.db.models import Q
278
279
class EnhancedTokenListView(AuthorizedTokensListView):
280
"""Enhanced token list with filtering and search"""
281
282
def get_queryset(self):
283
"""Add filtering and search capabilities"""
284
queryset = super().get_queryset()
285
286
# Filter by application
287
app_filter = self.request.GET.get('application')
288
if app_filter:
289
queryset = queryset.filter(application__name__icontains=app_filter)
290
291
# Filter by scope
292
scope_filter = self.request.GET.get('scope')
293
if scope_filter:
294
queryset = queryset.filter(scope__icontains=scope_filter)
295
296
# Filter active tokens only
297
if self.request.GET.get('active_only'):
298
from django.utils import timezone
299
queryset = queryset.filter(expires__gt=timezone.now())
300
301
return queryset.order_by('-created')
302
303
def get_context_data(self, **kwargs):
304
"""Add filter context"""
305
context = super().get_context_data(**kwargs)
306
context['applications'] = Application.objects.filter(
307
accesstoken__user=self.request.user
308
).distinct()
309
return context
310
```
311
312
### API Integration
313
314
```python
315
from oauth2_provider.views.application import ApplicationList
316
from django.http import JsonResponse
317
from django.views.generic import View
318
319
class ApplicationAPIView(View):
320
"""API endpoint for application management"""
321
322
def get(self, request):
323
"""Return applications as JSON"""
324
if not request.user.is_authenticated:
325
return JsonResponse({'error': 'Authentication required'}, status=401)
326
327
applications = Application.objects.filter(user=request.user)
328
data = []
329
330
for app in applications:
331
data.append({
332
'id': app.pk,
333
'name': app.name,
334
'client_id': app.client_id,
335
'client_type': app.client_type,
336
'authorization_grant_type': app.authorization_grant_type,
337
'created': app.created.isoformat(),
338
})
339
340
return JsonResponse({'applications': data})
341
342
class TokenAPIView(View):
343
"""API endpoint for token management"""
344
345
def get(self, request):
346
"""Return user's tokens as JSON"""
347
if not request.user.is_authenticated:
348
return JsonResponse({'error': 'Authentication required'}, status=401)
349
350
tokens = AccessToken.objects.filter(user=request.user)
351
data = []
352
353
for token in tokens:
354
data.append({
355
'id': token.pk,
356
'application': token.application.name,
357
'scope': token.scope,
358
'expires': token.expires.isoformat(),
359
'is_expired': token.is_expired(),
360
})
361
362
return JsonResponse({'tokens': data})
363
364
def delete(self, request, token_id):
365
"""Revoke specific token"""
366
if not request.user.is_authenticated:
367
return JsonResponse({'error': 'Authentication required'}, status=401)
368
369
try:
370
token = AccessToken.objects.get(pk=token_id, user=request.user)
371
token.revoke()
372
return JsonResponse({'message': 'Token revoked successfully'})
373
except AccessToken.DoesNotExist:
374
return JsonResponse({'error': 'Token not found'}, status=404)
375
```
376
377
### Bulk Operations
378
379
```python
380
from oauth2_provider.views.token import AuthorizedTokensListView
381
from django.shortcuts import redirect
382
from django.contrib import messages
383
384
class BulkTokenManagementView(AuthorizedTokensListView):
385
"""Token list view with bulk operations"""
386
387
def post(self, request, *args, **kwargs):
388
"""Handle bulk operations"""
389
action = request.POST.get('action')
390
token_ids = request.POST.getlist('selected_tokens')
391
392
if not token_ids:
393
messages.error(request, 'No tokens selected')
394
return redirect('oauth2_provider:authorized-token-list')
395
396
tokens = AccessToken.objects.filter(
397
pk__in=token_ids,
398
user=request.user
399
)
400
401
if action == 'revoke_selected':
402
count = 0
403
for token in tokens:
404
token.revoke()
405
count += 1
406
messages.success(request, f'{count} tokens revoked successfully')
407
408
elif action == 'revoke_expired':
409
expired_tokens = tokens.filter(expires__lt=timezone.now())
410
count = expired_tokens.count()
411
for token in expired_tokens:
412
token.revoke()
413
messages.success(request, f'{count} expired tokens revoked')
414
415
return redirect('oauth2_provider:authorized-token-list')
416
```