# Path: server/apps/authentication/models.py
# class Account(AbstractBaseUser):
# 
#     TZ_CHOICES = [(tz, tz) for tz in pytz.common_timezones]
# 
#     email = models.EmailField(unique=True)
#     username = models.CharField(max_length=40, unique=True)
#     slug = models.SlugField(max_length=60, unique=True)
# 
#     name = models.CharField(verbose_name='Full Name', max_length=120, blank=True)
#     tagline = models.CharField(max_length=260, blank=True)
# 
#     external_avatar_url = models.CharField(max_length=260, blank=True, null=True)
# 
#     is_staff = models.BooleanField(default=False)
#     is_active = models.BooleanField(default=True)
#     is_admin = models.BooleanField(default=False)
# 
#     time_zone = models.CharField(max_length=64, null=True, default=settings.TIME_ZONE)
# 
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)
# 
#     objects = AccountManager()
# 
#     USERNAME_FIELD = 'email'
#     REQUIRED_FIELDS = ['username']
# 
#     class Meta:
#         ordering = ['slug']
# 
#     def save(self, *args, **kwargs):
# 
#         slug = slugify(self.username)
#         self.slug = slug
#         count = 0
#         while Account.objects.filter(slug=self.slug).exclude(pk=self.id).exists():
#             self.slug = '{0}{1}'.format(slug, count)
#             logger.debug('Slug conflict. Trying again with {0}'.format(self.slug))
#             count += 1
# 
#         super(Account, self).save(*args, **kwargs)
# 
#     def __str__(self):
#         return '@{0}'.format(self.username)
# 
#     def get_full_name(self):
#         return self.name
# 
#     def get_short_name(self):
#         if (self.name != ''):
#             # Try to extract the first name
#             names = self.name.split()
#             first_name = names[0]
#             return first_name
#         return self.username
# 
#     # For full access to Permission system, we needed to add the PermissionMixin
#     def has_perm(self, perm, obj=None):
#         return True
# 
#     def has_perms(perm_list, obj=None):
#         return True
# 
#     def has_module_perms(self, app_label):
#         return True
# 
#     # Custom Methods
#     # --------------
#     def get_absolute_url(self):
#         return '/account/%s/' % self.slug
# 
#     def get_edit_url(self):
#         return '%sedit/' % self.get_absolute_url()
# 
#     def get_token(self):
#         try:
#             token = Token.objects.get(user=self)
#         except:
#             token = Token.objects.create(user=self)
#         return token
# 
#     def get_gravatar_thumbnail_url(self, size=100):
#         # Set your variables here
#         email = self.email
#         default = 'identicon'
# 
#         # construct the url
#         gravatar_url = "https://secure.gravatar.com/avatar/" + hashlib.md5(email.lower().encode('utf-8')).hexdigest() + "?"
#         try:
#             # Python 3.4
#             gravatar_url += urllib.parse.urlencode({'d': default, 's': str(size)})
#         except:
#             # Python 2.7
#             gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
# 
#         return gravatar_url
# 
# Path: server/apps/authentication/tasks.py
# def send_new_user_notification(id, username, email):
#     '''
#     Information about the ContactMe form is sent via
#     SQS to an EB worker, who will then send notifications
#     to our Staff
# 
#     :param instance: ContactMessage object to email
#     :return: Nothing
#     '''
# 
#     subject = 'User @{0} (ID={1}) has registered with email {2}'.format(username, id, email)
# 
#     logger.debug(subject)


