or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-endpoints.mdauth-backends.mdauth-manager.mdcli-commands.mdindex.mdmodels.md

models.mddocs/

0

# Models

1

2

SQLAlchemy models for user management, role assignment, and permission tracking. These models define the database schema for Flask-AppBuilder's security system as integrated with Airflow.

3

4

## Capabilities

5

6

### User Model

7

8

Represents an Airflow user with authentication credentials and role assignments.

9

10

```python { .api }

11

class User(Model, BaseUser):

12

"""Represents an Airflow user which has roles assigned to it."""

13

14

# Database fields

15

id: int # Primary key

16

first_name: str # User's first name (max 256 chars)

17

last_name: str # User's last name (max 256 chars)

18

username: str # Unique username (max 512 chars)

19

password: str # Hashed password (max 256 chars)

20

active: bool # Whether user account is active

21

email: str # Unique email address (max 512 chars)

22

last_login: datetime.datetime | None # Last login timestamp

23

login_count: int | None # Number of successful logins

24

fail_login_count: int | None # Number of failed login attempts

25

roles: list[Role] # Associated roles

26

created_on: datetime.datetime | None # Account creation timestamp

27

changed_on: datetime.datetime | None # Last modification timestamp

28

created_by_fk: int | None # ID of user who created this account

29

changed_by_fk: int | None # ID of user who last modified this account

30

31

# Relationships

32

created_by: User | None # User who created this account

33

changed_by: User | None # User who last modified this account

34

35

# Properties

36

@property

37

def is_authenticated(self) -> bool:

38

"""Always returns True for authenticated users."""

39

40

@property

41

def is_active(self) -> bool:

42

"""Returns the active status of the user."""

43

44

@property

45

def is_anonymous(self) -> bool:

46

"""Always returns False for registered users."""

47

48

@property

49

def perms(self) -> set[tuple[str, str]]:

50

"""Returns set of permission tuples (action, resource) for the user."""

51

52

# Methods

53

def get_id(self) -> int:

54

"""Returns the user's ID."""

55

56

def get_name(self) -> str:

57

"""Returns username, email, or user_id as identifier."""

58

59

def get_full_name(self) -> str:

60

"""Returns formatted full name."""

61

62

@classmethod

63

def get_user_id(cls) -> int | None:

64

"""Returns current user ID from Flask global context."""

65

```

66

67

### Role Model

68

69

Represents a user role to which permissions can be assigned.

70

71

```python { .api }

72

class Role(Model):

73

"""Represents a user role to which permissions can be assigned."""

74

75

id: int # Primary key

76

name: str # Unique role name (max 64 chars)

77

permissions: list[Permission] # Associated permissions

78

```

79

80

### Permission Model

81

82

Permission pair comprised of an Action + Resource combination.

83

84

```python { .api }

85

class Permission(Model):

86

"""Permission pair comprised of an Action + Resource combo."""

87

88

id: int # Primary key

89

action_id: int # Foreign key to Action

90

action: Action # Action relationship

91

resource_id: int # Foreign key to Resource

92

resource: Resource # Resource relationship

93

```

94

95

### Action Model

96

97

Represents permission actions such as `can_read`, `can_edit`, etc.

98

99

```python { .api }

100

class Action(Model):

101

"""Represents permission actions such as `can_read`."""

102

103

id: int # Primary key

104

name: str # Unique action name (max 100 chars)

105

```

106

107

### Resource Model

108

109

Represents permission objects such as `User`, `Dag`, `Connection`, etc.

110

111

```python { .api }

112

class Resource(Model):

113

"""Represents permission object such as `User` or `Dag`."""

114

115

id: int # Primary key

116

name: str # Unique resource name (max 250 chars)

117

118

def __eq__(self, other) -> bool:

119

"""Equality comparison based on name."""

120

121

def __neq__(self, other) -> bool:

122

"""Inequality comparison based on name."""

123

```

124

125

### RegisterUser Model

126

127

Represents a user registration before account activation.

128

129

```python { .api }

130

class RegisterUser(Model):

131

"""Represents a user registration."""

132

133

id: int # Primary key

134

first_name: str # First name (max 256 chars)

135

last_name: str # Last name (max 256 chars)

136

username: str # Unique username (max 512 chars)

137

password: str # Hashed password (max 256 chars)

138

email: str # Email address (max 512 chars)

139

registration_date: datetime.datetime | None # Registration timestamp

140

registration_hash: str # Registration verification hash (max 256 chars)

141

```

142

143

## Usage Examples

144

145

### Creating and Querying Users

146

147

```python

148

from airflow.providers.fab.auth_manager.models import User, Role

149

from sqlalchemy.orm import Session

150

151

# Query users

152

with Session() as session:

153

# Get all active users

154

active_users = session.query(User).filter(User.active == True).all()

155

156

# Get user by username

157

user = session.query(User).filter(User.username == "admin").first()

158

if user:

159

print(f"User: {user.get_full_name()}")

160

print(f"Email: {user.email}")

161

print(f"Active: {user.is_active}")

162

print(f"Roles: {[role.name for role in user.roles]}")

163

```

164

165

### Working with Permissions

166

167

```python

168

from airflow.providers.fab.auth_manager.models import User, Permission, Action, Resource

169

170

# Get user permissions

171

user = session.query(User).filter(User.username == "analyst").first()

172

if user:

173

# Get all permissions for user

174

user_perms = user.perms

175

print(f"User permissions: {user_perms}")

176

177

# Check specific permission

178

has_dag_read = ("can_read", "DAG") in user_perms

179

print(f"Can read DAGs: {has_dag_read}")

180

```

181

182

### Role Management

183

184

```python

185

from airflow.providers.fab.auth_manager.models import Role, Permission, Action, Resource

186

187

# Query roles and their permissions

188

admin_role = session.query(Role).filter(Role.name == "Admin").first()

189

if admin_role:

190

print(f"Role: {admin_role.name}")

191

for perm in admin_role.permissions:

192

print(f" {perm.action.name} on {perm.resource.name}")

193

```

194

195

### User Authentication Properties

196

197

```python

198

# Check user authentication status

199

if user.is_authenticated and user.is_active and not user.is_anonymous:

200

print(f"User {user.get_name()} is properly authenticated")

201

print(f"Login count: {user.login_count}")

202

print(f"Last login: {user.last_login}")

203

```

204

205

## Types

206

207

```python { .api }

208

import datetime

209

from typing import TYPE_CHECKING

210

from flask_appbuilder.models.sqla import Model

211

from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey

212

from sqlalchemy.orm import relationship

213

from airflow.auth.managers.models.base_user import BaseUser

214

215

if TYPE_CHECKING:

216

from sqlalchemy import Identity

217

```

218

219

## Database Tables

220

221

The models map to the following database tables:

222

223

- `ab_user`: User accounts

224

- `ab_role`: User roles

225

- `ab_permission_view`: Permissions (action + resource pairs)

226

- `ab_permission`: Actions

227

- `ab_view_menu`: Resources

228

- `ab_user_role`: User-role associations (many-to-many)

229

- `ab_permission_view_role`: Permission-role associations (many-to-many)

230

- `ab_register_user`: Pending user registrations