emailvalidator.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014 OpenMarket Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import logging
  16. import urllib
  17. from sydent.db.valsession import ThreePidValSessionStore
  18. from sydent.util.emailutils import sendEmail
  19. from sydent.validators import common
  20. from sydent.util import time_msec
  21. from sydent.validators import IncorrectClientSecretException, SessionExpiredException
  22. logger = logging.getLogger(__name__)
  23. class EmailValidator:
  24. def __init__(self, sydent):
  25. self.sydent = sydent
  26. def requestToken(self, emailAddress, clientSecret, sendAttempt, nextLink, ipaddress=None):
  27. valSessionStore = ThreePidValSessionStore(self.sydent)
  28. valSession = valSessionStore.getOrCreateTokenSession(medium='email', address=emailAddress,
  29. clientSecret=clientSecret)
  30. valSessionStore.setMtime(valSession.id, time_msec())
  31. if int(valSession.sendAttemptNumber) >= int(sendAttempt):
  32. logger.info("Not mailing code because current send attempt (%d) is not less than given send attempt (%s)", int(sendAttempt), int(valSession.sendAttemptNumber))
  33. return valSession.id
  34. ipstring = ipaddress if ipaddress else u"an unknown location"
  35. substitutions = {
  36. 'ipaddress': ipstring,
  37. 'link': self.makeValidateLink(valSession, clientSecret, nextLink),
  38. 'token': valSession.token,
  39. }
  40. logger.info(
  41. "Attempting to mail code %s (nextLink: %s) to %s",
  42. valSession.token, nextLink, emailAddress,
  43. )
  44. sendEmail(self.sydent, 'email.template', emailAddress, substitutions)
  45. valSessionStore.setSendAttemptNumber(valSession.id, sendAttempt)
  46. return valSession.id
  47. def makeValidateLink(self, valSession, clientSecret, nextLink):
  48. base = self.sydent.cfg.get('http', 'client_http_base')
  49. link = "%s/_matrix/identity/api/v1/validate/email/submitToken?token=%s&client_secret=%s&sid=%d" % (
  50. base,
  51. urllib.quote(valSession.token),
  52. urllib.quote(clientSecret),
  53. valSession.id,
  54. )
  55. if nextLink:
  56. # manipulate the nextLink to add the sid, because
  57. # the caller won't get it until we send a response,
  58. # by which time we've sent the mail.
  59. if '?' in nextLink:
  60. nextLink += '&'
  61. else:
  62. nextLink += '?'
  63. nextLink += "sid=" + urllib.quote(str(valSession.id))
  64. link += "&nextLink=%s" % (urllib.quote(nextLink))
  65. return link
  66. def validateSessionWithToken(self, sid, clientSecret, token):
  67. return common.validateSessionWithToken(self.sydent, sid, clientSecret, token)