from django.shortcuts import render, redirect
from django.conf import settings
from django.http import HttpResponse, JsonResponse

from pymongo import MongoClient

import datetime
import hashlib
import string
import random

from .decorators import cors_allow_credentials


def home(request):
    return render(request, 'home.html')


def redirect_rocketchat(request):
    return redirect(settings.ROCKETCHAT)


def generate_id():
    n = 17
    chars = string.ascii_letters + string.digits
    random_id = ''.join(random.SystemRandom().choice(chars) for _ in range(n))

    return random_id


@cors_allow_credentials()
def api(request):
    """
    Implements API for Rocket.Chat IFrame authentication
    """
    if not request.user.is_authenticated():
        return HttpResponse(status=401)

    # Try to get user in mongo
    client = MongoClient("mongodb://" + settings.MONGO_DB)
    mongo = client.rocketchat

    user = mongo.users.find_one({'username': request.user.username})

    if not user:
        # Create the user if doesn't exist in mongo
        fullname = ' '.join([request.user.first_name, request.user.last_name])\
                      .strip()

        user = {
            '_id': generate_id(),
            'createdAt': datetime.datetime.now(),
            'emails': [{
                'address': request.user.email,
                'verified': True
            }],
            'name': fullname,
            'username': request.user.username,
            'active': True,
            'roles': [
                'user'
            ],
            'type': 'user',
            'avatarOrigin': 'gravatar',

            'status': 'away',
            'statusConnection': 'online',
            'utcOffset': -3,
            'statusDefault': 'away'
        }

        mongo.users.insert_one(user)

    # Generate token
    n = 50
    chars = string.ascii_letters + string.digits
    token = ''.join(random.SystemRandom().choice(chars) for _ in range(n))
    token = hashlib.sha1(token.encode()).hexdigest()

    user['services'] = {'iframe': {'token': token}}

    # Save the user back to mongo
    mongo.users.update_one({'_id': user['_id']}, {'$set': user})

    # Add the user to default channels
    mongo.rocketchat_room.update(
        {'default': True},
        {'$addToSet': {'usernames': request.user.username}},
    )

    default_rooms = mongo.rocketchat_room.find({'default': True})
    for default_room in default_rooms:
        now = datetime.datetime.now()

        subscription = {
            '_id': generate_id(),
            'open': True,
            'alert': False,
            'unread': 0,
            'ts': now,
            'rid': default_room['_id'],
            'name': default_room['name'],
            't': 'c',
            'u': {'_id': user['_id'], 'username': user['username']},
            '_updatedAt': now,
            'ls': now,
        }

        mongo.rocketchat_subscription.insert_one(subscription)

    return JsonResponse({
        'token': user['services']['iframe']['token'],
    })

@@ -2439,16 +2439,187 @@
 _rooms:%0A
+%0A        subscription = mongo.users.find_one(%7B%0A            'rid': default_room%5B'_id'%5D,%0A            'u': %7B'_id': user%5B'_id'%5D%7D,%0A        %7D)%0A%0A        if not subscription:%0A    
         
@@ -2649,32 +2649,36 @@
 .now()%0A%0A        
+    
 subscription = %7B
@@ -2674,24 +2674,28 @@
 ription = %7B%0A
+    
             
@@ -2728,16 +2728,20 @@
         
+    
 'open': 
@@ -2758,16 +2758,20 @@
         
+  
+  
 'alert':
@@ -2790,16 +2790,20 @@
         
+    
 'unread'
@@ -2819,16 +2819,20 @@
         
+ 
+   
 'ts': no
@@ -2826,32 +2826,36 @@
      'ts': now,%0A
+    
             'rid
@@ -2882,32 +2882,36 @@
 '%5D,%0A            
+    
 'name': default_
@@ -2936,16 +2936,20 @@
         
+    
 't': 'c'
@@ -2950,16 +2950,20 @@
 ': 'c',%0A
+    
         
@@ -3035,16 +3035,20 @@
         
+  
+  
 '_update
@@ -3070,16 +3070,20 @@
         
+    
 'ls': no
@@ -3085,35 +3085,43 @@
 ': now,%0A        
+ 
-%7D%0A%0A
+   %7D%0A%0A    
         mongo.ro

Check if subscription exists before adding