Drop dependancies django-picklefield and django-bootstrap3

This commit is contained in:
Valentin Samir 2016-07-24 01:49:03 +02:00
parent ff9566289d
commit 3ff4bb16a9
21 changed files with 248 additions and 110 deletions

1
.gitignore vendored
View File

@ -4,7 +4,6 @@
*.swp *.swp
build/ build/
bootstrap3
cas/ cas/
dist/ dist/
db.sqlite3 db.sqlite3

View File

@ -44,7 +44,7 @@ test_venv/cas/manage.py: test_venv
mkdir -p test_venv/cas mkdir -p test_venv/cas
test_venv/bin/django-admin startproject cas test_venv/cas test_venv/bin/django-admin startproject cas test_venv/cas
ln -s ../../cas_server test_venv/cas/cas_server ln -s ../../cas_server test_venv/cas/cas_server
sed -i "s/'django.contrib.staticfiles',/'django.contrib.staticfiles',\n 'bootstrap3',\n 'cas_server',/" test_venv/cas/cas/settings.py sed -i "s/'django.contrib.staticfiles',/'django.contrib.staticfiles',\n 'cas_server',/" test_venv/cas/cas/settings.py
sed -i "s/'django.middleware.clickjacking.XFrameOptionsMiddleware',/'django.middleware.clickjacking.XFrameOptionsMiddleware',\n 'django.middleware.locale.LocaleMiddleware',/" test_venv/cas/cas/settings.py sed -i "s/'django.middleware.clickjacking.XFrameOptionsMiddleware',/'django.middleware.clickjacking.XFrameOptionsMiddleware',\n 'django.middleware.locale.LocaleMiddleware',/" test_venv/cas/cas/settings.py
sed -i 's/from django.conf.urls import url/from django.conf.urls import url, include/' test_venv/cas/cas/urls.py sed -i 's/from django.conf.urls import url/from django.conf.urls import url, include/' test_venv/cas/cas/urls.py
sed -i "s@url(r'^admin/', admin.site.urls),@url(r'^admin/', admin.site.urls),\n url(r'^', include('cas_server.urls', namespace='cas_server')),@" test_venv/cas/cas/urls.py sed -i "s@url(r'^admin/', admin.site.urls),@url(r'^admin/', admin.site.urls),\n url(r'^', include('cas_server.urls', namespace='cas_server')),@" test_venv/cas/cas/urls.py

View File

