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

60 statements  

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

1from itertools import chain 

2from types import MethodType 

3 

4from django.apps import apps 

5from django.conf import settings 

6from django.core import checks 

7 

8from .management import _get_builtin_permissions 

9 

10 

11def check_user_model(app_configs=None, **kwargs): 

12 if app_configs is None: 12 ↛ 15line 12 didn't jump to line 15, because the condition on line 12 was never false

13 cls = apps.get_model(settings.AUTH_USER_MODEL) 

14 else: 

15 app_label, model_name = settings.AUTH_USER_MODEL.split(".") 

16 for app_config in app_configs: 

17 if app_config.label == app_label: 

18 cls = app_config.get_model(model_name) 

19 break 

20 else: 

21 # Checks might be run against a set of app configs that don't 

22 # include the specified user model. In this case we simply don't 

23 # perform the checks defined below. 

24 return [] 

25 

26 errors = [] 

27 

28 # Check that REQUIRED_FIELDS is a list 

29 if not isinstance(cls.REQUIRED_FIELDS, (list, tuple)): 29 ↛ 30line 29 didn't jump to line 30, because the condition on line 29 was never true

30 errors.append( 

31 checks.Error( 

32 "'REQUIRED_FIELDS' must be a list or tuple.", 

33 obj=cls, 

34 id="auth.E001", 

35 ) 

36 ) 

37 

38 # Check that the USERNAME FIELD isn't included in REQUIRED_FIELDS. 

39 if cls.USERNAME_FIELD in cls.REQUIRED_FIELDS: 39 ↛ 40line 39 didn't jump to line 40, because the condition on line 39 was never true

40 errors.append( 

41 checks.Error( 

42 "The field named as the 'USERNAME_FIELD' " 

43 "for a custom user model must not be included in 'REQUIRED_FIELDS'.", 

44 hint=( 

45 "The 'USERNAME_FIELD' is currently set to '%s', you " 

46 "should remove '%s' from the 'REQUIRED_FIELDS'." 

47 % (cls.USERNAME_FIELD, cls.USERNAME_FIELD) 

48 ), 

49 obj=cls, 

50 id="auth.E002", 

51 ) 

52 ) 

53 

54 # Check that the username field is unique 

55 if not cls._meta.get_field(cls.USERNAME_FIELD).unique and not any( 55 ↛ exit,   55 ↛ 592 missed branches: 1) line 55 didn't run the generator expression on line 55, 2) line 55 didn't jump to line 59, because the condition on line 55 was never true

56 constraint.fields == (cls.USERNAME_FIELD,) 

57 for constraint in cls._meta.total_unique_constraints 

58 ): 

59 if settings.AUTHENTICATION_BACKENDS == [ 

60 "django.contrib.auth.backends.ModelBackend" 

61 ]: 

62 errors.append( 

63 checks.Error( 

64 "'%s.%s' must be unique because it is named as the " 

65 "'USERNAME_FIELD'." % (cls._meta.object_name, cls.USERNAME_FIELD), 

66 obj=cls, 

67 id="auth.E003", 

68 ) 

69 ) 

70 else: 

71 errors.append( 

72 checks.Warning( 

73 "'%s.%s' is named as the 'USERNAME_FIELD', but it is not unique." 

74 % (cls._meta.object_name, cls.USERNAME_FIELD), 

75 hint=( 

76 "Ensure that your authentication backend(s) can handle " 

77 "non-unique usernames." 

78 ), 

79 obj=cls, 

80 id="auth.W004", 

81 ) 

82 ) 

83 

84 if isinstance(cls().is_anonymous, MethodType): 84 ↛ 85line 84 didn't jump to line 85, because the condition on line 84 was never true

85 errors.append( 

86 checks.Critical( 

87 "%s.is_anonymous must be an attribute or property rather than " 

88 "a method. Ignoring this is a security issue as anonymous " 

89 "users will be treated as authenticated!" % cls, 

90 obj=cls, 

91 id="auth.C009", 

92 ) 

93 ) 

94 if isinstance(cls().is_authenticated, MethodType): 94 ↛ 95line 94 didn't jump to line 95, because the condition on line 94 was never true

