remove rfc3161 timestamping (#42352)
This commit is contained in:
parent
779138c4fd
commit
505d23bffb
|
@ -212,8 +212,6 @@ All settings must be donne in the file ``/etc/docbow/local_settings.py``. Availa
|
||||||
bytes. Default is 10 Mo.
|
bytes. Default is 10 Mo.
|
||||||
* ``DOCBOW_TRUNCATE_FILENAME``: the maximum length for filenames. Default is
|
* ``DOCBOW_TRUNCATE_FILENAME``: the maximum length for filenames. Default is
|
||||||
80 unicode characters (codepoints).
|
80 unicode characters (codepoints).
|
||||||
* ``DOCBOW_TIMESTAMP_PROVIDER``: the timestamp provider to use. Default is certum.
|
|
||||||
Other possibilities are fedit and e_szigno.
|
|
||||||
* ``DOCBOW_PERSONAL_EMAIL``: allow user to have a personal email,
|
* ``DOCBOW_PERSONAL_EMAIL``: allow user to have a personal email,
|
||||||
notifications will be sent to their institutional email and personal email.
|
notifications will be sent to their institutional email and personal email.
|
||||||
* ``DOCBOW_MOBILE_PHONE``: allow user to set a mobile phone number
|
* ``DOCBOW_MOBILE_PHONE``: allow user to set a mobile phone number
|
||||||
|
|
|
@ -20,7 +20,6 @@ Depends: ${misc:Depends}, python (>= 2.6),
|
||||||
python-django (>= 1:1.11),
|
python-django (>= 1:1.11),
|
||||||
python-django-debug-toolbar,
|
python-django-debug-toolbar,
|
||||||
python-beautifulsoup,
|
python-beautifulsoup,
|
||||||
python-rfc3161,
|
|
||||||
gunicorn,
|
gunicorn,
|
||||||
python-django-journal (>= 2.0.0),
|
python-django-journal (>= 2.0.0),
|
||||||
python-django-picklefield,
|
python-django-picklefield,
|
||||||
|
|
|
@ -41,10 +41,6 @@ class AppSettings(object):
|
||||||
def BASE_URL(self):
|
def BASE_URL(self):
|
||||||
return getattr(self.settings, 'DOCBOW_BASE_URL', 'http://localhost:8000')
|
return getattr(self.settings, 'DOCBOW_BASE_URL', 'http://localhost:8000')
|
||||||
|
|
||||||
@property
|
|
||||||
def TIMESTAMP_PROVIDER(self):
|
|
||||||
return getattr(self.settings, 'DOCBOW_TIMESTAMP_PROVIDER', 'certum')
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def TRUNCATE_FILENAME(self):
|
def TRUNCATE_FILENAME(self):
|
||||||
return getattr(self.settings, 'DOCBOW_TRUNCATE_FILENAME', 80)
|
return getattr(self.settings, 'DOCBOW_TRUNCATE_FILENAME', 80)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import csv
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
|
import time
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
import django.contrib.auth.models as auth_models
|
import django.contrib.auth.models as auth_models
|
||||||
|
@ -10,7 +11,6 @@ from django.db import transaction
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from ... import models
|
from ... import models
|
||||||
from ... import timestamp
|
|
||||||
from ....log import models as log_models
|
from ....log import models as log_models
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
|
@ -67,9 +67,7 @@ class Command(BaseCommand):
|
||||||
def timestamp_logs(self, path):
|
def timestamp_logs(self, path):
|
||||||
with open(os.path.join(path, 'log-timestamp.der'), 'w') as f:
|
with open(os.path.join(path, 'log-timestamp.der'), 'w') as f:
|
||||||
with open(os.path.join(path, 'log.csv')) as log_handle:
|
with open(os.path.join(path, 'log.csv')) as log_handle:
|
||||||
tst, message = timestamp.timestamp(log_handle.read())
|
tst = str(time.time())
|
||||||
if not tst:
|
|
||||||
raise CommandError('Failure to compute the timestamp: %s' % message)
|
|
||||||
f.write(tst)
|
f.write(tst)
|
||||||
|
|
||||||
def remove_profiles(self):
|
def remove_profiles(self):
|
||||||
|
|
|
@ -5,6 +5,7 @@ import hashlib
|
||||||
import re
|
import re
|
||||||
import urlparse
|
import urlparse
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
import time
|
||||||
|
|
||||||
from django.db.models import (Model, ForeignKey, DateTimeField, CharField,
|
from django.db.models import (Model, ForeignKey, DateTimeField, CharField,
|
||||||
FileField, ManyToManyField, TextField, Manager, BooleanField,
|
FileField, ManyToManyField, TextField, Manager, BooleanField,
|
||||||
|
@ -15,11 +16,10 @@ from django.template.defaultfilters import slugify
|
||||||
from django.utils.translation import ugettext_lazy as _, pgettext_lazy
|
from django.utils.translation import ugettext_lazy as _, pgettext_lazy
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from picklefield.fields import PickledObjectField
|
from picklefield.fields import PickledObjectField
|
||||||
from django.utils.timezone import now, utc, make_aware, is_aware, localtime
|
from django.utils.timezone import now, utc
|
||||||
from django.forms import ValidationError
|
from django.forms import ValidationError
|
||||||
|
|
||||||
from django_journal import journal as django_journal
|
from django_journal import journal as django_journal
|
||||||
import timestamp
|
|
||||||
from .validators import validate_phone
|
from .validators import validate_phone
|
||||||
from .utils import file_match_mime_types
|
from .utils import file_match_mime_types
|
||||||
from . import app_settings
|
from . import app_settings
|
||||||
|
@ -296,15 +296,8 @@ class Document(Model):
|
||||||
|
|
||||||
def timestamp(self, to=None):
|
def timestamp(self, to=None):
|
||||||
if not self._timestamp:
|
if not self._timestamp:
|
||||||
blob = self.timestamp_blob(to=to)
|
self._timestamp = time.time()
|
||||||
self._timestamp, gentime = timestamp.timestamp_json(blob)
|
self.date = dt.datetime.fromtimestamp(self._timestamp, utc)
|
||||||
if is_aware(gentime):
|
|
||||||
localdate = localtime(gentime, utc)
|
|
||||||
else:
|
|
||||||
localdate = make_aware(gentime, utc)
|
|
||||||
if localdate:
|
|
||||||
self.date = localdate
|
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
django_journal.record('timestamp', 'timestamped document {document} result is {timestamp}',
|
django_journal.record('timestamp', 'timestamped document {document} result is {timestamp}',
|
||||||
document=self, timestamp=self._timestamp)
|
document=self, timestamp=self._timestamp)
|
||||||
|
@ -317,11 +310,7 @@ class Document(Model):
|
||||||
to_with_origins = self.to_with_origin()
|
to_with_origins = self.to_with_origin()
|
||||||
to = [user for user in to_with_origins.keys() if user.is_active]
|
to = [user for user in to_with_origins.keys() if user.is_active]
|
||||||
# Create the timestamp
|
# Create the timestamp
|
||||||
try:
|
self.timestamp(to=to)
|
||||||
self.timestamp(to=to)
|
|
||||||
except timestamp.TimestampingError, e:
|
|
||||||
django_journal.record('warning', 'unable to timestamp {document}: '
|
|
||||||
'{exception}', document=self, exception=str(e))
|
|
||||||
# Record recipient lists
|
# Record recipient lists
|
||||||
for mailing_list in self.to_list.all():
|
for mailing_list in self.to_list.all():
|
||||||
django_journal.record('delivery', 'deliver document {document} to members of list {mailing_list}',
|
django_journal.record('delivery', 'deliver document {document} to members of list {mailing_list}',
|
||||||
|
@ -376,25 +365,6 @@ class Document(Model):
|
||||||
return recipients_count, DocumentForwarded.objects.create(from_document=self,
|
return recipients_count, DocumentForwarded.objects.create(from_document=self,
|
||||||
to_document=document, automatic=automatic)
|
to_document=document, automatic=automatic)
|
||||||
|
|
||||||
def timestamp_blob(self, to=None):
|
|
||||||
'''Create a dictionary containing information to timestamp.
|
|
||||||
|
|
||||||
It should be serialized (ex. using JSON) and cryptographically
|
|
||||||
timestamped (ex. using RFC3161).
|
|
||||||
'''
|
|
||||||
to = to or self.to()
|
|
||||||
blob = {}
|
|
||||||
blob['from'] = username(self.sender)
|
|
||||||
blob['to'] = ', '.join(map(username, to))
|
|
||||||
blob['filetype'] = unicode(self.filetype)
|
|
||||||
blob['comment'] = self.comment
|
|
||||||
blob['files'] = []
|
|
||||||
for f in self.attached_files.all():
|
|
||||||
d = dict(name=f.filename(), size=f.content.size,
|
|
||||||
digest=hashlib.sha1(f.content.read()).hexdigest())
|
|
||||||
blob['files'].append(d)
|
|
||||||
return blob
|
|
||||||
|
|
||||||
def sender_display(self):
|
def sender_display(self):
|
||||||
return username(self.sender)
|
return username(self.sender)
|
||||||
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
import rfc3161
|
|
||||||
import os.path
|
|
||||||
import importlib
|
|
||||||
import json
|
|
||||||
|
|
||||||
from . import app_settings
|
|
||||||
|
|
||||||
PROVIDERS = {
|
|
||||||
'certum': {
|
|
||||||
'class': 'rfc3161.RemoteTimestamper',
|
|
||||||
'url': 'http://time.certum.pl',
|
|
||||||
'certificate': file(os.path.join(os.path.dirname(__file__), 'certum_certificate.crt')).read(),
|
|
||||||
},
|
|
||||||
'fedict': {
|
|
||||||
'class': 'rfc3161.RemoteTimestamper',
|
|
||||||
'url': 'http://tsa.belgium.be/connect',
|
|
||||||
'certificate': file(os.path.join(os.path.dirname(__file__), 'fedict.crt')).read(),
|
|
||||||
},
|
|
||||||
'e_szigno': {
|
|
||||||
'class': 'rfc3161.RemoteTimestamper',
|
|
||||||
'url': 'https://teszt.e-szigno.hu:440/tsa',
|
|
||||||
'certificate': file(os.path.join(os.path.dirname(__file__), 'e_szigno_test_tsa2.crt')).read(),
|
|
||||||
'username': 'teszt',
|
|
||||||
'password': 'teszt',
|
|
||||||
'hashname': 'sha256',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimestampingError(RuntimeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def timestamp(content, provider=None):
|
|
||||||
provider = provider or app_settings.TIMESTAMP_PROVIDER
|
|
||||||
kwargs = PROVIDERS[provider].copy()
|
|
||||||
klass = kwargs.pop('class')
|
|
||||||
module, klass = klass.rsplit('.', 1)
|
|
||||||
module = importlib.import_module(module)
|
|
||||||
klass = getattr(module, klass)
|
|
||||||
timestamper = klass(**kwargs)
|
|
||||||
try:
|
|
||||||
return timestamper(data=content)
|
|
||||||
except Exception, e:
|
|
||||||
raise TimestampingError(e)
|
|
||||||
|
|
||||||
def encode_timestamp(provider, tst):
|
|
||||||
return '%s!%s' % (provider, tst.encode('base64').strip())
|
|
||||||
|
|
||||||
def decode_timestamp(encoded_tst):
|
|
||||||
return encoded_tst.split('!')
|
|
||||||
|
|
||||||
def timestamp_json(json_dict, provider=None):
|
|
||||||
provider = provider or app_settings.TIMESTAMP_PROVIDER
|
|
||||||
s = json.dumps(json_dict)
|
|
||||||
if s[-1] != '}':
|
|
||||||
raise ValueError("timestamp_json takes a dictionnary as argument: %s" % s)
|
|
||||||
tst, error = timestamp(s, provider=provider)
|
|
||||||
try:
|
|
||||||
dt = rfc3161.get_timestamp(tst)
|
|
||||||
except ValueError:
|
|
||||||
dt = None
|
|
||||||
if tst:
|
|
||||||
return s[:-1] + ',"timestamp": "%s"}' % encode_timestamp(provider, tst), dt
|
|
||||||
else:
|
|
||||||
raise TimestampingError(error)
|
|
||||||
|
|
||||||
def check_timestamp_json(content, certificate):
|
|
||||||
content, tst = content.rsplit(',"timestamp": "', 1)
|
|
||||||
content += '}'
|
|
||||||
tst = tst[:-2].decode('base64')
|
|
||||||
return rfc3161.check_timestamp(tst, certificate, data=content)
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from optparse import make_option
|
from datetime import datetime as dt
|
||||||
import sys
|
import sys
|
||||||
import mailbox
|
import mailbox
|
||||||
import email
|
import email
|
||||||
|
@ -7,6 +7,7 @@ import email.utils
|
||||||
import email.header
|
import email.header
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import time
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -17,7 +18,7 @@ from django.core.exceptions import MultipleObjectsReturned
|
||||||
from django.utils.timezone import utc, make_aware
|
from django.utils.timezone import utc, make_aware
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
|
|
||||||
from docbow_project.docbow import models, timestamp, utils
|
from docbow_project.docbow import models, utils
|
||||||
from docbow_project.docbow.email_utils import u2u_decode
|
from docbow_project.docbow.email_utils import u2u_decode
|
||||||
from django_journal.journal import record
|
from django_journal.journal import record
|
||||||
from django.db.transaction import atomic
|
from django.db.transaction import atomic
|
||||||
|
@ -275,11 +276,9 @@ In case of failure the following return value is returned:
|
||||||
name=filename)
|
name=filename)
|
||||||
attached_file.content.save(filename, content, save=False)
|
attached_file.content.save(filename, content, save=False)
|
||||||
attached_file.save()
|
attached_file.save()
|
||||||
blob = document.timestamp_blob()
|
|
||||||
try:
|
try:
|
||||||
tst, gentime = timestamp.timestamp_json(blob)
|
document._timestamp = time.time()
|
||||||
document._timestamp = tst
|
document.date = dt.datetime.fromtimestamp(document._timestamp, utc)
|
||||||
document.date = make_aware(gentime, utc) or document.date
|
|
||||||
document.save()
|
document.save()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from optparse import make_option
|
from datetime import datetime as dt
|
||||||
import sys
|
import sys
|
||||||
import mailbox
|
import mailbox
|
||||||
import email
|
import email
|
||||||
|
@ -7,6 +7,7 @@ import email.utils
|
||||||
import email.header
|
import email.header
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
@ -17,7 +18,7 @@ from django.utils.timezone import utc, make_aware
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.db.models.query import Q
|
from django.db.models.query import Q
|
||||||
|
|
||||||
from docbow_project.docbow import models, timestamp, utils
|
from docbow_project.docbow import models, utils
|
||||||
from docbow_project.docbow.email_utils import u2u_decode
|
from docbow_project.docbow.email_utils import u2u_decode
|
||||||
from django_journal.journal import record, error_record
|
from django_journal.journal import record, error_record
|
||||||
from django.db.transaction import atomic
|
from django.db.transaction import atomic
|
||||||
|
@ -242,11 +243,9 @@ In case of failure the following return value is returned:
|
||||||
name=filename)
|
name=filename)
|
||||||
attached_file.content.save(filename, content, save=False)
|
attached_file.content.save(filename, content, save=False)
|
||||||
attached_file.save()
|
attached_file.save()
|
||||||
blob = document.timestamp_blob()
|
|
||||||
try:
|
try:
|
||||||
tst, gentime = timestamp.timestamp_json(blob)
|
document._timestamp = time.time()
|
||||||
document._timestamp = tst
|
document.date = dt.datetime.fromtimestamp(document._timestamp, utc)
|
||||||
document.date = make_aware(gentime, utc) or document.date
|
|
||||||
document.save()
|
document.save()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -67,7 +67,6 @@ DOCBOW_PFWB_SENDMAIL_TABELLIO_EXPEDITION_USER_ID = None
|
||||||
DOCBOW_PFWB_SENDMAIL_ATTACHED_FILE_EMAIL = 'dontknow@pfwb.be'
|
DOCBOW_PFWB_SENDMAIL_ATTACHED_FILE_EMAIL = 'dontknow@pfwb.be'
|
||||||
DOCBOW_PFWB_SENDMAIL_ATTACHED_FILE_USER_ID = None
|
DOCBOW_PFWB_SENDMAIL_ATTACHED_FILE_USER_ID = None
|
||||||
DATE_INPUT_FORMATS = ('%d/%m/%Y', '%Y-%m-%d')
|
DATE_INPUT_FORMATS = ('%d/%m/%Y', '%Y-%m-%d')
|
||||||
DOCBOW_TIMESTAMP_PROVIDER = 'certum'
|
|
||||||
DOCBOW_MAX_FILE_SIZE = 10*1024*1024
|
DOCBOW_MAX_FILE_SIZE = 10*1024*1024
|
||||||
CUSTOMIZATION = os.environ.get('CUSTOMIZATION', 'pfwb')
|
CUSTOMIZATION = os.environ.get('CUSTOMIZATION', 'pfwb')
|
||||||
DOCBOW_PRIVATE_DOCUMENTS = False
|
DOCBOW_PRIVATE_DOCUMENTS = False
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -103,7 +103,6 @@ setup(name='docbow',
|
||||||
'typing', # For M2Crypto.util
|
'typing', # For M2Crypto.util
|
||||||
'django-debug-toolbar<0.9.0',
|
'django-debug-toolbar<0.9.0',
|
||||||
'BeautifulSoup<3.3.0',
|
'BeautifulSoup<3.3.0',
|
||||||
'rfc3161',
|
|
||||||
'gunicorn',
|
'gunicorn',
|
||||||
'django_journal>=2.0.0',
|
'django_journal>=2.0.0',
|
||||||
'django-picklefield',
|
'django-picklefield',
|
||||||
|
|
Loading…
Reference in New Issue