1class AppSettings(object): 2 3 class AuthenticationMethod: 4 USERNAME = 'username' 5 EMAIL = 'email' 6 USERNAME_EMAIL = 'username_email' 7 8 class EmailVerificationMethod: 9 # After signing up, keep the user account inactive until the email 10 # address is verified 11 MANDATORY = 'mandatory' 12 # Allow login with unverified e-mail (e-mail verification is 13 # still sent) 14 OPTIONAL = 'optional' 15 # Don't send e-mail verification mails during signup 16 NONE = 'none' 17 18 def __init__(self, prefix): 19 self.prefix = prefix 20 # If login is by email, email must be required 21 assert (not self.AUTHENTICATION_METHOD == 22 self.AuthenticationMethod.EMAIL) or self.EMAIL_REQUIRED 23 # If login includes email, login must be unique 24 assert (self.AUTHENTICATION_METHOD == 25 self.AuthenticationMethod.USERNAME) or self.UNIQUE_EMAIL 26 assert (self.EMAIL_VERIFICATION != 27 self.EmailVerificationMethod.MANDATORY) \ 28 or self.EMAIL_REQUIRED 29 if not self.USER_MODEL_USERNAME_FIELD: 30 assert not self.USERNAME_REQUIRED 31 assert self.AUTHENTICATION_METHOD \ 32 not in (self.AuthenticationMethod.USERNAME, 33 self.AuthenticationMethod.USERNAME_EMAIL) 34 35 def _setting(self, name, dflt): 36 from django.conf import settings 37 getter = getattr(settings, 38 'ALLAUTH_SETTING_GETTER', 39 lambda name, dflt: getattr(settings, name, dflt)) 40 return getter(self.prefix + name, dflt) 41 42 @property 43 def DEFAULT_HTTP_PROTOCOL(self): 44 return self._setting("DEFAULT_HTTP_PROTOCOL", "http").lower() 45 46 @property 47 def EMAIL_CONFIRMATION_EXPIRE_DAYS(self): 48 """ 49 Determines the expiration date of e-mail confirmation mails (# 50 of days) 51 """ 52 from django.conf import settings 53 return self._setting("EMAIL_CONFIRMATION_EXPIRE_DAYS", 54 getattr(settings, "EMAIL_CONFIRMATION_DAYS", 3)) 55 56 @property 57 def EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL(self): 58 """ 59 The URL to redirect to after a successful e-mail confirmation, in 60 case of an authenticated user 61 """ 62 return self._setting("EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL", 63 None) 64 65 @property 66 def EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL(self): 67 """ 68 The URL to redirect to after a successful e-mail confirmation, in 69 case no user is logged in 70 """ 71 from django.conf import settings 72 return self._setting("EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL", 73 settings.LOGIN_URL) 74 75 @property 76 def EMAIL_CONFIRMATION_COOLDOWN(self): 77 """ 78 The cooldown in seconds during which, after an email confirmation has 79 been sent, a second confirmation email will not be sent. 80 """ 81 return self._setting("EMAIL_CONFIRMATION_COOLDOWN", 3 * 60) 82 83 @property 84 def EMAIL_REQUIRED(self): 85 """ 86 The user is required to hand over an e-mail address when signing up 87 """ 88 return self._setting("EMAIL_REQUIRED", False) 89 90 @property 91 def EMAIL_VERIFICATION(self): 92 """ 93 See e-mail verification method 94 """ 95 ret = self._setting("EMAIL_VERIFICATION", 96 self.EmailVerificationMethod.OPTIONAL) 97 # Deal with legacy (boolean based) setting 98 if ret is True: 99 ret = self.EmailVerificationMethod.MANDATORY 100 elif ret is False: 101 ret = self.EmailVerificationMethod.OPTIONAL 102 return ret 103 104 @property 105 def AUTHENTICATION_METHOD(self): 106 ret = self._setting("AUTHENTICATION_METHOD", 107 self.AuthenticationMethod.USERNAME) 108 return ret 109 110 @property 111 def EMAIL_MAX_LENGTH(self): 112 """ 113 Adjust max_length of e-mail addresses 114 """ 115 return self._setting("EMAIL_MAX_LENGTH", 254) 116 117 @property 118 def UNIQUE_EMAIL(self): 119 """ 120 Enforce uniqueness of e-mail addresses 121 """ 122 return self._setting("UNIQUE_EMAIL", True) 123 124 @property 125 def SIGNUP_EMAIL_ENTER_TWICE(self): 126 """ 127 Signup email verification 128 """ 129 return self._setting("SIGNUP_EMAIL_ENTER_TWICE", False) 130 131 @property 132 def SIGNUP_PASSWORD_ENTER_TWICE(self): 133 """ 134 Signup password verification 135 """ 136 legacy = self._setting('SIGNUP_PASSWORD_VERIFICATION', True) 137 return self._setting('SIGNUP_PASSWORD_ENTER_TWICE', legacy) 138 139 @property 140 def PASSWORD_MIN_LENGTH(self): 141 """ 142 Minimum password Length 143 """ 144 from django.conf import settings 145 ret = None 146 if not settings.AUTH_PASSWORD_VALIDATORS: 147 ret = self._setting("PASSWORD_MIN_LENGTH", 6) 148 return ret 149 150 @property 151 def EMAIL_SUBJECT_PREFIX(self): 152 """ 153 Subject-line prefix to use for email messages sent 154 """ 155 return self._setting("EMAIL_SUBJECT_PREFIX", None) 156 157 @property 158 def SIGNUP_FORM_CLASS(self): 159 """ 160 Signup form 161 """ 162 return self._setting("SIGNUP_FORM_CLASS", None) 163 164 @property 165 def USERNAME_REQUIRED(self): 166 """ 167 The user is required to enter a username when signing up 168 """ 169 return self._setting("USERNAME_REQUIRED", True) 170 171 @property 172 def USERNAME_MIN_LENGTH(self): 173 """ 174 Minimum username Length 175 """ 176 return self._setting("USERNAME_MIN_LENGTH", 1) 177 178 @property 179 def USERNAME_BLACKLIST(self): 180 """ 181 List of usernames that are not allowed 182 """ 183 return self._setting("USERNAME_BLACKLIST", []) 184 185 @property 186 def PASSWORD_INPUT_RENDER_VALUE(self): 187 """ 188 render_value parameter as passed to PasswordInput fields 189 """ 190 return self._setting("PASSWORD_INPUT_RENDER_VALUE", False) 191 192 @property 193 def ADAPTER(self): 194 return self._setting('ADAPTER', 195 'allauth.account.adapter.DefaultAccountAdapter') 196 197 @property 198 def CONFIRM_EMAIL_ON_GET(self): 199 return self._setting('CONFIRM_EMAIL_ON_GET', False) 200 201 @property 202 def AUTHENTICATED_LOGIN_REDIRECTS(self): 203 return self._setting('AUTHENTICATED_LOGIN_REDIRECTS', True) 204 205 @property 206 def LOGIN_ON_EMAIL_CONFIRMATION(self): 207 """ 208 Automatically log the user in once they confirmed their email address 209 """ 210 return self._setting('LOGIN_ON_EMAIL_CONFIRMATION', False) 211 212 @property 213 def LOGIN_ON_PASSWORD_RESET(self): 214 """ 215 Automatically log the user in immediately after resetting 216 their password. 217 """ 218 return self._setting('LOGIN_ON_PASSWORD_RESET', False) 219 220 @property 221 def LOGOUT_REDIRECT_URL(self): 222 return self._setting('LOGOUT_REDIRECT_URL', '/') 223 224 @property 225 def LOGOUT_ON_GET(self): 226 return self._setting('LOGOUT_ON_GET', False) 227 228 @property 229 def LOGOUT_ON_PASSWORD_CHANGE(self): 230 return self._setting('LOGOUT_ON_PASSWORD_CHANGE', False) 231 232 @property 233 def USER_MODEL_USERNAME_FIELD(self): 234 return self._setting('USER_MODEL_USERNAME_FIELD', 'username') 235 236 @property 237 def USER_MODEL_EMAIL_FIELD(self): 238 return self._setting('USER_MODEL_EMAIL_FIELD', 'email') 239 240 @property 241 def SESSION_COOKIE_AGE(self): 242 """ 243 Deprecated -- use Django's settings.SESSION_COOKIE_AGE instead 244 """ 245 from django.conf import settings 246 return self._setting('SESSION_COOKIE_AGE', settings.SESSION_COOKIE_AGE) 247 248 @property 249 def SESSION_REMEMBER(self): 250 """ 251 Controls the life time of the session. Set to `None` to ask the user 252 ("Remember me?"), `False` to not remember, and `True` to always 253 remember. 254 """ 255 return self._setting('SESSION_REMEMBER', None) 256 257 @property 258 def TEMPLATE_EXTENSION(self): 259 """ 260 A string defining the template extension to use, defaults to `html`. 261 """ 262 return self._setting('TEMPLATE_EXTENSION', 'html') 263 264 @property 265 def FORMS(self): 266 return self._setting('FORMS', {}) 267 268 @property 269 def LOGIN_ATTEMPTS_LIMIT(self): 270 """ 271 Number of failed login attempts. When this number is 272 exceeded, the user is prohibited from logging in for the 273 specified `LOGIN_ATTEMPTS_TIMEOUT` 274 """ 275 return self._setting('LOGIN_ATTEMPTS_LIMIT', 5) 276 277 @property 278 def LOGIN_ATTEMPTS_TIMEOUT(self): 279 """ 280 Time period from last unsuccessful login attempt, during 281 which the user is prohibited from trying to log in. Defaults to 282 5 minutes. 283 """ 284 return self._setting('LOGIN_ATTEMPTS_TIMEOUT', 60 * 5) 285 286 @property 287 def EMAIL_CONFIRMATION_HMAC(self): 288 return self._setting('EMAIL_CONFIRMATION_HMAC', True) 289 290 @property 291 def SALT(self): 292 return self._setting('SALT', 'account') 293 294 @property 295 def PRESERVE_USERNAME_CASING(self): 296 return self._setting('PRESERVE_USERNAME_CASING', True) 297 298 @property 299 def USERNAME_VALIDATORS(self): 300 from django.core.exceptions import ImproperlyConfigured 301 from allauth.utils import import_attribute 302 from allauth.utils import get_user_model 303 304 path = self._setting('USERNAME_VALIDATORS', None) 305 if path: 306 ret = import_attribute(path) 307 if not isinstance(ret, list): 308 raise ImproperlyConfigured( 309 'ACCOUNT_USERNAME_VALIDATORS is expected to be a list') 310 else: 311 if self.USER_MODEL_USERNAME_FIELD is not None: 312 ret = get_user_model()._meta.get_field( 313 self.USER_MODEL_USERNAME_FIELD).validators 314 else: 315 ret = [] 316 return ret 317 318 319# Ugly? Guido recommends this himself ... 320# http://mail.python.org/pipermail/python-ideas/2012-May/014969.html 321import sys # noqa 322 323 324app_settings = AppSettings('ACCOUNT_') 325app_settings.__name__ = __name__ 326sys.modules[__name__] = app_settings 327