""" Generic helper functions """

import logging

import random

from datetime import datetime
from hashlib import sha1

from django.contrib.sites.models import Site
from django.utils.encoding import force_bytes


logger = logging.getLogger(__name__)


# Possible actions that user can perform
ACTIONS = ('subscribe', 'unsubscribe', 'update')


def make_activation_code():
    """ Generate a unique activation code. """
    random_string = str(random.random())
    random_digest = sha1(force_bytes(random_string)).hexdigest()[:5]
    time_string = str(datetime.now().microsecond)

    combined_string = random_digest + time_string

    return sha1(force_bytes(combined_string)).hexdigest()


def get_default_sites():
    """ Get a list of id's for all sites; the default for newsletters. """
    return [site.id for site in Site.objects.all()]


class Singleton(type):
    """
    Singleton metaclass.
    Source:
    http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python
    """
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(
                *args, **kwargs
            )

        return cls._instances[cls]

""" Generic helper functions """

import logging


from django.contrib.sites.models import Site
from django.utils.crypto import get_random_string

logger = logging.getLogger(__name__)


# Possible actions that user can perform
ACTIONS = ('subscribe', 'unsubscribe', 'update')


def make_activation_code():
    """ Generate a unique activation code. """

    # Use Django's crypto get_random_string() instead of rolling our own.
    return get_random_string(length=40)


def get_default_sites():
    """ Get a list of id's for all sites; the default for newsletters. """
    return [site.id for site in Site.objects.all()]


class Singleton(type):
    """
    Singleton metaclass.
    Source:
    http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python
    """
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(
                *args, **kwargs
            )

        return cls._instances[cls]

Use Django’s crypto code to generate random code.
Use Django’s crypto code to generate random code.

Many thanks to Cédric Picard for his extensive
security report.
  """ Generic helper functions """
  
  import logging
  
- import random
- 
- from datetime import datetime
- from hashlib import sha1
  
  from django.contrib.sites.models import Site
+ from django.utils.crypto import get_random_string
- from django.utils.encoding import force_bytes
- 
  
  logger = logging.getLogger(__name__)
  
  
  # Possible actions that user can perform
  ACTIONS = ('subscribe', 'unsubscribe', 'update')
  
  
  def make_activation_code():
      """ Generate a unique activation code. """
-     random_string = str(random.random())
-     random_digest = sha1(force_bytes(random_string)).hexdigest()[:5]
-     time_string = str(datetime.now().microsecond)
  
+     # Use Django's crypto get_random_string() instead of rolling our own.
+     return get_random_string(length=40)
-     combined_string = random_digest + time_string
- 
-     return sha1(force_bytes(combined_string)).hexdigest()
  
  
  def get_default_sites():
      """ Get a list of id's for all sites; the default for newsletters. """
      return [site.id for site in Site.objects.all()]
  
  
  class Singleton(type):
      """
      Singleton metaclass.
      Source:
      http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python
      """
      _instances = {}
  
      def __call__(cls, *args, **kwargs):
          if cls not in cls._instances:
              cls._instances[cls] = super(Singleton, cls).__call__(
                  *args, **kwargs
              )
  
          return cls._instances[cls]
  
Use Django’s crypto code to generate random code.
## Code Before:
""" Generic helper functions """

import logging

import random

from datetime import datetime
from hashlib import sha1

from django.contrib.sites.models import Site
from django.utils.encoding import force_bytes


logger = logging.getLogger(__name__)


# Possible actions that user can perform
ACTIONS = ('subscribe', 'unsubscribe', 'update')


def make_activation_code():
    """ Generate a unique activation code. """
    random_string = str(random.random())
    random_digest = sha1(force_bytes(random_string)).hexdigest()[:5]
    time_string = str(datetime.now().microsecond)

    combined_string = random_digest + time_string

    return sha1(force_bytes(combined_string)).hexdigest()


def get_default_sites():
    """ Get a list of id's for all sites; the default for newsletters. """
    return [site.id for site in Site.objects.all()]


class Singleton(type):
    """
    Singleton metaclass.
    Source:
    http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python
    """
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(
                *args, **kwargs
            )

        return cls._instances[cls]

## Instruction:
Use Django’s crypto code to generate random code.
## Code After:
""" Generic helper functions """

import logging


from django.contrib.sites.models import Site
from django.utils.crypto import get_random_string

logger = logging.getLogger(__name__)


# Possible actions that user can perform
ACTIONS = ('subscribe', 'unsubscribe', 'update')


def make_activation_code():
    """ Generate a unique activation code. """

    # Use Django's crypto get_random_string() instead of rolling our own.
    return get_random_string(length=40)


def get_default_sites():
    """ Get a list of id's for all sites; the default for newsletters. """
    return [site.id for site in Site.objects.all()]


class Singleton(type):
    """
    Singleton metaclass.
    Source:
    http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python
    """
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(
                *args, **kwargs
            )

        return cls._instances[cls]