@ -9,13 +9,6 @@ CAS Server is a Django application implementing the `CAS Protocol 3.0 Specificat
By default, the authentication process use django internal users but you can easily By default, the authentication process use django internal users but you can easily
use any sources (see auth classes in the auth.py file) use any sources (see auth classes in the auth.py file)
The default login/logout template use `django-bootstrap3 <https://github.com/dyve/django-bootstrap3>`__
but you can use your own templates using settings variables.
Note that for Django 1.7 compatibility, you need a version of
`django-bootstrap3 <https://github.com/dyve/django-bootstrap3>`__ < 7.0.0
like the 6.2.2 version.
.. contents:: Table of Contents .. contents:: Table of Contents
Features Features
@ -39,8 +32,6 @@ Dependencies
* Django >= 1.7 < 1.10 * Django >= 1.7 < 1.10
* requests >= 2.4 * requests >= 2.4
* requests_futures >= 0.9.5 * requests_futures >= 0.9.5
* django-picklefield >= 0.3.1
* django-bootstrap3 >= 5.4 (< 7.0.0 if using django 1.7)
* lxml >= 3.4 * lxml >= 3.4
* six >= 1 * six >= 1
@ -55,7 +46,7 @@ The recommended installation mode is to use a virtualenv with ``--system-site-pa
On debian like systems:: On debian like systems::
$ sudo apt-get install python-django python-requests python-django-picklefield python-six python-lxml $ sudo apt-get install python-django python-requests python-six python-lxml python-requests-futures
On debian jessie, you can use the version of python-django available in the On debian jessie, you can use the version of python-django available in the
`backports <https://backports.debian.org/Instructions/>`_. `backports <https://backports.debian.org/Instructions/>`_.
@ -105,7 +96,6 @@ Quick start
INSTALLED_APPS = ( INSTALLED_APPS = (
'django.contrib.admin', 'django.contrib.admin',
... ...
'bootstrap3',
'cas_server', 'cas_server',
) )
@ -173,6 +163,17 @@ Template settings
* ``CAS_LOGO_URL``: URL to the logo showed in the up left corner on the default * ``CAS_LOGO_URL``: URL to the logo showed in the up left corner on the default
templates. Set it to ``False`` to disable it. templates. Set it to ``False`` to disable it.
* ``CAS_COMPONENT_URLS``: URLs to css and javascript external components. It is a dictionnary
and it must have the five following keys: ``"bootstrap3_css"``, ``"bootstrap3_js"``,
``"html5shiv"``, ``"respond"``, ``"jquery"``. The default is::
{
"bootstrap3_css": "//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
"bootstrap3_js": "//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js",
"html5shiv": "//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js",
"respond": "//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js",
"jquery": "//code.jquery.com/jquery.min.js",
}
* ``CAS_LOGIN_TEMPLATE``: Path to the template showed on ``/login`` then the user * ``CAS_LOGIN_TEMPLATE``: Path to the template showed on ``/login`` then the user
is not autenticated. The default is ``"cas_server/login.html"``. is not autenticated. The default is ``"cas_server/login.html"``.

View File

@ -18,6 +18,14 @@ from importlib import import_module
#: URL to the logo showed in the up left corner on the default templates. #: URL to the logo showed in the up left corner on the default templates.
CAS_LOGO_URL = static("cas_server/logo.png") CAS_LOGO_URL = static("cas_server/logo.png")
#: URLs to css and javascript external components.
CAS_COMPONENT_URLS = {
"bootstrap3_css": "//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
"bootstrap3_js": "//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js",
"html5shiv": "//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js",
"respond": "//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js",
"jquery": "//code.jquery.com/jquery.min.js",
}
#: Path to the template showed on /login then the user is not autenticated. #: Path to the template showed on /login then the user is not autenticated.
CAS_LOGIN_TEMPLATE = 'cas_server/login.html' CAS_LOGIN_TEMPLATE = 'cas_server/login.html'
#: Path to the template showed on /login?service=... then the user is authenticated and has asked #: Path to the template showed on /login?service=... then the user is authenticated and has asked

View File

