or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

drf-integration.mdindex.mdmanagement-commands.mdmanagement-views.mdmodels.mdoauth2-endpoints.mdoidc.mdsettings.mdview-protection.md

models.mddocs/

0

# OAuth2 Models

1

2

Django OAuth Toolkit provides comprehensive Django model classes for managing OAuth2 entities. These models handle applications, tokens, grants, and OIDC ID tokens with full ORM integration, validation, and admin interface support.

3

4

## Capabilities

5

6

### Application Management

7

8

OAuth2 client application registration and management with support for different client types and authorization grant types.

9

10

```python { .api }

11

class Application(AbstractApplication):

12

"""

13

OAuth2 client application model.

14

15

Attributes:

16

client_id (str): Unique client identifier

17

client_secret (str): Confidential client secret (hashed)

18

hash_client_secret (bool): Whether to hash client secret on save

19

name (str): Human-readable application name

20

user (User): Application owner

21

redirect_uris (str): Space-separated allowed redirect URIs

22

post_logout_redirect_uris (str): Space-separated OIDC logout URIs

23

client_type (str): 'confidential' or 'public'

24

authorization_grant_type (str): Grant type supported

25

skip_authorization (bool): Skip user consent screen

26

algorithm (str): OIDC signing algorithm

27

allowed_origins (str): CORS allowed origins

28

created (datetime): Application creation timestamp

29

updated (datetime): Last modification timestamp

30

"""

31

32

# Client types

33

CLIENT_CONFIDENTIAL = "confidential"

34

CLIENT_PUBLIC = "public"

35

CLIENT_TYPES = (

36

(CLIENT_CONFIDENTIAL, "Confidential"),

37

(CLIENT_PUBLIC, "Public"),

38

)

39

40

# Grant types

41

GRANT_AUTHORIZATION_CODE = "authorization-code"

42

GRANT_IMPLICIT = "implicit"

43

GRANT_PASSWORD = "password"

44

GRANT_CLIENT_CREDENTIALS = "client-credentials"

45

GRANT_OPENID_HYBRID = "openid-hybrid"

46

GRANT_TYPES = (

47

(GRANT_AUTHORIZATION_CODE, "Authorization code"),

48

(GRANT_IMPLICIT, "Implicit"),

49

(GRANT_PASSWORD, "Resource owner password-based"),

50

(GRANT_CLIENT_CREDENTIALS, "Client credentials"),

51

(GRANT_OPENID_HYBRID, "OpenID connect hybrid"),

52

)

53

54

# OIDC algorithms

55

NO_ALGORITHM = ""

56

RS256_ALGORITHM = "RS256"

57

HS256_ALGORITHM = "HS256"

58

ALGORITHM_TYPES = (

59

(NO_ALGORITHM, "No OIDC support"),

60

(RS256_ALGORITHM, "RSA with SHA-2 256"),

61

(HS256_ALGORITHM, "HMAC with SHA-2 256"),

62

)

63

64

objects = ApplicationManager()

65

66

def redirect_uri_allowed(self, uri: str) -> bool:

67

"""Check if URI is allowed for redirect"""

68

69

def post_logout_redirect_uri_allowed(self, uri: str) -> bool:

70

"""Check if URI is allowed for OIDC logout redirect"""

71

72

def origin_allowed(self, origin: str) -> bool:

73

"""Check if origin is allowed for CORS"""

74

75

def allows_grant_type(self, *grant_types: str) -> bool:

76

"""Check if application supports given grant types"""

77

78

def is_usable(self, request) -> bool:

79

"""Check if application can be used for request"""

80

81

@property

82

def default_redirect_uri(self) -> str:

83

"""Get default redirect URI if only one exists"""

84

85

@property

86

def jwk_key(self):

87

"""Get JWK key for OIDC signing"""

88

89

class ApplicationManager(models.Manager):

90

def get_by_natural_key(self, client_id: str) -> Application:

91

"""Get application by client ID"""

92

```

93

94

### Access Token Management

95

96

OAuth2 access tokens with scope validation, expiration checking, and revocation support.

97

98

