remove rfc3161 timestamping (#42352)

This commit is contained in:
Emmanuel Cazenave 2020-04-30 18:39:33 +02:00
parent 779138c4fd
commit 505d23bffb
10 changed files with 17 additions and 131 deletions

View File

@ -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

1
debian/control vendored
View File

@ -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,

View File

@ -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)

View File

@ -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):

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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',