@ -84,7 +84,7 @@ class CASFederateValidateUser(object):
if username is not None: if username is not None:
if attributs is None: if attributs is None:
attributs = {} attributs = {}
attributs["provider"] = self.provider attributs["provider"] = self.provider.suffix
self.username = username self.username = username
self.attributs = attributs self.attributs = attributs
user = FederatedUser.objects.update_or_create( user = FederatedUser.objects.update_or_create(

View File

@ -18,7 +18,28 @@ import cas_server.utils as utils
import cas_server.models as models import cas_server.models as models
class WarnForm(forms.Form): class BootsrapForm(forms.Form):
"""Form base class to use boostrap then rendering the form fields"""
def __init__(self, *args, **kwargs):
super(BootsrapForm, self).__init__(*args, **kwargs)
for (name, field) in self.fields.items():
# Only tweak the fiel if it will be displayed
if not isinstance(field.widget, forms.HiddenInput):
# tell to display the field (used in form.html)
self[name].display = True
attrs = {}
if isinstance(field.widget, forms.CheckboxInput):
self[name].checkbox = True
else:
attrs['class'] = "form-control"
if field.label:
attrs["placeholder"] = field.label
if field.required:
attrs["required"] = "required"
field.widget.attrs.update(attrs)
class WarnForm(BootsrapForm):
""" """
Bases: :class:`django.forms.Form` Bases: :class:`django.forms.Form`
@ -38,7 +59,7 @@ class WarnForm(forms.Form):
lt = forms.CharField(widget=forms.HiddenInput(), required=False) lt = forms.CharField(widget=forms.HiddenInput(), required=False)
class FederateSelect(forms.Form): class FederateSelect(BootsrapForm):
""" """
Bases: :class:`django.forms.Form` Bases: :class:`django.forms.Form`
@ -66,7 +87,7 @@ class FederateSelect(forms.Form):
renew = forms.BooleanField(widget=forms.HiddenInput(), required=False) renew = forms.BooleanField(widget=forms.HiddenInput(), required=False)
class UserCredential(forms.Form): class UserCredential(BootsrapForm):
""" """
Bases: :class:`django.forms.Form` Bases: :class:`django.forms.Form`

View File

@ -4,7 +4,6 @@ from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
import django.db.models.deletion import django.db.models.deletion
import cas_server.utils import cas_server.utils
import picklefield.fields
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -31,7 +30,7 @@ class Migration(migrations.Migration):
name='ProxyGrantingTicket', name='ProxyGrantingTicket',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('attributs', picklefield.fields.PickledObjectField(editable=False)), ('attributs', models.TextField(blank=True, default=None, null=True)),
('validate', models.BooleanField(default=False)), ('validate', models.BooleanField(default=False)),
('service', models.TextField()), ('service', models.TextField()),
('creation', models.DateTimeField(auto_now_add=True)), ('creation', models.DateTimeField(auto_now_add=True)),
@ -47,7 +46,7 @@ class Migration(migrations.Migration):
name='ProxyTicket', name='ProxyTicket',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('attributs', picklefield.fields.PickledObjectField(editable=False)), ('attributs', models.TextField(blank=True, default=None, null=True)),
('validate', models.BooleanField(default=False)), ('validate', models.BooleanField(default=False)),
('service', models.TextField()), ('service', models.TextField()),
('creation', models.DateTimeField(auto_now_add=True)), ('creation', models.DateTimeField(auto_now_add=True)),
@ -80,7 +79,7 @@ class Migration(migrations.Migration):
name='ServiceTicket', name='ServiceTicket',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('attributs', picklefield.fields.PickledObjectField(editable=False)), ('attributs', models.TextField(blank=True, default=None, null=True)),
('validate', models.BooleanField(default=False)), ('validate', models.BooleanField(default=False)),
('service', models.TextField()), ('service', models.TextField()),
('creation', models.DateTimeField(auto_now_add=True)), ('creation', models.DateTimeField(auto_now_add=True)),

View File

@ -3,7 +3,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import picklefield.fields
import django.db.models.deletion import django.db.models.deletion
@ -41,7 +40,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('username', models.CharField(max_length=124)), ('username', models.CharField(max_length=124)),
('provider', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cas_server.FederatedIendityProvider')), ('provider', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cas_server.FederatedIendityProvider')),
('attributs', picklefield.fields.PickledObjectField(editable=False)), ('attributs', models.TextField(blank=True, default=None, null=True)),
('ticket', models.CharField(max_length=255)), ('ticket', models.CharField(max_length=255)),
('last_update', models.DateTimeField(auto_now=True)), ('last_update', models.DateTimeField(auto_now=True)),
], ],

