or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authorizers.mdfilesystems.mdhandlers.mdindex.mdioloop.mdservers.mdutilities.md

authorizers.mddocs/

0

# Authentication & Authorization

1

2

User authentication and permission management systems providing flexible approaches to FTP user management. pyftpdlib supports virtual users, system users, and custom authorization schemes with fine-grained permission control.

3

4

## Capabilities

5

6

### Virtual User Authorization

7

8

Basic authorizer for managing virtual users with in-memory user database, suitable for most FTP server deployments.

9

10

```python { .api }

11

class DummyAuthorizer:

12

# Permission constants

13

read_perms: str = "elr" # Read permissions: examine, list, retrieve

14

write_perms: str = "adfmwMT" # Write permissions: append, delete, file/mkdir, write, modify time

15

16

def __init__(self):

17

"""Initialize empty user database."""

18

19

def add_user(self, username, password, homedir, perm='elr', msg_login="Login successful.", msg_quit="Goodbye."):

20

"""

21

Add virtual user to database.

22

23

Parameters:

24

- username: user login name

25

- password: user password

26

- homedir: user home directory path

27

- perm: permission string (combination of elradfmwMT)

28

- msg_login: custom login message

29

- msg_quit: custom quit message

30

"""

31

32

def add_anonymous(self, homedir, **kwargs):

33

"""

34

Add anonymous user access.

35

36

Parameters:

37

- homedir: anonymous user home directory

38

- **kwargs: same options as add_user() except username/password

39

"""

40

41

def remove_user(self, username):

42

"""Remove user from database."""

43

44

def override_perm(self, username, directory, perm, recursive=False):

45

"""

46

Override permissions for specific directory.

47

48

Parameters:

49

- username: target user

50

- directory: directory path (relative to user home)

51

- perm: permission string to override

52

- recursive: apply to subdirectories

53

"""

54

55

def validate_authentication(self, username, password, handler):

56

"""

57

Validate user credentials.

58

59

Parameters:

60

- username: provided username

61

- password: provided password

62

- handler: FTPHandler instance

63

64

Raises:

65

- AuthenticationFailed: if credentials invalid

66

"""

67

68

def get_home_dir(self, username):

69

"""Get user home directory path."""

70

71

def impersonate_user(self, username, password):

72

"""Impersonate user (no-op in DummyAuthorizer)."""

73

74

def terminate_impersonation(self, username):

75

"""Terminate user impersonation (no-op in DummyAuthorizer)."""

76

77

def has_user(self, username):

78

"""Check if user exists in database."""

79

80

def has_perm(self, username, perm, path=None):

81

"""

82

Check if user has specific permission.

83

84

Parameters:

85

- username: user to check

86

- perm: permission letter (e,l,r,a,d,f,m,w,M,T)

87

- path: optional path for directory-specific permissions

88

"""

89

90

def get_perms(self, username):

91

"""Get user permission string."""

92

93

def get_msg_login(self, username):

94

"""Get user login message."""

95

96

def get_msg_quit(self, username):

97

"""Get user quit message."""

98

```

99

100

### Unix System User Authorization

101

102

Authorizer that authenticates against Unix system users, providing integration with existing system accounts. Available on POSIX systems only.

103

104

```python { .api }

105

class BaseUnixAuthorizer: # POSIX only

106

def __init__(self, anonymous_user=None):

107

"""

108

Initialize Unix authorizer.

109

110

Parameters:

111

- anonymous_user: system user for anonymous access (optional)

112

"""

113

114

def validate_authentication(self, username, password, handler):

115

"""Authenticate against system shadow database."""

116

117

def impersonate_user(self, username, password):

118

"""Change effective UID/GID to match system user."""

119

120

def terminate_impersonation(self, username):

121

"""Revert to original UID/GID."""

122

123

def has_user(self, username):

124

"""Check if system user exists."""

125

126

def get_home_dir(self, username):

127

"""Get system user home directory from passwd database."""

128

129

class UnixAuthorizer(BaseUnixAuthorizer): # POSIX only

130

def __init__(self, global_perm="elradfmwMT", allowed_users=None, rejected_users=None,

131

require_valid_shell=True, anonymous_user=None, msg_login="Login successful.",

132

msg_quit="Goodbye."):

133

"""

134

Initialize Unix authorizer with access controls.

135

136

Parameters:

137

- global_perm: default permissions for all users

138

- allowed_users: list/set of allowed usernames (None = all allowed)

139

- rejected_users: list/set of rejected usernames

140

- require_valid_shell: require valid shell in /etc/shells

141

- anonymous_user: system user for anonymous access

142

- msg_login/msg_quit: default messages

143

"""

144

```

145

146

### Windows System User Authorization

147

148

Authorizer that authenticates against Windows system users using Windows API. Available on Windows only.

149

150

