xref: /aosp_15_r20/external/autotest/frontend/apache_auth.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Lifrom django.contrib.auth.models import User, Group, check_password
2*9c5db199SXin Lifrom django.contrib.auth import backends
3*9c5db199SXin Lifrom django.contrib import auth
4*9c5db199SXin Lifrom django import http
5*9c5db199SXin Li
6*9c5db199SXin Lifrom autotest_lib.client.cros import constants
7*9c5db199SXin Lifrom autotest_lib.frontend import thread_local
8*9c5db199SXin Lifrom autotest_lib.frontend.afe import models, management
9*9c5db199SXin Lifrom autotest_lib.server import utils
10*9c5db199SXin Li
11*9c5db199SXin LiDEBUG_USER = 'debug_user'
12*9c5db199SXin Li
13*9c5db199SXin Liclass SimpleAuthBackend(backends.ModelBackend):
14*9c5db199SXin Li    """
15*9c5db199SXin Li    Automatically allows any login.  This backend is for use when Apache is
16*9c5db199SXin Li    doing the real authentication.  Also ensures logged-in user exists in
17*9c5db199SXin Li    frontend.afe.models.User database.
18*9c5db199SXin Li    """
19*9c5db199SXin Li    def authenticate(self, username=None, password=None):
20*9c5db199SXin Li        try:
21*9c5db199SXin Li            user = User.objects.get(username=username)
22*9c5db199SXin Li        except User.DoesNotExist:
23*9c5db199SXin Li            # password is meaningless
24*9c5db199SXin Li            user = User(username=username,
25*9c5db199SXin Li                        password='apache authentication')
26*9c5db199SXin Li            user.is_staff = True
27*9c5db199SXin Li            user.save() # need to save before adding groups
28*9c5db199SXin Li            user.groups.add(Group.objects.get(
29*9c5db199SXin Li                name=management.BASIC_ADMIN))
30*9c5db199SXin Li
31*9c5db199SXin Li        SimpleAuthBackend.check_afe_user(username)
32*9c5db199SXin Li        return user
33*9c5db199SXin Li
34*9c5db199SXin Li
35*9c5db199SXin Li    @staticmethod
36*9c5db199SXin Li    def check_afe_user(username):
37*9c5db199SXin Li        user, created = models.User.objects.get_or_create(login=username)
38*9c5db199SXin Li        if created:
39*9c5db199SXin Li            user.save()
40*9c5db199SXin Li
41*9c5db199SXin Li    def get_user(self, user_id):
42*9c5db199SXin Li        try:
43*9c5db199SXin Li            return User.objects.get(pk=user_id)
44*9c5db199SXin Li        except User.DoesNotExist:
45*9c5db199SXin Li            return None
46*9c5db199SXin Li
47*9c5db199SXin Li
48*9c5db199SXin Liclass GetApacheUserMiddleware(object):
49*9c5db199SXin Li    """
50*9c5db199SXin Li    Middleware for use when Apache is doing authentication.  Looks for
51*9c5db199SXin Li    REMOTE_USER in headers and passed the username found to
52*9c5db199SXin Li    thread_local.set_user().  If no such header is found, looks for
53*9c5db199SXin Li    HTTP_AUTHORIZATION header with username (this allows CLI to authenticate).
54*9c5db199SXin Li    If neither of those are found, DEBUG_USER is used.
55*9c5db199SXin Li    """
56*9c5db199SXin Li
57*9c5db199SXin Li    def process_request(self, request):
58*9c5db199SXin Li        # look for a username from Apache
59*9c5db199SXin Li        user = request.META.get('REMOTE_USER')
60*9c5db199SXin Li        if user is None:
61*9c5db199SXin Li            # look for a user in headers.  This is insecure but
62*9c5db199SXin Li            # it's our temporarily solution for CLI auth.
63*9c5db199SXin Li            user = request.META.get('HTTP_AUTHORIZATION')
64*9c5db199SXin Li        if user is None:
65*9c5db199SXin Li            # no user info - assume we're in development mode
66*9c5db199SXin Li            user = constants.MOBLAB_USER if utils.is_moblab() else DEBUG_USER
67*9c5db199SXin Li        thread_local.set_user(user)
68*9c5db199SXin Li
69*9c5db199SXin Li
70*9c5db199SXin Liclass ApacheAuthMiddleware(GetApacheUserMiddleware):
71*9c5db199SXin Li    """
72*9c5db199SXin Li    Like GetApacheUserMiddleware, but also logs the user into Django's auth
73*9c5db199SXin Li    system, and replaces the username in thread_local with the actual User model
74*9c5db199SXin Li    object.
75*9c5db199SXin Li    """
76*9c5db199SXin Li
77*9c5db199SXin Li
78*9c5db199SXin Li    def process_request(self, request):
79*9c5db199SXin Li        super(ApacheAuthMiddleware, self).process_request(request)
80*9c5db199SXin Li        username = thread_local.get_user()
81*9c5db199SXin Li        thread_local.set_user(None)
82*9c5db199SXin Li        user_object = auth.authenticate(username=username,
83*9c5db199SXin Li                                        password='')
84*9c5db199SXin Li        auth.login(request, user_object)
85*9c5db199SXin Li        thread_local.set_user(models.User.objects.get(login=username))
86