Skip to content

Commit

Permalink
Merge pull request #267 from certsocietegenerale/python3
Browse files Browse the repository at this point in the history
Python3
  • Loading branch information
udgover authored Jul 5, 2021
2 parents 3f46f8f + e5b2675 commit 3d26509
Show file tree
Hide file tree
Showing 89 changed files with 502 additions and 529 deletions.
7 changes: 4 additions & 3 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
FROM python:2.7-alpine AS builder
FROM python:3.8-alpine AS builder
WORKDIR /app
COPY . /app
RUN apk add --update python-dev \
RUN apk add --update git \
python3-dev \
libxml2-dev \
libxslt-dev \
build-base \
Expand All @@ -16,7 +17,7 @@ RUN apk add --update python-dev \
mv fir/config/installed_apps.txt.sample fir/config/installed_apps.txt && \
deactivate

FROM python:2.7-alpine AS fir
FROM python:3.8-alpine AS fir
COPY --from=builder /app /app
RUN apk add libxml2 libxslt mariadb-connector-c && \
rm -rf /var/cache/apk/* && \
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ services:
- fir_db
- fir_redis
env_file:
- fir.env
- fir.env
networks:
backend.fir:

Expand Down
2 changes: 1 addition & 1 deletion docker/fir.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ HOME=/app/FIR
DJANGO_SETTINGS_MODULE=fir.config.composeprod

ALLOWED_HOSTS=localhost,127.0.0.1
DEBUG=true
DEBUG=false

# Secret key
SECRET_KEY="not so secret"
Expand Down
7 changes: 4 additions & 3 deletions fir/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import os
from pkgutil import find_loader
from importlib import import_module
from distutils.util import strtobool

BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))

# Django settings for fir project.


ENFORCE_2FA = False
ENFORCE_2FA = bool(strtobool(os.getenv('ENFORCE_2FA', 'False')))

tf_error_message = """Django two factor is not installed and ENFORCE_2FA is set to True.
Either set ENFORCE_2FA to False or pip install django-two-factor-auth
Expand Down Expand Up @@ -71,7 +72,7 @@
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

MIDDLEWARE_CLASSES = (
MIDDLEWARE = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
Expand All @@ -84,7 +85,7 @@

if TF_INSTALLED:
TF_MIDDLEWARE = ('django_otp.middleware.OTPMiddleware',)
MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + TF_MIDDLEWARE
MIDDLEWARE = MIDDLEWARE + TF_MIDDLEWARE


# Authentication and authorization backends
Expand Down
6 changes: 6 additions & 0 deletions fir/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
'django.template.loaders.app_directories.Loader',
)

# Rest framework default pagination
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 100
}

# Dummy key for development
SECRET_KEY = 'DUMMY_KEY_FOR_DEVELOPMENT_DO_NOT_USE_IN_PRODUCTION'

Expand Down
17 changes: 9 additions & 8 deletions fir/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
from fir.config.base import INSTALLED_APPS, TF_INSTALLED
from incidents import views


# urls for core FIR components
urlpatterns = [
url(r'^logout/', views.user_logout, name='logout'),
url(r'^incidents/', include('incidents.urls', namespace='incidents')),
url(r'^incidents/', include(('incidents.urls', 'incidents'), namespace='incidents')),
url(r'^search/$', views.search, name='search'),
url(r'^events/', include('incidents.custom_urls.events', namespace='events')),
url(r'^stats/', include('incidents.custom_urls.stats', namespace='stats')),
url(r'^ajax/', include('incidents.custom_urls.ajax', namespace='ajax')),
url(r'^user/', include('incidents.custom_urls.user', namespace='user')),
url(r'^dashboard/', include('incidents.custom_urls.dashboard', namespace='dashboard')),
url(r'^admin/', include(admin.site.urls)),
url(r'^events/', include(('incidents.custom_urls.events', 'url_events'), namespace='events')),
url(r'^stats/', include(('incidents.custom_urls.stats', 'stats'), namespace='stats')),
url(r'^ajax/', include(('incidents.custom_urls.ajax', 'ajax'), namespace='ajax')),
url(r'^user/', include(('incidents.custom_urls.user', 'user'), namespace='user')),
url(r'^dashboard/', include(('incidents.custom_urls.dashboard', 'dashboard'), namespace='dashboard')),
url(r'^admin/', admin.site.urls),
url(r'^$', views.dashboard_main),
]

Expand All @@ -39,4 +40,4 @@
app_name = app[4:]
app_urls = '{}.urls'.format(app)
if find_loader(app_urls):
urlpatterns.append(url('^{}/'.format(app_name), include(app_urls, namespace=app_name)))
urlpatterns.append(url('^{}/'.format(app_name), include((app_urls, app), namespace=app_name)))
8 changes: 4 additions & 4 deletions fir_abuse/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ class AbuseTemplate(models.Model):
type = models.CharField(max_length=100, blank=True)
body = models.TextField()
subject = models.TextField()
incident_category = models.ForeignKey(IncidentCategory, blank=True, null=True)
incident_category = models.ForeignKey(IncidentCategory, on_delete=models.CASCADE, blank=True, null=True)

def __unicode__(self):
def __str__(self):
return self.name


Expand All @@ -20,10 +20,10 @@ class AbuseContact(models.Model):
to = models.CharField(max_length=100)
cc = models.CharField(max_length=100, blank=True)
bcc = models.CharField(max_length=100, blank=True)
incident_category = models.ForeignKey(IncidentCategory, blank=True, null=True)
incident_category = models.ForeignKey(IncidentCategory, on_delete=models.CASCADE, blank=True, null=True)
type = models.CharField(max_length=100, blank=True)

def __unicode__(self):
def __str__(self):
return self.name


Expand Down
2 changes: 1 addition & 1 deletion fir_abuse/templates/fir_abuse/plugins/details_static.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{% load staticfiles %}
{% load static %}
<script src="{% static "fir_abuse/js/abuse.js" %}"></script>
<link href="{% static "fir_abuse/css/abuse.css" %}" rel="stylesheet" />
2 changes: 2 additions & 0 deletions fir_abuse/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from fir_abuse import views

app_name='fir_abuse'

urlpatterns = [
url(r'^(?P<incident_id>\d+)/get_template/(?P<artifact_id>\d+)/$', views.get_template, name='get_template'),
url(r'^emailform/$', views.emailform, name='emailform'),
Expand Down
2 changes: 1 addition & 1 deletion fir_abuse/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def send_email(request):

return HttpResponse(dumps({'status': 'ok'}), content_type="application/json")

except Exception, e:
except Exception as e:
return HttpResponse(dumps({'status': 'ko', 'error': str(e)}), content_type="application/json")

return HttpResponseBadRequest(dumps({'status': 'ko'}), content_type="application/json")
Expand Down
18 changes: 18 additions & 0 deletions fir_alerting/migrations/0003_auto_20210209_0717.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.6 on 2021-02-09 07:17

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('fir_alerting', '0002_add_helptext_to_body'),
]

operations = [
migrations.AlterField(
model_name='categorytemplate',
name='body',
field=models.TextField(help_text='This is a Markdown field. You can use django templating language.'),
),
]
8 changes: 4 additions & 4 deletions fir_alerting/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ class RecipientTemplate(models.Model):
recipient_to = models.TextField()
recipient_cc = models.TextField()
recipient_bcc = models.TextField(null=True, blank=True)
business_line = models.ForeignKey(BusinessLine, null=True, blank=True)
business_line = models.ForeignKey(BusinessLine, on_delete=models.CASCADE, null=True, blank=True)

def __unicode__(self):
def __str__(self):
return self.name

class Meta:
Expand All @@ -25,9 +25,9 @@ class CategoryTemplate(models.Model):
type = models.CharField(max_length=100)
body = models.TextField(help_text="This is a Markdown field. You can use django templating language.")
subject = models.TextField()
incident_category = models.ForeignKey(IncidentCategory)
incident_category = models.ForeignKey(IncidentCategory, on_delete=models.CASCADE)

def __unicode__(self):
def __str__(self):
return self.name

class Meta:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{% load staticfiles %}
{% load static %}
<script src="{% static "fir_alerting/js/alerting.js" %}"></script>
<link href="{% static "fir_alerting/css/alerting.css" %}" rel="stylesheet" />
2 changes: 2 additions & 0 deletions fir_alerting/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from fir_alerting import views

app_name='fir_alerting'

urlpatterns = [
url(r'^(?P<incident_id>\d+)/get_template/(?P<template_type>[\w-]+)/$', views.get_template, name='get_template'),
url(r'^(?P<incident_id>\d+)/get_template/(?P<template_type>[\w-]+)/(?P<bl>[\d]+)/$', views.get_template, name='get_template'),
Expand Down
4 changes: 2 additions & 2 deletions fir_alerting/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def get_template(request, incident_id, template_type, bl=None, authorization_tar

try:
cat_template = CategoryTemplate.objects.get(incident_category=i.category, type=template_type)
except Exception, e:
except Exception as e:
cat_template = None

rec_template = None
Expand Down Expand Up @@ -119,7 +119,7 @@ def send_email(request):

return HttpResponse(dumps({'status': 'ok'}), content_type="application/json")

except Exception, e:
except Exception as e:
return HttpResponse(dumps({'status': 'ko', 'error': str(e)}), content_type="application/json")

return HttpResponseBadRequest(dumps({'status': 'ko'}), content_type="application/json")
27 changes: 8 additions & 19 deletions fir_api/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,15 @@ class TokenAuthentication(authentication.TokenAuthentication):

def authenticate(self, request):
meta = api_settings.user_settings['TOKEN_AUTHENTICATION_META']
auth = request.META.get(meta)

auth = request.META.get(meta)
if not auth:
return None

auth = auth.split(' ')
if auth[0].lower() != self.keyword.lower().encode():
return None

if len(auth) == 1:
msg = _('Invalid token header. No credentials provided.')
raise exceptions.AuthenticationFailed(msg)
elif len(auth) > 2:
msg = _('Invalid token header. Token string should not contain spaces.')
raise exceptions.AuthenticationFailed(msg)

try:
token = auth[1].decode()
except UnicodeError:
msg = _('Invalid token header. Token string should not contain invalid characters.')
auth_keyword, auth_token = auth.split(' ')
except ValueError:
msg = "Invalid token header. Header must be defined the following way: 'Token hexstring'"
raise exceptions.AuthenticationFailed(msg)

return self.authenticate_credentials(token)
if auth_keyword.lower() != self.keyword.lower():
msg = f"Provided keyword '{auth_keyword.lower()}' does not match defined one '{self.keyword.lower()}'"
raise exceptions.AuthenticationFailed(msg)
return self.authenticate_credentials(auth_token)
41 changes: 40 additions & 1 deletion fir_api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib.auth.models import User
from rest_framework import serializers

from incidents.models import Incident, Artifact, Label, File, IncidentCategory, BusinessLine
from incidents.models import Incident, Artifact, Label, File, IncidentCategory, BusinessLine, Comments, Attribute


# serializes data from the FIR User model
Expand Down Expand Up @@ -43,6 +43,23 @@ class Meta:
extra_kwargs = {'url': {'view_name': 'api:file-download'}}
depth = 2

# FIR Comment Model

class CommentsSerializer(serializers.ModelSerializer):
class Meta:
model = Comments
fields = ('id', 'comment', 'incident', 'opened_by', 'date', 'action')
read_only_fields = ('id', 'opened_by')


# FIR Label Model

class LabelSerializer(serializers.ModelSerializer):
class Meta:
model = Label
fields = ('id', 'name', 'group')
read_only_fields = ('id',)


# FIR Incident model

Expand All @@ -51,8 +68,30 @@ class IncidentSerializer(serializers.ModelSerializer):
actor = serializers.PrimaryKeyRelatedField(queryset=Label.objects.filter(group__name='actor'))
plan = serializers.PrimaryKeyRelatedField(queryset=Label.objects.filter(group__name='plan'))
file_set = AttachedFileSerializer(many=True, read_only=True)
comments_set = CommentsSerializer(many=True, read_only=True)

class Meta:
model = Incident
exclude = ['main_business_lines', 'artifacts']
read_only_fields = ('id', 'opened_by', 'main_business_lines', 'file_set')


# FIR attribute model

class AttributeSerializer(serializers.ModelSerializer):
class Meta:
model = Attribute
fields = ('id', 'name', 'value', 'incident')
read_only_fields = ('id', )

class BusinessLineSerializer(serializers.ModelSerializer):
class Meta:
model = Attribute
fields = ('id', 'name')
read_only_fields = ('id', 'name')

class IncidentCategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = IncidentCategory
fields = ('id', 'name', 'is_major')
read_only_fields = ('id', 'name', 'is_major')
3 changes: 2 additions & 1 deletion fir_api/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
# if you prefer to use default TokenAuthentication using Baisc Auth mechanism, replace fir_api.authentication.TokenAuthentication with rest_framework.authentication.TokenAuthentication
'DEFAULT_AUTHENTICATION_CLASSES': ('fir_api.authentication.TokenAuthentication', 'rest_framework.authentication.SessionAuthentication'),
'PAGE_SIZE': 10,
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 25,
# Following configuration is dedicated to fir_api.authentication.TokenAuthentication
'TOKEN_AUTHENTICATION_KEYWORD': 'Token',
'TOKEN_AUTHENTICATION_META': 'HTTP_X_API', # HTTP_X_API == X-Api in headers
Expand Down
7 changes: 7 additions & 0 deletions fir_api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from fir_api import views

app_name='fir_api'

# automatic URL routing for API
# include login URLs for the browsable API.
router = routers.DefaultRouter(trailing_slash=False)
Expand All @@ -12,6 +14,11 @@
router.register(r'incidents', views.IncidentViewSet)
router.register(r'artifacts', views.ArtifactViewSet)
router.register(r'files', views.FileViewSet)
router.register(r'comments', views.CommentViewSet)
router.register(r'labels', views.LabelViewSet)
router.register(r'attributes', views.AttributeViewSet)
router.register(r'businesslines', views.BusinessLinesViewSet)
router.register(r'incident_categories', views.IncidentCategoriesViewSet)

# urls for core FIR components
urlpatterns = [
Expand Down
Loading

0 comments on commit 3d26509

Please sign in to comment.