View File

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.8 on 2016-07-23 22:52
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cas_server', '0006_auto_20160706_1727'),
]
operations = [
migrations.RemoveField(
model_name='federateduser',
name='attributs',
),
migrations.RemoveField(
model_name='proxygrantingticket',
name='attributs',
),
migrations.RemoveField(
model_name='proxyticket',
name='attributs',
),
migrations.RemoveField(
model_name='serviceticket',
name='attributs',
),
migrations.AddField(
model_name='federateduser',
name='_attributs',
field=models.TextField(blank=True, default=None, null=True),
),
migrations.AddField(
model_name='proxygrantingticket',
name='_attributs',
field=models.TextField(blank=True, default=None, null=True),
),
migrations.AddField(
model_name='proxyticket',
name='_attributs',
field=models.TextField(blank=True, default=None, null=True),
),
migrations.AddField(
model_name='serviceticket',
name='_attributs',
field=models.TextField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='federatediendityprovider',
name='suffix',
field=models.CharField(help_text='Suffix append to backend CAS returned username: ``returned_username`` @ ``suffix``.', max_length=30, unique=True, verbose_name='suffix'),
),
]

View File

@ -18,7 +18,6 @@ from django.contrib import messages
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from picklefield.fields import PickledObjectField
import re import re
import sys import sys
@ -140,8 +139,8 @@ class FederatedUser(models.Model):
username = models.CharField(max_length=124) username = models.CharField(max_length=124)
#: A foreign key to :class:`FederatedIendityProvider` #: A foreign key to :class:`FederatedIendityProvider`
provider = models.ForeignKey(FederatedIendityProvider, on_delete=models.CASCADE) provider = models.ForeignKey(FederatedIendityProvider, on_delete=models.CASCADE)
#: The user attributes returned by the CAS backend on successful ticket validation #: The user attributes json encoded
attributs = PickledObjectField() _attributs = models.TextField(default=None, null=True, blank=True)
#: The last ticket used to authenticate :attr:`username` against :attr:`provider` #: The last ticket used to authenticate :attr:`username` against :attr:`provider`
ticket = models.CharField(max_length=255) ticket = models.CharField(max_length=255)
#: Last update timespampt. Usually, the last time :attr:`ticket` has been set. #: Last update timespampt. Usually, the last time :attr:`ticket` has been set.
@ -150,6 +149,17 @@ class FederatedUser(models.Model):
def __str__(self): def __str__(self):
return self.federated_username return self.federated_username
@property
def attributs(self):
"""The user attributes returned by the CAS backend on successful ticket validation"""
if self._attributs is not None:
return utils.json.loads(self._attributs)
@attributs.setter
def attributs(self, value):
"""attributs property setter"""
self._attributs = utils.json_encode(value)
@property @property
def federated_username(self): def federated_username(self):
"""The federated username with a suffix for the current :class:`FederatedUser`.""" """The federated username with a suffix for the current :class:`FederatedUser`."""
@ -712,8 +722,8 @@ class Ticket(models.Model):
abstract = True abstract = True
#: ForeignKey to a :class:`User`. #: ForeignKey to a :class:`User`.
user = models.ForeignKey(User, related_name="%(class)s") user = models.ForeignKey(User, related_name="%(class)s")
#: The user attributes to be transmited to the service on successful validation #: The user attributes to transmit to the service json encoded
attributs = PickledObjectField() _attributs = models.TextField(default=None, null=True, blank=True)
#: A boolean. ``True`` if the ticket has been validated #: A boolean. ``True`` if the ticket has been validated
validate = models.BooleanField(default=False) validate = models.BooleanField(default=False)
#: The service url for the ticket #: The service url for the ticket
@ -736,6 +746,17 @@ class Ticket(models.Model):
#: requests. #: requests.
TIMEOUT = settings.CAS_TICKET_TIMEOUT TIMEOUT = settings.CAS_TICKET_TIMEOUT
@property
def attributs(self):
"""The user attributes to be transmited to the service on successful validation"""
if self._attributs is not None:
return utils.json.loads(self._attributs)
@attributs.setter
def attributs(self, value):
"""attributs property setter"""
self._attributs = utils.json_encode(value)
class DoesNotExist(Exception): class DoesNotExist(Exception):
"""raised in :meth:`Ticket.get` then ticket prefix and ticket classes mismatch""" """raised in :meth:`Ticket.get` then ticket prefix and ticket classes mismatch"""
pass pass