import json
import logging
from django.conf import settings
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from allauth.socialaccount.helpers import complete_social_login
from allauth.socialaccount.models import SocialApp, SocialLogin, SocialToken
from allauth.socialaccount.providers.facebook.views import fb_complete_login
from rest_framework import permissions, status, views, viewsets
from rest_framework.authentication import SessionAuthentication
from rest_framework.authtoken.models import Token
from rest_framework.decorators import action, permission_classes
from rest_framework.parsers import JSONParser
from rest_framework.permissions import AllowAny
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from apps.utils.permissions import *
from .models import Account
from .permissions import IsAccountOwner
from .serializers import *
from .tasks import send_new_user_notification
        if self.request.method == 'POST':
            return (permissions.AllowAny(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    @csrf_exempt
    def create(self, request):
        '''
        When you create an object using the serializer's .save() method, the
        object's attributes are set literally. This means that a user registering with
        the password 'password' will have their password stored as 'password'. This is bad
        for a couple of reasons: 1) Storing passwords in plain text is a massive security
        issue. 2) Django hashes and salts passwords before comparing them, so the user
        wouldn't be able to log in using 'password' as their password.

        We solve this problem by overriding the .create() method for this viewset and
        using Account.objects.create_user() to create the Account object.
        '''

        serializer = self.serializer_class(data=request.data)

        if serializer.is_valid():
            password = serializer.validated_data['password']
            confirm_password = serializer.validated_data['confirm_password']

            if password and confirm_password and password == confirm_password:

                # Note that for now, Accounts default to is_active=False
                # which means that we need to manually active them
                # This is to keep the site secure until we go live

# Path: server/apps/authentication/models.py
# class Account(AbstractBaseUser):
# 
#     TZ_CHOICES = [(tz, tz) for tz in pytz.common_timezones]
# 
#     email = models.EmailField(unique=True)
#     username = models.CharField(max_length=40, unique=True)
#     slug = models.SlugField(max_length=60, unique=True)
# 
#     name = models.CharField(verbose_name='Full Name', max_length=120, blank=True)
#     tagline = models.CharField(max_length=260, blank=True)
# 
#     external_avatar_url = models.CharField(max_length=260, blank=True, null=True)
# 
#     is_staff = models.BooleanField(default=False)
#     is_active = models.BooleanField(default=True)
#     is_admin = models.BooleanField(default=False)
# 
#     time_zone = models.CharField(max_length=64, null=True, default=settings.TIME_ZONE)
# 
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)
# 
#     objects = AccountManager()
# 
#     USERNAME_FIELD = 'email'
#     REQUIRED_FIELDS = ['username']
# 
#     class Meta:
#         ordering = ['slug']
# 
#     def save(self, *args, **kwargs):
# 
#         slug = slugify(self.username)
#         self.slug = slug
#         count = 0
#         while Account.objects.filter(slug=self.slug).exclude(pk=self.id).exists():
#             self.slug = '{0}{1}'.format(slug, count)
#             logger.debug('Slug conflict. Trying again with {0}'.format(self.slug))
#             count += 1
# 
#         super(Account, self).save(*args, **kwargs)
# 
#     def __str__(self):
#         return '@{0}'.format(self.username)
# 
#     def get_full_name(self):
#         return self.name
# 
#     def get_short_name(self):
#         if (self.name != ''):
#             # Try to extract the first name
#             names = self.name.split()
#             first_name = names[0]
#             return first_name
#         return self.username
# 
#     # For full access to Permission system, we needed to add the PermissionMixin
#     def has_perm(self, perm, obj=None):
#         return True
# 
#     def has_perms(perm_list, obj=None):
#         return True
# 
#     def has_module_perms(self, app_label):
#         return True
# 
#     # Custom Methods
#     # --------------
#     def get_absolute_url(self):
#         return '/account/%s/' % self.slug
# 
#     def get_edit_url(self):
#         return '%sedit/' % self.get_absolute_url()
# 
#     def get_token(self):
#         try:
#             token = Token.objects.get(user=self)
#         except:
#             token = Token.objects.create(user=self)
#         return token
# 
#     def get_gravatar_thumbnail_url(self, size=100):
#         # Set your variables here
#         email = self.email
#         default = 'identicon'
# 
#         # construct the url
#         gravatar_url = "https://secure.gravatar.com/avatar/" + hashlib.md5(email.lower().encode('utf-8')).hexdigest() + "?"
#         try:
#             # Python 3.4
#             gravatar_url += urllib.parse.urlencode({'d': default, 's': str(size)})
#         except:
#             # Python 2.7
#             gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
# 
#         return gravatar_url
# 
# Path: server/apps/authentication/tasks.py
# def send_new_user_notification(id, username, email):
#     '''
#     Information about the ContactMe form is sent via
#     SQS to an EB worker, who will then send notifications
#     to our Staff
# 
#     :param instance: ContactMessage object to email
#     :return: Nothing
#     '''
# 
#     subject = 'User @{0} (ID={1}) has registered with email {2}'.format(username, id, email)
# 
#     logger.debug(subject)


# Path: server/apps/authentication/api_views.py
import json
import logging
from django.conf import settings
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from allauth.socialaccount.helpers import complete_social_login
from allauth.socialaccount.models import SocialApp, SocialLogin, SocialToken
from allauth.socialaccount.providers.facebook.views import fb_complete_login
from rest_framework import permissions, status, views, viewsets
from rest_framework.authentication import SessionAuthentication
from rest_framework.authtoken.models import Token
from rest_framework.decorators import action, permission_classes
from rest_framework.parsers import JSONParser
from rest_framework.permissions import AllowAny
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from apps.utils.permissions import *
from .models import Account
from .permissions import IsAccountOwner
from .serializers import *
from .tasks import send_new_user_notification

        if self.request.method == 'POST':
            return (permissions.AllowAny(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    @csrf_exempt
    def create(self, request):
        '''
        When you create an object using the serializer's .save() method, the
        object's attributes are set literally. This means that a user registering with
        the password 'password' will have their password stored as 'password'. This is bad
        for a couple of reasons: 1) Storing passwords in plain text is a massive security
        issue. 2) Django hashes and salts passwords before comparing them, so the user
        wouldn't be able to log in using 'password' as their password.

        We solve this problem by overriding the .create() method for this viewset and
        using Account.objects.create_user() to create the Account object.
        '''

        serializer = self.serializer_class(data=request.data)

        if serializer.is_valid():
            password = serializer.validated_data['password']
            confirm_password = serializer.validated_data['confirm_password']

            if password and confirm_password and password == confirm_password:

                # Note that for now, Accounts default to is_active=False
                # which means that we need to manually active them
                # This is to keep the site secure until we go live

                account = Account.objects.create_user(**serializer.validated_data)