]> git.ipfire.org Git - ipfire.org.git/blobdiff - src/backend/accounts.py
people: Check StopForumSpam when registering accounts
[ipfire.org.git] / src / backend / accounts.py
index 71253a44b6fda195ec53b68d69e98ecdf90ede04..1c348a2a639374b0da27c22e3e835eb6db8dcaae 100644 (file)
@@ -2,6 +2,7 @@
 # encoding: utf-8
 
 import datetime
+import json
 import ldap
 import ldap.modlist
 import logging
@@ -9,6 +10,7 @@ import os
 import phonenumbers
 import sshpubkeys
 import time
+import tornado.httpclient
 import urllib.parse
 import urllib.request
 import zxcvbn
@@ -163,6 +165,15 @@ class Accounts(Object):
                        "(&(objectClass=inetOrgPerson)(|(sipAuthenticationUser=%s)(telephoneNumber=%s)(homePhone=%s)(mobile=%s)))" \
                        % (number, number, number, number))
 
+       @tornado.gen.coroutine
+       def check_spam(self, uid, email, address):
+               sfs = StopForumSpam(self.backend, uid, email, address)
+
+               # Get spam score
+               score = yield sfs.check()
+
+               return score >= 50
+
        # Registration
 
        def register(self, uid, email, first_name, last_name):
@@ -920,6 +931,85 @@ class Account(Object):
                        ])
 
 
+class StopForumSpam(Object):
+       def init(self, uid, email, address):
+               self.uid, self.email, self.address = uid, email, address
+
+       @tornado.gen.coroutine
+       def send_request(self, **kwargs):
+               arguments = {
+                       "json" : "1",
+               }
+               arguments.update(kwargs)
+
+               # Create request
+               request = tornado.httpclient.HTTPRequest(
+                       "https://api.stopforumspam.org/api", method="POST")
+               request.body = urllib.parse.urlencode(arguments)
+
+               # Send the request
+               response = yield self.backend.http_client.fetch(request)
+
+               # Decode the JSON response
+               return json.loads(response.body.decode())
+
+       @tornado.gen.coroutine
+       def check_address(self):
+               response = yield self.send_request(ip=self.address)
+
+               try:
+                       confidence = response["ip"]["confidence"]
+               except KeyError:
+                       confidence = 100
+
+               logging.debug("Confidence for %s: %s" % (self.address, confidence))
+
+               return confidence
+
+       @tornado.gen.coroutine
+       def check_username(self):
+               response = yield self.send_request(username=self.uid)
+
+               try:
+                       confidence = response["username"]["confidence"]
+               except KeyError:
+                       confidence = 100
+
+               logging.debug("Confidence for %s: %s" % (self.uid, confidence))
+
+               return confidence
+
+       @tornado.gen.coroutine
+       def check_email(self):
+               response = yield self.send_request(email=self.email)
+
+               try:
+                       confidence = response["email"]["confidence"]
+               except KeyError:
+                       confidence = 100
+
+               logging.debug("Confidence for %s: %s" % (self.email, confidence))
+
+               return confidence
+
+       @tornado.gen.coroutine
+       def check(self, threshold=95):
+               """
+                       This function tries to detect if we have a spammer.
+
+                       To honour the privacy of our users, we only send the IP
+                       address and username and if those are on the database, we
+                       will send the email address as well.
+               """
+               confidences = yield [self.check_address(), self.check_username()]
+
+               if any((c < threshold for c in confidences)):
+                       confidences += yield [self.check_email()]
+
+               # Build a score based on the lowest confidence
+               return 100 - min(confidences)
+
+
 if __name__ == "__main__":
        a = Accounts()