View File

@ -1,16 +1,23 @@
{% extends 'bootstrap3/bootstrap3.html' %}
{% load i18n %} {% load i18n %}
{% block bootstrap3_title %}{% block title %}{% trans "Central Authentication Service" %}{% endblock %}{% endblock %}
{% load staticfiles %} {% load staticfiles %}
{% load bootstrap3 %} <!DOCTYPE html>
<html{% if request.LANGUAGE_CODE %} lang="{{ request.LANGUAGE_CODE }}"{% endif %}>
{% block bootstrap3_extra_head %} <head>
<link rel="shortcut icon" href="/static/cas_server/favicon.ico?v=1" /> <meta charset="utf-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge" /><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% trans "Central Authentication Service" %}{% endblock %}</title>
<link href="{{settings.CAS_COMPONENT_URLS.bootstrap3_css}}" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="{{settings.CAS_COMPONENT_URLS.html5shiv}}"></script>
<script src="{{settings.CAS_COMPONENT_URLS.respond}}"></script>
<![endif]-->
<link rel="shortcut icon" href="{% static "cas_server/favicon.ico?v=1" %}" />
<link href="{% static "cas_server/login.css" %}" rel="stylesheet"> <link href="{% static "cas_server/login.css" %}" rel="stylesheet">
{% endblock %} </head>
<body>
{% block bootstrap3_content %}
<div class="container"> <div class="container">
{% if auto_submit %}<noscript>{% endif %} {% if auto_submit %}<noscript>{% endif %}
<div class="row"> <div class="row">
@ -24,13 +31,33 @@
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-3 col-sm-2 col-xs-12"></div> <div class="col-lg-3 col-md-3 col-sm-2 col-xs-12"></div>
<div class="col-lg-6 col-md-6 col-sm-8 col-xs-12"> <div class="col-lg-6 col-md-6 col-sm-8 col-xs-12">
{% block ante_messages %}{% endblock %}
{% if auto_submit %}<noscript>{% endif %} {% if auto_submit %}<noscript>{% endif %}
{% bootstrap_messages %} {% for message in messages %}
<div {% spaceless %}
{% if message.level == message_levels.DEBUG %}
class="alert alert-warning alert-dismissable"
{% elif message.level == message_levels.INFO %}
class="alert alert-info alert-dismissable"
{% elif message.level == message_levels.SUCCESS %}
class="alert alert-success alert-dismissable"
{% elif message.level == message_levels.WARNING %}
class="alert alert-warning alert-dismissable"
{% else %}
class="alert alert-danger alert-dismissable"
{% endif %}
{% endspaceless %}>
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&#215;</button>
{{ message }}
</div>
{% endfor %}
{% if auto_submit %}</noscript>{% endif %} {% if auto_submit %}</noscript>{% endif %}
{% block content %} {% block content %}{% endblock %}
{% endblock %}
</div> </div>
<div class="col-lg-3 col-md-3 col-sm-2 col-xs-0"></div> <div class="col-lg-3 col-md-3 col-sm-2 col-xs-0"></div>
</div> </div>
</div> <!-- /container --> </div> <!-- /container -->
{% endblock %} <script src="{{settings.CAS_COMPONENT_URLS.jquery}}"></script>
<script src="{{settings.CAS_COMPONENT_URLS.bootstrap3_js}}"></script>
</body>
</html>

View File

