Skip to content

Commit

Permalink
Merge pull request #20 from hsmett/master
Browse files Browse the repository at this point in the history
Add support Django 1.9, tests, flake8, isort and fix travis
  • Loading branch information
wo0dyn authored Jun 21, 2017
2 parents 9fcfe6d + 23cdd08 commit a95b516
Show file tree
Hide file tree
Showing 21 changed files with 218 additions and 25 deletions.
16 changes: 16 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[flake8]
ignore=E501
max-complexity = 100
exclude =
.tox,
__pycache__,
.git,
*.css,
*.html,
*.xml,
*.yml,
*.txt,
*.md,
*.js,
.flake8
filename = *.py
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ nosetests.xml
.mr.developer.cfg
.project
.pydevproject
.idea
11 changes: 9 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
language: python
python:
- "2.7"
install: pip install . --use-mirrors
script: python setup.py test
env:
- TOXENV=py27-django18
- TOXENV=py27-django19
- TOXENV=isort
- TOXENV=flake8

install:
- pip install tox
script: tox -e $TOXENV
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
develop:
python setup.py develop

demo:
python setup.py develop
(cd demo; python setup.py develop)
demo syncdb
demo migrate
demo runserver
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,14 @@ Store the certificate in Django
class Certificate(models.Model):
"""Certificate x509 to contact the API."""
site = models.ForeignKey(Site)
serial = UUIDField(unique=True)
dn = models.TextField(_('Distinguished Name'))
serial = models.UUIDField(unique=True)
created_at = models.DateTimeField()
expire_at = models.DateTimeField()
def __unicode__(self):
return u'%s - %s' % (self.site, self.dn)
return u'%s' % self.dn
Build the certificate
Expand Down
2 changes: 1 addition & 1 deletion demo/demoproject/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

urlpatterns = patterns(
'',
url(r'^/login/$', views.whoami, name='whoami'),
url(r'^login/$', views.whoami, name='whoami'),
url(r'^add_pem/$', pem_form_view, name='add_pem'),
url(r'^admin/', include(admin.site.urls)),
)
2 changes: 1 addition & 1 deletion demo/demoproject/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class WhoIsLinkedToMe(View):
def get(self, request, *args, **kwargs):
response = HttpResponse(mimetype='text/plain')
response = HttpResponse(content_type='text/plain')
response.status_code = 403

try:
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pyOpenSSL
python-dateutil
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ def read_relative_file(filename):
packages=['x509'],
include_package_data=True,
zip_safe=False,
install_requires=['pyOpenSSL'],
install_requires=['pyOpenSSL', 'python-dateutil'],
)
21 changes: 21 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[tox]
envlist = flake8,isort,py27-django{18,19}

[testenv]
usedevelop = True
deps =
django18: Django>=1.8,<1.9
django19: Django>=1.9,<1.10
-rrequirements.txt
commands =
django-admin test --settings=x509.tests.settings_for_tests

[testenv:flake8]
deps =
flake8
commands = flake8 x509

[testenv:isort]
deps =
isort
commands = isort --recursive --atomic --check-only ./x509/
5 changes: 2 additions & 3 deletions x509/django/compat.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
try:
from django.db.models import UUIDField
from django.db.models import UUIDField # noqa F401
except ImportError:
# Django < 1.8
try:
from uuidfield import UUIDField
from uuidfield import UUIDField # noqa F401
except ImportError:
raise ImportError("In order to use django-x509 with Django < 1.8 you "
"must install django-uuidfield.")

9 changes: 5 additions & 4 deletions x509/django/forms.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# -*- coding: utf-8 -*-
from OpenSSL import crypto

from cStringIO import StringIO
from dateutil.parser import parse
from uuid import UUID

from django import forms
from dateutil.parser import parse
from OpenSSL import crypto

from django import forms
from x509.django.models import Certificate
from x509.exceptions import CertificateAlreadyExist
from x509.utils import get_subject_from_components
from x509.django.models import Certificate


class PEMForm(forms.Form):
Expand Down
12 changes: 8 additions & 4 deletions x509/django/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.db import models

from x509.django.compat import UUIDField

try:
from django.contrib.contenttypes.generic import GenericForeignKey
except ImportError:
from django.contrib.contenttypes.fields import GenericForeignKey


class Certificate(models.Model):
"""Certificate x509 to link with something."""
Expand All @@ -14,15 +18,15 @@ class Certificate(models.Model):
expire_at = models.DateTimeField(blank=True, null=True)

def __unicode__(self):
return u'%s' % (self.dn)
return u'%s' % self.dn


class GenericCertificateM2M(models.Model):
"""Link a Certificate to any other object (User, object)."""
certificate = models.ForeignKey(Certificate, related_name='attachees')
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
content_object = GenericForeignKey('content_type', 'object_id')

def __unicode__(self):
return u'%s: %s' % (self.content_object, self.certificate)
6 changes: 3 additions & 3 deletions x509/django/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
from uuid import UUID

from x509.django.models import Certificate
from x509.exceptions import (
CertificateMissing, CertificateInvalid, HeaderMissing
)
from x509.exceptions import (CertificateInvalid, CertificateMissing,
HeaderMissing)


def raise_for_certificate(environ):
Expand Down
3 changes: 1 addition & 2 deletions x509/django/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from django.views.generic import FormView
from django.http import HttpResponse

