or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdajax-json.mdform-processing.mdhttp-utilities.mdindex.mdquery-optimization.md

access-control.mddocs/

0

# Access Control and Authentication

1

2

Comprehensive authentication and authorization mixins for Django class-based views. These mixins provide fine-grained access control, from simple login requirements to complex permission checking and secure connection enforcement.

3

4

## Capabilities

5

6

### Common Access Control Attributes

7

8

All access control mixins inherit common functionality for login redirects and permission handling. These attributes are available on all access mixins:

9

10

- `login_url = None` - URL to redirect to for login (defaults to settings.LOGIN_URL)

11

- `raise_exception = False` - Whether to raise PermissionDenied or redirect

12

- `redirect_field_name = 'next'` - Field name for storing redirect URL

13

- `redirect_unauthenticated_users = False` - Special handling for unauthenticated users

14

15

Common methods available on access mixins:

16

- `get_login_url()` - Get the login URL (can be overridden)

17

- `get_redirect_field_name()` - Get redirect field name (can be overridden)

18

- `handle_no_permission(request)` - Handle permission failures

19

- `no_permissions_fail(request)` - Default failure handler (redirects to login)

20

21

### User Authentication

22

23

Require user authentication with flexible redirect handling.

24

25

```python { .api }

26

class LoginRequiredMixin(AccessMixin):

27

"""Requires the user to be authenticated"""

28

29

def dispatch(self, request, *args, **kwargs):

30

"""Call appropriate method after checking authentication"""

31

```

32

33

Usage example:

34

35

```python

36

from django.views.generic import ListView

37

from braces.views import LoginRequiredMixin

38

39

class ProtectedListView(LoginRequiredMixin, ListView):

40

model = MyModel

41

login_url = '/accounts/login/'

42

redirect_field_name = 'next'

43

raise_exception = False # Redirect instead of 403

44

```

45

46

### Anonymous User Requirement

47

48

Require user to be unauthenticated, useful for login/register pages.

49

50

```python { .api }

51

class AnonymousRequiredMixin(AccessMixin):

52

"""Requires the user to be unauthenticated"""

53

authenticated_redirect_url = '/accounts/profile/'

54

55

def dispatch(self, request, *args, **kwargs):

56

"""Call appropriate handler after guaranteeing anonymity"""

57

58

def get_authenticated_redirect_url(self):

59

"""Return the reversed authenticated redirect url"""

60

```

61

62

Usage example:

63

64

```python

65

from django.views.generic import TemplateView

66

from braces.views import AnonymousRequiredMixin

67

68

class LoginPageView(AnonymousRequiredMixin, TemplateView):

69

template_name = 'registration/login.html'

70

authenticated_redirect_url = '/dashboard/'

71

```

72

73

### Permission-Based Access

74

75

Require specific Django permissions before granting access.

76

77

```python { .api }

78

class PermissionRequiredMixin(AccessMixin):

79

"""Requires user to have specific permission(s)"""

80

permission_required = None

81

object_level_permissions = False

82

83

def get_permission_required(self, request=None):

84

"""Get required permissions and return them"""

85

86

def check_permissions(self, request):

87

"""Returns whether user has permissions"""

88

89

def dispatch(self, request, *args, **kwargs):

90

"""Check user has required permission"""

91

```

92

93

Usage example:

94

95

```python

96

from django.views.generic import UpdateView

97

from braces.views import PermissionRequiredMixin

98

99

class EditPostView(PermissionRequiredMixin, UpdateView):

100

model = Post

101

permission_required = 'blog.change_post'

102

object_level_permissions = True # Check permission on specific object

103

raise_exception = True # Return 403 instead of redirect

104

```

105

106

### Multiple Permission Requirements

107

108

Complex permission checking with AND/OR logic for multiple permissions.

109

110

```python { .api }

111

class MultiplePermissionsRequiredMixin(PermissionRequiredMixin):

112

"""Allows specifying multiple permissions with 'all' and 'any' logic"""

113

permissions = None # Dict with 'all' and/or 'any' keys

114

115

def get_permission_required(self, request=None):

116

"""Get which permission is required"""

117

118

def check_permissions(self, request):

119

"""Get the permissions, both all and any"""

120

```

121

122

Usage example:

123

124

```python

125

from django.views.generic import CreateView

126

from braces.views import MultiplePermissionsRequiredMixin

127

128

class CreatePostView(MultiplePermissionsRequiredMixin, CreateView):

129

model = Post

130

permissions = {

131

'all': ('blog.add_post', 'blog.change_post'), # Must have ALL of these

132

'any': ('blog.publish_post', 'user.is_editor') # Must have ANY of these

133

}

134

```

