Compatibility with different session backend + admin layout
This commit is contained in:
		@@ -14,25 +14,35 @@ from .models import ServiceTicket, ProxyTicket, ProxyGrantingTicket, User, Servi
 | 
			
		||||
from .models import Username, ReplaceAttributName, ReplaceAttributValue, FilterAttributValue
 | 
			
		||||
from .forms import TicketForm
 | 
			
		||||
 | 
			
		||||
tickets_readonly_fields=('validate', 'service', 'service_pattern', 'creation', 'renew', 'single_log_out', 'value')
 | 
			
		||||
tickets_fields = ('validate', 'service', 'service_pattern', 'creation', 'renew', 'single_log_out')
 | 
			
		||||
class ServiceTicketInline(admin.TabularInline):
 | 
			
		||||
    """`ServiceTicket` in admin interface"""
 | 
			
		||||
    model = ServiceTicket
 | 
			
		||||
    extra = 0
 | 
			
		||||
    form = TicketForm
 | 
			
		||||
    readonly_fields = tickets_readonly_fields
 | 
			
		||||
    fields = tickets_fields
 | 
			
		||||
class ProxyTicketInline(admin.TabularInline):
 | 
			
		||||
    """`ProxyTicket` in admin interface"""
 | 
			
		||||
    model = ProxyTicket
 | 
			
		||||
    extra = 0
 | 
			
		||||
    form = TicketForm
 | 
			
		||||
    readonly_fields = tickets_readonly_fields
 | 
			
		||||
    fields = tickets_fields
 | 
			
		||||
class ProxyGrantingInline(admin.TabularInline):
 | 
			
		||||
    """`ProxyGrantingTicket` in admin interface"""
 | 
			
		||||
    model = ProxyGrantingTicket
 | 
			
		||||
    extra = 0
 | 
			
		||||
    form = TicketForm
 | 
			
		||||
    readonly_fields = tickets_readonly_fields
 | 
			
		||||
    fields = tickets_fields[1:]
 | 
			
		||||
 | 
			
		||||
class UserAdmin(admin.ModelAdmin):
 | 
			
		||||
    """`User` in admin interface"""
 | 
			
		||||
    inlines = (ServiceTicketInline, ProxyTicketInline, ProxyGrantingInline)
 | 
			
		||||
    readonly_fields=('username', 'date', "session_key")
 | 
			
		||||
    fields = ('username', 'date', "session_key")
 | 
			
		||||
 | 
			
		||||
class UsernamesInline(admin.TabularInline):
 | 
			
		||||
    """`Username` in admin interface"""
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ import models
 | 
			
		||||
class UserCredential(forms.Form):
 | 
			
		||||
    """Form used on the login page to retrive user credentials"""
 | 
			
		||||
    username = forms.CharField(label=_('login'))
 | 
			
		||||
    service = forms.CharField(widget=forms.HiddenInput(), required=False)
 | 
			
		||||
    service = forms.CharField(label=_('service'), widget=forms.HiddenInput(), required=False)
 | 
			
		||||
    password = forms.CharField(label=_('password'), widget=forms.PasswordInput)
 | 
			
		||||
    lt = forms.CharField(widget=forms.HiddenInput(), required=False)
 | 
			
		||||
    method = forms.CharField(widget=forms.HiddenInput(), required=False)
 | 
			
		||||
@@ -34,12 +34,17 @@ class UserCredential(forms.Form):
 | 
			
		||||
        cleaned_data = super(UserCredential, self).clean()
 | 
			
		||||
        auth = utils.import_attr(settings.CAS_AUTH_CLASS)(cleaned_data.get("username"))
 | 
			
		||||
        if auth.test_password(cleaned_data.get("password")):
 | 
			
		||||
            session = utils.get_session(self.request)
 | 
			
		||||
            try:
 | 
			
		||||
                user = models.User.objects.get(username=auth.username, session=session)
 | 
			
		||||
                user = models.User.objects.get(
 | 
			
		||||
                    username=auth.username,
 | 
			
		||||
                    session_key=self.request.session_key
 | 
			
		||||
                )
 | 
			
		||||
                user.save()
 | 
			
		||||
            except models.User.DoesNotExist:
 | 
			
		||||
                user = models.User.objects.create(username=auth.username, session=session)
 | 
			
		||||
                user = models.User.objects.create(
 | 
			
		||||
                    username=auth.username,
 | 
			
		||||
                    session_key=self.request.session_key
 | 
			
		||||
                )
 | 
			
		||||
                user.save()
 | 
			
		||||
        else:
 | 
			
		||||
            raise forms.ValidationError(_(u"Bad user"))
 | 
			
		||||
