| | 21 | |
|---|
| | 22 | def _display_login_form(request, error_message=''): |
|---|
| | 23 | request.session.set_test_cookie() |
|---|
| | 24 | if request.POST and request.POST.has_key('post_data'): |
|---|
| | 25 | # User has failed login BUT has previously saved post data. |
|---|
| | 26 | post_data = request.POST['post_data'] |
|---|
| | 27 | elif request.POST: |
|---|
| | 28 | # User's session must have expired; save their post data. |
|---|
| | 29 | post_data = _encode_post_data(request.POST) |
|---|
| | 30 | else: |
|---|
| | 31 | post_data = _encode_post_data({}) |
|---|
| | 32 | return render_to_response('admin/login.html', { |
|---|
| | 33 | 'title': _('Log in'), |
|---|
| | 34 | 'app_path': request.path, |
|---|
| | 35 | 'post_data': post_data, |
|---|
| | 36 | 'error_message': error_message |
|---|
| | 37 | }, context_instance=template.RequestContext(request)) |
|---|
| | 38 | |
|---|
| | 39 | def _encode_post_data(post_data): |
|---|
| | 40 | from django.conf import settings |
|---|
| | 41 | pickled = pickle.dumps(post_data) |
|---|
| | 42 | pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest() |
|---|
| | 43 | return base64.encodestring(pickled + pickled_md5) |
|---|
| | 44 | |
|---|
| | 45 | def _decode_post_data(encoded_data): |
|---|
| | 46 | from django.conf import settings |
|---|
| | 47 | encoded_data = base64.decodestring(encoded_data) |
|---|
| | 48 | pickled, tamper_check = encoded_data[:-32], encoded_data[-32:] |
|---|
| | 49 | if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check: |
|---|
| | 50 | from django.core.exceptions import SuspiciousOperation |
|---|
| | 51 | raise SuspiciousOperation, "User may have tampered with session cookie." |
|---|
| | 52 | return pickle.loads(pickled) |
|---|
| | 90 | def has_permission(self, request): |
|---|
| | 91 | """ |
|---|
| | 92 | Returns True if the given HttpRequest has permission to view |
|---|
| | 93 | *at least one* page in the admin site. |
|---|
| | 94 | """ |
|---|
| | 95 | return request.user.is_authenticated() and request.user.is_staff |
|---|
| | 96 | |
|---|
| | 97 | def root(self, request, url): |
|---|
| | 98 | """ |
|---|
| | 99 | Handles main URL routing for the admin app. |
|---|
| | 100 | |
|---|
| | 101 | `url` is the remainder of the URL -- e.g. 'comments/comment/'. |
|---|
| | 102 | """ |
|---|
| | 103 | if not self.has_permission(request): |
|---|
| | 104 | return self.login(request) |
|---|
| | 105 | url = url.rstrip('/') # Trim trailing slash, if it exists. |
|---|
| | 106 | if url == '': |
|---|
| | 107 | return self.index(request) |
|---|
| | 108 | raise NotImplementedError('Only the admin index page is implemented.') |
|---|
| | 109 | |
|---|
| | 110 | def login(self, request): |
|---|
| | 111 | """ |
|---|
| | 112 | Displays the login form for the given HttpRequest. |
|---|
| | 113 | """ |
|---|
| | 114 | # If this isn't already the login page, display it. |
|---|
| | 115 | if not request.POST.has_key(LOGIN_FORM_KEY): |
|---|
| | 116 | if request.POST: |
|---|
| | 117 | message = _("Please log in again, because your session has expired. Don't worry: Your submission has been saved.") |
|---|
| | 118 | else: |
|---|
| | 119 | message = "" |
|---|
| | 120 | return _display_login_form(request, message) |
|---|
| | 121 | |
|---|
| | 122 | # Check that the user accepts cookies. |
|---|
| | 123 | if not request.session.test_cookie_worked(): |
|---|
| | 124 | message = _("Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again.") |
|---|
| | 125 | return _display_login_form(request, message) |
|---|
| | 126 | |
|---|
| | 127 | # Check the password. |
|---|
| | 128 | username = request.POST.get('username', None) |
|---|
| | 129 | password = request.POST.get('password', None) |
|---|
| | 130 | user = authenticate(username=username, password=password) |
|---|
| | 131 | if user is None: |
|---|
| | 132 | message = ERROR_MESSAGE |
|---|
| | 133 | if '@' in username: |
|---|
| | 134 | # Mistakenly entered e-mail address instead of username? Look it up. |
|---|
| | 135 | try: |
|---|
| | 136 | user = User.objects.get(email=username) |
|---|
| | 137 | except User.DoesNotExist: |
|---|
| | 138 | message = _("Usernames cannot contain the '@' character.") |
|---|
| | 139 | else: |
|---|
| | 140 | message = _("Your e-mail address is not your username. Try '%s' instead.") % user.username |
|---|
| | 141 | return _display_login_form(request, message) |
|---|
| | 142 | |
|---|
| | 143 | # The user data is correct; log in the user in and continue. |
|---|
| | 144 | else: |
|---|
| | 145 | if user.is_active and user.is_staff: |
|---|
| | 146 | login(request, user) |
|---|
| | 147 | # TODO: set last_login with an event. |
|---|
| | 148 | user.last_login = datetime.datetime.now() |
|---|
| | 149 | user.save() |
|---|
| | 150 | if request.POST.has_key('post_data'): |
|---|
| | 151 | post_data = _decode_post_data(request.POST['post_data']) |
|---|
| | 152 | if post_data and not post_data.has_key(LOGIN_FORM_KEY): |
|---|
| | 153 | # overwrite request.POST with the saved post_data, and continue |
|---|
| | 154 | request.POST = post_data |
|---|
| | 155 | request.user = user |
|---|
| | 156 | return view_func(request, *args, **kwargs) |
|---|
| | 157 | else: |
|---|
| | 158 | request.session.delete_test_cookie() |
|---|
| | 159 | return http.HttpResponseRedirect(request.path) |
|---|
| | 160 | else: |
|---|
| | 161 | return _display_login_form(request, ERROR_MESSAGE) |
|---|
| | 162 | |
|---|
| | 163 | def index(self, request): |
|---|
| | 164 | app_list = [] |
|---|
| | 165 | user = request.user |
|---|
| | 166 | for model, model_admin in self._registry.items(): |
|---|
| | 167 | app_label = model._meta.app_label |
|---|
| | 168 | has_module_perms = user.has_module_perms(app_label) |
|---|
| | 169 | if has_module_perms: |
|---|
| | 170 | perms = { |
|---|
| | 171 | 'add': user.has_perm("%s.%s" % (app_label, model._meta.get_add_permission())), |
|---|
| | 172 | 'change': user.has_perm("%s.%s" % (app_label, model._meta.get_change_permission())), |
|---|
| | 173 | 'delete': user.has_perm("%s.%s" % (app_label, model._meta.get_delete_permission())), |
|---|
| | 174 | } |
|---|
| | 175 | |
|---|
| | 176 | # Check whether user has any perm for this module. |
|---|
| | 177 | # If so, add the module to the model_list. |
|---|
| | 178 | if True in perms.values(): |
|---|
| | 179 | model_dict = { |
|---|
| | 180 | 'name': capfirst(model._meta.verbose_name_plural), |
|---|
| | 181 | 'admin_url': '%s/%s/' % (app_label, model.__name__.lower()), |
|---|
| | 182 | 'perms': perms, |
|---|
| | 183 | } |
|---|
| | 184 | app_list.append({ |
|---|
| | 185 | 'name': app_label.title(), |
|---|
| | 186 | 'has_module_perms': has_module_perms, |
|---|
| | 187 | 'models': [model_dict], |
|---|
| | 188 | }) |
|---|
| | 189 | return render_to_response('admin/index.html', { |
|---|
| | 190 | 'title': _('Site administration'), |
|---|
| | 191 | 'app_list': app_list, |
|---|
| | 192 | }, context_instance=template.RequestContext(request)) |
|---|
| | 193 | |
|---|