# Path: apps/core/models.py
# class UserProfile(models.Model):
#     """
#     denotes additional information of single user
#     - user:            user object
#     - gender:          gender; *H / *M / *F / *E or others
#     - birthday:        birthday
#     - point:           point for public services
#     - point_test:      point for test services
#     - email_new:       new email before auth
#     - email_authed:    email authed state
#     - test_only:       indicate test only account
#     - test_enabled:    test mode state
#     - facebook_id:     facebook unique id
#     - twitter_id:      twitter unique id
#     - kaist_id:        kaist uid
#     - kaist_info:      additional kaist info
#     - kaist_info_time: kaist info updated time
#     - sparcs_id:       sparcs id iff sparcs member
#     - expire_time:     expire time for permanent deletion
#     """
#     user = models.OneToOneField(User, on_delete=models.CASCADE,
#                                 related_name='profile')
#     gender = models.CharField(max_length=30)
#     birthday = models.DateField(blank=True, null=True)
#     point = models.IntegerField(default=0)
#     point_test = models.IntegerField(default=0)
#     email_new = models.EmailField(blank=True, null=True)
#     email_authed = models.BooleanField(default=False)
#     test_only = models.BooleanField(default=False)
#     test_enabled = models.BooleanField(default=False)
#     facebook_id = models.CharField(max_length=50, blank=True, null=True)
#     twitter_id = models.CharField(max_length=50, blank=True, null=True)
#     kaist_id = models.CharField(max_length=50, blank=True, null=True)
#     kaist_info = models.TextField(blank=True, null=True)
#     kaist_info_time = models.DateField(blank=True, null=True)
#     sparcs_id = models.CharField(max_length=50, blank=True, null=True)
#     expire_time = models.DateTimeField(blank=True, null=True)
# 
#     @property
#     def flags(self):
#         return {
#             'test': self.test_enabled,
#             'test-only': self.test_only,
#             'dev': self.user.is_staff or bool(self.sparcs_id),
#             'sparcs': bool(self.sparcs_id),
#             'sysop': self.user.is_staff,
#         }
# 
#     def gender_display(self):
#         if self.gender == '*M':
#             return 'Male'
#         elif self.gender == '*F':
#             return 'Female'
#         elif self.gender == '*H':
#             return 'Hide'
#         elif self.gender == '*E':
#             return 'etc'
#         return self.gender
# 
#     def activate(self):
#         if self.expire_time:
#             self.expire_time = None
#             self.save()
#             return True
#         return False
# 
#     def save_kaist_info(self, info):
#         self.kaist_id = info['userid']
#         self.kaist_info = json.dumps(info['kaist_info'])
#         self.kaist_info_time = timezone.now()
#         self.save()
# 
#     def __str__(self):
#         return f'{self.user}''s profile'


import json
import logging
import re
import uuid
import ldap3
import oauth2 as oauth
import requests
from urllib.parse import parse_qsl, urlencode
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from apps.core.models import UserProfile

def auth_tw_init(callback_url):
    body = f'oauth_callback={callback_url}'
    resp, content = tw_client.request(
        'https://twitter.com/oauth/request_token', 'POST', body)

    tokens = dict(parse_qsl(content.decode('utf-8')))
    oauth_token = tokens['oauth_token']
    url = f'https://twitter.com/oauth/authenticate?oauth_token={oauth_token}'
    return url, tokens


def auth_tw_callback(tokens, verifier):
    token = oauth.Token(tokens['oauth_token'], tokens['oauth_token_secret'])
    token.set_verifier(verifier)
    client = oauth.Client(tw_consumer, token)

    resp, content = client.request(
        'https://twitter.com/oauth/access_token', 'POST')
    tw_info = dict(parse_qsl(content.decode('utf-8')))

    # access denied
    if 'user_id' not in tw_info:
        return None, None

    info = {
        'userid': tw_info['user_id'],
        'first_name': tw_info['screen_name'],
        'gender': '*H',
    }

