Search code examples
pythondjangoemailwhitelistblacklist

email whitelist/blacklist in python/django


I am writing a django app that keeps track of which email addresses are allowed to post content to a user's account. The user can whitelist and blacklist addresses as they like.

Any addresses that aren't specified can either be handled per message or just default to whitelist or blacklist (again user specified).

Here are the django models I wrote... do you think is a good way to do it? or should I add a whitelist and blacklist field to each user's profile model?

class knownEmail(models.Model):
    # The user who set this address' permission, NOT
    # the user who the address belongs to...
    relatedUser = models.ManyToManyField(User)
    email = models.EmailField()

class whiteList(knownEmail):
    pass

class blackList(knownEmail):
    pass

Then I could do something like:

def checkPermission(user, emailAddress):
    "Check if 'emailAddress' is allowed to post content to 'user's profile"
    if whiteList.objects.filter(relatedUser=user, email=emailAddress):
        return True
    elif blackList.objects.filter(relatedUser=user, email=emailAddress):
        return False
    else:
        return None

Is there a better way?


Solution

  • I would restructure it so both lists were contained in one model.

    class PermissionList(models.Model):
        setter = models.ManyToManyField(User)
        email = models.EmailField(unique=True) #don't want conflicting results
        permission = models.BooleanField()
    

    Then, your lists would just be:

    # whitelist
    PermissionList.objects.filter(permission=True)
    # blacklist
    PermissionList.objects.filter(permission=False)
    

    To check a particular user, you just add a couple functions to the model:

    class PermissionList(...):
        ...
        @classmethod
        def is_on_whitelist(email):
            return PermissionList.objects.filter(email=email, permission=True).count() > 0
    
        @classmethod
        def is_on_blacklist(email):
            return PermissionList.objects.filter(email=email, permission=False).count() > 0
    
        @classmethod
        def has_permission(email):
            if PermissionList.is_on_whitelist(email):
                return True
            if PermissionList.is_on_blacklist(email):
                return False
            return None
    

    Having everything in one place is a lot simpler, and you can make more interesting queries with less work.