diff --git a/.dockerignore b/.dockerignore index 318700ad6..4ff7fdc82 100644 --- a/.dockerignore +++ b/.dockerignore @@ -12,3 +12,10 @@ bower .travis.yml .env .idea +.DS_Store +.coveragerc +*.swp +.coveragerc +.drone.yml +.github +release.sh diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 20c75374a..9de3d4612 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -33,11 +33,11 @@ services: networks: - sapl-net sapl: - image: interlegis/sapl:3.1.164-RC3 -# build: -# context: ../ -# dockerfile: ./docker/Dockerfile -# container_name: sapl +# image: interlegis/sapl:3.1.164-RC3 + build: + context: ../ + dockerfile: ./docker/Dockerfile + container_name: sapl labels: NAME: "sapl" restart: always diff --git a/docker/startup_scripts/start.sh b/docker/startup_scripts/start.sh index 316d73f8a..bd98bdfc0 100755 --- a/docker/startup_scripts/start.sh +++ b/docker/startup_scripts/start.sh @@ -4,19 +4,16 @@ IFS=$'\n\t' APP_DIR="/var/interlegis/sapl" DATA_DIR="/var/interlegis/sapl/data" -MEDIA_DIR="/var/interlegis/sapl/media" RUN_DIR="/var/interlegis/sapl/run" ENV_FILE="$APP_DIR/.env" SECRET_FILE="$DATA_DIR/secret.key" chown -R root:nginx "$RUN_DIR" || true -chown -R root:nginx "$MEDIA_DIR" || true chmod -R g+rwX "$RUN_DIR" || true -chmod -R g+rwX "$MEDIA_DIR" || true # setgid bit on our writable trees (not data/) -find "$RUN_DIR" "$MEDIA_DIR" -type d -exec chmod g+s {} + 2>/dev/null || true +find "$RUN_DIR" -type d -exec chmod g+s {} + 2>/dev/null || true log() { printf '[%s] %s\n' "$(date -Is)" "$*"; } err() { printf '[%s] ERROR: %s\n' "$(date -Is)" "$*" >&2; } diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 5a05149da..ce158228b 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -1461,6 +1461,7 @@ class TramitacaoCrud(MasterDetailCrud): return initial + @method_decorator(ratelimit(key='ip', rate='10/m', block=True), name='dispatch') class ListView(MasterDetailCrud.ListView): def get_queryset(self): @@ -1533,6 +1534,7 @@ class TramitacaoCrud(MasterDetailCrud): return HttpResponseRedirect(url) + @method_decorator(ratelimit(key='ip', rate='10/m', block=True), name='dispatch') class DetailView(MasterDetailCrud.DetailView): template_name = "materia/tramitacao_detail.html" @@ -2044,6 +2046,7 @@ class AcompanhamentoExcluirView(TemplateView): return HttpResponseRedirect(self.get_success_url()) +@method_decorator(ratelimit(key='ip', rate='10/m', block=True), name='dispatch') class MateriaLegislativaPesquisaView(MultiFormatOutputMixin, FilterView): model = MateriaLegislativa filterset_class = MateriaLegislativaFilterSet diff --git a/sapl/norma/views.py b/sapl/norma/views.py index bcd059805..488e73c90 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -150,6 +150,7 @@ class NormaRelacionadaCrud(MasterDetailCrud): layout_key = 'NormaRelacionadaDetail' +@method_decorator(ratelimit(key='ip', rate='10/m', block=True), name='dispatch') class NormaPesquisaView(MultiFormatOutputMixin, FilterView): model = NormaJuridica filterset_class = NormaFilterSet @@ -235,6 +236,7 @@ class AnexoNormaJuridicaCrud(MasterDetailCrud): initial['ano'] = self.object.ano return initial + @method_decorator(ratelimit(key='ip', rate='10/m', block=True), name='dispatch') class DetailView(MasterDetailCrud.DetailView): form_class = AnexoNormaJuridicaForm layout_key = 'AnexoNormaJuridica' diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 7d8ec4bd1..4ee5e6da9 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -28,6 +28,9 @@ from django.views.generic.edit import FormMixin from django_filters.views import FilterView import pytz +from ratelimit.decorators import ratelimit +from django.utils.decorators import method_decorator + from sapl.base.models import AppConfig as AppsAppConfig from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, MasterDetailCrud, @@ -3794,6 +3797,7 @@ class SessaoListView(ListView): return context +@method_decorator(ratelimit(key='ip', rate='10/m', block=True), name='dispatch') class PautaSessaoView(TemplateView): model = SessaoPlenaria template_name = "sessao/pauta_inexistente.html" @@ -3809,6 +3813,7 @@ class PautaSessaoView(TemplateView): reverse('sapl.sessao:pauta_sessao_detail', kwargs={'pk': sessao.pk})) +@method_decorator(ratelimit(key='ip', rate='10/m', block=True), name='dispatch') class PautaSessaoDetailView(PautaMultiFormatOutputMixin, DetailView): template_name = "sessao/pauta_sessao_detail.html" model = SessaoPlenaria diff --git a/scripts/gunicorn_start.sh b/scripts/gunicorn_start.sh index d01503235..bd2932985 100755 --- a/scripts/gunicorn_start.sh +++ b/scripts/gunicorn_start.sh @@ -15,8 +15,8 @@ then fi NAME="SAPL" # Name of the application (*) -DJANGODIR=$SAPL_DIR/ # Django project directory (*) -SOCKFILE=$SAPL_DIR/run/gunicorn.sock # we will communicate using this unix socket (*) +DJANGODIR="$SAPL_DIR/" # Django project directory (*) +SOCKFILE="$SAPL_DIR/run/gunicorn.sock" # we will communicate using this unix socket (*) USER=`whoami` # the user to run as (*) GROUP=`whoami` # the group to run as (*) NUM_WORKERS=3 # how many worker processes should Gunicorn spawn (*)