```python { .api }

99

class AccessToken(AbstractAccessToken):

100

"""

101

OAuth2 access token model.

102

103

Attributes:

104

token (str): The access token value

105

token_checksum (str): SHA-256 checksum of token

106

user (User): Token owner

107

application (Application): Associated client application

108

expires (datetime): Token expiration time

109

scope (str): Space-separated granted scopes

110

source_refresh_token (RefreshToken): Source refresh token if any

111

id_token (IDToken): Associated OIDC ID token if any

112

"""

113

114

def is_valid(self, scopes=None) -> bool:

115

"""

116

Check if access token is valid.

117

118

Args:

119

scopes: Optional list of required scopes

120

121

Returns:

122

True if token is not expired and has required scopes

123

"""

124

125

def is_expired(self) -> bool:

126

"""Check if token has expired"""

127

128

def allow_scopes(self, scopes) -> bool:

129

"""

130

Check if token allows the provided scopes.

131

132

Args:

133

scopes: Iterable of scope names to check

134

135

Returns:

136

True if all scopes are allowed

137

"""

138

139

def revoke(self) -> None:

140

"""Revoke the access token by deleting it"""

141

142

@property

143

def scopes(self) -> dict:

144

"""Get dictionary of allowed scope names with descriptions"""

145

```

146

147

### Refresh Token Management

148

149

OAuth2 refresh tokens for obtaining new access tokens with revocation and family tracking.

150

151

```python { .api }

152

class RefreshToken(AbstractRefreshToken):

153

"""

154

OAuth2 refresh token model.

155

156

Attributes:

157

token (str): The refresh token value

158

user (User): Token owner

159

application (Application): Associated client application

160

access_token (AccessToken): Associated access token

161

token_family (UUID): Token family for rotation tracking

162

revoked (datetime): Revocation timestamp if revoked

163

"""

164

165

def revoke(self) -> None:

166

"""

167

Revoke refresh token and associated access token.

168

Handles atomic operations and prevents race conditions.

169

"""

170

```

171

172

### Authorization Grant Management

173

174

OAuth2 authorization grants for the authorization code flow with PKCE support.

175

176

```python { .api }

177

class Grant(AbstractGrant):

178

"""

179

OAuth2 authorization grant model.

180

181

Attributes:

182

user (User): User who authorized the grant

183

code (str): Authorization code

184

application (Application): Client application

185

expires (datetime): Grant expiration time

186

redirect_uri (str): Redirect URI for this grant

187

scope (str): Granted scopes

188

code_challenge (str): PKCE code challenge

189

code_challenge_method (str): PKCE challenge method ('plain' or 'S256')

190

nonce (str): OIDC nonce value

191

claims (str): OIDC claims parameter

192

"""

193

194

CODE_CHALLENGE_PLAIN = "plain"

195

CODE_CHALLENGE_S256 = "S256"

196

CODE_CHALLENGE_METHODS = (

197

(CODE_CHALLENGE_PLAIN, "plain"),

198

(CODE_CHALLENGE_S256, "S256")

199

)

200

201

def is_expired(self) -> bool:

202

"""Check if grant has expired"""

203

204

def redirect_uri_allowed(self, uri: str) -> bool:

205

"""Check if URI matches grant's redirect URI"""

206

```

207

208

### OIDC ID Token Management

209

210

OpenID Connect ID tokens for identity information with JWT token ID tracking.

211

212

```python { .api }

213

class IDToken(AbstractIDToken):

214

"""

215

OIDC ID token model.

216

217

Attributes:

218

jti (UUID): JWT Token ID for unique identification

219

user (User): Token subject

220

application (Application): Client application

221

expires (datetime): Token expiration time

222

scope (str): Token scopes

223

"""

224

225

def is_valid(self, scopes=None) -> bool:

226

"""Check if ID token is valid and has required scopes"""

227

228

def is_expired(self) -> bool:

229

"""Check if token has expired"""

230

231

def allow_scopes(self, scopes) -> bool:

232

"""Check if token allows the provided scopes"""

233

234

def revoke(self) -> None:

235

"""Revoke the ID token by deleting it"""

236

237

@property

238

def scopes(self) -> dict:

239

"""Get dictionary of allowed scope names with descriptions"""

240

```

