Create: collector models, protect storage, download view
This commit is contained in:
parent
4f288f04ff
commit
b944d58943
3
.gitignore
vendored
3
.gitignore
vendored
@ -160,3 +160,6 @@ cython_debug/
|
|||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
|
# Project specific
|
||||||
|
**/archives
|
||||||
|
**/media
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import Platform, Archive, Ticket
|
||||||
|
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
|
class PlatformAdmin(admin.ModelAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TicketAdmin(admin.ModelAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ArchiveAdmin(admin.ModelAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
admin.site.register(Platform, PlatformAdmin)
|
||||||
|
admin.site.register(Ticket, TicketAdmin)
|
||||||
|
admin.site.register(Archive, ArchiveAdmin)
|
||||||
|
52
logs_collector/collector/migrations/0001_initial.py
Normal file
52
logs_collector/collector/migrations/0001_initial.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# Generated by Django 4.2 on 2023-07-27 02:04
|
||||||
|
|
||||||
|
import collector.models
|
||||||
|
from django.conf import settings
|
||||||
|
import django.core.files.storage
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Platform',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=20)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Ticket',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('number', models.IntegerField()),
|
||||||
|
('resolved', models.BooleanField(default=False)),
|
||||||
|
('note', models.TextField(blank=True)),
|
||||||
|
('time_create', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('time_update', models.DateTimeField(auto_now=True)),
|
||||||
|
('platform', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='collector.platform')),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Archive',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('file', models.FileField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(base_url='/archives/', location=pathlib.PurePosixPath('/home/stepan/Documents/Dev/ISPsystem/logs-collector/logs_collector/archives')), upload_to=collector.models.logs_dir_path)),
|
||||||
|
('sha1', models.CharField(editable=False, max_length=1024)),
|
||||||
|
('time_create', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('time_update', models.DateTimeField(auto_now=True)),
|
||||||
|
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='collector.ticket')),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -1,3 +1,69 @@
|
|||||||
from django.db import models
|
import hashlib
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
# Create your models here.
|
from django.contrib.auth.models import User
|
||||||
|
from django.db import models
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.files.storage import FileSystemStorage
|
||||||
|
from django.db.models import FileField
|
||||||
|
|
||||||
|
|
||||||
|
# Create a custom storage location, using a value from your settings file
|
||||||
|
sensitive_upload_storage = FileSystemStorage(
|
||||||
|
location=settings.MEDIA_ROOT_FOR_SENSITIVE_FILES,
|
||||||
|
base_url=settings.MEDIA_URL_FOR_SENSITIVE_FILES
|
||||||
|
)
|
||||||
|
# ... and a file field that will use the custom storage
|
||||||
|
AuthenticatedFileField = partial(FileField, storage=sensitive_upload_storage)
|
||||||
|
|
||||||
|
|
||||||
|
def logs_dir_path(instance, filename):
|
||||||
|
# file will be uploaded to
|
||||||
|
# MEDIA_ROOT_FOR_SENSITIVE_FILES/<ticket>/<filename>
|
||||||
|
return f'{instance.ticket}/{filename}'
|
||||||
|
|
||||||
|
|
||||||
|
class Archive(models.Model):
|
||||||
|
file = AuthenticatedFileField(
|
||||||
|
upload_to=logs_dir_path,
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
sha1 = models.CharField(max_length=1024, editable=False)
|
||||||
|
time_create = models.DateTimeField(auto_now_add=True)
|
||||||
|
time_update = models.DateTimeField(auto_now=True)
|
||||||
|
ticket = models.ForeignKey('Ticket', on_delete=models.CASCADE)
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
# calculate sha 1 hash sum and write sha1 field to db
|
||||||
|
with self.file.open('rb') as f:
|
||||||
|
sha1 = hashlib.sha1()
|
||||||
|
for byte_block in iter(lambda: f.read(4096), b""):
|
||||||
|
sha1.update(byte_block)
|
||||||
|
self.sha1 = sha1.hexdigest()
|
||||||
|
# Call the "real" save() method
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.file)
|
||||||
|
|
||||||
|
|
||||||
|
class Platform(models.Model):
|
||||||
|
name = models.CharField(max_length=20)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class Ticket(models.Model):
|
||||||
|
number = models.IntegerField()
|
||||||
|
resolved = models.BooleanField(default=False)
|
||||||
|
note = models.TextField(blank=True)
|
||||||
|
time_create = models.DateTimeField(auto_now_add=True)
|
||||||
|
time_update = models.DateTimeField(auto_now=True)
|
||||||
|
platform = models.ForeignKey('Platform', on_delete=models.CASCADE)
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.number)
|
||||||
|
9
logs_collector/collector/urls.py
Normal file
9
logs_collector/collector/urls.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', views.index, name='index',),
|
||||||
|
path('test/<str:path>/', views.test_page, name='test_page'),
|
||||||
|
path('archives/<ticket>/<archive>', views.download, name="download")
|
||||||
|
]
|
0
logs_collector/collector/utils.py
Normal file
0
logs_collector/collector/utils.py
Normal file
@ -1,3 +1,25 @@
|
|||||||
from django.shortcuts import render
|
# from django.shortcuts import render
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.http import FileResponse, HttpResponse, Http404
|
||||||
|
from .models import Archive
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
# handles the url "/archives/{PATH}"".
|
||||||
|
@login_required
|
||||||
|
def download(request, ticket, file):
|
||||||
|
path = f'{ticket}/{file}'
|
||||||
|
try:
|
||||||
|
file = Archive.objects.get(file=path)
|
||||||
|
except Archive.DoesNotExist:
|
||||||
|
return Http404
|
||||||
|
|
||||||
|
return FileResponse(file.file)
|
||||||
|
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
return HttpResponse('<h1>Index Page</h1>')
|
||||||
|
|
||||||
|
|
||||||
|
def test_page(request, path):
|
||||||
|
return HttpResponse(f'<h1>{path} Page</h1>')
|
||||||
|
@ -1,14 +1,3 @@
|
|||||||
"""
|
|
||||||
Django settings for logs_collector project.
|
|
||||||
|
|
||||||
Generated by 'django-admin startproject' using Django 4.2.
|
|
||||||
|
|
||||||
For more information on this file, see
|
|
||||||
https://docs.djangoproject.com/en/4.2/topics/settings/
|
|
||||||
|
|
||||||
For the full list of settings and their values, see
|
|
||||||
https://docs.djangoproject.com/en/4.2/ref/settings/
|
|
||||||
"""
|
|
||||||
import environ
|
import environ
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@ -22,8 +11,6 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||||||
|
|
||||||
environ.Env.read_env(BASE_DIR / '.env')
|
environ.Env.read_env(BASE_DIR / '.env')
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
|
||||||
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
|
|
||||||
|
|
||||||
# SECURITY WARNING: keep the secret key used in production secret!
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
SECRET_KEY = env('SECRET_KEY')
|
SECRET_KEY = env('SECRET_KEY')
|
||||||
@ -32,7 +19,9 @@ SECRET_KEY = env('SECRET_KEY')
|
|||||||
DEBUG = env('DEBUG')
|
DEBUG = env('DEBUG')
|
||||||
|
|
||||||
ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", default=["*"])
|
ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", default=["*"])
|
||||||
CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS", default=["*"])
|
|
||||||
|
# TODO: required for docker image
|
||||||
|
# CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS", default=["*"])
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
@ -46,6 +35,7 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'collector.apps.CollectorConfig', # main app
|
'collector.apps.CollectorConfig', # main app
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
|
'django_cleanup.apps.CleanupConfig', # required bottom
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -130,3 +120,9 @@ STATIC_URL = 'static/'
|
|||||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
|
MEDIA_ROOT = BASE_DIR / 'media'
|
||||||
|
MEDIA_URL = 'media/'
|
||||||
|
|
||||||
|
MEDIA_ROOT_FOR_SENSITIVE_FILES = BASE_DIR / 'archives'
|
||||||
|
MEDIA_URL_FOR_SENSITIVE_FILES = '/archives/'
|
||||||
|
@ -14,9 +14,20 @@ Including another URLconf
|
|||||||
1. Import the include() function: from django.urls import include, path
|
1. Import the include() function: from django.urls import include, path
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
|
from django.conf.urls.static import static
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
|
|
||||||
|
from logs_collector import settings
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('', include('collector.urls')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
if settings.DEBUG:
|
||||||
|
urlpatterns += static(
|
||||||
|
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user