def __init__(self): self._registry = OrderedDict(key=lambda t: t[1].order)
class AdminSite(object): url_prefix = 'stepping_out_admin' login_template = 'stepping_out/admin/login.html' logout_template = 'stepping_out/admin/logout.html' home_template = 'stepping_out/admin/home.html' account_create_template = 'stepping_out/registration/account_create.html' #account_create_done_template = 'stepping_out/registration/account_create_done.html' def __init__(self): self._registry = OrderedDict(key=lambda t: t[1].order) def register(self, section): """ Registers a given section with this AdminSite instance. """ if not issubclass(section, AdminSection): raise TypeError('%s must be a subclass of %s' % (section, AdminSection.__name__)) if section.slug in self._registry: raise AlreadyRegistered('A section is already registered as %s.' % section.slug) self._registry[section.slug] = section(self) def get_section(self, slug): try: return self._registry[slug] except KeyError: raise NotRegistered("Module with slug '%s' not found in registry" % slug) @property def sections(self): return self._registry def has_permission(self, request): if request.user.is_authenticated() and request.user.is_active: return True return False def admin_view(self, view, cacheable=False): """ Decorator to apply common decorators to views for this admin. """ # FIXME: prohibit caching? def inner(request, *args, **kwargs): if not self.has_permission(request): return self.login(request, *args, **kwargs) return view(request, *args, **kwargs) inner = csrf_protect(inner) return inner def get_urls(self): def wrap(view, cacheable=False): return self.admin_view(view, cacheable) # (*args, **kwargs) urlpatterns = patterns('', url(r'^$', wrap(self.home), name='%s_root' % self.url_prefix), url(r'^logout/$', self.logout, name='%s_logout' % self.url_prefix), url(r'^password/reset/$', 'django.contrib.auth.views.password_reset', {'template_name': 'stepping_out/registration/password_reset_form.html'}, name='%s_password_reset' % self.url_prefix), url(r'^password/reset/done/?$', auth_views.password_reset_done, {'template_name': 'stepping_out/registration/password_reset_done.html'}, name='%s_password_reset_done' % self.url_prefix), url(r'^password/reset/complete/?$', auth_views.password_reset_complete, {'template_name': 'stepping_out/registration/password_reset_complete.html'}, name='%s_password_reset_complete' % self.url_prefix), url(r'^password/reset/(?P<uidb36>\w+)/(?P<token>[^/]+)$', auth_views.password_reset_confirm, {'template_name': 'stepping_out/registration/password_reset_confirm.html'}, name='%s_password_reset_confirm' % self.url_prefix), url(r'^create/$', self.account_create, name='%s_account_create' % self.url_prefix), #url(r'^create/done/$', self.account_create_done, name='%s_account_create_done' % self.url_prefix), url(r'^create/confirm/(?P<uidb36>\w+)-(?P<token>.+)/$', self.account_confirm, name='%s_account_confirm' % self.url_prefix), url(r'^emails/add/(?P<uidb36>\w+)-(?P<eidb36>\w+)-(?P<token>.+)/$', self.add_email, name='%s_email_add' % self.url_prefix) ) for section in self._registry.values(): urlpatterns += patterns('', url(r'^%s/' % section.slug, include(section.urls)), ) return urlpatterns urls = property(get_urls) def get_context(self): return {} def get_nav(self, request): navbar = [] for admin in self._registry.values(): navbar += admin.get_nav(request) return navbar def home(self, request): try: return HttpResponseRedirect(self.get_section('home').get_root_url()) except NotRegistered: return render_to_response( self.home_template, context_instance=RequestContext(request) ) except: raise def display_login_form(self, request, message): request.session.set_test_cookie() if request.POST: form = LoginForm(request.POST) else: form = LoginForm() context = { 'message': message, 'form': form } return render_to_response( self.login_template, context, context_instance = RequestContext(request) ) def login(self, request, *args, **kwargs): """ Displays the login form for the given HttpRequest. """ from django.contrib.auth.models import User # If this isn't already the login page, display it. if not request.POST.has_key(LOGIN_FORM_KEY): if request.POST: message = _("Please log in again, because your session has expired.") else: message = "" return self.display_login_form(request, message) # Check that the user accepts cookies. if not request.session.test_cookie_worked(): message = _("Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again.") return self.display_login_form(request, message) else: request.session.delete_test_cookie() # Check the password. username = request.POST.get('username', None) password = request.POST.get('password', None) user = authenticate(username=username, password=password) if user is None: message = ERROR_MESSAGE if username is not None and u'@' in username: # Then they tried to log in with an email address and it failed. message = _("Please enter a correct email and password. Note that both fields are case-sensitive.") return self.display_login_form(request, message) # The user data is correct; log in the user in and continue. else: if user.is_active: login(request, user) return HttpResponseRedirect(request.get_full_path()) else: return self.display_login_form(request, ERROR_MESSAGE) login = never_cache(login) def logout(self, request): from django.contrib.auth.views import logout defaults = {} if self.logout_template is not None: defaults['template_name'] = self.logout_template return logout(request, **defaults) def account_create(self, request, token_generator=registration_token_generator): if request.method == 'POST': form = PendUserCreationForm(request.POST) humanity_form = TestHumanityForm(request.POST) if form.is_valid(): user = form.save() current_site = Site.objects.get_current() t = loader.get_template('stepping_out/registration/account_create_confirm_email.html') c = RequestContext(request, { 'site': current_site, 'protocol': 'http', 'url': reverse('%s_account_confirm' % self.url_prefix, kwargs={'uidb36': int_to_base36(user.id), 'token': token_generator.make_token(user)}) }) # send an email! send_mail('Account confirmation link', t.render(c), 'noreply@%s' % current_site.domain, [user.email]) messages.add_message(request, messages.SUCCESS, 'Account created. An email has been sent to the address you provided detailing how to activate your account.') return HttpResponseRedirect('') else: form = PendUserCreationForm() humanity_form = TestHumanityForm() c = { 'form': form, 'humanity_form': humanity_form } c.update(self.get_context(request)) return render_to_response(self.account_create_template, c, context_instance=RequestContext(request)) def account_confirm(self, request, uidb36=None, token=None, token_generator=registration_token_generator): assert uidb36 is not None and token is not None try: uid_int = base36_to_int(uidb36) except ValueError: raise Http404 user = get_object_or_404(User, id=uid_int) if token_generator.check_token(user, token): user.is_active = True # Set up their first useremail before save so that nasty things # don't happen w/ the autosyncing. useremail = UserEmail.objects.get_or_create(email=user.email)[0] useremail.user = user useremail.save() true_password = user.password try: user.set_password('tmp') user.save() user = authenticate(username=user.username, password='******') login(request, user) messages.add_message(request, messages.SUCCESS, "Your account's been activated! Welcome!") except: messages.add_message(request, messages.SUCCESS, "Your account's been activated! Go ahead and log in!") finally: # to make sure the true password is returned to its rightful place. user.password = true_password user.save() return HttpResponseRedirect(reverse('%s_root' % self.url_prefix)) # Should there be a pretty "link expired" page? raise Http404 def add_email(self, request, uidb36=None, eidb36=None, token=None, token_generator=email_token_generator): assert uidb36 is not None and eidb36 is not None and token is not None try: uid_int = base36_to_int(uidb36) eid_int = base36_to_int(eidb36) except ValueError: raise Http404 user = get_object_or_404(User, id=uid_int) email = get_object_or_404(UserEmail, id=eid_int) if token_generator.check_token(user, email, token): email.user = user email.save() messages.add_message(request, messages.SUCCESS, 'Email added successfully.') return HttpResponseRedirect(reverse('%s_root' % self.url_prefix)) raise Http404