204 lines
8.3 KiB
Python
204 lines
8.3 KiB
Python
import logging
|
|
import yaml
|
|
import os
|
|
import json
|
|
import time
|
|
|
|
from django.shortcuts import render, redirect , get_object_or_404
|
|
from .forms import OrganizationForm
|
|
from .models import Organization,Document, DocumentTemplate, DemoCode, DocumentRiskControl, Risk, Control
|
|
from backend.accounts.utils import send_confirmation_email, send_document_email, send_documet_to_expert, send_document_to_reviewer
|
|
from django.contrib.admin.views.decorators import staff_member_required
|
|
from .utils import generate_pdf, generate_risk_graph, generate_residual_risk_graph
|
|
from .tables import risk_matrix_table ,get_risk_table, get_safeguard_summary_table
|
|
from django.conf import settings
|
|
from .processors import render_template
|
|
from django.http import JsonResponse, FileResponse, Http404, HttpResponse
|
|
from django.core.exceptions import ValidationError
|
|
from django.core.validators import validate_email
|
|
from django.utils import timezone
|
|
from weasyprint import HTML
|
|
from django.template.loader import render_to_string
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from backend.accounts.models import ExpertAnalysisEmails
|
|
|
|
|
|
# @login_required
|
|
# def index(request):
|
|
# return HttpResponse('<h1>Django</h1><p>Página simples.</p>')
|
|
|
|
logger = logging.getLogger(__name__)
|
|
site_domain = settings.SITE_DOMAIN
|
|
|
|
# @login_required
|
|
def index(request):
|
|
template_name = 'index.html'
|
|
return render(request, template_name)
|
|
|
|
|
|
def signup(request):
|
|
if request.method == 'POST':
|
|
form = OrganizationForm(request.POST)
|
|
if form.is_valid():
|
|
form.save()
|
|
send_confirmation_email(form.data['email'])
|
|
|
|
return render(request, 'thankyou.html', {
|
|
'email': form.data['email'],
|
|
})
|
|
else:
|
|
logging.error(form.errors)
|
|
return render(request, 'signup.html', {'form': form})
|
|
else:
|
|
form = OrganizationForm()
|
|
|
|
return render(request, 'signup.html', {'form': form})
|
|
|
|
|
|
def validate_form_fields(request):
|
|
name = request.GET.get('name', '').strip()
|
|
email = request.GET.get('email', '').strip()
|
|
errors = {}
|
|
|
|
if name and Organization.objects.filter(name__iexact=name).exists():
|
|
errors['name'] = 'Organization with this name already exists.'
|
|
if email:
|
|
try:
|
|
validate_email(email)
|
|
except ValidationError:
|
|
errors['email'] = 'Please enter a valid email address.'
|
|
else:
|
|
if Organization.objects.filter(email__iexact=email).exists():
|
|
errors['email'] = 'This email is already registered.'
|
|
|
|
return JsonResponse({'errors': errors})
|
|
|
|
|
|
def thankyou(request):
|
|
return render(request, 'thankyou.html')
|
|
|
|
def document(request, document_id):
|
|
document = get_object_or_404(Document, id=document_id)
|
|
risks_with_controls = get_risk_table(document)
|
|
table_risk_matrix = risk_matrix_table()
|
|
safeguard_summary_table = get_safeguard_summary_table(risks_with_controls)
|
|
graph_base64 = generate_risk_graph(risks_with_controls)
|
|
residual_graph_base64 = generate_residual_risk_graph(risks_with_controls)
|
|
template_obj = get_object_or_404(DocumentTemplate, name="Default Template")
|
|
template_content = template_obj.content
|
|
|
|
try:
|
|
template_segments = yaml.safe_load(template_content)
|
|
except yaml.YAMLError as e:
|
|
return render(request, 'error.html', {'error_message': 'Error parsing template.'})
|
|
context = {
|
|
'document': document,
|
|
'risks_with_controls': risks_with_controls,
|
|
'graph': graph_base64,
|
|
'table_risk_matrix': table_risk_matrix,
|
|
'residual_graph': residual_graph_base64,
|
|
'safeguard_summary_table': safeguard_summary_table,
|
|
'table_risk_matrix_header' : table_risk_matrix[0],
|
|
'table_risk_matrix_rows': table_risk_matrix[1:],
|
|
}
|
|
rendered_content = render_template(template_segments, context)
|
|
return render(request, 'document.html',
|
|
{'rendered_html': rendered_content,
|
|
'document': document,})
|
|
|
|
|
|
@staff_member_required
|
|
def template_preview(request, name):
|
|
template = get_object_or_404(DocumentTemplate, name=name)
|
|
parsed_template = template.to_dict()
|
|
return render(request, 'template_preview.html', {'template': parsed_template})
|
|
|
|
def pdf_view(request, document_id):
|
|
document = get_object_or_404(Document, id=document_id)
|
|
return generate_pdf(document)
|
|
|
|
def payment_page(request):
|
|
error = None
|
|
email = request.GET.get('email')
|
|
if request.method == 'POST':
|
|
import re
|
|
code = re.sub(r'\s+', '', request.POST.get('code', '')).upper()[:10]
|
|
try:
|
|
payment_code = DemoCode.objects.get(code=code)
|
|
if payment_code.used:
|
|
error = "CODE INVALID"
|
|
else:
|
|
org = Organization.objects.filter(email__iexact=email).first()
|
|
payment_code.used = True
|
|
payment_code.used_at = timezone.now()
|
|
payment_code.company = org
|
|
payment_code.save()
|
|
document = Document.objects.get(organization = org)
|
|
url = f"{site_domain}/pdf/{document.id}/"
|
|
expert_emails_qs = ExpertAnalysisEmails.objects.values_list('email', flat=True).distinct()
|
|
|
|
# If document is incomplete, notify reviewers
|
|
if document.status == Document.STATUS_INCOMPLETE:
|
|
if expert_emails_qs:
|
|
for email_addr in expert_emails_qs:
|
|
try:
|
|
send_document_to_reviewer(email_addr, document)
|
|
except Exception:
|
|
logger.exception("Failed to send incomplete document email to %s", email_addr)
|
|
return render(request, 'payment_review.html', {'email': email, 'document': document})
|
|
|
|
# If organization requested expert analysis, mark waiting and notify experts
|
|
if org.expert_analysis:
|
|
document.status = Document.STATUS_WAITING
|
|
document.save(update_fields=['status', 'modified_at'])
|
|
expert_emails = [e for e in expert_emails_qs if e]
|
|
if expert_emails:
|
|
for email_addr in expert_emails:
|
|
try:
|
|
send_documet_to_expert(email_addr, document)
|
|
except Exception:
|
|
logger.exception("Failed to send expert analysis email to %s", email_addr)
|
|
else:
|
|
logger.info("No expert emails configured; skipping expert notifications.")
|
|
return render(request, 'payment_expert_analysis.html', {'email': email, 'document': document})
|
|
send_document_email(email, url, document)
|
|
document.status = Document.STATUS_DONE
|
|
document.save(update_fields=['status', 'modified_at'])
|
|
return redirect(url)
|
|
except DemoCode.DoesNotExist:
|
|
error = "❌ Invalid code"
|
|
return render(request, 'payment.html', {'error': error})
|
|
|
|
def no_confidential_data(request):
|
|
return render(request, "no_confidential_data.html")
|
|
|
|
|
|
|
|
@staff_member_required
|
|
def demo_codes_pdf_view(request):
|
|
filter_by = request.GET.get('filter_by', 'all')
|
|
if filter_by == 'used':
|
|
codes = DemoCode.objects.filter(used=True)
|
|
elif filter_by == 'available':
|
|
codes = DemoCode.objects.filter(used=False)
|
|
else:
|
|
codes = DemoCode.objects.all()
|
|
html_string = render_to_string('demo_code_report.html', {'codes': codes})
|
|
pdf_content = HTML(string=html_string, base_url=request.build_absolute_uri('/')).write_pdf()
|
|
response = HttpResponse(pdf_content, content_type='application/pdf')
|
|
response['Content-Disposition'] = f'inline; filename=demo_codes_{timezone.now().strftime("%Y%m%d_%H%M%S")}.pdf'
|
|
return response
|
|
|
|
@csrf_exempt
|
|
def validate_code(request):
|
|
if request.method == "POST":
|
|
try:
|
|
data = json.loads(request.body)
|
|
code = data.get("code", "").strip().upper()
|
|
from .models import DemoCode
|
|
valid = DemoCode.objects.filter(code=code, used=False).exists()
|
|
time.sleep(3)
|
|
return JsonResponse({"valid": valid})
|
|
except Exception:
|
|
return JsonResponse({"valid": False})
|
|
return JsonResponse({"valid": False}) |