Show More
@@ -0,0 +1,82 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | from south.utils import datetime_utils as datetime | |||
|
3 | from south.db import db | |||
|
4 | from south.v2 import SchemaMigration | |||
|
5 | from django.db import models | |||
|
6 | ||||
|
7 | ||||
|
8 | class Migration(SchemaMigration): | |||
|
9 | ||||
|
10 | def forwards(self, orm): | |||
|
11 | # Adding field 'KeyPair.primary' | |||
|
12 | db.add_column('boards_keypair', 'primary', | |||
|
13 | self.gf('django.db.models.fields.BooleanField')(default=False), | |||
|
14 | keep_default=False) | |||
|
15 | ||||
|
16 | ||||
|
17 | def backwards(self, orm): | |||
|
18 | # Deleting field 'KeyPair.primary' | |||
|
19 | db.delete_column('boards_keypair', 'primary') | |||
|
20 | ||||
|
21 | ||||
|
22 | models = { | |||
|
23 | 'boards.ban': { | |||
|
24 | 'Meta': {'object_name': 'Ban'}, | |||
|
25 | 'can_read': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |||
|
26 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
27 | 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |||
|
28 | 'reason': ('django.db.models.fields.CharField', [], {'default': "'Auto'", 'max_length': '200'}) | |||
|
29 | }, | |||
|
30 | 'boards.keypair': { | |||
|
31 | 'Meta': {'object_name': 'KeyPair'}, | |||
|
32 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
33 | 'key_type': ('django.db.models.fields.TextField', [], {}), | |||
|
34 | 'primary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |||
|
35 | 'private_key': ('django.db.models.fields.TextField', [], {}), | |||
|
36 | 'public_key': ('django.db.models.fields.TextField', [], {}) | |||
|
37 | }, | |||
|
38 | 'boards.post': { | |||
|
39 | 'Meta': {'object_name': 'Post', 'ordering': "('id',)"}, | |||
|
40 | '_text_rendered': ('django.db.models.fields.TextField', [], {}), | |||
|
41 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
42 | 'images': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'symmetrical': 'False', 'db_index': 'True', 'to': "orm['boards.PostImage']", 'null': 'True', 'related_name': "'ip+'"}), | |||
|
43 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
44 | 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |||
|
45 | 'poster_user_agent': ('django.db.models.fields.TextField', [], {}), | |||
|
46 | 'pub_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
47 | 'public_key': ('django.db.models.fields.TextField', [], {'blank': 'True', 'null': 'True'}), | |||
|
48 | 'referenced_posts': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'symmetrical': 'False', 'db_index': 'True', 'to': "orm['boards.Post']", 'null': 'True', 'related_name': "'rfp+'"}), | |||
|
49 | 'refmap': ('django.db.models.fields.TextField', [], {'blank': 'True', 'null': 'True'}), | |||
|
50 | 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}), | |||
|
51 | 'text_markup_type': ('django.db.models.fields.CharField', [], {'default': "'bbcode'", 'max_length': '30'}), | |||
|
52 | 'thread_new': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['boards.Thread']", 'default': 'None', 'null': 'True'}), | |||
|
53 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) | |||
|
54 | }, | |||
|
55 | 'boards.postimage': { | |||
|
56 | 'Meta': {'object_name': 'PostImage', 'ordering': "('id',)"}, | |||
|
57 | 'hash': ('django.db.models.fields.CharField', [], {'max_length': '36'}), | |||
|
58 | 'height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
59 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
60 | 'image': ('boards.thumbs.ImageWithThumbsField', [], {'blank': 'True', 'max_length': '100'}), | |||
|
61 | 'pre_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
62 | 'pre_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
63 | 'width': ('django.db.models.fields.IntegerField', [], {'default': '0'}) | |||
|
64 | }, | |||
|
65 | 'boards.tag': { | |||
|
66 | 'Meta': {'object_name': 'Tag', 'ordering': "('name',)"}, | |||
|
67 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
68 | 'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100'}), | |||
|
69 | 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['boards.Thread']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True', 'related_name': "'tag+'"}) | |||
|
70 | }, | |||
|
71 | 'boards.thread': { | |||
|
72 | 'Meta': {'object_name': 'Thread'}, | |||
|
73 | 'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |||
|
74 | 'bump_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
75 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
76 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
77 | 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['boards.Post']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True', 'related_name': "'tre+'"}), | |||
|
78 | 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['boards.Tag']", 'symmetrical': 'False'}) | |||
|
79 | } | |||
|
80 | } | |||
|
81 | ||||
|
82 | complete_apps = ['boards'] No newline at end of file |
@@ -8,7 +8,10 b" APP_LABEL_BOARDS = 'boards'" | |||||
8 |
|
8 | |||
9 |
|
9 | |||
10 | class KeyPairManager(models.Manager): |
|
10 | class KeyPairManager(models.Manager): | |
11 | def generate_key(self, key_type=TYPE_ECDSA): |
|
11 | def generate_key(self, key_type=TYPE_ECDSA, primary=False): | |
|
12 | if primary and self.filter(primary=True).exists(): | |||
|
13 | raise Exception('There can be only one primary key') | |||
|
14 | ||||
12 | if key_type == TYPE_ECDSA: |
|
15 | if key_type == TYPE_ECDSA: | |
13 | private = SigningKey.generate() |
|
16 | private = SigningKey.generate() | |
14 | public = private.get_verifying_key() |
|
17 | public = private.get_verifying_key() | |
@@ -18,9 +21,9 b' class KeyPairManager(models.Manager):' | |||||
18 |
|
21 | |||
19 | return self.create(public_key=public_key_str, |
|
22 | return self.create(public_key=public_key_str, | |
20 | private_key=private_key_str, |
|
23 | private_key=private_key_str, | |
21 | key_type=TYPE_ECDSA) |
|
24 | key_type=TYPE_ECDSA, primary=primary) | |
22 | else: |
|
25 | else: | |
23 | return None |
|
26 | raise Exception('Key type not supported') | |
24 |
|
27 | |||
25 | def verify(self, public_key_str, string, signature, key_type=TYPE_ECDSA): |
|
28 | def verify(self, public_key_str, string, signature, key_type=TYPE_ECDSA): | |
26 | if key_type == TYPE_ECDSA: |
|
29 | if key_type == TYPE_ECDSA: | |
@@ -32,7 +35,7 b' class KeyPairManager(models.Manager):' | |||||
32 | except BadSignatureError: |
|
35 | except BadSignatureError: | |
33 | return False |
|
36 | return False | |
34 | else: |
|
37 | else: | |
35 | return False |
|
38 | raise Exception('Key type not supported') | |
36 |
|
39 | |||
37 |
|
40 | |||
38 | class KeyPair(models.Model): |
|
41 | class KeyPair(models.Model): | |
@@ -44,6 +47,7 b' class KeyPair(models.Model):' | |||||
44 | public_key = models.TextField() |
|
47 | public_key = models.TextField() | |
45 | private_key = models.TextField() |
|
48 | private_key = models.TextField() | |
46 | key_type = models.TextField() |
|
49 | key_type = models.TextField() | |
|
50 | primary = models.BooleanField(default=False) | |||
47 |
|
51 | |||
48 | def __str__(self): |
|
52 | def __str__(self): | |
49 | return '%s: %s' % (self.key_type, self.public_key) |
|
53 | return '%s: %s' % (self.key_type, self.public_key) |
@@ -277,3 +277,12 b' class KeyTest(TestCase):' | |||||
277 | key_type='ecdsa') |
|
277 | key_type='ecdsa') | |
278 |
|
278 | |||
279 | self.assertTrue(valid, 'Message verification failed.') |
|
279 | self.assertTrue(valid, 'Message verification failed.') | |
|
280 | ||||
|
281 | def test_primary_constraint(self): | |||
|
282 | KeyPair.objects.generate_key(key_type='ecdsa', primary=True) | |||
|
283 | ||||
|
284 | try: | |||
|
285 | KeyPair.objects.generate_key(key_type='ecdsa', primary=True) | |||
|
286 | self.fail('Exception should be thrown indicating there can be only one primary key.') | |||
|
287 | except Exception: | |||
|
288 | pass |
General Comments 0
You need to be logged in to leave comments.
Login now