@ -0,0 +1,25 @@
{% for error in form.non_field_errors %}
<div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&#215;</button>
{{error}}
</div>
{% endfor %}
{% for field in form %}{% if field.display %}
<div class="form-group{% spaceless %}
{% if not form.non_field_errors %}
{% if field.errors %} has-error
{% elif form.cleaned_data %} has-success
{% endif %}
{% endif %}"
{% endspaceless %}>{% spaceless %}
{% if field.checkbox %}
<div class="checkbox"><label for="{{field.auto_id}}">{{field}}{{field.label}}</label>
{% else %}
<label class="control-label" for="{{field.auto_id}}">{{field.label}}</label>
{{field}}
{% endif %}
{% for error in field.errors %}
<span class="help-block">{{error}}</span>
{% endfor %}
{% endspaceless %}</div>
{% else %}{{field}}{% endif %}{% endfor %}

View File

@ -1,6 +1,4 @@
{% extends "cas_server/base.html" %} {% extends "cas_server/base.html" %}
{% load bootstrap3 %}
{% load staticfiles %}
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}
<div class="alert alert-success" role="alert">{% trans "Logged" %}</div> <div class="alert alert-success" role="alert">{% trans "Logged" %}</div>
@ -10,7 +8,7 @@
<input type="checkbox" name="all" value="1"> {% trans "Log me out from all my sessions" %} <input type="checkbox" name="all" value="1"> {% trans "Log me out from all my sessions" %}
</label> </label>
</div> </div>
{% bootstrap_button _('Logout') size='lg' button_type="submit" button_class="btn-danger btn-block"%} <button class="btn btn-danger btn-block btn-lg" type="submit">{% trans "Logout" %}</button>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -1,16 +1,17 @@
{% extends "cas_server/base.html" %} {% extends "cas_server/base.html" %}
{% load bootstrap3 %}
{% load staticfiles %}
{% load i18n %} {% load i18n %}
{% block content %}
<form class="form-signin" method="post" id="login_form"{% if post_url %} action="{{post_url}}"{% endif %}> {% block ante_messages %}
{% if auto_submit %}<noscript>{% endif %} {% if auto_submit %}<noscript>{% endif %}
<h2 class="form-signin-heading">{% trans "Please log in" %}</h2> <h2 class="form-signin-heading">{% trans "Please log in" %}</h2>
{% if auto_submit %}</noscript>{% endif %} {% if auto_submit %}</noscript>{% endif %}
{% endblock %}
{% block content %}
<form class="form-signin" method="post" id="login_form"{% if post_url %} action="{{post_url}}"{% endif %}>
{% csrf_token %} {% csrf_token %}
{% bootstrap_form form %} {% include "cas_server/form.html" %}
{% if auto_submit %}<noscript>{% endif %} {% if auto_submit %}<noscript>{% endif %}
{% bootstrap_button _('Login') size='lg' button_type="submit" button_class="btn-primary btn-block"%} <button class="btn btn-primary btn-block btn-lg" type="submit">{% trans "Login" %}</button>
{% if auto_submit %}</noscript>{% endif %} {% if auto_submit %}</noscript>{% endif %}
</form> </form>
{% if auto_submit %} {% if auto_submit %}

View File

@ -1,5 +1,4 @@
{% extends "cas_server/base.html" %} {% extends "cas_server/base.html" %}
{% load bootstrap3 %}
{% load staticfiles %} {% load staticfiles %}
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}

View File

@ -1,12 +1,11 @@
{% extends "cas_server/base.html" %} {% extends "cas_server/base.html" %}
{% load bootstrap3 %}
{% load staticfiles %} {% load staticfiles %}
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}
<form class="form-signin" method="post"> <form class="form-signin" method="post">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form form %} {% include "cas_server/form.html" %}
{% bootstrap_button _('Connect to the service') size='lg' button_type="submit" button_class="btn-primary btn-block"%} <button class="btn btn-primary btn-block btn-lg" type="submit">{% trans "Connect to the service" %}</button>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -37,7 +37,6 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'bootstrap3',
'cas_server', 'cas_server',
] ]

View File

