diff --git a/synapse/config/registration.py b/synapse/config/registration.py
index fa98eced34..f5ef36a9f4 100644
--- a/synapse/config/registration.py
+++ b/synapse/config/registration.py
@@ -33,6 +33,7 @@ class RegistrationConfig(Config):
self.registration_shared_secret = config.get("registration_shared_secret")
self.macaroon_secret_key = config.get("macaroon_secret_key")
+ self.bcrypt_rounds = config.get("bcrypt_rounds", 12)
def default_config(self, **kwargs):
registration_shared_secret = random_string_with_symbols(50)
@@ -48,6 +49,11 @@ class RegistrationConfig(Config):
registration_shared_secret: "%(registration_shared_secret)s"
macaroon_secret_key: "%(macaroon_secret_key)s"
+
+ # Set the number of bcrypt rounds used to generate password hash.
+ # Larger numbers increase the work factor needed to generate the hash.
+ # The default number of rounds is 12.
+ bcrypt_rounds: 12
""" % locals()
def add_arguments(self, parser):
diff --git a/synapse/events/utils.py b/synapse/events/utils.py
index b36eec0993..48548f8c40 100644
--- a/synapse/events/utils.py
+++ b/synapse/events/utils.py
@@ -66,7 +66,6 @@ def prune_event(event):
"users_default",
"events",
"events_default",
- "events_default",
"state_default",
"ban",
"kick",
diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py
index 484f719253..055d395b20 100644
--- a/synapse/handlers/auth.py
+++ b/synapse/handlers/auth.py
@@ -44,6 +44,7 @@ class AuthHandler(BaseHandler):
LoginType.EMAIL_IDENTITY: self._check_email_identity,
LoginType.DUMMY: self._check_dummy_auth,
}
+ self.bcrypt_rounds = hs.config.bcrypt_rounds
self.sessions = {}
@defer.inlineCallbacks
@@ -432,7 +433,7 @@ class AuthHandler(BaseHandler):
Returns:
Hashed password (str).
"""
- return bcrypt.hashpw(password, bcrypt.gensalt())
+ return bcrypt.hashpw(password, bcrypt.gensalt(self.bcrypt_rounds))
def validate_hash(self, password, stored_hash):
"""Validates that self.hash(password) == stored_hash.
diff --git a/synapse/rest/client/v1/login.py b/synapse/rest/client/v1/login.py
index 2e3e4f39f3..dacc416055 100644
--- a/synapse/rest/client/v1/login.py
+++ b/synapse/rest/client/v1/login.py
@@ -192,36 +192,6 @@ class LoginRestServlet(ClientV1RestServlet):
return (user, attributes)
-class LoginFallbackRestServlet(ClientV1RestServlet):
- PATTERN = client_path_pattern("/login/fallback$")
-
- def on_GET(self, request):
- # TODO(kegan): This should be returning some HTML which is capable of
- # hitting LoginRestServlet
- return (200, {})
-
-
-class PasswordResetRestServlet(ClientV1RestServlet):
- PATTERN = client_path_pattern("/login/reset")
-
- @defer.inlineCallbacks
- def on_POST(self, request):
- reset_info = _parse_json(request)
- try:
- email = reset_info["email"]
- user_id = reset_info["user_id"]
- handler = self.handlers.login_handler
- yield handler.reset_password(user_id, email)
- # purposefully give no feedback to avoid people hammering different
- # combinations.
- defer.returnValue((200, {}))
- except KeyError:
- raise SynapseError(
- 400,
- "Missing keys. Requires 'email' and 'user_id'."
- )
-
-
class SAML2RestServlet(ClientV1RestServlet):
PATTERN = client_path_pattern("/login/saml2")
diff --git a/synapse/util/emailutils.py b/synapse/util/emailutils.py
deleted file mode 100644
index 7f9a77bf44..0000000000
--- a/synapse/util/emailutils.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2014, 2015 OpenMarket Ltd
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-""" This module allows you to send out emails.
-"""
-import email.utils
-import smtplib
-import twisted.python.log
-from email.mime.text import MIMEText
-from email.mime.multipart import MIMEMultipart
-
-import logging
-
-logger = logging.getLogger(__name__)
-
-
-class EmailException(Exception):
- pass
-
-
-def send_email(smtp_server, from_addr, to_addr, subject, body):
- """Sends an email.
-
- Args:
- smtp_server(str): The SMTP server to use.
- from_addr(str): The address to send from.
- to_addr(str): The address to send to.
- subject(str): The subject of the email.
- body(str): The plain text body of the email.
- Raises:
- EmailException if there was a problem sending the mail.
- """
- if not smtp_server or not from_addr or not to_addr:
- raise EmailException("Need SMTP server, from and to addresses. Check"
- " the config to set these.")
-
- msg = MIMEMultipart('alternative')
- msg['Subject'] = subject
- msg['From'] = from_addr
- msg['To'] = to_addr
- plain_part = MIMEText(body)
- msg.attach(plain_part)
-
- raw_from = email.utils.parseaddr(from_addr)[1]
- raw_to = email.utils.parseaddr(to_addr)[1]
- if not raw_from or not raw_to:
- raise EmailException("Couldn't parse from/to address.")
-
- logger.info("Sending email to %s on server %s with subject %s",
- to_addr, smtp_server, subject)
-
- try:
- smtp = smtplib.SMTP(smtp_server)
- smtp.sendmail(raw_from, raw_to, msg.as_string())
- smtp.quit()
- except Exception as origException:
- twisted.python.log.err()
- ese = EmailException()
- ese.cause = origException
- raise ese
|