Show More
@@ -0,0 +1,74 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 'Post.public_key' | |||
|
12 | db.add_column('boards_post', 'public_key', | |||
|
13 | self.gf('django.db.models.fields.TextField')(blank=True, null=True), | |||
|
14 | keep_default=False) | |||
|
15 | ||||
|
16 | ||||
|
17 | def backwards(self, orm): | |||
|
18 | # Deleting field 'Post.public_key' | |||
|
19 | db.delete_column('boards_post', 'public_key') | |||
|
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', [], {'max_length': '200', 'default': "'Auto'"}) | |||
|
29 | }, | |||
|
30 | 'boards.post': { | |||
|
31 | 'Meta': {'ordering': "('id',)", 'object_name': 'Post'}, | |||
|
32 | '_text_rendered': ('django.db.models.fields.TextField', [], {}), | |||
|
33 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
34 | 'images': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'null': 'True', 'related_name': "'ip+'", 'to': "orm['boards.PostImage']", 'db_index': 'True'}), | |||
|
35 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
36 | 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |||
|
37 | 'poster_user_agent': ('django.db.models.fields.TextField', [], {}), | |||
|
38 | 'pub_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
39 | 'public_key': ('django.db.models.fields.TextField', [], {'blank': 'True', 'null': 'True'}), | |||
|
40 | 'referenced_posts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'null': 'True', 'related_name': "'rfp+'", 'to': "orm['boards.Post']", 'db_index': 'True'}), | |||
|
41 | 'refmap': ('django.db.models.fields.TextField', [], {'blank': 'True', 'null': 'True'}), | |||
|
42 | 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}), | |||
|
43 | 'text_markup_type': ('django.db.models.fields.CharField', [], {'max_length': '30', 'default': "'bbcode'"}), | |||
|
44 | 'thread_new': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.Thread']", 'null': 'True'}), | |||
|
45 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) | |||
|
46 | }, | |||
|
47 | 'boards.postimage': { | |||
|
48 | 'Meta': {'ordering': "('id',)", 'object_name': 'PostImage'}, | |||
|
49 | 'hash': ('django.db.models.fields.CharField', [], {'max_length': '36'}), | |||
|
50 | 'height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
51 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
52 | 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}), | |||
|
53 | 'pre_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
54 | 'pre_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
55 | 'width': ('django.db.models.fields.IntegerField', [], {'default': '0'}) | |||
|
56 | }, | |||
|
57 | 'boards.tag': { | |||
|
58 | 'Meta': {'ordering': "('name',)", 'object_name': 'Tag'}, | |||
|
59 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
60 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'db_index': 'True'}), | |||
|
61 | 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Thread']", 'null': 'True', 'blank': 'True', 'related_name': "'tag+'"}) | |||
|
62 | }, | |||
|
63 | 'boards.thread': { | |||
|
64 | 'Meta': {'object_name': 'Thread'}, | |||
|
65 | 'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |||
|
66 | 'bump_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
67 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
68 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
69 | 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Post']", 'null': 'True', 'blank': 'True', 'related_name': "'tre+'"}), | |||
|
70 | 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Tag']"}) | |||
|
71 | } | |||
|
72 | } | |||
|
73 | ||||
|
74 | complete_apps = ['boards'] No newline at end of file |
@@ -0,0 +1,85 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 model 'KeyPair' | |||
|
12 | db.create_table('boards_keypair', ( | |||
|
13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), | |||
|
14 | ('public_key', self.gf('django.db.models.fields.TextField')()), | |||
|
15 | ('private_key', self.gf('django.db.models.fields.TextField')()), | |||
|
16 | ('key_type', self.gf('django.db.models.fields.TextField')()), | |||
|
17 | )) | |||
|
18 | db.send_create_signal('boards', ['KeyPair']) | |||
|
19 | ||||
|
20 | ||||
|
21 | def backwards(self, orm): | |||
|
22 | # Deleting model 'KeyPair' | |||
|
23 | db.delete_table('boards_keypair') | |||
|
24 | ||||
|
25 | ||||
|
26 | models = { | |||
|
27 | 'boards.ban': { | |||
|
28 | 'Meta': {'object_name': 'Ban'}, | |||
|
29 | 'can_read': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |||
|
30 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
31 | 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |||
|
32 | 'reason': ('django.db.models.fields.CharField', [], {'max_length': '200', 'default': "'Auto'"}) | |||
|
33 | }, | |||
|
34 | 'boards.keypair': { | |||
|
35 | 'Meta': {'object_name': 'KeyPair'}, | |||
|
36 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
37 | 'key_type': ('django.db.models.fields.TextField', [], {}), | |||
|
38 | 'private_key': ('django.db.models.fields.TextField', [], {}), | |||
|
39 | 'public_key': ('django.db.models.fields.TextField', [], {}) | |||
|
40 | }, | |||
|
41 | 'boards.post': { | |||
|
42 | 'Meta': {'ordering': "('id',)", 'object_name': 'Post'}, | |||
|
43 | '_text_rendered': ('django.db.models.fields.TextField', [], {}), | |||
|
44 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
45 | 'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['boards.PostImage']", 'db_index': 'True', 'related_name': "'ip+'", 'symmetrical': 'False', 'blank': 'True', 'null': 'True'}), | |||
|
46 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
47 | 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |||
|
48 | 'poster_user_agent': ('django.db.models.fields.TextField', [], {}), | |||
|
49 | 'pub_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
50 | 'public_key': ('django.db.models.fields.TextField', [], {'blank': 'True', 'null': 'True'}), | |||
|
51 | 'referenced_posts': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['boards.Post']", 'db_index': 'True', 'related_name': "'rfp+'", 'symmetrical': 'False', 'blank': 'True', 'null': 'True'}), | |||
|
52 | 'refmap': ('django.db.models.fields.TextField', [], {'blank': 'True', 'null': 'True'}), | |||
|
53 | 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}), | |||
|
54 | 'text_markup_type': ('django.db.models.fields.CharField', [], {'max_length': '30', 'default': "'bbcode'"}), | |||
|
55 | 'thread_new': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.Thread']", 'null': 'True'}), | |||
|
56 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) | |||
|
57 | }, | |||
|
58 | 'boards.postimage': { | |||
|
59 | 'Meta': {'ordering': "('id',)", 'object_name': 'PostImage'}, | |||
|
60 | 'hash': ('django.db.models.fields.CharField', [], {'max_length': '36'}), | |||
|
61 | 'height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
62 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
63 | 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}), | |||
|
64 | 'pre_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
65 | 'pre_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |||
|
66 | 'width': ('django.db.models.fields.IntegerField', [], {'default': '0'}) | |||
|
67 | }, | |||
|
68 | 'boards.tag': { | |||
|
69 | 'Meta': {'ordering': "('name',)", 'object_name': 'Tag'}, | |||
|
70 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
71 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'db_index': 'True'}), | |||
|
72 | 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Thread']", 'null': 'True', 'blank': 'True', 'related_name': "'tag+'"}) | |||
|
73 | }, | |||
|
74 | 'boards.thread': { | |||
|
75 | 'Meta': {'object_name': 'Thread'}, | |||
|
76 | 'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |||
|
77 | 'bump_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
78 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |||
|
79 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |||
|
80 | 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Post']", 'null': 'True', 'blank': 'True', 'related_name': "'tre+'"}), | |||
|
81 | 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Tag']"}) | |||
|
82 | } | |||
|
83 | } | |||
|
84 | ||||
|
85 | complete_apps = ['boards'] No newline at end of file |
@@ -14,7 +14,7 b' class Migration(DataMigration):' | |||||
14 | # Note: Don't use "from appname.models import ModelName". |
|
14 | # Note: Don't use "from appname.models import ModelName". | |
15 | # Use orm.ModelName to refer to models in this application, |
|
15 | # Use orm.ModelName to refer to models in this application, | |
16 | # and orm['appname.ModelName'] for models in other applications. |
|
16 | # and orm['appname.ModelName'] for models in other applications. | |
17 | for post in Post.objects.all(): |
|
17 | for post in orm['boards.Post'].objects.all(): | |
18 | post.build_refmap() |
|
18 | post.build_refmap() | |
19 | post.save() |
|
19 | post.save() | |
20 |
|
20 |
@@ -5,3 +5,4 b' from boards.models.thread import Thread' | |||||
5 | from boards.models.post import Post |
|
5 | from boards.models.post import Post | |
6 | from boards.models.tag import Tag |
|
6 | from boards.models.tag import Tag | |
7 | from boards.models.user import Ban |
|
7 | from boards.models.user import Ban | |
|
8 | from boards.models.sync_key import KeyPair |
@@ -188,12 +188,20 b' class Post(models.Model, Viewable):' | |||||
188 | db_index=True) |
|
188 | db_index=True) | |
189 | last_edit_time = models.DateTimeField() |
|
189 | last_edit_time = models.DateTimeField() | |
190 |
|
190 | |||
|
191 | # Replies to the post | |||
191 | referenced_posts = models.ManyToManyField('Post', symmetrical=False, |
|
192 | referenced_posts = models.ManyToManyField('Post', symmetrical=False, | |
192 | null=True, |
|
193 | null=True, | |
193 | blank=True, related_name='rfp+', |
|
194 | blank=True, related_name='rfp+', | |
194 | db_index=True) |
|
195 | db_index=True) | |
|
196 | ||||
|
197 | # Replies map. This is built from the referenced posts list to speed up | |||
|
198 | # page loading (no need to get all the referenced posts from the database). | |||
195 | refmap = models.TextField(null=True, blank=True) |
|
199 | refmap = models.TextField(null=True, blank=True) | |
196 |
|
200 | |||
|
201 | # Sender key. If the message was downloaded from another server, this | |||
|
202 | # indicates the server. | |||
|
203 | public_key = models.TextField(null=True, blank=True) | |||
|
204 | ||||
197 | def __unicode__(self): |
|
205 | def __unicode__(self): | |
198 | return '#' + str(self.id) + ' ' + self.title + ' (' + \ |
|
206 | return '#' + str(self.id) + ' ' + self.title + ' (' + \ | |
199 | self.text.raw[:50] + ')' |
|
207 | self.text.raw[:50] + ')' |
@@ -1,5 +1,5 b'' | |||||
1 | VERSION = '1.8.1 Kara' |
|
1 | VERSION = '1.8.1 Kara' | |
2 |
SITE_NAME = ' |
|
2 | SITE_NAME = 'n3b0a2d' | |
3 |
|
3 | |||
4 | CACHE_TIMEOUT = 600 # Timeout for caching, if cache is used |
|
4 | CACHE_TIMEOUT = 600 # Timeout for caching, if cache is used | |
5 | LOGIN_TIMEOUT = 3600 # Timeout between login tries |
|
5 | LOGIN_TIMEOUT = 3600 # Timeout between login tries | |
@@ -20,4 +20,4 b' ARCHIVE_THREADS = True' | |||||
20 | LIMIT_POSTING_SPEED = False |
|
20 | LIMIT_POSTING_SPEED = False | |
21 |
|
21 | |||
22 | # This password is used to add admin permissions to the user |
|
22 | # This password is used to add admin permissions to the user | |
23 | MASTER_PASSWORD = u'password' No newline at end of file |
|
23 | MASTER_PASSWORD = u'password' |
@@ -437,6 +437,11 b' ul {' | |||||
437 | font-size: 1.2em; |
|
437 | font-size: 1.2em; | |
438 | } |
|
438 | } | |
439 |
|
439 | |||
|
440 | /* Post */ | |||
|
441 | .post > .message, .post > .image { | |||
|
442 | padding-left: 1em; | |||
|
443 | } | |||
|
444 | ||||
440 | /* Reflink preview */ |
|
445 | /* Reflink preview */ | |
441 | .post_preview { |
|
446 | .post_preview { | |
442 | border-left: 1px solid #777; |
|
447 | border-left: 1px solid #777; |
@@ -8,7 +8,7 b' from django.test.client import Client' | |||||
8 | from django.core.urlresolvers import reverse, NoReverseMatch |
|
8 | from django.core.urlresolvers import reverse, NoReverseMatch | |
9 | from boards.abstracts.settingsmanager import get_settings_manager |
|
9 | from boards.abstracts.settingsmanager import get_settings_manager | |
10 |
|
10 | |||
11 | from boards.models import Post, Tag, Thread |
|
11 | from boards.models import Post, Tag, Thread, KeyPair | |
12 | from boards import urls |
|
12 | from boards import urls | |
13 | from boards import settings |
|
13 | from boards import settings | |
14 | import neboard |
|
14 | import neboard | |
@@ -261,3 +261,19 b' class AbstractTest(TestCase):' | |||||
261 | class MockRequest: |
|
261 | class MockRequest: | |
262 | def __init__(self): |
|
262 | def __init__(self): | |
263 | self.session = dict() |
|
263 | self.session = dict() | |
|
264 | ||||
|
265 | ||||
|
266 | class KeyTest(TestCase): | |||
|
267 | def test_create_key(self): | |||
|
268 | key = KeyPair.objects.generate_key('ecdsa') | |||
|
269 | ||||
|
270 | self.assertIsNotNone(key, 'The key was not created.') | |||
|
271 | ||||
|
272 | def test_validation(self): | |||
|
273 | key = KeyPair.objects.generate_key(key_type='ecdsa') | |||
|
274 | message = 'msg' | |||
|
275 | signature = key.sign(message) | |||
|
276 | valid = KeyPair.objects.verify(key.public_key, message, signature, | |||
|
277 | key_type='ecdsa') | |||
|
278 | ||||
|
279 | self.assertTrue(valid, 'Message verification failed.') |
General Comments 0
You need to be logged in to leave comments.
Login now