from django.views.generic import FormView
from x509.django.forms import PEMForm


Expand Down
3 changes: 2 additions & 1 deletion x509/test_app.py → x509/script_test_app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from flask import Flask, request, make_response
from cStringIO import StringIO

from flask import Flask, make_response, request

application = Flask(__name__)


Expand Down
Empty file added x509/tests/__init__.py
Empty file.
23 changes: 23 additions & 0 deletions x509/tests/settings_for_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'django_x509.sqlite',
},
}

USE_I18N = True
USE_L10N = True

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'x509.django',
]

USE_TZ = True

SECRET_KEY = '0'
48 changes: 48 additions & 0 deletions x509/tests/tests_forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-

import os

from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from x509.django.forms import PEMForm
from x509.exceptions import CertificateAlreadyExist

TEST_DIR = os.path.dirname(os.path.abspath(__file__))
TEST_EXAMPLES_DIR = os.path.join(os.path.dirname(os.path.dirname(TEST_DIR)), "examples")


class CertificateFormTestCase(TestCase):

def test_when_i_post_empty_form_it_is_a_fail(self):
form = PEMForm(data={})
self.assertFalse(form.is_valid())

def test_when_i_post_a_good_form_it_is_valid(self):
certificat_1_path = os.path.join(TEST_EXAMPLES_DIR, 'localhost', 'client1.crt')

with open(certificat_1_path, 'rb') as cert_file:
form = PEMForm(data={}, files={'pem_file': SimpleUploadedFile('pem_file', cert_file.read())})
self.assertTrue(form.is_valid())

def test_when_i_post_a_good_form_once_i_got_a_certificate(self):
certificat_1_path = os.path.join(TEST_EXAMPLES_DIR, 'localhost', 'client1.crt')

with open(certificat_1_path, 'rb') as cert_file:
form = PEMForm(data={}, files={'pem_file': SimpleUploadedFile('pem_file', cert_file.read())})
form.is_valid()
certificate = form.get_certificate()
self.assertEqual(certificate.serial, "34fed2e8613747cb904f935dc17f1aba")

def test_when_i_post_a_good_form_twice_i_got_an_exception(self):
certificat_1_path = os.path.join(TEST_EXAMPLES_DIR, 'localhost', 'client1.crt')

with open(certificat_1_path, 'rb') as cert_file:
form = PEMForm(data={}, files={'pem_file': SimpleUploadedFile('pem_file', cert_file.read())})
form.is_valid()
form.get_certificate()

with open(certificat_1_path, 'rb') as cert_file:
form = PEMForm(data={}, files={'pem_file': SimpleUploadedFile('pem_file', cert_file.read())})
form.is_valid()
with self.assertRaises(CertificateAlreadyExist):
form.get_certificate()
35 changes: 35 additions & 0 deletions x509/tests/tests_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-

from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from django.utils.timezone import now, timedelta

from ..django.models import Certificate, GenericCertificateM2M


class ModelsTestCase(TestCase):

def test_i_can_create_a_certificate_instance(self):
created = now()
expire = now() + timedelta(days=320)
test_dn = "My Distinguished Nameeeee"
cert = Certificate.objects.create(serial='{12345678-1234-5678-1234-567812345678}',
dn=test_dn,
created_at=created,
expire_at=expire)
self.assertEqual(cert.created_at, created)
self.assertEqual(cert.expire_at, expire)
self.assertEqual(cert.dn, test_dn)

def test_i_can_create_a_generic_certificate_m2m(self):
cert = Certificate.objects.create(serial='{12345678-1234-5678-1234-567812345678}',
dn="My Distinguished Nameeeee",
created_at=now(),
expire_at=now() + timedelta(days=320))
user = User.objects.create(username="user")
certif_link = GenericCertificateM2M.objects.create(certificate=cert,
content_type=ContentType.objects.get_for_model(User),
object_id=user.id)
self.assertEqual(certif_link.content_object, user)
self.assertEqual(certif_link.certificate, cert)
32 changes: 32 additions & 0 deletions x509/tests/tests_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-

import os

from django.test import TestCase
from django.test.client import RequestFactory
from x509.django.models import Certificate
from x509.django.views import PEMFormView
from x509.exceptions import CertificateAlreadyExist

TEST_DIR = os.path.dirname(os.path.abspath(__file__))
TEST_EXAMPLES_DIR = os.path.join(os.path.dirname(os.path.dirname(TEST_DIR)), "examples")


class PEMFormViewTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()

def test_i_can_post_a_certificate(self):
certificat_1_path = os.path.join(TEST_EXAMPLES_DIR, 'localhost', 'client1.crt')
with open(certificat_1_path, 'rb') as cert_file:
request = self.factory.post('/add_pem', {'pem_file': cert_file})
PEMFormView.as_view()(request)
self.assertEqual(1, Certificate.objects.count())

def test_i_cant_post_twice_the_same_certificate(self):
certificat_1_path = os.path.join(TEST_EXAMPLES_DIR, 'localhost', 'client1.crt')
with open(certificat_1_path, 'rb') as cert_file:
request = self.factory.post('/add_pem', {'pem_file': cert_file})
PEMFormView.as_view()(request)
with self.assertRaises(CertificateAlreadyExist):
PEMFormView.as_view()(request)

0 comments on commit a95b516

Please sign in to comment.