135

136

### Group Membership

137

138

Require membership in specific Django groups.

139

140

```python { .api }

141

class GroupRequiredMixin(AccessMixin):

142

"""Requires user membership in specific group(s)"""

143

group_required = None # String, list, or tuple of group names

144

145

def get_group_required(self):

146

"""Get which group's membership is required"""

147

148

def check_membership(self, groups):

149

"""Check user's membership in required groups"""

150

151

def dispatch(self, request, *args, **kwargs):

152

"""Call appropriate handler if user is group member"""

153

```

154

155

Usage example:

156

157

```python

158

from django.views.generic import ListView

159

from braces.views import GroupRequiredMixin

160

161

class AdminListView(GroupRequiredMixin, ListView):

162

model = MyModel

163

group_required = ['admins', 'moderators'] # User must be in one of these groups

164

```

165

166

### Custom User Tests

167

168

Custom validation logic for user access control.

169

170

```python { .api }

171

class UserPassesTestMixin(AccessMixin):

172

"""User must pass custom test before accessing view"""

173

174

def test_func(self, user):

175

"""The function to test the user with - must be implemented"""

176

177

def get_test_func(self):

178

"""Get the test function"""

179

180

def dispatch(self, request, *args, **kwargs):

181

"""Call appropriate handler if user passes test"""

182

```

183

184

Usage example:

185

186

```python

187

from django.views.generic import DetailView

188

from braces.views import UserPassesTestMixin

189

190

class ProfileView(UserPassesTestMixin, DetailView):

191

model = Profile

192

193

def test_func(self, user):

194

profile = self.get_object()

195

return user == profile.user or user.is_staff

196

```

197

198

### Superuser and Staff Requirements

199

200

Quick access control for administrative users.

201

202

```python { .api }

203

class SuperuserRequiredMixin(AccessMixin):

204

"""Require users to be superusers"""

205

206

def dispatch(self, request, *args, **kwargs):

207

"""Call appropriate handler if user is superuser"""

208

209

class StaffuserRequiredMixin(AccessMixin):

210

"""Require users to be marked as staff"""

211

212

def dispatch(self, request, *args, **kwargs):

213

"""Call appropriate handler if user is staff member"""

214

```

215

216

Usage example:

217

218

```python

219

from django.views.generic import ListView

220

from braces.views import SuperuserRequiredMixin

221

222

class AdminOnlyView(SuperuserRequiredMixin, ListView):

223

model = SensitiveModel

224

raise_exception = True

225

```

226

227

### Secure Connection Requirement

228

229

Enforce HTTPS connections with automatic redirect or error handling.

230

231

```python { .api }

232

class SSLRequiredMixin:

233

"""Require requests to be made over secure connection"""

234

raise_exception = False

235

236

def dispatch(self, request, *args, **kwargs):

237

"""Call appropriate handler if connection is secure"""

238

```

239

240

Usage example:

241

242

```python

243

from django.views.generic import FormView

244

from braces.views import SSLRequiredMixin

245

246

class PaymentFormView(SSLRequiredMixin, FormView):

247

template_name = 'payment.html'

248

raise_exception = True # Return 404 for non-HTTPS requests

249

```

250

251

### Recent Login Requirement

252

253

Force re-authentication after a specified time period.

254

255

```python { .api }

256

class RecentLoginRequiredMixin(LoginRequiredMixin):

257

"""Require user to have logged in within number of seconds"""

258

max_last_login_delta = 1800 # Default 30 minutes

259

260

def dispatch(self, request, *args, **kwargs):

261

"""Call appropriate method if user's login is recent"""

262

```

263

264

Usage example:

265

266

```python

267

from django.views.generic import UpdateView

268

from braces.views import RecentLoginRequiredMixin

269

270

class SensitiveUpdateView(RecentLoginRequiredMixin, UpdateView):

271

model = UserProfile

272

max_last_login_delta = 900 # Require login within last 15 minutes

273

```

274

275

## Common Usage Patterns

276

277

### Combining Access Controls

278

279

Multiple access mixins can be combined for layered security:

280

281

```python

282

from braces.views import LoginRequiredMixin, PermissionRequiredMixin, SSLRequiredMixin

283

284

class SecureAdminView(SSLRequiredMixin, LoginRequiredMixin, PermissionRequiredMixin, UpdateView):

285

model = SensitiveModel

286

permission_required = 'myapp.change_sensitivemodel'

287

raise_exception = True

288

```

289

290

### Mixin Order

291

292

Access mixins should be placed leftmost in the inheritance chain (except when combined with CsrfExemptMixin, which should be leftmost).