Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/contrib/auth/models.py: 51%

209 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1from django.apps import apps 

2from django.contrib import auth 

3from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager 

4from django.contrib.auth.hashers import make_password 

5from django.contrib.contenttypes.models import ContentType 

6from django.core.exceptions import PermissionDenied 

7from django.core.mail import send_mail 

8from django.db import models 

9from django.db.models.manager import EmptyManager 

10from django.utils import timezone 

11from django.utils.translation import gettext_lazy as _ 

12 

13from .validators import UnicodeUsernameValidator 

14 

15 

16def update_last_login(sender, user, **kwargs): 

17 """ 

18 A signal receiver which updates the last_login date for 

19 the user logging in. 

20 """ 

21 user.last_login = timezone.now() 

22 user.save(update_fields=["last_login"]) 

23 

24 

25class PermissionManager(models.Manager): 

26 use_in_migrations = True 

27 

28 def get_by_natural_key(self, codename, app_label, model): 

29 return self.get( 

30 codename=codename, 

31 content_type=ContentType.objects.db_manager(self.db).get_by_natural_key( 

32 app_label, model 

33 ), 

34 ) 

35 

36 

37class Permission(models.Model): 

38 """ 

39 The permissions system provides a way to assign permissions to specific 

40 users and groups of users. 

41 

42 The permission system is used by the Django admin site, but may also be 

43 useful in your own code. The Django admin site uses permissions as follows: 

44 

45 - The "add" permission limits the user's ability to view the "add" form 

46 and add an object. 

47 - The "change" permission limits a user's ability to view the change 

48 list, view the "change" form and change an object. 

49 - The "delete" permission limits the ability to delete an object. 

50 - The "view" permission limits the ability to view an object. 

51 

52 Permissions are set globally per type of object, not per specific object 

53 instance. It is possible to say "Mary may change news stories," but it's 

54 not currently possible to say "Mary may change news stories, but only the 

55 ones she created herself" or "Mary may only change news stories that have a 

56 certain status or publication date." 

57 

58 The permissions listed above are automatically created for each model. 

59 """ 

60 

61 name = models.CharField(_("name"), max_length=255) 

62 content_type = models.ForeignKey( 

63 ContentType, 

64 models.CASCADE, 

65 verbose_name=_("content type"), 

66 ) 

67 codename = models.CharField(_("codename"), max_length=100) 

68 

69 objects = PermissionManager() 

70 

71 class Meta: 

72 verbose_name = _("permission") 

73 verbose_name_plural = _("permissions") 

74 unique_together = [["content_type", "codename"]] 

75 ordering = ["content_type__app_label", "content_type__model", "codename"] 

76 

77 def __str__(self): 

78 return "%s | %s" % (self.content_type, self.name) 

79 

80 def natural_key(self): 

81 return (self.codename,) + self.content_type.natural_key() 

82 

83 natural_key.dependencies = ["contenttypes.contenttype"] 

84 

85 

86class GroupManager(models.Manager): 

87 """ 

88 The manager for the auth's Group model. 

89 """ 

90 

91 use_in_migrations = True 

92 

93 def get_by_natural_key(self, name): 

94 return self.get(name=name) 

95 

96 

97class Group(models.Model): 

98 """ 

99 Groups are a generic way of categorizing users to apply permissions, or 

100 some other label, to those users. A user can belong to any number of 

101 groups. 

102 

103 A user in a group automatically has all the permissions granted to that 

104 group. For example, if the group 'Site editors' has the permission 

105 can_edit_home_page, any user in that group will have that permission. 

106 

107 Beyond permissions, groups are a convenient way to categorize users to 

108 apply some label, or extended functionality, to them. For example, you 

109 could create a group 'Special users', and you could write code that would 

110 do special things to those users -- such as giving them access to a 

111 members-only portion of your site, or sending them members-only email 

112 messages. 

113 """ 

114 

115 name = models.CharField(_("name"), max_length=150, unique=True) 

