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