# Path: apps/core/models.py
# class UserProfile(models.Model):
#     """
#     denotes additional information of single user
#     - user:            user object
#     - gender:          gender; *H / *M / *F / *E or others
#     - birthday:        birthday
#     - point:           point for public services
#     - point_test:      point for test services
#     - email_new:       new email before auth
#     - email_authed:    email authed state
#     - test_only:       indicate test only account
#     - test_enabled:    test mode state
#     - facebook_id:     facebook unique id
#     - twitter_id:      twitter unique id
#     - kaist_id:        kaist uid
#     - kaist_info:      additional kaist info
#     - kaist_info_time: kaist info updated time
#     - sparcs_id:       sparcs id iff sparcs member
#     - expire_time:     expire time for permanent deletion
#     """
#     user = models.OneToOneField(User, on_delete=models.CASCADE,
#                                 related_name='profile')
#     gender = models.CharField(max_length=30)
#     birthday = models.DateField(blank=True, null=True)
#     point = models.IntegerField(default=0)
#     point_test = models.IntegerField(default=0)
#     email_new = models.EmailField(blank=True, null=True)
#     email_authed = models.BooleanField(default=False)
#     test_only = models.BooleanField(default=False)
#     test_enabled = models.BooleanField(default=False)
#     facebook_id = models.CharField(max_length=50, blank=True, null=True)
#     twitter_id = models.CharField(max_length=50, blank=True, null=True)
#     kaist_id = models.CharField(max_length=50, blank=True, null=True)
#     kaist_info = models.TextField(blank=True, null=True)
#     kaist_info_time = models.DateField(blank=True, null=True)
#     sparcs_id = models.CharField(max_length=50, blank=True, null=True)
#     expire_time = models.DateTimeField(blank=True, null=True)
# 
#     @property
#     def flags(self):
#         return {
#             'test': self.test_enabled,
#             'test-only': self.test_only,
#             'dev': self.user.is_staff or bool(self.sparcs_id),
#             'sparcs': bool(self.sparcs_id),
#             'sysop': self.user.is_staff,
#         }
# 
#     def gender_display(self):
#         if self.gender == '*M':
#             return 'Male'
#         elif self.gender == '*F':
#             return 'Female'
#         elif self.gender == '*H':
#             return 'Hide'
#         elif self.gender == '*E':
#             return 'etc'
#         return self.gender
# 
#     def activate(self):
#         if self.expire_time:
#             self.expire_time = None
#             self.save()
#             return True
#         return False
# 
#     def save_kaist_info(self, info):
#         self.kaist_id = info['userid']
#         self.kaist_info = json.dumps(info['kaist_info'])
#         self.kaist_info_time = timezone.now()
#         self.save()
# 
#     def __str__(self):
#         return f'{self.user}''s profile'


# Path: apps/core/backends/auth.py
import json
import logging
import re
import uuid
import ldap3
import oauth2 as oauth
import requests
from urllib.parse import parse_qsl, urlencode
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from apps.core.models import UserProfile


def auth_tw_init(callback_url):
    body = f'oauth_callback={callback_url}'
    resp, content = tw_client.request(
        'https://twitter.com/oauth/request_token', 'POST', body)

    tokens = dict(parse_qsl(content.decode('utf-8')))
    oauth_token = tokens['oauth_token']
    url = f'https://twitter.com/oauth/authenticate?oauth_token={oauth_token}'
    return url, tokens


def auth_tw_callback(tokens, verifier):
    token = oauth.Token(tokens['oauth_token'], tokens['oauth_token_secret'])
    token.set_verifier(verifier)
    client = oauth.Client(tw_consumer, token)

    resp, content = client.request(
        'https://twitter.com/oauth/access_token', 'POST')
    tw_info = dict(parse_qsl(content.decode('utf-8')))

    # access denied
    if 'user_id' not in tw_info:
        return None, None

    info = {
        'userid': tw_info['user_id'],
        'first_name': tw_info['screen_name'],
        'gender': '*H',
    }

    tw_profile = UserProfile.objects.filter(twitter_id=info['userid'],