95 errors.append( 

96 checks.Critical( 

97 "%s.is_authenticated must be an attribute or property rather " 

98 "than a method. Ignoring this is a security issue as anonymous " 

99 "users will be treated as authenticated!" % cls, 

100 obj=cls, 

101 id="auth.C010", 

102 ) 

103 ) 

104 return errors 

105 

106 

107def check_models_permissions(app_configs=None, **kwargs): 

108 if app_configs is None: 108 ↛ 111line 108 didn't jump to line 111, because the condition on line 108 was never false

109 models = apps.get_models() 

110 else: 

111 models = chain.from_iterable( 

112 app_config.get_models() for app_config in app_configs 

113 ) 

114 

115 Permission = apps.get_model("auth", "Permission") 

116 permission_name_max_length = Permission._meta.get_field("name").max_length 

117 permission_codename_max_length = Permission._meta.get_field("codename").max_length 

118 errors = [] 

119 

120 for model in models: 

121 opts = model._meta 

122 builtin_permissions = dict(_get_builtin_permissions(opts)) 

123 # Check builtin permission name length. 

124 max_builtin_permission_name_length = ( 

125 max(len(name) for name in builtin_permissions.values()) 

126 if builtin_permissions 

127 else 0 

128 ) 

129 if max_builtin_permission_name_length > permission_name_max_length: 129 ↛ 130line 129 didn't jump to line 130, because the condition on line 129 was never true

130 verbose_name_max_length = permission_name_max_length - ( 

131 max_builtin_permission_name_length - len(opts.verbose_name_raw) 

132 ) 

133 errors.append( 

134 checks.Error( 

135 "The verbose_name of model '%s' must be at most %d " 

136 "characters for its builtin permission names to be at " 

137 "most %d characters." 

138 % (opts.label, verbose_name_max_length, permission_name_max_length), 

139 obj=model, 

140 id="auth.E007", 

141 ) 

142 ) 

143 # Check builtin permission codename length. 

144 max_builtin_permission_codename_length = ( 

145 max(len(codename) for codename in builtin_permissions.keys()) 

146 if builtin_permissions 

147 else 0 

148 ) 

149 if max_builtin_permission_codename_length > permission_codename_max_length: 149 ↛ 150line 149 didn't jump to line 150, because the condition on line 149 was never true

150 model_name_max_length = permission_codename_max_length - ( 

151 max_builtin_permission_codename_length - len(opts.model_name) 

152 ) 

153 errors.append( 

154 checks.Error( 

155 "The name of model '%s' must be at most %d characters " 

156 "for its builtin permission codenames to be at most %d " 

157 "characters." 

158 % ( 

159 opts.label, 

160 model_name_max_length, 

161 permission_codename_max_length, 

162 ), 

163 obj=model, 

164 id="auth.E011", 

165 ) 

166 ) 

167 codenames = set() 

168 for codename, name in opts.permissions: 168 ↛ 170line 168 didn't jump to line 170, because the loop on line 168 never started

169 # Check custom permission name length. 

170 if len(name) > permission_name_max_length: 

171 errors.append( 

172 checks.Error( 

173 "The permission named '%s' of model '%s' is longer " 

174 "than %d characters." 

175 % ( 

176 name, 

177 opts.label, 

178 permission_name_max_length, 

179 ), 

180 obj=model, 

181 id="auth.E008", 

182 ) 

183 ) 

184 # Check custom permission codename length. 

185 if len(codename) > permission_codename_max_length: 

186 errors.append( 

187 checks.Error( 

188 "The permission codenamed '%s' of model '%s' is " 

189 "longer than %d characters." 

190 % ( 

191 codename, 

192 opts.label, 

193 permission_codename_max_length, 

194 ), 

195 obj=model, 

196 id="auth.E012", 

197 ) 

198 ) 

199 # Check custom permissions codename clashing. 

200 if codename in builtin_permissions: 

201 errors.append( 

202 checks.Error( 

203 "The permission codenamed '%s' clashes with a builtin " 

204 "permission for model '%s'." % (codename, opts.label), 

205 obj=model, 

206 id="auth.E005", 

207 ) 

208 ) 

209 elif codename in codenames: 

210 errors.append( 

211 checks.Error( 

212 "The permission codenamed '%s' is duplicated for " 

213 "model '%s'." % (codename, opts.label), 

214 obj=model, 

215 id="auth.E006", 

216 ) 

217 ) 

218 codenames.add(codename) 

219 

220 return errors