Commit a59f8851 authored by Odair M.'s avatar Odair M. Committed by Odair M.

Closes #159: implements autorization system

parent bd2d5a1e
......@@ -47,7 +47,7 @@ docker-production:
docker-compose --project-directory . -f docker_scripts/docker-production.yml -p adega up
docker-remove-all:
docker rm adega_web_1 adega_db_1
docker rm adega_web adega_db_1
docker rmi adega_web
......@@ -68,6 +68,6 @@ args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`
docker-manage:
@echo $(call args,"")
docker exec -it adega_web_1 bash -c "cd src; python3 manage.py $(call args,'')"
docker exec -it adega_web bash -c "cd src; python3 manage.py $(call args,'')"
......@@ -44,6 +44,7 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'django_extensions',
'widget_tweaks',
'guardian',
'adega',
'public',
......@@ -104,8 +105,13 @@ DATABASES = {
}
}
AUTHENTICATION_BACKENDS = ['public.auth.EmailBackend']
AUTHENTICATION_BACKENDS = [
'public.auth.EmailBackend',
'guardian.backends.ObjectPermissionBackend',
]
ANONYMOUS_USER_NAME = "Público"
LOGIN_URL = 'public:index'
......
......@@ -6,8 +6,10 @@ from django.contrib import messages
from degree.models import Degree
from report_api.views import get_list_admission, get_admission_detail
from submission.models import Submission
from guardian.decorators import permission_required_or_403
@permission_required_or_403('view_admission', (Submission, 'id', 'submission_id'))
def detail(request, submission_id, ano, semestre):
submission_id = int(submission_id)
submission = Submission.objects.get(id=submission_id)
......@@ -43,6 +45,7 @@ def detail(request, submission_id, ano, semestre):
})
@permission_required_or_403('view_admission', (Submission, 'id', 'submission_id'))
def index(request, submission_id):
submission_id = int(submission_id)
submission = Submission.objects.get(id=submission_id)
......
......@@ -6,8 +6,10 @@ from django.contrib import messages
from degree.models import Degree
from report_api.views import get_list_courses, get_course_detail
from submission.models import Submission
from guardian.decorators import permission_required_or_403
@permission_required_or_403('view_course', (Submission, 'id', 'submission_id'))
def detail(request, submission_id, codigo_disciplina):
submission_id = int(submission_id)
submission = Submission.objects.get(id=submission_id)
......@@ -31,6 +33,7 @@ def detail(request, submission_id, codigo_disciplina):
})
@permission_required_or_403('view_course', (Submission, 'id', 'submission_id'))
def index(request, submission_id):
submission_id = int(submission_id)
submission = Submission.objects.get(id=submission_id)
......
from django.db import models
from django.contrib.auth.models import User
class Degree(models.Model):
name = models.CharField(max_length=40)
code = models.CharField(max_length=40)
manager = models.ForeignKey(User)
def __str__(self):
return self.name
def clean_code(self):
if '/' in self.code:
raise ValidationError('Valor inválido: O código não pode conter "/"')
from django.shortcuts import render, redirect
from django.views.generic import View
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout as process_logout
from report_api.views import get_degree_information
from degree.models import Degree
from submission.models import Submission
import json
from guardian.decorators import permission_required_or_403
@login_required
@permission_required_or_403('view_degree', (Submission, 'id', 'submission_id'))
def index(request, submission_id):
submission_id = int(submission_id)
......@@ -27,18 +27,3 @@ def index(request, submission_id):
"degree_data":degree_data
})
#class Views(View):
# template_name = "index.html"
# @login_required
# def setDegree(self,request,degree_id):
# request.session["degree"] = degree_id
# return redirect('degree:index' )
# def index(self,request):
# if("degree" in request.session):
# degree = Degree.objects.get(code = request.session["degree"])
# else:
# return redirect("adega:dashboard")
# submission = degree.submission
# return render(request,"degree/index",{"degree":degree})
#
#
......@@ -9,7 +9,9 @@ from report_api.views import get_list_students, get_student_detail
import json
from submission.models import Submission
from guardian.decorators import permission_required_or_403
@permission_required_or_403('view_student', (Submission, 'id', 'submission_id'))
def detail(request, submission_id, grr):
submission_id = int(submission_id)
submission = Submission.objects.get(id=submission_id)
......@@ -46,6 +48,7 @@ def detail(request, submission_id, grr):
@permission_required_or_403('view_student', (Submission, 'id', 'submission_id'))
def index(request, submission_id):
submission_id = int(submission_id)
submission = Submission.objects.get(id=submission_id)
......
......@@ -37,29 +37,30 @@ class Submission(models.Model):
historico = models.FileField(upload_to=get_path)
matricula = models.FileField(upload_to=get_path)
degree = models.ForeignKey(Degree)
timestamp = models.DateTimeField(default=timezone.now)
last = models.BooleanField(default=True)
processed = models.BooleanField(default=False)
process_time = models.IntegerField(null=True)
analysis_status = models.IntegerField(default=0, choices=ANALYSIS_STATUS_CHOICES)
analysis_status = models.IntegerField(
default=0,
choices=ANALYSIS_STATUS_CHOICES
)
last_error = models.CharField(default="", max_length=4096)
relative_year = models.IntegerField(null=True)
relative_semester = models.IntegerField(null=True)
semester_status = models.IntegerField(null=True, choices=STATUS_CHOICES)
done_in = models.DateTimeField(null=True)
class Meta:
permissions = (
# ('view_submission', 'Visualizar Relatórios'),
('view_course', 'Visualizar disciplinas'),
('view_student', 'Visualizar alunos'),
('view_degree', 'Visualizar curso'),
('view_admission', 'Visualizar turma ingresso'),
)
def save(self, *args, **kwargs):
"""
Sobrescrita do metodo save.
......@@ -101,10 +102,3 @@ class Submission(models.Model):
self.analysis_status = 2
self.last_error = error_message
self.save()
# @receiver(models.signals.post_save, sender=Submission)
# def execute_after_save(sender, instance, created, *args, **kwargs):
# if created:
# print(sender,instance,created)
# # submission_analysis.analyze(instance, debug=False)
# submission_analysis.analyze(sender)
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div class="alert alert-warning" role="alert">
......@@ -33,36 +35,124 @@
</div>
<div class="formBox form-group">
<form method="post" enctype="multipart/form-data" >
<div class="formBox form-group ">
<form id="form_sub" method="post" accept-charset="utf-8" enctype="multipart/form-data">
{% csrf_token %}
<!-- Uploads files -->
<div class="form-row">
<div class="col-lg-5 col-md-5 col-sm-4">
<label for="historico" type="file"
class="custom-file-label">Histórico</label>
<input type="file" name="historico"
class="custom-file-input" id="historico"/>
</div>
<div class="col-lg-5 col-md-5 col-sm-4 offset-lg-1 offset-md-1">
<label for="matricula" class="custom-file-label">Matrícula</label>
<input type="file" name="matricula" id="matricula"
class="custom-file-input"/>
</div>
</div>
<!-- Integer field -->
<div class="form-row">
<div class="col-lg-5 col-md-5">
<label for="relative_year">Ano do relatório</label>
<input type="number" class="form-control" name="relative_year" id="relative_year"
value="{{form.relative_year.field.initial}}" />
</div>
<div class="col-lg-5 col-md-5 offset-lg-1 offset-md-1">
<label for="relative_semester">Semestre do relatório</label>
<input type="number" class="form-control" name="relative_semester" id="relative_semester"
value="{{form.relative_semester.field.initial}}" />
</div>
</div>
<!-- Select field -->
<div class="form-row">
<div class="col-lg-5 col-md-5">
<label>Selecione o status do semestre</label>
<select name="semester_status" class="browser-default custom-select" id="semester_status">
{% for choice in form.semester_status.field.choices %}
<option value="{{choice.0}}">{{choice.1}}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-5 col-md-5 offset-lg-1 offset-md-1">
<label>Selecione o curso de graduação</label>
<select name="degree" class="browser-default custom-select" id="degree">
{% for choice in form.degree.field.choices %}
<option value="{{choice.0}}">{{choice.1}}</option>
{% endfor %}
</select>
</div>
</div>
<!-- Permissions -->
<div class="row">
<table class="table table-striped" id="ptable" >
<thead >
<tr>
<th rowspan="3">Usuário</th>
<th colspan="5">Permissões</th>
</tr>
<tr>
{% for permission in permissions %}
<th scope="col"> {{permission}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<th>{{user}}</th>
{% for permission in perms %}
<td>
<div class="form-check">
<input class="form-check-input position-static"
type="checkbox"
id="perm-{{user}}-{{permission}}"
name="perm-{{user}}-{{permission}}"
value=1 aria-label="...">
</div>
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 col-sm-4">
{{ form.as_p }}
</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 col-sm-4">
<div class="col-lg-3 col-md-4 col-sm-4 offset-lg-2">
<button class="btn btn-success btn-block" type="submit">Enviar relatório</button>
</div>
<div class="col-lg-3 col-md-4 col-sm-4">
<button class="btn btn-danger btn-block" type="submit">Cancelar</button>
</div>
</div>
</form>
</form>
</div>
<script charset="utf-8">
$("input[type=file]").change(function () {
var fieldVal = $(this).val();
// Change the node's value by removing the fake path (Chrome)
fieldVal = fieldVal.replace("C:\\fakepath\\", "");
if (fieldVal != undefined || fieldVal != "") {
$(this).next(".custom-file-label").attr('data-content', fieldVal);
$(this).next(".custom-file-label").text(fieldVal);
}
});
</script>
{% endblock content %}
{% block js-foot %}
<script src="{% static 'datatables/jquery.dataTables.min.js' %}">
$('#ptable').dataTable({
"bPaginate": true,
"bInfo": false,
"aaSorting": [[ 1, "desc" ]],
"responsive": true
});
</script>
{% endblock js-foot %}
......@@ -6,7 +6,16 @@ from submission.models import Submission
from submission.forms import SubmissionForm
from degree.models import Degree
from submission.analysis import main as submission_analysis
from educator.models import Educator
from django.contrib.auth.models import User
from guardian.shortcuts import assign_perm
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.db.models import Q
@method_decorator(login_required, name='dispatch')
class SubmissionCreate(SuccessMessageMixin, CreateView):
model = Submission
form_class = SubmissionForm
......@@ -16,6 +25,9 @@ class SubmissionCreate(SuccessMessageMixin, CreateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["users"] = User.objects.filter(~Q(username=self.request.user.username))
context["permissions"] = [x[1] for x in Submission._meta.permissions]
context["perms"] = [x[0] for x in Submission._meta.permissions]
context["hide_navbar"] = True
return context
......@@ -30,11 +42,31 @@ class SubmissionCreate(SuccessMessageMixin, CreateView):
response = super(SubmissionCreate, self).form_valid(form)
# trata permissoes
data = self.request.POST.copy()
users = {}
for i in data.keys():
# gets only permission data
if i.startswith("perm-"):
perm_str = i.split('-')
# cache user
if perm_str[1] not in users:
users[perm_str[1]] = User.objects.get(username=perm_str[1])
# assing permission perm_str[2] to user perm_str[1] for
# submission self.object
assign_perm(perm_str[2], users[perm_str[1]], self.object)
# assing all permission for self user
for perm in Submission._meta.permissions:
assign_perm(perm[0], self.request.user, self.object)
submission_analysis.analyze(self.object, debug=False)
return response
@method_decorator(login_required, name='dispatch')
class SubmissionUpdate(UpdateView):
model = Submission
template_name = 'submission_update.html'
......@@ -52,6 +84,8 @@ class SubmissionUpdate(UpdateView):
context["hide_navbar"] = True
return context
@method_decorator(login_required, name='dispatch')
class SubmissionDelete(DeleteView):
model = Submission
template_name = 'submission_delete.html'
......@@ -62,6 +96,8 @@ class SubmissionDelete(DeleteView):
context["hide_navbar"] = True
return context
@method_decorator(login_required, name='dispatch')
class SubmissionList(ListView):
model = Submission
template_name = 'submission_list.html'
......@@ -80,6 +116,7 @@ class SubmissionList(ListView):
return self.model.objects.filter(author=educator)
@method_decorator(login_required, name='dispatch')
class SubmissionDetail(DetailView):
model = Submission
template_name = 'submission_detail.html'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment