File size: 2,268 Bytes
24e6f5b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import logging
from datetime import datetime
from bson import ObjectId
from django.conf import settings
from django.contrib.auth.hashers import check_password, make_password
from expense_tracker.utils import MongoDBClient

class MongoUser:
    """
    A custom User class that mimics Django's User model but stores data in MongoDB.
    """
    def __init__(self, data):
        self._id = data.get('_id')
        self.pk = str(self._id) if self._id else None
        self.id = self.pk
        
        self.username = data.get('username')
        self.email = data.get('email')
        self.password = data.get('password') # Hashed
        self.is_active = data.get('is_active', True)
        self.is_staff = data.get('is_staff', False)
        self.is_superuser = data.get('is_superuser', False)
        self.last_login = data.get('last_login')
        self.date_joined = data.get('date_joined')

    @property
    def is_authenticated(self):
        return True

    def save(self):
        # This is a helper, but actual saving logic might be in views/backend
        pass

    def __str__(self):
        return self.username

    def __eq__(self, other):
        return isinstance(other, MongoUser) and self.pk == other.pk

class MongoBackend:
    """
    Authentication Backend to authenticate against MongoDB users collection.
    """
    def authenticate(self, request, username=None, password=None, **kwargs):
        db = MongoDBClient.get_client()
        if username is None:
            username = kwargs.get('email')
            
        # Try finding by username or email
        user_data = db.users.find_one({'$or': [{'username': username}, {'email': username}]})
        
        if user_data:
            if check_password(password, user_data.get('password')):
                # Update last login
                db.users.update_one({'_id': user_data['_id']}, {'$set': {'last_login': datetime.now()}})
                return MongoUser(user_data)
        return None

    def get_user(self, user_id):
        try:
            db = MongoDBClient.get_client()
            user_data = db.users.find_one({'_id': ObjectId(user_id)})
            if user_data:
                return MongoUser(user_data)
        except:
            pass
        return None