diff --git a/.envs/.local/.postgres b/.envs/.local/.postgres
index ddf23c54..bfb10230 100755
--- a/.envs/.local/.postgres
+++ b/.envs/.local/.postgres
@@ -5,3 +5,4 @@ POSTGRES_PORT=5432
POSTGRES_DB=orochi
POSTGRES_USER=debug
POSTGRES_PASSWORD=debug
+DATABASE_URL=postgresql://debug:debug@posgtgres:5432/orochi
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index c3ac67a3..9abf900b 100755
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -11,7 +11,7 @@ repos:
- id: check-yaml
- repo: https://github.com/psf/black
- rev: 24.3.0
+ rev: 24.4.2
hooks:
- id: black
diff --git a/compose/local/dask/Dockerfile b/compose/local/dask/Dockerfile
index 6d345e62..102b2e51 100644
--- a/compose/local/dask/Dockerfile
+++ b/compose/local/dask/Dockerfile
@@ -1,4 +1,4 @@
-FROM daskdev/dask:2024.4.1-py3.12
+FROM daskdev/dask:2024.5.1-py3.12
ENV DEBIAN_FRONTEND noninteractive
ARG local_folder=/uploads
@@ -47,7 +47,7 @@ RUN python setup.py build \
# Workers should have similar reqs as django
WORKDIR /
COPY ./requirements /requirements
-RUN pip install uv==0.1.29 -e git+https://github.com/volatilityfoundation/volatility3.git@a19dfb57a68cc7efc8926d9f6e7c24e5a2dbab9d#egg=volatility3 \
+RUN pip install uv==0.1.44 -e git+https://github.com/volatilityfoundation/volatility3.git@dc7a3878fa39156d89d567c3e823f1956675f192#egg=volatility3 \
&& uv pip install --no-cache --system -r /requirements/base.txt
COPY ./compose/local/dask/prepare.sh /usr/bin/prepare.sh
diff --git a/compose/local/django/Dockerfile b/compose/local/django/Dockerfile
index 60314eb9..7aa05de3 100644
--- a/compose/local/django/Dockerfile
+++ b/compose/local/django/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.12.2-slim-bookworm as common-base
+FROM python:3.12.3-slim-bookworm as common-base
ENV DJANGO_SETTINGS_MODULE config.settings.local
ENV PYTHONUNBUFFERED 1
@@ -65,7 +65,7 @@ RUN /usr/local/go/bin/go build
FROM common-base
WORKDIR /
COPY ./requirements /requirements
-RUN pip install uv==0.1.29 -e git+https://github.com/volatilityfoundation/volatility3.git@a19dfb57a68cc7efc8926d9f6e7c24e5a2dbab9d#egg=volatility3 \
+RUN pip install uv==0.1.44 -e git+https://github.com/volatilityfoundation/volatility3.git@dc7a3878fa39156d89d567c3e823f1956675f192#egg=volatility3 \
&& uv pip install --no-cache --system -r /requirements/base.txt
COPY ./compose/local/__init__.py /src/volatility3/volatility3/framework/constants/__init__.py
diff --git a/config/settings/base.py b/config/settings/base.py
index d285b5ef..65eec6da 100644
--- a/config/settings/base.py
+++ b/config/settings/base.py
@@ -91,18 +91,12 @@
]
-if use_ldap := env.bool("USE_LDAP", False):
- AUTHENTICATION_BACKENDS = [
- "django_auth_ldap.backend.LDAPBackend"
- "django.contrib.auth.backends.ModelBackend",
- "guardian.backends.ObjectPermissionBackend",
- ]
-else:
- AUTHENTICATION_BACKENDS = [
- "django.contrib.auth.backends.ModelBackend",
- "allauth.account.auth_backends.AuthenticationBackend",
- "guardian.backends.ObjectPermissionBackend",
- ]
+AUTHENTICATION_BACKENDS = [
+ "django_auth_ldap.backend.LDAPBackend",
+ "django.contrib.auth.backends.ModelBackend",
+ "guardian.backends.ObjectPermissionBackend",
+ "allauth.account.auth_backends.AuthenticationBackend",
+]
AUTH_USER_MODEL = "users.User"
LOGIN_REDIRECT_URL = "users:redirect"
@@ -244,6 +238,7 @@
"root": {"level": DEBUG_LEVEL, "handlers": ["console"]},
"loggers": {
"distributed": {"level": DEBUG_LEVEL, "handlers": ["console"]},
+ "django_auth_ldap": {"level": DEBUG_LEVEL, "handlers": ["console"]},
},
}
@@ -251,8 +246,8 @@
# ------------------------------------------------------------------------------
ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True)
ACCOUNT_AUTHENTICATION_METHOD = "username"
-ACCOUNT_EMAIL_REQUIRED = True
-ACCOUNT_EMAIL_VERIFICATION = "mandatory"
+ACCOUNT_EMAIL_REQUIRED = False
+ACCOUNT_EMAIL_VERIFICATION = "optional"
ACCOUNT_ADAPTER = "orochi.users.adapters.AccountAdapter"
SOCIALACCOUNT_ADAPTER = "orochi.users.adapters.SocialAccountAdapter"
@@ -281,16 +276,15 @@
# LDAP
# ------------------------------------------------------------------------------
-if use_ldap:
- AUTH_LDAP_SERVER_URI = env("AUTH_LDAP_SERVER_URI")
- AUTH_LDAP_BIND_DN = env("AUTH_LDAP_BIND_DN")
- AUTH_LDAP_BIND_PASSWORD = env("AUTH_LDAP_BIND_PASSWORD")
- AUTH_LDAP_USER_SEARCH = LDAPSearch(
- env("AUTH_LDAP_USER_SEARCH_DN"),
- ldap.SCOPE_SUBTREE,
- env("AUTH_LDAP_USER_SEARCH_ALIAS"),
- )
- AUTH_LDAP_USER_ATTR_MAP = env.dict("AUTH_LDAP_USER_ATTR_MAP")
+AUTH_LDAP_SERVER_URI = env("AUTH_LDAP_SERVER_URI")
+AUTH_LDAP_BIND_DN = env("AUTH_LDAP_BIND_DN")
+AUTH_LDAP_BIND_PASSWORD = env("AUTH_LDAP_BIND_PASSWORD")
+AUTH_LDAP_USER_SEARCH = LDAPSearch(
+ env("AUTH_LDAP_USER_SEARCH_DN"),
+ ldap.SCOPE_SUBTREE,
+ env("AUTH_LDAP_USER_SEARCH_ALIAS"),
+)
+AUTH_LDAP_USER_ATTR_MAP = env.dict("AUTH_LDAP_USER_ATTR_MAP")
# django-cors-headers - https://github.com/adamchainz/django-cors-headers#setup
CORS_URLS_REGEX = r"^/api/.*$"
diff --git a/docker-compose.yml b/docker-compose.yml
index d6daad8d..73be38e5 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -121,7 +121,7 @@ services:
- "6379:6379"
es01:
- image: elasticsearch:8.9.0
+ image: elasticsearch:8.13.0
container_name: orochi_es01
environment:
- discovery.type=single-node
@@ -144,7 +144,7 @@ services:
- 9200:9200
kib01:
- image: kibana:8.9.0
+ image: kibana:8.13.0
container_name: orochi_kib01
ports:
- 5601:5601
diff --git a/orochi/api/api.py b/orochi/api/api.py
index 8dea779d..f008272a 100644
--- a/orochi/api/api.py
+++ b/orochi/api/api.py
@@ -15,4 +15,4 @@
api.add_router("/dumps/", dumps_router, tags=["Dumps"])
api.add_router("/plugins/", plugins_router, tags=["Plugins"])
api.add_router("/utils/", utils_router, tags=["Utils"])
-api.add_router("/bookmars/", bookmarks_router, tags=["Bookmars"])
+api.add_router("/bookmarks/", bookmarks_router, tags=["Bookmarks"])
diff --git a/orochi/api/models.py b/orochi/api/models.py
index ad766799..a87d2fed 100644
--- a/orochi/api/models.py
+++ b/orochi/api/models.py
@@ -6,7 +6,7 @@
from ninja.orm import create_schema
from orochi.website.defaults import OSEnum
-from orochi.website.models import Bookmark, Dump, Folder, Plugin, Result
+from orochi.website.models import Bookmark, Dump, Folder, Plugin
###################################################
# Auth
@@ -210,6 +210,13 @@ class ResultSmallOutSchema(Schema):
###################################################
# Bookmarks
###################################################
+class BookmarksEditInSchema(ModelSchema):
+
+ class Meta:
+ model = Bookmark
+ fields = ["name", "icon", "query"]
+
+
class BookmarksSchema(ModelSchema):
user: UserOutSchema = None
indexes: List[DumpSchema] = []
@@ -217,3 +224,12 @@ class BookmarksSchema(ModelSchema):
class Meta:
model = Bookmark
fields = ["id", "name", "icon", "star", "query"]
+
+
+class BookmarksInSchema(Schema):
+ selected_indexes: str = None
+ name: str = None
+ star: bool = False
+ icon: str = None
+ selected_plugin: str = None
+ query: Optional[str] = None
diff --git a/orochi/api/routers/bookmarks.py b/orochi/api/routers/bookmarks.py
index dbf0f0c3..03f86910 100644
--- a/orochi/api/routers/bookmarks.py
+++ b/orochi/api/routers/bookmarks.py
@@ -1,15 +1,78 @@
from typing import List
+import django
+import psycopg2
from django.shortcuts import get_object_or_404
+from guardian.shortcuts import get_objects_for_user
from ninja import Router
from ninja.security import django_auth
-from orochi.api.models import BookmarksSchema, ErrorsOut, SuccessResponse
-from orochi.website.models import Bookmark
+from orochi.api.models import (
+ BookmarksEditInSchema,
+ BookmarksInSchema,
+ BookmarksSchema,
+ ErrorsOut,
+ SuccessResponse,
+)
+from orochi.website.models import Bookmark, Dump, Plugin
router = Router()
+@router.post(
+ "/",
+ auth=django_auth,
+ response={201: BookmarksSchema, 400: ErrorsOut},
+ url_name="create_bookmark",
+)
+def create_bookmarks(request, bookmarks_in: BookmarksInSchema):
+ """
+ Create bookmarks for the user.
+
+ Args:
+ request: The request object.
+ bookmarks_in: Input data for creating bookmarks.
+
+ Returns:
+ Tuple[int, Bookmark]: A tuple containing the status code and the created bookmark.
+
+ Raises:
+ 400: If an exception occurs during the bookmark creation process.
+ """
+ try:
+ indexes = []
+ ok_indexes = list(
+ get_objects_for_user(request.user, "website.can_see").values_list(
+ "index", flat=True
+ )
+ )
+ for index_id in bookmarks_in.selected_indexes.split(","):
+ index_id = str(index_id)
+ if index_id not in ok_indexes:
+ continue
+ index = get_object_or_404(Dump, index=index_id)
+ indexes.append(index)
+ if indexes:
+ plugin = get_object_or_404(Plugin, name=bookmarks_in.selected_plugin)
+ bookmark = Bookmark.objects.create(
+ user=request.user,
+ plugin=plugin,
+ star=bookmarks_in.star,
+ icon=bookmarks_in.icon,
+ name=bookmarks_in.name,
+ query=bookmarks_in.query,
+ )
+ bookmark.save()
+ for index in indexes:
+ bookmark.indexes.add(index)
+ return 201, bookmark
+ return 400, {"errors": "No valid indexes selected"}
+ except (psycopg2.errors.UniqueViolation, django.db.utils.IntegrityError):
+ return 400, {"errors": "Bookmark name already used"}
+ except Exception as excp:
+ return 400, {"errors": str(excp)}
+
+
@router.get("/", auth=django_auth, response=List[BookmarksSchema])
def list_bookmarks(request):
"""
@@ -21,6 +84,64 @@ def list_bookmarks(request):
return Bookmark.objects.filter(user=request.user)
+@router.get(
+ "/{int:id}",
+ auth=django_auth,
+ response={200: BookmarksSchema, 400: ErrorsOut},
+ url_name="get_bookmark",
+)
+def get_bookmark(request, id: int):
+ """
+ Retrieves a bookmark by its ID.
+
+ Args:
+ request: The request object.
+ id: The ID of the bookmark to retrieve.
+
+ Returns:
+ dict: A dictionary containing the bookmark data.
+
+ Raises:
+ 400: If an exception occurs during the process.
+ """
+ try:
+ bookmark = get_object_or_404(Bookmark, pk=id, user=request.user)
+ return 200, bookmark
+ except Exception as excp:
+ return 400, {"errors": str(excp)}
+
+
+@router.patch(
+ "/{int:id}",
+ response={201: BookmarksSchema, 400: ErrorsOut},
+ auth=django_auth,
+ url_name="edit_bookmark",
+)
+def edit_bookmark(request, id: int, data: BookmarksEditInSchema):
+ """
+ Edit bookmark.
+
+ Args:
+ request: The request object.
+ id: The ID of the bookmark to edit.
+ data: Input data for editing bookmarks.
+
+ Returns:
+ Bookmark: The edited bookmark object.
+
+ Raises:
+ 400: If an exception occurs during the process.
+ """
+ try:
+ bookmark = get_object_or_404(Bookmark, pk=id, user=request.user)
+ for attr, value in data.dict(exclude_unset=True).items():
+ setattr(bookmark, attr, value)
+ bookmark.save()
+ return 201, bookmark
+ except Exception as excp:
+ return 400, {"errors": str(excp)}
+
+
@router.delete(
"/{int:id}",
auth=django_auth,
diff --git a/orochi/static/README.txt b/orochi/static/README.txt
index ae4b3062..51fe47c7 100644
--- a/orochi/static/README.txt
+++ b/orochi/static/README.txt
@@ -41,7 +41,7 @@
# Keyrune [MTG icons]
--> https://github.com/andrewgioia/keyrune
---> version 3.12.2
+--> version 3.14.0
# Marked [Changelog with MD]
--> https://github.com/markedjs/marked
diff --git a/orochi/static/fonts/keyrune.ttf b/orochi/static/fonts/keyrune.ttf
index d6d04864..530bbc2e 100644
Binary files a/orochi/static/fonts/keyrune.ttf and b/orochi/static/fonts/keyrune.ttf differ
diff --git a/orochi/static/fonts/keyrune.woff b/orochi/static/fonts/keyrune.woff
index f48ba64d..da9c8d78 100644
Binary files a/orochi/static/fonts/keyrune.woff and b/orochi/static/fonts/keyrune.woff differ
diff --git a/orochi/static/fonts/keyrune.woff2 b/orochi/static/fonts/keyrune.woff2
index d7d781e1..aed768be 100644
Binary files a/orochi/static/fonts/keyrune.woff2 and b/orochi/static/fonts/keyrune.woff2 differ
diff --git a/orochi/templates/users/user_bookmarks.html b/orochi/templates/users/user_bookmarks.html
index 70e54d6d..eda778fa 100644
--- a/orochi/templates/users/user_bookmarks.html
+++ b/orochi/templates/users/user_bookmarks.html
@@ -105,34 +105,45 @@
$(document).on("submit", "#edit-bookmark", function (e) {
e.preventDefault();
var form = $(this);
+
+ let formData = form.serializeArray();
+ let obj = {};
+ formData.forEach(item => {
+ if (item.name != 'csrfmiddlewaretoken') {
+ obj[item.name] = item.value;
+ }
+ });
+ $.ajaxSetup({
+ headers: { 'X-CSRFToken': $('input[name="csrfmiddlewaretoken"]').val() }
+ });
+
$.ajax({
url: form.attr("action"),
- data: form.serialize(),
- type: form.attr("method"),
+ data: JSON.stringify(obj),
+ type: 'PATCH',
dataType: 'json',
success: function (data) {
- if (data.form_is_valid) {
- $("#modal-update").modal('hide');
- var d = table.row(row).data();
- d[0] = ``;
- d[1] = data.data.name;
- d[4] = data.data.query;
- table.row(row).data(d).draw();
- $.toast({
- title: 'Bookmark status!',
- content: 'Bookmark updated.',
- type: 'success',
- delay: 5000
- });
- } else {
- $("#modal-update .modal-content").html(data.html_form);
- $.toast({
- title: 'Bookmark status!',
- content: 'Error during submission.',
- type: 'error',
- delay: 5000
- });
- }
+ var d = table.row(row).data();
+ d[0] = ``;
+ d[1] = data.name;
+ d[4] = data.query;
+ table.row(row).data(d).draw();
+ $.toast({
+ title: 'Bookmark status!',
+ content: 'Bookmark updated.',
+ type: 'success',
+ delay: 5000
+ });
+ $("#modal-update").modal('hide');
+ },
+ error: function () {
+ $.toast({
+ title: 'Bookmark status!',
+ content: 'Error during submission.',
+ type: 'error',
+ delay: 5000
+ });
+ $("#modal-update").modal('hide');
}
});
});
diff --git a/orochi/templates/website/index.html b/orochi/templates/website/index.html
index c2d5cd1e..6e7e0e0a 100644
--- a/orochi/templates/website/index.html
+++ b/orochi/templates/website/index.html
@@ -116,7 +116,7 @@
History Log
});
// ADD BOOKMARK FORM SUBMIT
- $(document).on("submit", "#add-bookmark", function (e) {
+ $(document).on("submit", "#create-bookmark", function (e) {
e.preventDefault();
var form = $(this);
@@ -124,29 +124,41 @@ History Log
$("#id_selected_plugin").val(selected_plugin);
$("#id_query").val($("#example_filter input").val());
+ let formData = form.serializeArray();
+ let obj = {};
+ formData.forEach(item=>{
+ if(item.name != 'csrfmiddlewaretoken'){
+ obj[item.name] = item.value;
+ }
+ });
+ $.ajaxSetup({
+ headers: { 'X-CSRFToken': $('input[name="csrfmiddlewaretoken"]').val() }
+ });
+
$.ajax({
url: form.attr("action"),
- data: form.serialize(),
+ data: JSON.stringify(obj),
+ contentType: "application/json",
type: form.attr("method"),
dataType: 'json',
success: function (data) {
- if (data.form_is_valid) {
- $("#modal-update").modal('hide');
- $.toast({
- title: 'Bookmark saved!',
- content: 'Bookmark saved.',
- type: 'success',
- delay: 5000
- });
- } else {
- $("#modal-update").modal('hide');
- $.toast({
- title: 'Bookmark status!',
- content: 'Error during submission.',
- type: 'error',
- delay: 5000
- });
- }
+
+ $.toast({
+ title: 'Bookmark saved!',
+ content: 'Bookmark saved.',
+ type: 'success',
+ delay: 5000
+ });
+ $("#modal-update").modal('hide');
+ },
+ error: function () {
+ $.toast({
+ title: 'Bookmark status!',
+ content: 'Error during submission.',
+ type: 'error',
+ delay: 5000
+ });
+ $("#modal-update").modal('hide');
}
});
});
diff --git a/orochi/templates/website/partial_bookmark_create.html b/orochi/templates/website/partial_bookmark_create.html
index 32ccd3cb..a8d7a9b5 100644
--- a/orochi/templates/website/partial_bookmark_create.html
+++ b/orochi/templates/website/partial_bookmark_create.html
@@ -1,7 +1,7 @@
{% load widget_tweaks %}
{% load custom_tags %}
-
\ No newline at end of file
+
diff --git a/orochi/templates/website/partial_bookmark_edit.html b/orochi/templates/website/partial_bookmark_edit.html
index c97d2a44..3cb6ccaa 100644
--- a/orochi/templates/website/partial_bookmark_edit.html
+++ b/orochi/templates/website/partial_bookmark_edit.html
@@ -1,6 +1,6 @@
{% load widget_tweaks %}
-
\ No newline at end of file
+
diff --git a/orochi/website/defaults.py b/orochi/website/defaults.py
index d6b6b6ea..54f9fc8b 100644
--- a/orochi/website/defaults.py
+++ b/orochi/website/defaults.py
@@ -66,105 +66,114 @@ class OSEnum(models.TextChoices):
(RESULT_STATUS_ERROR, "Error"),
(RESULT_STATUS_DISABLED, "Disabled"),
)
-ICONS = (
- ("ss-arn", "Arabian Nights"),
- ("ss-atq", "Antiquities"),
- ("ss-leg", "Legends"),
- ("ss-drk", "The Dark"),
- ("ss-fem", "Fallen Empires"),
- ("ss-hml", "Homelands"),
- ("ss-ice", "Ice Age"),
- ("ss-ice2", "Ice Age (Original)"),
- ("ss-all", "Alliances"),
- ("ss-csp", "Coldsnap"),
- ("ss-mir", "Mirage"),
- ("ss-vis", "Visions"),
- ("ss-wth", "Weatherlight"),
- ("ss-tmp", "Tempest"),
- ("ss-sth", "Stronghold"),
- ("ss-exo", "Exodus"),
- ("ss-usg", "Urza's Saga"),
- ("ss-ulg", "Urza's Legacy"),
- ("ss-uds", "Urza's Destiny"),
- ("ss-mmq", "Mercadian Masques"),
- ("ss-nem", "Nemesis"),
- ("ss-pcy", "Prophecy"),
- ("ss-inv", "Invasion"),
- ("ss-pls", "Planeshift"),
- ("ss-apc", "Apocalypse"),
- ("ss-ody", "Odyssey"),
- ("ss-tor", "Torment"),
- ("ss-jud", "Judgement"),
- ("ss-ons", "Onslaught"),
- ("ss-lgn", "Legions"),
- ("ss-scg", "Scourge"),
- ("ss-mrd", "Mirrodin"),
- ("ss-dst", "Darksteel"),
- ("ss-5dn", "Fifth Dawn"),
- ("ss-chk", "Champions of Kamigawa"),
- ("ss-bok", "Betrayers of Kamigawa"),
- ("ss-sok", "Saviors of Kamigawa"),
- ("ss-rav", "Ravnica"),
- ("ss-gpt", "Guildpact"),
- ("ss-dis", "Dissension"),
- ("ss-tsp", "Time Spiral"),
- ("ss-plc", "Planar Chaos"),
- ("ss-fut", "Future Sight"),
- ("ss-lrw", "Lorwyn"),
- ("ss-mor", "Morningtide"),
- ("ss-shm", "Shadowmoor"),
- ("ss-eve", "Eventide"),
- ("ss-ala", "Shards of Alara"),
- ("ss-con", "Conflux"),
- ("ss-arb", "Alara Reborn"),
- ("ss-zen", "Zendikar"),
- ("ss-wwk", "Worldwake"),
- ("ss-roe", "Rise of the Eldrazi"),
- ("ss-som", "Scars of Mirrodin"),
- ("ss-mbs", "Mirrodin Besieged"),
- ("ss-nph", "New Phyrexia"),
- ("ss-isd", "Innistrad"),
- ("ss-dka", "Dark Ascension"),
- ("ss-avr", "Avacyn Restored"),
- ("ss-rtr", "Return to Ravnica"),
- ("ss-gtc", "Gatecrash"),
- ("ss-dgm", "Dragon's Maze"),
- ("ss-ths", "Theros"),
- ("ss-bng", "Born of the Gods"),
- ("ss-jou", "Journey into Nyx"),
- ("ss-ktk", "Khans of Tarkir"),
- ("ss-frf", "Fate Reforged"),
- ("ss-dtk", "Dragons of Tarkir"),
- ("ss-bfz", "Battle for Zendikar"),
- ("ss-ogw", "Oath of the Gatewatch"),
- ("ss-soi", "Shadows Over Innistrad"),
- ("ss-emn", "Eldritch Moon"),
- ("ss-kld", "Kaladesh"),
- ("ss-aer", "Aether Revolt"),
- ("ss-akh", "Amonkhet"),
- ("ss-hou", "Hour of Devastation"),
- ("ss-xln", "Ixalan"),
- ("ss-rix", "Rivals of Ixalan"),
- ("ss-dom", "Dominaria"),
- ("ss-grn", "Guilds of Ravnica"),
- ("ss-rna", "Ravnica Allegiance"),
- ("ss-war", "War of the Spark"),
- ("ss-eld", "Throne of Eldraine"),
- ("ss-thb", "Theros: Beyond Death"),
- ("ss-iko", "koria: Lair of Behemoths"),
- ("ss-znr", "Zendikar Rising"),
- ("ss-khm", "Kaldheim"),
- ("ss-stx", "Strixhaven: School of Mages"),
- ("ss-mid", "Innistrad: Midnight Hunt"),
- ("ss-vow", "Innistrad: Crimson Vow"),
- ("ss-neo", "Kamigawa: Neon Dynasty"),
- ("ss-snc", "Streets of New Capenna"),
- ("ss-dmu", "Dominaria United"),
- ("ss-bro", "The Brothers' War"),
- ("ss-one", "Phyrexia: All Will Be One"),
- ("ss-mom", "March of the Machine"),
- ("ss-mat", "March of the Machine: The Aftermath"),
- ("ss-woe", "Wilds of Eldraine"),
-)
+
+
+class IconEnum(models.TextChoices):
+ SS_ORI = "ss-ori", "Magic Origins"
+ SS_AFR = "ss-afr", "Adventures in the Forgotten Realms"
+ SS_ARN = "ss-arn", "Arabian Nights"
+ SS_ATQ = "ss-atq", "Antiquities"
+ SS_LEG = "ss-leg", "Legends"
+ SS_DRK = "ss-drk", "The Dark"
+ SS_FEM = "ss-fem", "Fallen Empires"
+ SS_HML = "ss-hml", "Homelands"
+ SS_ICE = "ss-ice", "Ice Age"
+ SS_ICE2 = "ss-ice2", "Ice Age (Original)"
+ SS_ALL = "ss-all", "Alliances"
+ SS_CSP = "ss-csp", "Coldsnap"
+ SS_MIR = "ss-mir", "Mirage"
+ SS_VIS = "ss-vis", "Visions"
+ SS_WTH = "ss-wth", "Weatherlight"
+ SS_TMP = "ss-tmp", "Tempest"
+ SS_STH = "ss-sth", "Stronghold"
+ SS_EXO = "ss-exo", "Exodus"
+ SS_USG = "ss-usg", "Urza's Saga"
+ SS_ULG = "ss-ulg", "Urza's Legacy"
+ SS_UDS = "ss-uds", "Urza's Destiny"
+ SS_MMQ = "ss-mmq", "Mercadian Masques"
+ SS_NEM = "ss-nem", "Nemesis"
+ SS_PCY = "ss-pcy", "Prophecy"
+ SS_INV = "ss-inv", "Invasion"
+ SS_PLS = "ss-pls", "Planeshift"
+ SS_APC = "ss-apc", "Apocalypse"
+ SS_ODY = "ss-ody", "Odyssey"
+ SS_TOR = "ss-tor", "Torment"
+ SS_JUD = "ss-jud", "Judgement"
+ SS_ONS = "ss-ons", "Onslaught"
+ SS_LGN = "ss-lgn", "Legions"
+ SS_SCG = "ss-scg", "Scourge"
+ SS_MRD = "ss-mrd", "Mirrodin"
+ SS_DST = "ss-dst", "Darksteel"
+ SS_5DN = "ss-5dn", "Fifth Dawn"
+ SS_CHK = "ss-chk", "Champions of Kamigawa"
+ SS_BOK = "ss-bok", "Betrayers of Kamigawa"
+ SS_SOK = "ss-sok", "Saviors of Kamigawa"
+ SS_RAV = "ss-rav", "Ravnica"
+ SS_GPT = "ss-gpt", "Guildpact"
+ SS_DIS = "ss-dis", "Dissension"
+ SS_TSP = "ss-tsp", "Time Spiral"
+ SS_PLC = "ss-plc", "Planar Chaos"
+ SS_FUT = "ss-fut", "Future Sight"
+ SS_LRW = "ss-lrw", "Lorwyn"
+ SS_MOR = "ss-mor", "Morningtide"
+ SS_SHM = "ss-shm", "Shadowmoor"
+ SS_EVE = "ss-eve", "Eventide"
+ SS_ALA = "ss-ala", "Shards of Alara"
+ SS_CON = "ss-con", "Conflux"
+ SS_ARB = "ss-arb", "Alara Reborn"
+ SS_ZEN = "ss-zen", "Zendikar"
+ SS_WWK = "ss-wwk", "Worldwake"
+ SS_ROE = "ss-roe", "Rise of the Eldrazi"
+ SS_SOM = "ss-som", "Scars of Mirrodin"
+ SS_MBS = "ss-mbs", "Mirrodin Besieged"
+ SS_NPH = "ss-nph", "New Phyrexia"
+ SS_ISD = "ss-isd", "Innistrad"
+ SS_DKA = "ss-dka", "Dark Ascension"
+ SS_AVR = "ss-avr", "Avacyn Restored"
+ SS_RTR = "ss-rtr", "Return to Ravnica"
+ SS_GTC = "ss-gtc", "Gatecrash"
+ SS_DGM = "ss-dgm", "Dragon's Maze"
+ SS_THS = "ss-ths", "Theros"
+ SS_BNG = "ss-bng", "Born of the Gods"
+ SS_JOU = "ss-jou", "Journey into Nyx"
+ SS_KTK = "ss-ktk", "Khans of Tarkir"
+ SS_FRF = "ss-frf", "Fate Reforged"
+ SS_DTK = "ss-dtk", "Dragons of Tarkir"
+ SS_BFZ = "ss-bfz", "Battle for Zendikar"
+ SS_OGW = "ss-ogw", "Oath of the Gatewatch"
+ SS_SOI = "ss-soi", "Shadows Over Innistrad"
+ SS_EMN = "ss-emn", "Eldritch Moon"
+ SS_KLD = "ss-kld", "Kaladesh"
+ SS_AER = "ss-aer", "Aether Revolt"
+ SS_AKH = "ss-akh", "Amonkhet"
+ SS_HOU = "ss-hou", "Hour of Devastation"
+ SS_XLN = "ss-xln", "Ixalan"
+ SS_RIX = "ss-rix", "Rivals of Ixalan"
+ SS_DOM = "ss-dom", "Dominaria"
+ SS_GRN = "ss-grn", "Guilds of Ravnica"
+ SS_RNA = "ss-rna", "Ravnica Allegiance"
+ SS_WAR = "ss-war", "War of the Spark"
+ SS_ELD = "ss-eld", "Throne of Eldraine"
+ SS_THB = "ss-thb", "Theros: Beyond Death"
+ SS_IKO = "ss-iko", "koria: Lair of Behemoths"
+ SS_ZNR = "ss-znr", "Zendikar Rising"
+ SS_KHM = "ss-khm", "Kaldheim"
+ SS_STX = "ss-stx", "Strixhaven: School of Mages"
+ SS_MID = "ss-mid", "Innistrad: Midnight Hunt"
+ SS_VOW = "ss-vow", "Innistrad: Crimson Vow"
+ SS_NEO = "ss-neo", "Kamigawa: Neon Dynasty"
+ SS_SNC = "ss-snc", "Streets of New Capenna"
+ SS_DMU = "ss-dmu", "Dominaria United"
+ SS_BRO = "ss-bro", "The Brothers' War"
+ SS_ONE = "ss-one", "Phyrexia: All Will Be One"
+ SS_MOM = "ss-mom", "March of the Machine"
+ SS_MAT = "ss-mat", "March of the Machine: The Aftermath"
+ SS_WOE = "ss-woe", "Wilds of Eldraine"
+ SS_LCI = "ss-lci", "Lost Caverns of Ixalan"
+ SS_MKM = "ss-mkm", "Murders at Karlov Manor"
+ SS_OTJ = "ss-otj", "Outlaws of Thunder Junction"
+ SS_BIG = "ss-big", "The Big Score"
+ SS_BLB = "ss-blb", "Bloomburrow"
+
DEFAULT_YARA_PATH = "/yara/default.yara"
diff --git a/orochi/website/forms.py b/orochi/website/forms.py
index a248575f..3d257156 100644
--- a/orochi/website/forms.py
+++ b/orochi/website/forms.py
@@ -53,7 +53,6 @@ class Meta:
class EditBookmarkForm(forms.ModelForm):
- selected_bookmark = forms.CharField(widget=forms.HiddenInput())
class Meta:
model = Bookmark
diff --git a/orochi/website/migrations/0056_alter_bookmark_icon.py b/orochi/website/migrations/0056_alter_bookmark_icon.py
new file mode 100644
index 00000000..740e22d8
--- /dev/null
+++ b/orochi/website/migrations/0056_alter_bookmark_icon.py
@@ -0,0 +1,128 @@
+# Generated by Django 5.0.4 on 2024-04-16 16:35
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("website", "0055_alter_dump_status"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="bookmark",
+ name="icon",
+ field=models.CharField(
+ choices=[
+ ("ss-ori", "Magic Origins"),
+ ("ss-afr", "Adventures in the Forgotten Realms"),
+ ("ss-arn", "Arabian Nights"),
+ ("ss-atq", "Antiquities"),
+ ("ss-leg", "Legends"),
+ ("ss-drk", "The Dark"),
+ ("ss-fem", "Fallen Empires"),
+ ("ss-hml", "Homelands"),
+ ("ss-ice", "Ice Age"),
+ ("ss-ice2", "Ice Age (Original)"),
+ ("ss-all", "Alliances"),
+ ("ss-csp", "Coldsnap"),
+ ("ss-mir", "Mirage"),
+ ("ss-vis", "Visions"),
+ ("ss-wth", "Weatherlight"),
+ ("ss-tmp", "Tempest"),
+ ("ss-sth", "Stronghold"),
+ ("ss-exo", "Exodus"),
+ ("ss-usg", "Urza's Saga"),
+ ("ss-ulg", "Urza's Legacy"),
+ ("ss-uds", "Urza's Destiny"),
+ ("ss-mmq", "Mercadian Masques"),
+ ("ss-nem", "Nemesis"),
+ ("ss-pcy", "Prophecy"),
+ ("ss-inv", "Invasion"),
+ ("ss-pls", "Planeshift"),
+ ("ss-apc", "Apocalypse"),
+ ("ss-ody", "Odyssey"),
+ ("ss-tor", "Torment"),
+ ("ss-jud", "Judgement"),
+ ("ss-ons", "Onslaught"),
+ ("ss-lgn", "Legions"),
+ ("ss-scg", "Scourge"),
+ ("ss-mrd", "Mirrodin"),
+ ("ss-dst", "Darksteel"),
+ ("ss-5dn", "Fifth Dawn"),
+ ("ss-chk", "Champions of Kamigawa"),
+ ("ss-bok", "Betrayers of Kamigawa"),
+ ("ss-sok", "Saviors of Kamigawa"),
+ ("ss-rav", "Ravnica"),
+ ("ss-gpt", "Guildpact"),
+ ("ss-dis", "Dissension"),
+ ("ss-tsp", "Time Spiral"),
+ ("ss-plc", "Planar Chaos"),
+ ("ss-fut", "Future Sight"),
+ ("ss-lrw", "Lorwyn"),
+ ("ss-mor", "Morningtide"),
+ ("ss-shm", "Shadowmoor"),
+ ("ss-eve", "Eventide"),
+ ("ss-ala", "Shards of Alara"),
+ ("ss-con", "Conflux"),
+ ("ss-arb", "Alara Reborn"),
+ ("ss-zen", "Zendikar"),
+ ("ss-wwk", "Worldwake"),
+ ("ss-roe", "Rise of the Eldrazi"),
+ ("ss-som", "Scars of Mirrodin"),
+ ("ss-mbs", "Mirrodin Besieged"),
+ ("ss-nph", "New Phyrexia"),
+ ("ss-isd", "Innistrad"),
+ ("ss-dka", "Dark Ascension"),
+ ("ss-avr", "Avacyn Restored"),
+ ("ss-rtr", "Return to Ravnica"),
+ ("ss-gtc", "Gatecrash"),
+ ("ss-dgm", "Dragon's Maze"),
+ ("ss-ths", "Theros"),
+ ("ss-bng", "Born of the Gods"),
+ ("ss-jou", "Journey into Nyx"),
+ ("ss-ktk", "Khans of Tarkir"),
+ ("ss-frf", "Fate Reforged"),
+ ("ss-dtk", "Dragons of Tarkir"),
+ ("ss-bfz", "Battle for Zendikar"),
+ ("ss-ogw", "Oath of the Gatewatch"),
+ ("ss-soi", "Shadows Over Innistrad"),
+ ("ss-emn", "Eldritch Moon"),
+ ("ss-kld", "Kaladesh"),
+ ("ss-aer", "Aether Revolt"),
+ ("ss-akh", "Amonkhet"),
+ ("ss-hou", "Hour of Devastation"),
+ ("ss-xln", "Ixalan"),
+ ("ss-rix", "Rivals of Ixalan"),
+ ("ss-dom", "Dominaria"),
+ ("ss-grn", "Guilds of Ravnica"),
+ ("ss-rna", "Ravnica Allegiance"),
+ ("ss-war", "War of the Spark"),
+ ("ss-eld", "Throne of Eldraine"),
+ ("ss-thb", "Theros: Beyond Death"),
+ ("ss-iko", "koria: Lair of Behemoths"),
+ ("ss-znr", "Zendikar Rising"),
+ ("ss-khm", "Kaldheim"),
+ ("ss-stx", "Strixhaven: School of Mages"),
+ ("ss-mid", "Innistrad: Midnight Hunt"),
+ ("ss-vow", "Innistrad: Crimson Vow"),
+ ("ss-neo", "Kamigawa: Neon Dynasty"),
+ ("ss-snc", "Streets of New Capenna"),
+ ("ss-dmu", "Dominaria United"),
+ ("ss-bro", "The Brothers' War"),
+ ("ss-one", "Phyrexia: All Will Be One"),
+ ("ss-mom", "March of the Machine"),
+ ("ss-mat", "March of the Machine: The Aftermath"),
+ ("ss-woe", "Wilds of Eldraine"),
+ ("ss-lci", "Lost Caverns of Ixalan"),
+ ("ss-mkm", "Murders at Karlov Manor"),
+ ("ss-otj", "Outlaws of Thunder Junction"),
+ ("ss-big", "The Big Score"),
+ ("ss-blb", "Bloomburrow"),
+ ],
+ default="ss-ori",
+ max_length=50,
+ ),
+ ),
+ ]
diff --git a/orochi/website/models.py b/orochi/website/models.py
index 27119692..ff2bb90a 100644
--- a/orochi/website/models.py
+++ b/orochi/website/models.py
@@ -14,7 +14,6 @@
from orochi.website.defaults import (
DEFAULT_YARA_PATH,
- ICONS,
RESULT,
RESULT_STATUS_DISABLED,
RESULT_STATUS_NOT_STARTED,
@@ -22,6 +21,7 @@
STATUS,
TOAST_DUMP_COLORS,
TOAST_RESULT_COLORS,
+ IconEnum,
OSEnum,
)
from orochi.ya.models import Ruleset
@@ -144,7 +144,9 @@ class Bookmark(models.Model):
indexes = models.ManyToManyField(Dump)
plugin = models.ForeignKey(Plugin, on_delete=models.CASCADE)
name = models.CharField(max_length=250)
- icon = models.CharField(choices=ICONS, default="ss-ori", max_length=50)
+ icon = models.CharField(
+ choices=IconEnum.choices, default=IconEnum.SS_ORI, max_length=50
+ )
star = models.BooleanField(default=False)
query = models.CharField(max_length=500, blank=True, null=True)
diff --git a/orochi/website/views.py b/orochi/website/views.py
index 71aa82b1..c64561c7 100644
--- a/orochi/website/views.py
+++ b/orochi/website/views.py
@@ -822,92 +822,30 @@ def export(request):
# BOOKMARKS
##############################
@login_required
+@require_http_methods(["GET"])
def add_bookmark(request):
"""Add bookmark in user settings"""
- data = {}
-
- if request.method == "POST":
- updated_request = {
- "name": request.POST.get("name"),
- "query": request.POST.get("query"),
- "star": request.POST.get("star"),
- "icon": request.POST.get("icon"),
- }
-
- id_indexes = request.POST.get("selected_indexes")
- indexes = []
- for id_index in id_indexes.split(","):
- index = get_object_or_404(Dump, index=id_index)
- indexes.append(index)
-
- id_plugin = request.POST.get("selected_plugin")
- plugin = get_object_or_404(Plugin, name=id_plugin)
-
- form = BookmarkForm(data=updated_request)
- if form.is_valid():
- bookmark = form.save(commit=False)
- bookmark.user = request.user
- bookmark.plugin = plugin
- bookmark.save()
- for index in indexes:
- bookmark.indexes.add(index)
- data["form_is_valid"] = True
- else:
- data["form_is_valid"] = False
- else:
- form = BookmarkForm()
-
- context = {"form": form}
- data["html_form"] = render_to_string(
- "website/partial_bookmark_create.html",
- context,
- request=request,
- )
+ data = {
+ "html_form": render_to_string(
+ "website/partial_bookmark_create.html",
+ {"form": BookmarkForm()},
+ request=request,
+ )
+ }
return JsonResponse(data)
@login_required
+@require_http_methods(["GET"])
def edit_bookmark(request):
"""Edit bookmark information"""
- data = {}
- bookmark = None
-
- if request.method == "POST":
- bookmark = get_object_or_404(
- Bookmark, name=request.POST.get("selected_bookmark"), user=request.user
- )
- elif request.method == "GET":
- bookmark = get_object_or_404(
- Bookmark, pk=request.GET.get("pk"), user=request.user
- )
-
- if request.method == "POST":
- form = EditBookmarkForm(
- data=request.POST,
- instance=bookmark,
- )
- if form.is_valid():
- bookmark = form.save()
- data["form_is_valid"] = True
- data["data"] = {
- "name": bookmark.name,
- "icon": bookmark.icon,
- "query": bookmark.query,
- }
- else:
- data["form_is_valid"] = False
- else:
- form = EditBookmarkForm(
- instance=bookmark,
- initial={"selected_bookmark": bookmark.name},
+ bookmark = get_object_or_404(Bookmark, pk=request.GET.get("pk"), user=request.user)
+ context = {"form": EditBookmarkForm(instance=bookmark), "id": bookmark.pk}
+ data = {
+ "html_form": render_to_string(
+ "website/partial_bookmark_edit.html", context, request=request
)
-
- context = {"form": form}
- data["html_form"] = render_to_string(
- "website/partial_bookmark_edit.html",
- context,
- request=request,
- )
+ }
return JsonResponse(data)
diff --git a/requirements/base.txt b/requirements/base.txt
index cc56bad1..1cd7be5a 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -7,7 +7,7 @@ argon2-cffi==23.1.0
# https://github.com/evansd/whitenoise
whitenoise==6.6.0
# https://github.com/andymccurdy/redis-py
-redis==5.0.3
+redis==5.0.4
# https://github.com/redis/hiredis-py
hiredis==2.3.2
# https://github.com/psycopg/psycopg2
@@ -20,21 +20,21 @@ python-magic==0.4.27
# Django
# ------------------------------------------------------------------------------
# https://www.djangoproject.com/
-django==5.0.4
+django==5.0.6
# https://github.com/django/channels
-channels[daphne]==4.0.0
+channels[daphne]==4.1.0
# https://github.com/django/channels_redis
channels_redis==4.2.0
# https://github.com/joke2k/django-environ
django-environ==0.11.2
# https://github.com/pennersr/django-allauth
-django-allauth==0.61.1
+django-allauth==0.63.1
# https://github.com/django-crispy-forms/django-crispy-forms
django-crispy-forms==2.1
# https://github.com/jazzband/django-redis
django-redis==5.4.0
# https://gunicorn.org/
-gunicorn==21.2.0
+gunicorn==22.0.0
# Django Ninja
@@ -64,18 +64,18 @@ django-admin-multiple-choice-list-filter==0.1.1
# Elasticsearch
# ------------------------------------------------------------------------------
# https://github.com/elastic/elasticsearch-py
-elasticsearch==8.13.0
+elasticsearch==8.13.1
# https://github.com/elastic/elasticsearch-dsl-py
-elasticsearch-dsl==8.13.0
+elasticsearch-dsl==8.13.1
# https://github.com/jurismarches/luqum
luqum==0.13.0
# Dask & co
# ------------------------------------------------------------------------------
# https://github.com/dask/dask
-dask==2024.4.1
+dask==2024.5.1
# https://github.com/dask/distributed
-distributed==2024.4.1
+distributed==2024.5.1
# https://msgpack.org/ TO BE ALIGNED WITH SCHEDULER
msgpack==1.0.8
# https://github.com/python-lz4/python-lz4
@@ -89,7 +89,7 @@ toolz==0.12.1
# https://pypi.org/project/tornado/
tornado==6.4
# https://pandas.pydata.org/
-pandas==2.2.1
+pandas==2.2.2
# Volatility
# ------------------------------------------------------------------------------
@@ -100,13 +100,13 @@ pandas==2.2.1
# https://github.com/Viicos/clamdpy
clamdpy==0.1.0.post1
# https://github.com/VirusTotal/vt-py
-vt-py==0.18.0
+vt-py==0.18.2
# https://github.com/mkorman90/regipy/
-regipy[full]==4.1.1
+regipy[full]==4.2.1
# http://www.capstone-engine.org/
capstone==5.0.1
# https://github.com/Julian/jsonschema
-jsonschema==4.21.1
+jsonschema==4.22.0
# https://github.com/Legrandin/pycryptodome
pycryptodome==3.20.0
# https://github.com/maxmind/GeoIP2-python
@@ -133,7 +133,7 @@ pefile==2023.2.7
# misp export
# ------------------------------------------------------------------------------
# https://github.com/MISP/PyMISP
-pymisp==2.4.188
+pymisp==2.4.190
# ldap
# ------------------------------------------------------------------------------
diff --git a/requirements/local.txt b/requirements/local.txt
index 6c84a993..e3a5c767 100644
--- a/requirements/local.txt
+++ b/requirements/local.txt
@@ -5,7 +5,7 @@
# https://github.com/python/mypy
mypy==1.9.0
# https://github.com/typeddjango/django-stubs
-django-stubs==4.2.7
+django-stubs==5.0.0
# https://github.com/pytest-dev/pytest
pytest==8.1.1
# https://github.com/Frozenball/pytest-sugar
@@ -18,13 +18,13 @@ flake8==7.0.0
# https://github.com/gforcada/flake8-isort
flake8-isort==6.1.1
# https://github.com/nedbat/coveragepy
-coverage==7.4.4
+coverage==7.5.1
# https://github.com/ambv/black
-black==24.3.0
+black==24.4.2
# https://github.com/PyCQA/pylint-django
pylint-django==2.5.5
# https://github.com/pre-commit/pre-commit
-pre-commit==3.6.2
+pre-commit==3.7.1
# Django
# ------------------------------------------------------------------------------