Update public source

This commit is contained in:
2026-10-07 09:13:34 +03:00
parent f231cc5b1f
commit ea8ca2a613
5 changed files with 332 additions and 12 deletions
+100
View File
@@ -128,6 +128,106 @@ def methods_page():
methods=method_rows,
)
@cracklab_bp.route(
"/methods/<method_id>/edit/",
methods=["GET", "POST"],
)
def method_edit_page(method_id: str):
error = None
conn = connect_database()
try:
service = MethodService(conn)
method = service.get_method(method_id)
if method is None:
raise MethodServiceError(
"Метод не найден."
)
latest = service.get_latest_method_version(
method_id,
)
if latest is None:
raise MethodServiceError(
"У метода отсутствует версия."
)
if request.method == "POST":
try:
name = request.form.get(
"name",
"",
).strip()
description = request.form.get(
"description",
"",
).strip()
hash_mode_raw = request.form.get(
"hash_mode",
"22000",
).strip()
if not name:
raise MethodServiceError(
"Введите название метода."
)
if hash_mode_raw != "22000":
raise MethodServiceError(
"Сейчас поддерживается только hash mode 22000."
)
steps = _build_steps_from_form()
definition = {
"schema_version": 1,
"hash_mode": 22000,
"steps": steps,
}
with conn:
service.update_method(
method_id=method_id,
name=name,
description=description or None,
)
service.update_method_version(
method_id=method_id,
version=latest["version"],
definition=definition,
)
return redirect(
url_for(
"cracklab.methods_page",
)
)
except (MethodServiceError, ValueError) as exc:
error = str(exc)
definition = json.loads(
latest["definition_json"]
)
return render_template(
"method_create.html",
active_page="methods",
error=error,
method=method,
definition=definition,
edit_mode=True,
)
finally:
conn.close()
@cracklab_bp.route("/methods/create/", methods=["GET", "POST"])
def method_create_page():
+114 -12
View File
@@ -322,11 +322,19 @@
<div>
<h1 class="page-title">
Создание метода
{% if edit_mode %}
Редактирование метода
{% else %}
Создание метода
{% endif %}
</h1>
<div class="page-description">
Новый рабочий метод будет сохранён в базе данных.
{% if edit_mode %}
Изменения будут сохранены в текущей версии метода.
{% else %}
Новый рабочий метод будет сохранён в базе данных.
{% endif %}
</div>
</div>
@@ -366,6 +374,7 @@
type="text"
required
autocomplete="off"
value="{{ method.name if method else '' }}"
>
</div>
@@ -405,7 +414,7 @@
id="description"
name="description"
placeholder="Например: имя + четыре цифры"
></textarea>
>{{ method.description if method and method.description else '' }}</textarea>
</div>
@@ -498,7 +507,11 @@
type="submit"
class="methods-button"
>
Сохранить метод
{% if edit_mode %}
Сохранить изменения
{% else %}
Сохранить метод
{% endif %}
</button>
<a
@@ -516,6 +529,12 @@
<script>
const editMode =
{{ "true" if edit_mode else "false" }};
const initialSteps =
{{ definition.get("steps", []) | tojson if definition else "[]" }};
const stepsContainer =
document.getElementById("steps");
@@ -567,7 +586,16 @@
name,
label,
help,
value = "",
) {
const displayValue =
value
? value.replace(
/^wordlist:/,
"",
)
: "";
return `
<div class="method-field">
<label>
@@ -580,6 +608,7 @@
placeholder="insidepro-wpa"
required
autocomplete="off"
value="${escapeHtml(displayValue)}"
>
<div class="method-help">
@@ -590,7 +619,10 @@
}
function maskField(name) {
function maskField(
name,
value = "",
) {
return `
<div class="method-field">
<label>
@@ -603,6 +635,7 @@
placeholder="?d?d?d?d?d?d?d?d"
required
autocomplete="off"
value="${escapeHtml(value)}"
>
<div class="method-help">
@@ -1004,6 +1037,7 @@
function renderStepFields(
stepNumber,
mode,
stepData = null,
) {
const prefix =
`step_${stepNumber}`;
@@ -1016,6 +1050,7 @@
`${prefix}_dictionary`,
"Словарь",
"Укажите логическое имя wordlist, которое настроено на клиенте.",
stepData?.dictionary?.resource || "",
);
}
@@ -1025,12 +1060,14 @@
`${prefix}_dictionary_1`,
"Словарь — Left",
"Этот словарь образует левую часть кандидата.",
stepData?.dictionaries?.[0]?.resource || "",
);
html += dictionaryField(
`${prefix}_dictionary_2`,
"Словарь — Right",
"Этот словарь образует правую часть кандидата.",
stepData?.dictionaries?.[1]?.resource || "",
);
}
@@ -1038,6 +1075,7 @@
if (mode === "3") {
html += maskField(
`${prefix}_mask`,
stepData?.mask || "",
);
html += `
@@ -1058,10 +1096,12 @@
`${prefix}_dictionary`,
"Словарь — Left",
"Словарь образует левую часть кандидата.",
stepData?.dictionary?.resource || "",
);
html += maskField(
`${prefix}_mask`,
stepData?.mask || "",
);
html += `
@@ -1079,6 +1119,7 @@
if (mode === "7") {
html += maskField(
`${prefix}_mask`,
stepData?.mask || "",
);
html += `
@@ -1095,6 +1136,7 @@
`${prefix}_dictionary`,
"Словарь — Right",
"Словарь образует правую часть кандидата.",
stepData?.dictionary?.resource || "",
);
}
@@ -1304,7 +1346,9 @@
}
function addStep() {
function addStep(
initialStep = null,
) {
stepCount += 1;
const currentStepNumber =
@@ -1440,6 +1484,27 @@
</div>
`;
if (initialStep) {
modeSelect.value =
String(
initialStep.attack_mode,
);
workloadProfile =
step.querySelector(
"[data-workload-profile]",
);
if (
workloadProfile &&
initialStep.workload_profile
) {
workloadProfile.value =
String(
initialStep.workload_profile,
);
}
}
stepsContainer.appendChild(
step,
@@ -1462,7 +1527,9 @@
);
function updateStep() {
function updateStep(
initialData = null,
) {
const mode =
modeSelect.value;
@@ -1475,6 +1542,7 @@
renderStepFields(
number,
mode,
initialData,
);
modeLabel.textContent =
@@ -1498,7 +1566,9 @@
modeSelect.addEventListener(
"change",
updateStep,
() => {
updateStep();
},
);
@@ -1521,13 +1591,38 @@
);
updateStep();
if (initialStep) {
modeSelect.value =
String(
initialStep.attack_mode,
);
const workloadProfile =
step.querySelector(
"[data-workload-profile]",
);
if (
workloadProfile &&
initialStep.workload_profile
) {
workloadProfile.value =
String(
initialStep.workload_profile,
);
}
}
updateStep(
initialStep,
);
stepCountInput.value =
stepCount;
return step;
}
function rebuildStepNumbers() {
@@ -1693,8 +1788,15 @@
},
);
addStep();
if (initialSteps.length > 0) {
initialSteps.forEach(
(step) => {
addStep(step);
},
);
} else {
addStep();
}
</script>
{% endblock %}
@@ -93,6 +93,13 @@
</div>
<a
class="methods-button-secondary"
href="{{ url_for('cracklab.method_edit_page', method_id=method.id) }}"
>
Редактировать
</a>
</article>
{% endfor %}