241

242

### Model Factory Functions

243

244

Functions to get the active model classes, supporting Django's swappable model system.

245

246

```python { .api }

247

def get_application_model():

248

"""Return the Application model class active in this project"""

249

250

def get_access_token_model():

251

"""Return the AccessToken model class active in this project"""

252

253

def get_refresh_token_model():

254

"""Return the RefreshToken model class active in this project"""

255

256

def get_grant_model():

257

"""Return the Grant model class active in this project"""

258

259

def get_id_token_model():

260

"""Return the IDToken model class active in this project"""

261

```

262

263

### Token Cleanup Functions

264

265

Utility functions for managing token lifecycle and cleanup.

266

267

```python { .api }

268

def clear_expired() -> None:

269

"""

270

Remove all expired tokens and grants from the database.

271

Handles batch deletion to avoid memory issues with large datasets.

272

Processes refresh tokens, access tokens, ID tokens, and grants.

273

"""

274

```

275

276

### Validation Utilities

277

278

Helper functions for URI and origin validation.

279

280

```python { .api }

281

def redirect_to_uri_allowed(uri: str, allowed_uris: list) -> bool:

282

"""

283

Check if URI can be redirected to based on allowed URIs.

284

Handles exact matches and RFC 8252 loopback IP rules.

285

286

Args:

287

uri: URI to validate

288

allowed_uris: List of allowed redirect URIs

289

290

Returns:

291

True if redirect is allowed

292

"""

293

294

def is_origin_allowed(origin: str, allowed_origins: list) -> bool:

295

"""

296

Check if origin is allowed based on CORS configuration.

297

298

Args:

299

origin: Origin URI to validate

300

allowed_origins: List of allowed origin URIs

301

302

Returns:

303

True if origin is allowed

304

"""

305

```

306

307

## Model Admin Helpers

308

309

Factory functions for retrieving active admin classes for OAuth2 models. These functions return the admin classes configured through Django settings.

310

311

```python { .api }

312

def get_application_admin_class():

313

"""Return the Application admin class that is active in this project."""

314

315

def get_access_token_admin_class():

316

"""Return the AccessToken admin class that is active in this project."""

317

318

def get_grant_admin_class():

319

"""Return the Grant admin class that is active in this project."""

320

321

def get_id_token_admin_class():

322

"""Return the IDToken admin class that is active in this project."""

323

324

def get_refresh_token_admin_class():

325

"""Return the RefreshToken admin class that is active in this project."""

326

```

327

328

## Usage Examples

329

330

### Creating Applications

331

332

```python

333

from oauth2_provider.models import Application

334

335

# Confidential web application

336

web_app = Application.objects.create(

337

name="My Web Application",

338

client_type=Application.CLIENT_CONFIDENTIAL,

339

authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,

340

redirect_uris="http://localhost:8000/callback/",

341

)

342

343

# Public mobile application

344

mobile_app = Application.objects.create(

345

name="My Mobile App",

346

client_type=Application.CLIENT_PUBLIC,

347

authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,

348

redirect_uris="myapp://callback/",

349

)

350

```

351

352

### Working with Tokens

353

354

```python

355

from oauth2_provider.models import AccessToken, get_access_token_model

356

357

# Check token validity

358

token = AccessToken.objects.get(token="your-token-here")

359

if token.is_valid(['read', 'write']):

360

print("Token is valid for read/write operations")

361

362

# Revoke tokens

363

token.revoke()

364

365

# Clean up expired tokens

366

from oauth2_provider.models import clear_expired

367

clear_expired()

368

```

369

370

### Model Relationships

371

372

```python

373

# Access related objects

374

application = Application.objects.get(client_id="your-client-id")

375

tokens = application.accesstoken_set.filter(expires__gt=timezone.now())

376

377

# Get user's applications

378

user_apps = Application.objects.filter(user=request.user)

379

380

# Get user's authorized tokens

381

user_tokens = AccessToken.objects.filter(user=request.user)

382

```