```python { .api }

151

class BaseWindowsAuthorizer: # Windows only

152

def __init__(self, anonymous_user=None):

153

"""

154

Initialize Windows authorizer.

155

156

Parameters:

157

- anonymous_user: Windows user for anonymous access (optional)

158

"""

159

160

def validate_authentication(self, username, password, handler):

161

"""Authenticate against Windows user database."""

162

163

def impersonate_user(self, username, password):

164

"""Impersonate Windows user account."""

165

166

def terminate_impersonation(self, username):

167

"""End user impersonation."""

168

169

class WindowsAuthorizer(BaseWindowsAuthorizer): # Windows only

170

def __init__(self, global_perm="elradfmwMT", allowed_users=None, rejected_users=None,

171

anonymous_user=None, msg_login="Login successful.", msg_quit="Goodbye."):

172

"""Initialize Windows authorizer with same parameters as UnixAuthorizer."""

173

```

174

175

## Exception Classes

176

177

```python { .api }

178

class AuthorizerError(Exception):

179

"""Base class for authorizer-related exceptions."""

180

181

class AuthenticationFailed(Exception):

182

"""Raised when user authentication fails."""

183

```

184

185

## Utility Functions

186

187

```python { .api }

188

def replace_anonymous(callable):

189

"""

190

Decorator to replace anonymous user references.

191

Used internally for handling anonymous user in system authorizers.

192

"""

193

```

194

195

## Permission System

196

197

### Permission Letters

198

199

- **e** - examine: Change directory (CWD, CDUP commands)

200

- **l** - list: List directory contents (LIST, NLST, STAT commands)

201

- **r** - retrieve: Download files (RETR command)

202

- **a** - append: Append to files (APPE command)

203

- **d** - delete: Delete files and directories (DELE, RMD commands)

204

- **f** - file operations: Create files, rename (STOR, MKD, RNFR, RNTO commands)

205

- **m** - mode: Change file mode/permissions (SITE CHMOD command)

206

- **w** - write: Full write access (covers adf permissions)

207

- **M** - modify: Change file modification time (MFMT command)

208

- **T** - transfer mode: Change transfer mode (MODE, STRU, TYPE commands)

209

210

### Common Permission Combinations

211

212

- **"elr"** - Read-only access (browse and download)

213

- **"elradfmwMT"** - Full access (all permissions)

214

- **"elrw"** - Read and write access (equivalent to elradfm)

215

216

## Usage Examples

217

218

### Virtual Users with Different Permissions

219

220

```python

221

from pyftpdlib.authorizers import DummyAuthorizer

222

223

authorizer = DummyAuthorizer()

224

225

# Full access user

226

authorizer.add_user("admin", "secret", "/home/admin", perm="elradfmwMT")

227

228

# Read-only user

229

authorizer.add_user("guest", "guest", "/home/guest", perm="elr")

230

231

# User with limited write access (no delete)

232

authorizer.add_user("upload", "pass", "/home/upload", perm="elrafmwMT")

233

234

# Anonymous read-only access

235

authorizer.add_anonymous("/home/public", perm="elr")

236

```

237

238

### Directory-Specific Permissions

239

240

```python

241

authorizer = DummyAuthorizer()

242

authorizer.add_user("user", "pass", "/home/user", perm="elr")

243

244

# Allow write access only to uploads directory

245

authorizer.override_perm("user", "uploads", "elradfmwMT", recursive=True)

246

247

# Allow delete access only to temp directory

248

authorizer.override_perm("user", "temp", "elrd")

249

```

250

251

### Unix System Users

252

253

```python

254

from pyftpdlib.authorizers import UnixAuthorizer

255

256

# Allow all system users with valid shells

257

authorizer = UnixAuthorizer()

258

259

# Restrict to specific users only

260

authorizer = UnixAuthorizer(

261

allowed_users=["john", "jane", "bob"],

262

require_valid_shell=True

263

)

264

265

# Block specific users

266

authorizer = UnixAuthorizer(

267

rejected_users=["root", "daemon", "nobody"],

268

global_perm="elr" # Read-only for all users

269

)

270

271

# Enable anonymous access using 'ftp' system user

272

authorizer = UnixAuthorizer(anonymous_user="ftp")

273

```

274

275

### Windows System Users

276

277

```python

278

from pyftpdlib.authorizers import WindowsAuthorizer

279

280

# Allow all Windows users

281

authorizer = WindowsAuthorizer()

282

283

# Restrict access and enable anonymous

284

authorizer = WindowsAuthorizer(

285

allowed_users=["Administrator", "User1"],

286

anonymous_user="Guest",

287

global_perm="elr"

288

)

289

```

290

291

### Custom Authorizer

292

293

```python

294

class CustomAuthorizer(DummyAuthorizer):

295

def validate_authentication(self, username, password, handler):

296

# Custom authentication logic (database, LDAP, etc.)

297

if self.authenticate_user(username, password):

298

return

299

raise AuthenticationFailed("Invalid credentials")

300

301

def has_perm(self, username, perm, path=None):

302

# Custom permission logic

303

if path and path.startswith("/restricted/"):

304

return False

305

return super().has_perm(username, perm, path)

306

```

307

308

## Integration with FTP Handlers

309

310

```python

311

from pyftpdlib.handlers import FTPHandler

312

313

# Assign authorizer to handler

314

handler = FTPHandler

315

handler.authorizer = authorizer

316

317

# Or subclass for custom behavior

318

class CustomFTPHandler(FTPHandler):

319

authorizer = authorizer

320

321

def on_login(self, username):

322

print(f"User {username} logged in from {self.remote_ip}")

323

```