116 permissions = models.ManyToManyField( 

117 Permission, 

118 verbose_name=_("permissions"), 

119 blank=True, 

120 ) 

121 

122 objects = GroupManager() 

123 

124 class Meta: 

125 verbose_name = _("group") 

126 verbose_name_plural = _("groups") 

127 

128 def __str__(self): 

129 return self.name 

130 

131 def natural_key(self): 

132 return (self.name,) 

133 

134 

135class UserManager(BaseUserManager): 

136 use_in_migrations = True 

137 

138 def _create_user(self, username, email, password, **extra_fields): 

139 """ 

140 Create and save a user with the given username, email, and password. 

141 """ 

142 if not username: 

143 raise ValueError("The given username must be set") 

144 email = self.normalize_email(email) 

145 # Lookup the real model class from the global app registry so this 

146 # manager method can be used in migrations. This is fine because 

147 # managers are by definition working on the real model. 

148 GlobalUserModel = apps.get_model( 

149 self.model._meta.app_label, self.model._meta.object_name 

150 ) 

151 username = GlobalUserModel.normalize_username(username) 

152 user = self.model(username=username, email=email, **extra_fields) 

153 user.password = make_password(password) 

154 user.save(using=self._db) 

155 return user 

156 

157 def create_user(self, username, email=None, password=None, **extra_fields): 

158 extra_fields.setdefault("is_staff", False) 

159 extra_fields.setdefault("is_superuser", False) 

160 return self._create_user(username, email, password, **extra_fields) 

161 

162 def create_superuser(self, username, email=None, password=None, **extra_fields): 

163 extra_fields.setdefault("is_staff", True) 

164 extra_fields.setdefault("is_superuser", True) 

165 

166 if extra_fields.get("is_staff") is not True: 

167 raise ValueError("Superuser must have is_staff=True.") 

168 if extra_fields.get("is_superuser") is not True: 

169 raise ValueError("Superuser must have is_superuser=True.") 

170 

171 return self._create_user(username, email, password, **extra_fields) 

172 

173 def with_perm( 

174 self, perm, is_active=True, include_superusers=True, backend=None, obj=None 

175 ): 

176 if backend is None: 

177 backends = auth._get_backends(return_tuples=True) 

178 if len(backends) == 1: 

179 backend, _ = backends[0] 

180 else: 

181 raise ValueError( 

182 "You have multiple authentication backends configured and " 

183 "therefore must provide the `backend` argument." 

184 ) 

185 elif not isinstance(backend, str): 

186 raise TypeError( 

187 "backend must be a dotted import path string (got %r)." % backend 

188 ) 

189 else: 

190 backend = auth.load_backend(backend) 

191 if hasattr(backend, "with_perm"): 

192 return backend.with_perm( 

193 perm, 

194 is_active=is_active, 

195 include_superusers=include_superusers, 

196 obj=obj, 

197 ) 

198 return self.none() 

199 

200 

201# A few helper functions for common logic between User and AnonymousUser. 

202def _user_get_permissions(user, obj, from_name): 

203 permissions = set() 

204 name = "get_%s_permissions" % from_name 

205 for backend in auth.get_backends(): 

206 if hasattr(backend, name): 

207 permissions.update(getattr(backend, name)(user, obj)) 

208 return permissions 

209 

210 

211def _user_has_perm(user, perm, obj): 

212 """ 

213 A backend can raise `PermissionDenied` to short-circuit permission checking. 

214 """ 

215 for backend in auth.get_backends(): 

216 if not hasattr(backend, "has_perm"): 

217 continue 

218 try: 

219 if backend.has_perm(user, perm, obj): 

220 return True 

221 except PermissionDenied: 

222 return False 

223 return False 

224 

225 

226def _user_has_module_perms(user, app_label): 

227 """ 

228 A backend can raise `PermissionDenied` to short-circuit permission checking. 

229 """ 

230 for backend in auth.get_backends(): 

231 if not hasattr(backend, "has_module_perms"): 

232 continue 

233 try: 

234 if backend.has_module_perms(user, app_label): 

