initial commit

This commit is contained in:
Serghei Mihai 2015-05-15 18:20:53 +02:00
commit 5b270afc98
10 changed files with 311 additions and 0 deletions

3
MANIFEST.in Normal file
View File

@ -0,0 +1,3 @@
include COPYING
recursive-include src/authentic2_beid/templates *.html
recursive-include src/authentic2_beid/static *.js *.css *.png

0
README Normal file
View File

125
setup.py Normal file
View File

@ -0,0 +1,125 @@
#!/usr/bin/python
import sys
import os
import subprocess
from setuptools import setup, find_packages
from setuptools.command.install_lib import install_lib as _install_lib
from distutils.command.build import build as _build
from distutils.command.sdist import sdist
from distutils.cmd import Command
class compile_translations(Command):
description = 'compile message catalogs to MO files via django compilemessages'
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
try:
from django.core.management.commands.compilemessages import \
compile_messages
for path, dirs, files in os.walk('src'):
if 'locale' not in dirs:
continue
curdir = os.getcwd()
os.chdir(os.path.realpath(path))
compile_messages(sys.stderr)
os.chdir(curdir)
except ImportError:
print
sys.stderr.write('!!! Please install Django >= 1.4 to build translations')
print
print
class build(_build):
sub_commands = [('compile_translations', None)] + _build.sub_commands
class build(_build):
sub_commands = [('compile_translations', None)] + _build.sub_commands
class eo_sdist(sdist):
def run(self):
print "creating VERSION file"
if os.path.exists('VERSION'):
os.remove('VERSION')
version = get_version()
version_file = open('VERSION', 'w')
version_file.write(version)
version_file.close()
sdist.run(self)
print "removing VERSION file"
if os.path.exists('VERSION'):
os.remove('VERSION')
class install_lib(_install_lib):
def run(self):
self.run_command('compile_translations')
_install_lib.run(self)
def get_version():
'''Use the VERSION, if absent generates a version with git describe, if not
tag exists, take 0.0.0- and add the length of the commit log.
'''
if os.path.exists('VERSION'):
with open('VERSION', 'r') as v:
return v.read()
if os.path.exists('.git'):
p = subprocess.Popen(['git','describe','--dirty','--match=v*'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = p.communicate()[0]
if p.returncode == 0:
return result.split()[0][1:].replace('-', '.')
else:
return '0.0.0-%s' % len(
subprocess.check_output(
['git', 'rev-list', 'HEAD']).splitlines())
return '0.0.0'
README = file(os.path.join(
os.path.dirname(__file__),
'README')).read()
setup(name='authentic2-beid',
version=get_version(),
license='AGPLv3',
description='Authentic2 Belgian eID authentication',
long_description=README,
author="Entr'ouvert",
author_email="info@entrouvert.com",
packages=find_packages('src'),
package_dir={
'': 'src',
},
package_data={
'authentic2_beid': [
'locale/fr/LC_MESSAGES/*.po',
'locale/fr/LC_MESSAGES/*.mo',
'templates/authentic2_beid/*.html',
'static/authentic2_beid/js/*.js',
'static/authentic2_beid/css/*.css',
'static/authentic2_beid/img/*.png',
],
},
install_requires=[
'authentic2',
],
entry_points={
'authentic2.plugin': [
'authentic2-beid = authentic2_beid:Plugin',
],
},
cmdclass={
'build': build,
'install_lib': install_lib,
'compile_translations': compile_translations,
'sdist': eo_sdist},
)

View File

@ -0,0 +1,20 @@
__version__ = '0.0.1'
class Plugin(object):
def get_before_urls(self):
from django.conf.urls import url, patterns, include
return patterns('', url('accounts/beid/', include(__name__ + '.urls')))
def get_apps(self):
return [__name__]
def get_authentication_backends(self):
return ('authentic2_beid.backends.BeIDBackend',)
def get_auth_frontends(self):
return ('authentic2_beid.frontends.BeIDFrontend',)
def get_after_middleware(self):
return ('authentic2.auth2_auth.auth2_ssl.middleware.SSLAuthMiddleware',)

View File

@ -0,0 +1,9 @@
from authentic2.auth2_auth.auth2_ssl.backends import SSLBackend
from authentic2.auth2_auth.auth2_ssl import util
class BeIDBackend(SSLBackend):
def build_username(ssl_info):
dn = dict(util.explode_dn(ssl_info.subject_dn))
return dn.get('serialNumber')

View File

@ -0,0 +1,31 @@
from django.utils.translation import gettext_noop
from django.contrib.auth import authenticate
from django.shortcuts import render
import django.forms
from authentic2.utils import redirect_to_login
from . import views
class BeIDFrontend(object):
def enabled(self):
return True
def id(self):
return 'eid'
def name(self):
return gettext_noop('Belgian eID card')
def post(self, request, form, nonce, next_url):
return redirect_to_login(request, login_url='beid_signin',)
def form(self):
return django.forms.Form
def template(self):
return 'beid/login_form.html'
def profile(self, request, *args, **kwargs):
return views.profile(request, *args, **kwargs)

View File

@ -0,0 +1,19 @@
{% load i18n %}
<div id="login-ssl">
<p>
{% trans "Use your Belgian identity card to log in." %}
</p>
<p>
{% trans "Please connect the card reader and put your identity card in" %}
</p>
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="{{ submit_name }}" value="{% trans "Log in" %}"/>
{% if cancel %}
<input type="submit" name="cancel" value="{% trans 'Cancel' %}"/>
{% endif %}
</form>
</div>

View File

@ -0,0 +1,33 @@
{% load i18n %}
<h4 id="a2-beid-certificate-profile" class="a2-bied-certificate-profile-title">
{% trans "Belgian eID card" %}
</h4>
<div class="a2-beid-certificate-profile-body">
<ul class="a2-beid-certificate-list">
{% for certificate in certificates %}
<li class="a2-ssl-certificate-item">
<form action="{% url "delete_beid" certificate_pk=certificate.pk %}"
method="post">
{% csrf_token %}
<p class="a2-ssl-certificate-dn">
<dl class="a2-ssl-certificate-dn-parts">
{% for k, v in certificate.explode_subject_dn %}
<dt class="a2-ssl-certificate-dn-part-name">{{ k }}</dt>
<dd class="a2-ssl-certificate-dn-part-value">{{ v }}</dd>
{% endfor %}
</dl>
</p>
<input type="submit" class="submit-button a2-ssl-certificate-submit-button" value="{% trans "Delete" %}">
</form>
</p>
{% endfor %}
</ul>
<p>
<form action="{% url "add_beid" %}" method="get">
<label for="id_del_cert">{% trans "Have a belgian eID card?" %}</label>
<input type="hidden" name="next" value="{% url "account_management" %}#a2-beid-certificate-profile" />
<input type="submit" class="submit-button a2-ssl-certificate-submit-button" value="{% trans "Link it to your account" %}">
</form>
</p>
</div>

View File

@ -0,0 +1,12 @@
from django.conf.urls import patterns, url
from .views import *
urlpatterns = patterns('',
url(r'^$',
handle_authentication,
name='beid_signin'),
url(r'^add_beid/', add_beid, name='add_beid'),
url(r'^delete_beid/(?P<certificate_pk>\d+)/$',
delete_beid, name='delete_beid')
)

View File

@ -0,0 +1,59 @@
import logging
from django.utils.translation import ugettext as _
from django.template.loader import render_to_string
from django.template import RequestContext
from django.contrib.auth import authenticate, login
from django.contrib import messages
from authentic2.auth2_auth.auth2_ssl import models, util
from authentic2.utils import continue_to_next_url, redirect
from .backends import BeIDBackend
logger = logging.getLogger(__name__)
def handle_authentication(request, *args, **kwargs):
ssl_info = util.SSLInfo(request)
logger.debug('received SSL info: %s', ssl_info)
user = authenticate(ssl_info=ssl_info)
logger.debug('got user: %s', user)
if not request.user.is_authenticated():
login(request, user)
return continue_to_next_url(request)
def add_beid(request):
if request.user.is_authenticated:
ssl_info = util.SSLInfo(request)
if BeIDBackend().link_user(ssl_info, request.user):
logger.info('Successful linking of the SSL '
'Certificate to an account, redirection to %s' % next_url)
messages.info(request, _('BeID card successfully linked to your account'))
else:
logger.error('eid linking failed')
messages.error(request, _('BeID linking failed. Internal server error.'))
else:
return redirect(request, 'account_management',
fragment='a2-beid-certificate-profile')
def profile(request, template_name='beid/profile.html', *args, **kwargs):
context_instance = kwargs.pop('context_instance', None) or \
RequestContext(request)
certificates = models.ClientCertificate.objects.filter(user=request.user)
ctx = {'certificates': certificates}
return render_to_string(template_name, ctx,
context_instance=context_instance)
def delete_beid(request, certificate_pk):
try:
beid = models.ClientCertificate.objects.get(pk=certificate_pk)
beid.delete()
logger.info('client certificate %s deleted', beid)
messages.info(request, _('Your BeID card informations are successfully deleted'))
except models.ClientCertificate.DoesNotExist:
logger.info('no client certificate %s', certificate_pk)
messages.error(request, _('No BeID card associated to this account'))
return redirect(request, 'account_management',
fragment='a2-beid-certificate-profile')