diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fe92fa31..9237a5314 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Delete partial token from session if still present - Use `userPrincipalName` to set `username` and `email` accordingly - Send authorization headers to Kakao OAuth2, properly fill user details +- Add settings for controlling email validation code expiry ## [1.7.0](https://github.com/python-social-auth/social-core/releases/tag/1.7.0) - 2018-02-20 diff --git a/social_core/storage.py b/social_core/storage.py index e276ac522..e21c2e79d 100644 --- a/social_core/storage.py +++ b/social_core/storage.py @@ -256,6 +256,7 @@ class CodeMixin(object): email = '' code = '' verified = False + timestamp = None def verify(self): self.verified = True diff --git a/social_core/strategy.py b/social_core/strategy.py index 41e9540f0..4b34691fd 100644 --- a/social_core/strategy.py +++ b/social_core/strategy.py @@ -1,6 +1,7 @@ import time import random import hashlib +from datetime import datetime, timedelta from .utils import setting_name, module_member, PARTIAL_TOKEN_SESSION_NAME from .store import OpenIdStore, OpenIdSessionWrapper @@ -136,11 +137,19 @@ def send_email_validation(self, backend, email, partial_token=None): def validate_email(self, email, code): verification_code = self.storage.code.get_code(code) + allow_reuse = self.setting('EMAIL_VALIDATION_ALLOW_REUSE') + expiry = self.setting('EMAIL_VALIDATION_EXPIRED_THRESHOLD') + expired_code = expiry and verification_code.timestamp and \ + ((verification_code.timestamp + \ + timedelta(seconds=expiry)).utctimetuple() < \ + datetime.utcnow().utctimetuple()) if not verification_code or verification_code.code != code: return False elif verification_code.email != email: return False - elif verification_code.verified: + elif expired_code: + return False + elif verification_code.verified and not allow_reuse: return False else: verification_code.verify()