@ -15,6 +15,8 @@ from .default_settings import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.contrib import messages from django.contrib import messages
from django.contrib.messages import constants as DEFAULT_MESSAGE_LEVELS
from django.core.serializers.json import DjangoJSONEncoder
import random import random
import string import string
@ -29,6 +31,15 @@ from datetime import datetime, timedelta
from six.moves.urllib.parse import urlparse, urlunparse, parse_qsl, urlencode from six.moves.urllib.parse import urlparse, urlunparse, parse_qsl, urlencode
def json_encode(obj):
"""Encode a python object to json"""
try:
return json_encode.encoder.encode(obj)
except AttributeError:
json_encode.encoder = DjangoJSONEncoder(default=six.text_type)
return json_encode(obj)
def context(params): def context(params):
""" """
Function that add somes variable to the context before template rendering Function that add somes variable to the context before template rendering
@ -39,6 +50,7 @@ def context(params):
:rtype: dict :rtype: dict
""" """
params["settings"] = settings params["settings"] = settings
params["message_levels"] = DEFAULT_MESSAGE_LEVELS
return params return params

View File

@ -6,7 +6,5 @@ pytest-pythonpath>=0.3
pytest-cov>=2.2.1 pytest-cov>=2.2.1
requests>=2.4 requests>=2.4
requests_futures>=0.9.5 requests_futures>=0.9.5
django-picklefield>=0.3.1
django-bootstrap3>=5.4
lxml>=3.4 lxml>=3.4
six>=1 six>=1

View File

@ -2,7 +2,5 @@ Django >= 1.8,<1.10
setuptools>=5.5 setuptools>=5.5
requests>=2.4 requests>=2.4
requests_futures>=0.9.5 requests_futures>=0.9.5
django-picklefield>=0.3.1
django-bootstrap3>=5.4
lxml>=3.4 lxml>=3.4
six>=1 six>=1

View File

@ -11,27 +11,6 @@ if __name__ == '__main__':
# allow setup.py to be run from any path # allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
# if we have Django 1.8 available, use last version of django-boostrap3
try:
pkg_resources.require('Django >= 1.8')
django_bootstrap3 = 'django-bootstrap3 >= 5.4'
django = 'Django >= 1.8,<1.10'
except pkg_resources.VersionConflict:
# Else if we have django 1.7, we need django-boostrap3 < 7.0.0
try:
pkg_resources.require('Django >= 1.7')
django_bootstrap3 = 'django-bootstrap3 >= 5.4,<7.0.0'
django = 'Django >= 1.7,<1.8'
except (pkg_resources.VersionConflict, pkg_resources.DistributionNotFound):
# Else we need to install Django, assume version will be >= 1.8
django_bootstrap3 = 'django-bootstrap3 >= 5.4'
django = 'Django >= 1.8,<1.10'
# No version of django installed, assume version will be >= 1.8
except pkg_resources.DistributionNotFound:
django_bootstrap3 = 'django-bootstrap3 >= 5.4'
django = 'Django >= 1.8,<1.10'
setup( setup(
name='django-cas-server', name='django-cas-server',
version=VERSION, version=VERSION,
@ -80,9 +59,8 @@ if __name__ == '__main__':
}, },
keywords=['django', 'cas', 'cas3', 'server', 'sso', 'single sign-on', 'authentication', 'auth'], keywords=['django', 'cas', 'cas3', 'server', 'sso', 'single sign-on', 'authentication', 'auth'],
install_requires=[ install_requires=[
django, 'requests >= 2.4', 'requests_futures >= 0.9.5', 'Django >= 1.7,<1.10', 'requests >= 2.4', 'requests_futures >= 0.9.5',
'django-picklefield >= 0.3.1', django_bootstrap3, 'lxml >= 3.4', 'lxml >= 3.4', 'six >= 1'
'six >= 1'
], ],
url="https://github.com/nitmir/django-cas-server", url="https://github.com/nitmir/django-cas-server",
download_url="https://github.com/nitmir/django-cas-server/releases", download_url="https://github.com/nitmir/django-cas-server/releases",