235 return True 

236 except PermissionDenied: 

237 return False 

238 return False 

239 

240 

241class PermissionsMixin(models.Model): 

242 """ 

243 Add the fields and methods necessary to support the Group and Permission 

244 models using the ModelBackend. 

245 """ 

246 

247 is_superuser = models.BooleanField( 

248 _("superuser status"), 

249 default=False, 

250 help_text=_( 

251 "Designates that this user has all permissions without " 

252 "explicitly assigning them." 

253 ), 

254 ) 

255 groups = models.ManyToManyField( 

256 Group, 

257 verbose_name=_("groups"), 

258 blank=True, 

259 help_text=_( 

260 "The groups this user belongs to. A user will get all permissions " 

261 "granted to each of their groups." 

262 ), 

263 related_name="user_set", 

264 related_query_name="user", 

265 ) 

266 user_permissions = models.ManyToManyField( 

267 Permission, 

268 verbose_name=_("user permissions"), 

269 blank=True, 

270 help_text=_("Specific permissions for this user."), 

271 related_name="user_set", 

272 related_query_name="user", 

273 ) 

274 

275 class Meta: 

276 abstract = True 

277 

278 def get_user_permissions(self, obj=None): 

279 """ 

280 Return a list of permission strings that this user has directly. 

281 Query all available auth backends. If an object is passed in, 

282 return only permissions matching this object. 

283 """ 

284 return _user_get_permissions(self, obj, "user") 

285 

286 def get_group_permissions(self, obj=None): 

287 """ 

288 Return a list of permission strings that this user has through their 

289 groups. Query all available auth backends. If an object is passed in, 

290 return only permissions matching this object. 

291 """ 

292 return _user_get_permissions(self, obj, "group") 

293 

294 def get_all_permissions(self, obj=None): 

295 return _user_get_permissions(self, obj, "all") 

296 

297 def has_perm(self, perm, obj=None): 

298 """ 

299 Return True if the user has the specified permission. Query all 

300 available auth backends, but return immediately if any backend returns 

301 True. Thus, a user who has permission from a single auth backend is 

302 assumed to have permission in general. If an object is provided, check 

303 permissions for that object. 

304 """ 

305 # Active superusers have all permissions. 

306 if self.is_active and self.is_superuser: 

307 return True 

308 

309 # Otherwise we need to check the backends. 

310 return _user_has_perm(self, perm, obj) 

311 

312 def has_perms(self, perm_list, obj=None): 

313 """ 

314 Return True if the user has each of the specified permissions. If 

315 object is passed, check if the user has all required perms for it. 

316 """ 

317 return all(self.has_perm(perm, obj) for perm in perm_list) 

318 

319 def has_module_perms(self, app_label): 

320 """ 

321 Return True if the user has any permissions in the given app label. 

322 Use similar logic as has_perm(), above. 

323 """ 

324 # Active superusers have all permissions. 

325 if self.is_active and self.is_superuser: 

326 return True 

327 

328 return _user_has_module_perms(self, app_label) 

329 

330 

331class AbstractUser(AbstractBaseUser, PermissionsMixin): 

332 """ 

333 An abstract base class implementing a fully featured User model with 

334 admin-compliant permissions. 

335 

336 Username and password are required. Other fields are optional. 

337 """ 

338 

339 username_validator = UnicodeUsernameValidator() 

340 

341 username = models.CharField( 

342 _("username"), 

343 max_length=150, 

344 unique=True, 

345 help_text=_( 

346 "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." 

347 ), 

348 validators=[username_validator], 

349 error_messages={ 

350 "unique": _("A user with that username already exists."), 

351 }, 

352 ) 

353 first_name = models.CharField(_("first name"), max_length=150, blank=True) 

354 last_name = models.CharField(_("last name"), max_length=150, blank=True) 

355 email = models.EmailField(_("email address"), blank=True) 

356 is_staff = models.BooleanField( 

357 _("staff status"), 

358 default=False, 

359 help_text=_("Designates whether the user can log into this admin site."), 

360 ) 

