Validate twitter accounts when submitting a new blog
authorMagnus Hagander <magnus@hagander.net>
Sat, 18 Nov 2017 14:54:19 +0000 (15:54 +0100)
committerMagnus Hagander <magnus@hagander.net>
Sat, 18 Nov 2017 14:55:02 +0000 (15:55 +0100)
Do this by connecting to the twitter API and actually validate both that
the account exists, and that it's not protected. Protected accounts will
cause the follower-sync script to keep trying over and over again for
following, and there's not any point in promoting those anyway.

This adds a dependency on requests_oauthlib, but that's already used in
other pgweb projects so shouldn't be a problem.

hamnadmin/hamnadmin/register/forms.py
hamnadmin/hamnadmin/settings.py

index 5bf38e0a9cf8b08a239c089e84a6fb5d5d5b69f3..554bcd418b4682149e568c140657722f5152b017 100644 (file)
@@ -1,11 +1,15 @@
 from django import forms
 from django.contrib import messages
 from django.core.validators import MinLengthValidator
+from django.conf import settings
 
 from models import Blog
 
 from hamnadmin.util.aggregate import FeedFetcher
 
+import requests
+import requests_oauthlib
+
 class BlogEditForm(forms.ModelForm):
        class Meta:
                model = Blog
@@ -46,10 +50,32 @@ class BlogEditForm(forms.ModelForm):
                return self.cleaned_data
 
        def clean_twitteruser(self):
-               if self.cleaned_data['twitteruser'].startswith('@'):
-                       return self.cleaned_data['twitteruser'][1:]
-               else:
-                       return self.cleaned_data['twitteruser']
+               if self.cleaned_data['twitteruser'] == '':
+                       return ''
+
+               u = self.cleaned_data['twitteruser']
+               if u.startswith('@'):
+                       u = u[1:]
+
+               if not settings.TWITTER_CLIENT:
+                       # Can't validate beyond this unless we have client keys configured
+                       return u
+
+               tw = requests_oauthlib.OAuth1Session(settings.TWITTER_CLIENT,
+                                                                                        settings.TWITTER_CLIENTSECRET,
+                                                                                        settings.TWITTER_TOKEN,
+                                                                                        settings.TWITTER_TOKENSECRET)
+               try:
+                       r = tw.get('https://api.twitter.com/1.1/users/show.json?screen_name={0}'.format(u),
+                       timeout=5)
+                       if r.status_code != 200:
+                               raise forms.ValidationError("Could not find twitter user")
+                       j = r.json()
+                       if j['protected']:
+                               raise forms.ValidationError("Cannot register protected twitter accounts")
+               except requests.exceptions.ReadTimeout:
+                       raise forms.ValidationError("Timeout trying to validate account with twitter")
+               return u
 
 class ModerateRejectForm(forms.Form):
        message = forms.CharField(min_length=30, required=True, widget=forms.Textarea)
index 9de04158e57aec5f063f9de7cdd09acce518904c..1f240340b380fc4e3bb1420202f4acff9fbc3b28 100644 (file)
@@ -1,4 +1,5 @@
 # Django settings for admin project.
+import os
 
 DEBUG = False
 
@@ -74,6 +75,22 @@ NOTIFICATION_RECEIVER='planet@postgresql.org'
 # Set to None for testing
 VARNISH_URL="http://localhost/varnish-purge"
 
+# Dynamically load settings from the "outer" planet.ini that might
+# be needed.
+try:
+       import ConfigParser
+       _configparser = ConfigParser.ConfigParser()
+       _configparser.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), '../../planet.ini'))
+       TWITTER_CLIENT=_configparser.get('twitter', 'consumer')
+       TWITTER_CLIENTSECRET=_configparser.get('twitter', 'consumersecret')
+       TWITTER_TOKEN=_configparser.get('twitter', 'token')
+       TWITTER_TOKENSECRET=_configparser.get('twitter', 'secret')
+except:
+       TWITTER_CLIENT=None
+       TWITTER_CLIENTSECRET=None
+       TWITTER_TOKEN=None
+       TWITTER_TOKENSECRET=None
+
 # If there is a local_settings.py, let it override our settings
 try:
        from local_settings import *