| @ -1,22 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-08-23 05:10 | |||
| from django.db import migrations, models | |||
| import edivorce.apps.core.redis | |||
| class Migration(migrations.Migration): | |||
| initial = True | |||
| dependencies = [ | |||
| ] | |||
| operations = [ | |||
| migrations.CreateModel( | |||
| name='Document', | |||
| fields=[ | |||
| ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||
| ('file', models.FileField(storage=edivorce.apps.core.redis.RedisStorage, upload_to='docs_%Y_%m_%d_%H_%M_%S')), | |||
| ], | |||
| ), | |||
| ] | |||
| @ -1,24 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-08-23 06:06 | |||
| from django.db import migrations, models | |||
| import edivorce.apps.core.redis | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('poc', '0001_initial'), | |||
| ] | |||
| operations = [ | |||
| migrations.AddField( | |||
| model_name='document', | |||
| name='filename', | |||
| field=models.CharField(max_length=128, null=True), | |||
| ), | |||
| migrations.AlterField( | |||
| model_name='document', | |||
| name='file', | |||
| field=models.FileField(storage=edivorce.apps.core.redis.RedisStorage(), upload_to=edivorce.apps.core.redis.generate_unique_filename), | |||
| ), | |||
| ] | |||
| @ -1,23 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-09-15 23:45 | |||
| from django.db import migrations, models | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('poc', '0002_auto_20200823_0606'), | |||
| ] | |||
| operations = [ | |||
| migrations.AddField( | |||
| model_name='document', | |||
| name='docType', | |||
| field=models.CharField(max_length=4, null=True), | |||
| ), | |||
| migrations.AddField( | |||
| model_name='document', | |||
| name='partyId', | |||
| field=models.IntegerField(default=0), | |||
| ), | |||
| ] | |||
| @ -1,18 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-09-17 17:08 | |||
| from django.db import migrations, models | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('poc', '0003_auto_20200915_1645'), | |||
| ] | |||
| operations = [ | |||
| migrations.AlterField( | |||
| model_name='document', | |||
| name='docType', | |||
| field=models.CharField(blank=True, max_length=4, null=True), | |||
| ), | |||
| ] | |||
| @ -1,42 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-09-21 19:55 | |||
| from django.db import migrations, models | |||
| import django.db.models.deletion | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('core', '0020_auto_20200903_2328'), | |||
| ('poc', '0004_auto_20200917_1008'), | |||
| ] | |||
| operations = [ | |||
| migrations.RenameField( | |||
| model_name='document', | |||
| old_name='docType', | |||
| new_name='doc_type', | |||
| ), | |||
| migrations.RenameField( | |||
| model_name='document', | |||
| old_name='partyId', | |||
| new_name='party_id', | |||
| ), | |||
| migrations.AddField( | |||
| model_name='document', | |||
| name='bceid_user', | |||
| field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='uploads', to='core.BceidUser'), | |||
| ), | |||
| migrations.AddField( | |||
| model_name='document', | |||
| name='length', | |||
| field=models.IntegerField(default=0), | |||
| ), | |||
| migrations.AlterUniqueTogether( | |||
| name='document', | |||
| unique_together={('bceid_user', 'doc_type', 'party_id', 'filename', 'length')}, | |||
| ), | |||
| migrations.RunSQL( | |||
| sql='delete from poc_document' | |||
| ) | |||
| ] | |||
| @ -1,20 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-09-21 20:01 | |||
| from django.db import migrations, models | |||
| import django.db.models.deletion | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('poc', '0005_auto_20200921_1255'), | |||
| ] | |||
| operations = [ | |||
| migrations.AlterField( | |||
| model_name='document', | |||
| name='bceid_user', | |||
| field=models.ForeignKey(default='', on_delete=django.db.models.deletion.CASCADE, related_name='uploads', to='core.BceidUser'), | |||
| preserve_default=False, | |||
| ), | |||
| ] | |||
| @ -1,23 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-09-21 22:23 | |||
| from django.db import migrations, models | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('poc', '0006_auto_20200921_1301'), | |||
| ] | |||
| operations = [ | |||
| migrations.AddField( | |||
| model_name='document', | |||
| name='order', | |||
| field=models.IntegerField(default=1), | |||
| ), | |||
| migrations.AddField( | |||
| model_name='document', | |||
| name='rotation', | |||
| field=models.IntegerField(default=0), | |||
| ), | |||
| ] | |||
| @ -1,39 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-09-22 17:27 | |||
| import datetime | |||
| from django.db import migrations, models | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('core', '0020_auto_20200903_2328'), | |||
| ('poc', '0007_auto_20200921_1523'), | |||
| ] | |||
| operations = [ | |||
| migrations.RenameField( | |||
| model_name='document', | |||
| old_name='party_id', | |||
| new_name='party_code', | |||
| ), | |||
| migrations.RenameField( | |||
| model_name='document', | |||
| old_name='length', | |||
| new_name='size', | |||
| ), | |||
| migrations.RenameField( | |||
| model_name='document', | |||
| old_name='order', | |||
| new_name='sort_order', | |||
| ), | |||
| migrations.AddField( | |||
| model_name='document', | |||
| name='date_uploaded', | |||
| field=models.DateTimeField(default=datetime.datetime.now), | |||
| ), | |||
| migrations.AlterUniqueTogether( | |||
| name='document', | |||
| unique_together={('bceid_user', 'doc_type', 'party_code', 'filename', 'size')}, | |||
| ), | |||
| ] | |||
| @ -1,18 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-09-22 17:33 | |||
| from django.db import migrations, models | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('poc', '0008_auto_20200922_1027'), | |||
| ] | |||
| operations = [ | |||
| migrations.AlterField( | |||
| model_name='document', | |||
| name='date_uploaded', | |||
| field=models.DateTimeField(auto_now_add=True), | |||
| ), | |||
| ] | |||
| @ -1,16 +0,0 @@ | |||
| # Generated by Django 2.2.15 on 2020-09-24 00:37 | |||
| from django.db import migrations | |||
| class Migration(migrations.Migration): | |||
| dependencies = [ | |||
| ('poc', '0009_auto_20200922_1033'), | |||
| ] | |||
| operations = [ | |||
| migrations.DeleteModel( | |||
| name='Document', | |||
| ), | |||
| ] | |||
| @ -1,45 +0,0 @@ | |||
| {% extends 'base.html' %} | |||
| {% load input_field %} | |||
| {% load step_order %} | |||
| {% block title %}{{ block.super }}: POC{% endblock %} | |||
| {% block progress %}{% include "poc-sidebar.html" %}{% endblock %} | |||
| {% block content %} | |||
| <h1><small>Proof of Concept:</small>Efiling Hub Integration</h1> | |||
| <form method="post" enctype="multipart/form-data"> | |||
| {% csrf_token %} | |||
| <div class="question-well"> | |||
| <h3>Specify files to upload to the eFiling Hub.</h3> | |||
| <div class="form-group {% if form.upload_file.errors %}has-error{% endif %}"> | |||
| <div>{{ form.upload_file }}</div> | |||
| {% if form.upload_file.errors %} | |||
| <span class="help-block"> | |||
| {% for err in form.upload_file.errors %}{{ err }}{% endfor %} | |||
| </span> | |||
| {% endif %} | |||
| </div> | |||
| </div> | |||
| <div class="form-buttons clearfix"> | |||
| <button type="submit" class="btn btn-primary pull-right">Submit</button> | |||
| </div> | |||
| </form> | |||
| {% endblock %} | |||
| {% block formbuttons %} | |||
| {% endblock %} | |||
| {% block sidebarNav %} | |||
| <!-- no sidebar --> | |||
| {% endblock %} | |||
| {% block sidebar %} | |||
| <!-- no sidebar --> | |||
| {% endblock %} | |||
| @ -1,18 +0,0 @@ | |||
| {% load step_order %} | |||
| <div class="col-flex progress-column"> | |||
| <h4>POC</h4> | |||
| <a href="{% url 'poc-scan' %}" class="progress-question"> | |||
| <span class="progress-icon"><i class="fa fa-share-alt" aria-hidden="true"></i></span> | |||
| <span class="progress-content">File Scanning</span> | |||
| </a> | |||
| <a href="{% url 'poc-storage' %}" class="progress-question"> | |||
| <span class="progress-icon"><i class="fa fa-info" aria-hidden="true"></i></span> | |||
| <span class="progress-content">Redis Storage</span> | |||
| </a> | |||
| <a href="{% url 'poc-hub' %}" class="progress-question"> | |||
| <span class="progress-icon"><i class="fa fa-location-arrow" aria-hidden="true"></i></span> | |||
| <span class="progress-content">eFiling Hub</span> | |||
| </a> | |||
| </div> | |||
| @ -1,26 +0,0 @@ | |||
| {% extends 'base.html' %} | |||
| {% load input_field %} | |||
| {% load step_order %} | |||
| {% block title %}{{ block.super }}: POC{% endblock %} | |||
| {% block progress %}{% include "poc-sidebar.html" %}{% endblock %} | |||
| {% block content %} | |||
| <form method="post">{% csrf_token %} | |||
| <p>Are you sure you want to delete "{{ object }}"?</p> | |||
| <input type="submit" value="Confirm"> | |||
| </form> | |||
| {% endblock %} | |||
| {% block formbuttons %} | |||
| {% endblock %} | |||
| {% block sidebarNav %} | |||
| <!-- no sidebar --> | |||
| {% endblock %} | |||
| {% block sidebar %} | |||
| <!-- no sidebar --> | |||
| {% endblock %} | |||
| @ -1,46 +0,0 @@ | |||
| {% extends 'base.html' %} | |||
| {% load input_field %} | |||
| {% load step_order %} | |||
| {% block title %}{{ block.super }}: POC{% endblock %} | |||
| {% block progress %}{% include "poc-sidebar.html" %}{% endblock %} | |||
| {% block content %} | |||
| <h1><small>Proof of Concept:</small>File scanning</h1> | |||
| <form method="post" enctype="multipart/form-data"> | |||
| {% csrf_token %} | |||
| <div class="question-well"> | |||
| <h3>Upload a file to test virus scanning.</h3> | |||
| <div class="form-group {% if form.upload_file.errors %}has-error{% elif validation_success %}has-success{% endif %}"> | |||
| <div>{{ form.upload_file }}</div> | |||
| {% if form.upload_file.errors %} | |||
| <span class="help-block"> | |||
| {% for err in form.upload_file.errors %}{{ err }}{% endfor %} | |||
| </span> | |||
| {% endif %} | |||
| {% if validation_success %}<span class="help-block">No viruses found</span>{% endif %} | |||
| </div> | |||
| </div> | |||
| <div class="form-buttons clearfix"> | |||
| <button type="submit" class="btn btn-primary pull-right">Submit</button> | |||
| </div> | |||
| </form> | |||
| {% endblock %} | |||
| {% block formbuttons %} | |||
| {% endblock %} | |||
| {% block sidebarNav %} | |||
| <!-- no sidebar --> | |||
| {% endblock %} | |||
| {% block sidebar %} | |||
| <!-- no sidebar --> | |||
| {% endblock %} | |||
| @ -1,71 +0,0 @@ | |||
| {% extends 'base.html' %} | |||
| {% load input_field %} | |||
| {% load step_order %} | |||
| {% block title %}{{ block.super }}: POC{% endblock %} | |||
| {% block progress %}{% include "poc-sidebar.html" %}{% endblock %} | |||
| {% block content %} | |||
| <h1><small>Proof of Concept:</small>File storage</h1> | |||
| <form id="form" method="post" enctype="multipart/form-data"> | |||
| {% csrf_token %} | |||
| <div class="question-well"> | |||
| <h3>Upload a file to store in Redis.</h3> | |||
| <div class="form-group {% if form.file.errors %}has-error{% elif validation_success %}has-success{% endif %}"> | |||
| <div>{{ form.file }}</div> | |||
| {% if form.file.errors %} | |||
| <span class="help-block"> | |||
| {% for err in form.file.errors %}{{ err }}{% endfor %} | |||
| </span> | |||
| {% endif %} | |||
| {% if validation_success %}<span class="help-block">No viruses found</span>{% endif %} | |||
| </div> | |||
| </div> | |||
| <div class="form-buttons clearfix"> | |||
| <button type="submit" class="btn btn-primary pull-right">Submit</button> | |||
| </div> | |||
| <div class="question-well"> | |||
| <h3>Stored documents</h3> | |||
| <table class="table"> | |||
| <thead> | |||
| <tr> | |||
| <th>File name</th> | |||
| <th>Redis key</th> | |||
| <th></th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {% for document in documents %} | |||
| <tr> | |||
| <td class="fact-sheet-question"> | |||
| <a href="{% url "poc-storage-download" document.id %}" target="_blank"> | |||
| {{ document.filename|default:'' }} | |||
| </a> | |||
| </td> | |||
| <td class="fact-sheet-question">{{ document.file.name }}</td> | |||
| <td><a href="{% url "poc-storage-delete" document.id %}" class="delete-link">Delete</a></td> | |||
| </tr> | |||
| {% endfor %} | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </form> | |||
| {% endblock %} | |||
| {% block formbuttons %} | |||
| {% endblock %} | |||
| {% block sidebarNav %} | |||
| <!-- no sidebar --> | |||
| {% endblock %} | |||
| {% block sidebar %} | |||
| <!-- no sidebar --> | |||
| {% endblock %} | |||
| @ -1,12 +0,0 @@ | |||
| from django.conf.urls import url | |||
| from django.contrib.auth.decorators import login_required | |||
| from edivorce.apps.poc import views | |||
| urlpatterns = [ | |||
| url(r'scan', login_required(views.UploadScan.as_view()), name="poc-scan"), | |||
| url(r'hub', login_required(views.EFilingSubmissionUpload.as_view()), name="poc-hub"), | |||
| url(r'storage/doc/(?P<document_id>\d+)', login_required(views.view_document_file), name="poc-storage-download"), | |||
| url(r'storage/delete/(?P<pk>\d+)', login_required(views.UploadStorageDelete.as_view()), name="poc-storage-delete"), | |||
| url(r'storage', login_required(views.UploadStorage.as_view()), name="poc-storage"), | |||
| ] | |||
| @ -1,112 +0,0 @@ | |||
| import logging | |||
| from django.shortcuts import render | |||
| from django.utils.decorators import method_decorator | |||
| from django.views.decorators.csrf import csrf_exempt | |||
| from django.views.generic.edit import FormView, CreateView, DeleteView | |||
| from django import forms | |||
| from django.http import HttpResponse | |||
| from django.conf import settings | |||
| from edivorce.apps.core.utils.efiling_submission import EFilingSubmission | |||
| from edivorce.apps.core.utils.efiling_packaging import PACKAGE_PARTY_FORMAT | |||
| from edivorce.apps.core.validators import file_scan_validation | |||
| from edivorce.apps.core.models import Document | |||
| logger = logging.getLogger(__name__) | |||
| """ | |||
| Everything in this file is considered as proof of concept work and should not be used for production code. | |||
| """ | |||
| class UploadScanForm(forms.Form): | |||
| upload_file = forms.FileField(validators=[file_scan_validation]) | |||
| class MultipleUploadForm(forms.Form): | |||
| upload_file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True})) | |||
| class UploadScan(FormView): | |||
| form_class = UploadScanForm | |||
| template_name = "scan.html" | |||
| def form_valid(self, form): | |||
| context = self.get_context_data() | |||
| context['validation_success'] = True | |||
| return render(self.request, self.template_name, context) | |||
| class UploadStorage(CreateView): | |||
| model = Document | |||
| fields = ['file', 'doc_type', 'party_code'] | |||
| template_name = "storage.html" | |||
| success_url = settings.FORCE_SCRIPT_NAME + 'poc/storage' | |||
| @method_decorator(csrf_exempt) | |||
| def dispatch(self, request, *args, **kwargs): | |||
| return super(UploadStorage, self).dispatch(request, *args, **kwargs) | |||
| def get_context_data(self, **kwargs): | |||
| kwargs['documents'] = Document.objects.all() | |||
| return super(UploadStorage, self).get_context_data(**kwargs) | |||
| def form_valid(self, form): | |||
| obj = form.save(commit=False) | |||
| obj.bceid_user = self.request.user | |||
| return super(UploadStorage, self).form_valid(form) | |||
| class UploadStorageDelete(DeleteView): | |||
| model = Document | |||
| success_url = settings.FORCE_SCRIPT_NAME + 'poc/storage' | |||
| template_name = 'poc/document_confirm_delete.html' | |||
| def view_document_file(request, document_id): | |||
| doc = Document.objects.get(id=document_id) | |||
| content_type = 'application/pdf' if 'pdf' in doc.file.name else 'image/jpeg' | |||
| response = HttpResponse(doc.file.read(), content_type=content_type) | |||
| response['Content-Disposition'] = 'attachment; filename={}'.format(doc.filename) | |||
| return response | |||
| class EFilingSubmissionUpload(FormView): | |||
| form_class = MultipleUploadForm | |||
| template_name = 'hub.html' | |||
| success_url = '/poc/hub' | |||
| def post(self, request, *args, **kwargs): | |||
| form_class = self.get_form_class() | |||
| form = self.get_form(form_class) | |||
| files = request.FILES.getlist('upload_file') | |||
| if form.is_valid(): | |||
| # NOTE: this does not do any validation for file types .. make sure that is done | |||
| # prior to sending to eFiling Hub | |||
| post_files = [] | |||
| if files: | |||
| for file in files: | |||
| post_files.append(('files', (file.name, file.read()))) | |||
| # generate the list of parties to send to eFiling Hub | |||
| parties = [] | |||
| for i in range(0, 2): | |||
| party = PACKAGE_PARTY_FORMAT.copy() | |||
| party['firstName'] = 'Party {}'.format(i) | |||
| party['lastName'] = 'Test' | |||
| parties.append(party) | |||
| hub = EFilingSubmission(initial_filing=True) | |||
| redirect, msg = hub.upload(request, post_files, parties=parties) | |||
| if redirect: | |||
| self.success_url = redirect | |||
| return self.form_valid(form) | |||
| form.add_error('upload_file', msg) | |||
| return self.form_invalid(form) | |||