361 is_active = models.BooleanField( 

362 _("active"), 

363 default=True, 

364 help_text=_( 

365 "Designates whether this user should be treated as active. " 

366 "Unselect this instead of deleting accounts." 

367 ), 

368 ) 

369 date_joined = models.DateTimeField(_("date joined"), default=timezone.now) 

370 

371 objects = UserManager() 

372 

373 EMAIL_FIELD = "email" 

374 USERNAME_FIELD = "username" 

375 REQUIRED_FIELDS = ["email"] 

376 

377 class Meta: 

378 verbose_name = _("user") 

379 verbose_name_plural = _("users") 

380 abstract = True 

381 

382 def clean(self): 

383 super().clean() 

384 self.email = self.__class__.objects.normalize_email(self.email) 

385 

386 def get_full_name(self): 

387 """ 

388 Return the first_name plus the last_name, with a space in between. 

389 """ 

390 full_name = "%s %s" % (self.first_name, self.last_name) 

391 return full_name.strip() 

392 

393 def get_short_name(self): 

394 """Return the short name for the user.""" 

395 return self.first_name 

396 

397 def email_user(self, subject, message, from_email=None, **kwargs): 

398 """Send an email to this user.""" 

399 send_mail(subject, message, from_email, [self.email], **kwargs) 

400 

401 

402class User(AbstractUser): 

403 """ 

404 Users within the Django authentication system are represented by this 

405 model. 

406 

407 Username and password are required. Other fields are optional. 

408 """ 

409 

410 class Meta(AbstractUser.Meta): 

411 swappable = "AUTH_USER_MODEL" 

412 

413 

414class AnonymousUser: 

415 id = None 

416 pk = None 

417 username = "" 

418 is_staff = False 

419 is_active = False 

420 is_superuser = False 

421 _groups = EmptyManager(Group) 

422 _user_permissions = EmptyManager(Permission) 

423 

424 def __str__(self): 

425 return "AnonymousUser" 

426 

427 def __eq__(self, other): 

428 return isinstance(other, self.__class__) 

429 

430 def __hash__(self): 

431 return 1 # instances always return the same hash value 

432 

433 def __int__(self): 

434 raise TypeError( 

435 "Cannot cast AnonymousUser to int. Are you trying to use it in place of " 

436 "User?" 

437 ) 

438 

439 def save(self): 

440 raise NotImplementedError( 

441 "Django doesn't provide a DB representation for AnonymousUser." 

442 ) 

443 

444 def delete(self): 

445 raise NotImplementedError( 

446 "Django doesn't provide a DB representation for AnonymousUser." 

447 ) 

448 

449 def set_password(self, raw_password): 

450 raise NotImplementedError( 

451 "Django doesn't provide a DB representation for AnonymousUser." 

452 ) 

453 

454 def check_password(self, raw_password): 

455 raise NotImplementedError( 

456 "Django doesn't provide a DB representation for AnonymousUser." 

457 ) 

458 

459 @property 

460 def groups(self): 

461 return self._groups 

462 

463 @property 

464 def user_permissions(self): 

465 return self._user_permissions 

466 

467 def get_user_permissions(self, obj=None): 

468 return _user_get_permissions(self, obj, "user") 

469 

470 def get_group_permissions(self, obj=None): 

471 return set() 

472 

473 def get_all_permissions(self, obj=None): 

474 return _user_get_permissions(self, obj, "all") 

475 

476 def has_perm(self, perm, obj=None): 

477 return _user_has_perm(self, perm, obj=obj) 

478 

479 def has_perms(self, perm_list, obj=None): 

480 return all(self.has_perm(perm, obj) for perm in perm_list) 

481 

482 def has_module_perms(self, module): 

483 return _user_has_module_perms(self, module) 

484 

485 @property 

486 def is_anonymous(self): 

487 return True 

488 

489 @property 

490 def is_authenticated(self): 

491 return False 

492 

493 def get_username(self): 

494 return self.username