@@ -50,4 +55,4 @@ class TicketForm(forms.ModelForm):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = models.Ticket
 | 
			
		||||
        exclude = []
 | 
			
		||||
    service = forms.CharField(widget=forms.TextInput)
 | 
			
		||||
    service = forms.CharField(label=_('service'), widget=forms.TextInput)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								cas_server/management/commands/cas_clean_sessions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								cas_server/management/commands/cas_clean_sessions.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
 | 
			
		||||
from ... import models
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
    args = ''
 | 
			
		||||
    help = _(u"Clean deleted sessions")
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        models.User.clean_deleted_sessions()
 | 
			
		||||
							
								
								
									
										28
									
								
								cas_server/migrations/0021_auto_20150611_2102.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								cas_server/migrations/0021_auto_20150611_2102.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import models, migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('cas_server', '0020_auto_20150609_1917'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='session_key',
 | 
			
		||||
            field=models.CharField(max_length=40, null=True, blank=True),
 | 
			
		||||
            preserve_default=True,
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterUniqueTogether(
 | 
			
		||||
            name='user',
 | 
			
		||||
            unique_together=set([('username', 'session_key')]),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.RemoveField(
 | 
			
		||||
            model_name='user',
 | 
			
		||||
            name='session',
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -17,33 +17,44 @@ from django.db.models import Q
 | 
			
		||||
from django.contrib import messages
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
from django.utils import timezone
 | 
			
		||||
from django.contrib.sessions.models import Session
 | 
			
		||||
from picklefield.fields import PickledObjectField
 | 
			
		||||
 | 
			
		||||
import re
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
from importlib import import_module
 | 
			
		||||
from datetime import timedelta
 | 
			
		||||
from concurrent.futures import ThreadPoolExecutor
 | 
			
		||||
from requests_futures.sessions import FuturesSession
 | 
			
		||||
 | 
			
		||||
import utils
 | 
			
		||||
 | 
			
		||||
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
 | 
			
		||||
 | 
			
		||||
class User(models.Model):
 | 
			
		||||
    """A user logged into the CAS"""
 | 
			
		||||
    class Meta:
 | 
			
		||||
        unique_together = ("username", "session")
 | 
			
		||||
    session = models.OneToOneField(Session, related_name="cas_server_user", blank=True, null=True, on_delete=models.SET_NULL)
 | 
			
		||||
        unique_together = ("username", "session_key")
 | 
			
		||||
    session_key = models.CharField(max_length=40, blank=True, null=True)
 | 
			
		||||
    username = models.CharField(max_length=30)
 | 
			
		||||
    date = models.DateTimeField(auto_now_add=True, auto_now=True)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def clean_old_entries(cls):
 | 
			
		||||
        users = cls.objects.filter(session=None)
 | 
			
		||||
        users = cls.objects.filter(
 | 
			
		||||
            date__lt=(timezone.now() - timedelta(seconds=settings.SESSION_COOKIE_AGE))
 | 
			
		||||
        )
 | 
			
		||||
        for user in users:
 | 
			
		||||
            user.logout()
 | 
			
		||||
        users.delete()
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def clean_deleted_sessions(cls):
 | 
			
		||||
        for user in cls.objects.all():
 | 
			
		||||
            if not SessionStore(session_key=user.session_key).get('authenticated'):
 | 
			
		||||
                user.logout()
 | 
			
		||||
                user.delete()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def attributs(self):
 | 
			
		||||
        """return a fresh dict for the user attributs"""
 | 
			
		||||
@@ -108,6 +119,7 @@ class User(models.Model):
 | 
			
		||||
            single_log_out=service_pattern.single_log_out
 | 
			
		||||
        )
 | 
			
		||||
        ticket.save()
 | 
			
		||||
        self.save()
 | 
			
		||||
        return ticket
 | 
			
		||||
 | 
			
		||||
    def get_service_url(self, service, service_pattern, renew):
 | 
			
		||||
@@ -321,7 +333,7 @@ class Ticket(models.Model):
 | 
			
		||||
    TIMEOUT = settings.CAS_TICKET_TIMEOUT
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return u"Ticket(%s, %s)" % (self.user, self.service)
 | 
			
		||||
        return u"Ticket-%s" % self.pk
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def clean_old_entries(cls):
 | 
			
		||||
@@ -394,13 +406,13 @@ class ServiceTicket(Ticket):
 | 
			
		||||
    PREFIX = settings.CAS_SERVICE_TICKET_PREFIX
 | 
			
		||||
    value = models.CharField(max_length=255, default=utils.gen_st, unique=True)
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return u"ServiceTicket(%s, %s, %s)" % (self.user, self.value, self.service)
 | 
			
		||||
        return u"ServiceTicket-%s" % self.pk
 | 
			
		||||
class ProxyTicket(Ticket):
 | 
			
		||||
    """A Proxy Ticket"""
 | 
			
		||||
    PREFIX = settings.CAS_PROXY_TICKET_PREFIX
 | 
			
		||||
    value = models.CharField(max_length=255, default=utils.gen_pt, unique=True)
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return u"ProxyTicket(%s, %s, %s)" % (self.user, self.value, self.service)
 | 
			
		||||
        return u"ProxyTicket-%s" % self.pk
 | 
			
		||||
class ProxyGrantingTicket(Ticket):
 | 
			
		||||
    """A Proxy Granting Ticket"""
 | 
			
		||||
    PREFIX = settings.CAS_PROXY_GRANTING_TICKET_PREFIX
 | 
			
		||||
@@ -409,7 +421,7 @@ class ProxyGrantingTicket(Ticket):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return u"ProxyGrantingTicket(%s, %s, %s)" % (self.user, self.value, self.service)
 | 
			
		||||
        return u"ProxyGrantingTicket-%s" % self.pk
 | 
			
		||||
 | 
			
		||||
class Proxy(models.Model):
 | 
			
		||||
    """A list of proxies on `ProxyTicket`"""
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ from .default_settings import settings
 | 
			
		||||
from django.utils.importlib import import_module
 | 
			
		||||
from django.core.urlresolvers import reverse
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.contrib.sessions.models import Session
 | 
			
		||||
 | 
			
		||||
import urlparse
 | 
			
		||||
import urllib
 | 
			
		||||
@@ -102,8 +101,3 @@ def gen_pgtiou():
 | 
			
		||||
def gen_saml_id():
 | 
			
		||||
    """Generate an saml id"""
 | 
			
		||||
    return _gen_ticket('_')
 | 
			
		||||
 | 
			
		||||
def get_session(request):
 | 
			
		||||
    if not request.session.exists(request.session.session_key):
 | 
			
		||||
        request.session.create()
 | 
			
		||||
    return Session.objects.get(session_key=request.session.session_key)
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ class LogoutMixin(object):
 | 
			
		||||
        try:
 | 
			
		||||
            user = models.User.objects.get(
 | 
			
		||||
                username=self.request.session.get("username"),
 | 
			
		||||
                session=utils.get_session(self.request)
 | 
			
		||||
                session_key=self.request.session_key
 | 
			
		||||
            )
 | 
			
		||||
            user.logout(self.request)
 | 
			
		||||
            user.delete()
 | 
			
		||||
@@ -156,7 +156,7 @@ class LoginView(View, LogoutMixin):
 | 
			
		||||
            if self.form.is_valid():
 | 
			
		||||
                self.user = models.User.objects.get(
 | 
			
		||||
                    username=self.form.cleaned_data['username'],
 | 
			
		||||
                    session=utils.get_session(self.request)
 | 
			
		||||
                    session_key=self.request.session_key
 | 
			
		||||
                )
 | 
			
		||||
                request.session.set_expiry(0)
 | 
			
		||||
                request.session["username"] = self.form.cleaned_data['username']
 | 
			
		||||
@@ -263,7 +263,7 @@ class LoginView(View, LogoutMixin):
 | 
			
		||||
        try:
 | 
			
		||||
            self.user = models.User.objects.get(
 | 
			
		||||
                username=self.request.session.get("username"),
 | 
			
		||||
                session=utils.get_session(self.request)
 | 
			
		||||
                session_key=self.request.session_key
 | 
			
		||||
            )
 | 
			
		||||
        except models.User.DoesNotExist:
 | 
			
		||||
            self.logout()
 | 
			
		||||
@@ -351,7 +351,7 @@ class Auth(View):
 | 
			
		||||
            try:
 | 
			
		||||
                user = models.User.objects.get(
 | 
			
		||||
                    username=form.cleaned_data['username'],
 | 
			
		||||
                    session=utils.get_session(request)
 | 
			
		||||
                    session_key=self.request.session_key
 | 
			
		||||
                )
 | 
			
		||||
                # is the service allowed
 | 
			
		||||
                service_pattern = ServicePattern.validate(service)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user