mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Merge pull request #894 from bunkerity/dev
Merge branch "dev" into branch "staging"
This commit is contained in:
commit
ec0aeb8d7f
86 changed files with 7161 additions and 340 deletions
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
|
|
@ -35,12 +35,12 @@ jobs:
|
|||
python -m pip install --no-cache-dir --require-hashes -r src/common/db/requirements.txt
|
||||
echo "CODEQL_PYTHON=$(which python)" >> $GITHUB_ENV
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
uses: github/codeql-action/init@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql.yml
|
||||
setup-python-dependencies: false
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
uses: github/codeql-action/analyze@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
|
|
|||
2
.github/workflows/scorecards-analysis.yml
vendored
2
.github/workflows/scorecards-analysis.yml
vendored
|
|
@ -25,6 +25,6 @@ jobs:
|
|||
results_format: sarif
|
||||
publish_results: true
|
||||
- name: "Upload SARIF results to code scanning"
|
||||
uses: github/codeql-action/upload-sarif@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
uses: github/codeql-action/upload-sarif@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ RUN apk add --no-cache bash && \
|
|||
chmod 750 cli/main.py helpers/*.sh /usr/bin/bwcli autoconf/main.py deps/python/bin/*
|
||||
|
||||
# Fix CVEs
|
||||
RUN apk add --no-cache "libcrypto3>=3.1.4-r3" "libssl3>=3.1.4-r3" "sqlite-libs>=3.41.2-r3"
|
||||
RUN apk add --no-cache "libcrypto3>=3.1.4-r5" "libssl3>=3.1.4-r5" "sqlite-libs>=3.41.2-r3"
|
||||
|
||||
VOLUME /data /etc/nginx
|
||||
|
||||
|
|
|
|||
|
|
@ -258,10 +258,15 @@ api.global.GET["^/bans$"] = function(self)
|
|||
"can't access ttl " .. k .. " from datastore : " .. ttl
|
||||
)
|
||||
end
|
||||
local ban_data = decode(result)
|
||||
local ban =
|
||||
local ban_data
|
||||
ok, ban_data = pcall(decode, result)
|
||||
if not ok then
|
||||
ban_data = { reason = result, date = -1 }
|
||||
end
|
||||
table.insert(
|
||||
data,
|
||||
{ ip = k:sub(9, #k), reason = ban_data["reason"], date = ban_data["date"], exp = math.floor(ttl) }
|
||||
table.insert(data, ban)
|
||||
)
|
||||
end
|
||||
end
|
||||
return self:response(HTTP_OK, "success", data)
|
||||
|
|
|
|||
|
|
@ -317,7 +317,11 @@ utils.get_reason = function(ctx)
|
|||
end
|
||||
local banned, _ = datastore:get("bans_ip_" .. ip)
|
||||
if banned then
|
||||
return decode(banned)["reason"], {}
|
||||
local ok, ban_data = pcall(decode, banned)
|
||||
if ok then
|
||||
banned = ban_data["reason"]
|
||||
end
|
||||
return banned, {}
|
||||
end
|
||||
-- unknown
|
||||
if ngx.status == utils.get_deny_status() then
|
||||
|
|
@ -642,12 +646,16 @@ utils.is_banned = function(ip)
|
|||
if not result and err ~= "not found" then
|
||||
return nil, "datastore:get() error : " .. result
|
||||
elseif result and err ~= "not found" then
|
||||
local ok, ttl = datastore:ttl("bans_ip_" .. ip)
|
||||
local ban_data = decode(result)
|
||||
if not ok then
|
||||
return true, ban_data["reason"], -1
|
||||
local ok, ban_data = pcall(decode, result)
|
||||
if ok then
|
||||
result = ban_data["reason"]
|
||||
end
|
||||
return true, ban_data["reason"], ttl
|
||||
local ttl
|
||||
ok, ttl = datastore:ttl("bans_ip_" .. ip)
|
||||
if not ok then
|
||||
return true, result, -1
|
||||
end
|
||||
return true, result, ttl
|
||||
end
|
||||
-- Redis case
|
||||
local use_redis, err = utils.get_variable("USE_REDIS", false)
|
||||
|
|
@ -694,7 +702,12 @@ utils.is_banned = function(ip)
|
|||
if not ok then
|
||||
return nil, "datastore:set() error : " .. err
|
||||
end
|
||||
return true, decode(data[1])["reason"], data[2]
|
||||
local ban_data
|
||||
ok, ban_data = pcall(decode, data[1])
|
||||
if ok then
|
||||
data[1] = ban_data["reason"]
|
||||
end
|
||||
return true, data[1], data[2]
|
||||
end
|
||||
clusterstore:close()
|
||||
return false, "not banned"
|
||||
|
|
|
|||
|
|
@ -258,7 +258,13 @@ class CLI(ApiCaller):
|
|||
cli_str += "No ban found\n"
|
||||
|
||||
for ban in bans:
|
||||
cli_str += f"- {ban['ip']} ; banned the {datetime.fromtimestamp(ban['date']).strftime('%d-%m-%Y at %H:%M:%S')} for {format_remaining_time(ban['exp'])} remaining with reason \"{ban.get('reason', 'no reason given')}\"\n"
|
||||
banned_date = ""
|
||||
remaining = "for eternity"
|
||||
if ban["date"] != -1:
|
||||
banned_date = f"the {datetime.fromtimestamp(ban['date']).strftime('%d-%m-%Y at %H:%M:%S')} "
|
||||
if ban["exp"] != -1:
|
||||
remaining = f"for {format_remaining_time(ban['exp'])} remaining"
|
||||
cli_str += f"- {ban['ip']} ; banned {banned_date}{remaining} with reason \"{ban.get('reason', 'no reason given')}\"\n"
|
||||
cli_str += "\n"
|
||||
|
||||
return True, cli_str
|
||||
|
|
|
|||
1
src/common/core/antibot/ui/actions.py
Normal file
1
src/common/core/antibot/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
69
src/common/core/antibot/ui/template.html
Normal file
69
src/common/core/antibot/ui/template.html
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ antibot_info or "Anti-bot technology is designed to detect and
|
||||
mitigate suspicious or malicious bots, preventing them from reaching an
|
||||
organization's websites or IT ecosystem." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
Challenges
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ antibot_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-sky-500 mx-0.5"
|
||||
>total number</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-sky-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-75 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z"
|
||||
/>
|
||||
<path
|
||||
d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z"
|
||||
/>
|
||||
<path
|
||||
d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/authbasic/ui/actions.py
Normal file
1
src/common/core/authbasic/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
65
src/common/core/authbasic/ui/template.html
Normal file
65
src/common/core/authbasic/ui/template.html
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ authbasic_info or "Basic Auth is a method for an HTTP user agent
|
||||
(e.g. a web browser) to provide a user name and password when making a
|
||||
request." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
AUTH BASIC
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ authbasic_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-green-500 mx-0.5"
|
||||
>passed credentials</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-green-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="stroke-none scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M15.75 1.5a6.75 6.75 0 0 0-6.651 7.906c.067.39-.032.717-.221.906l-6.5 6.499a3 3 0 0 0-.878 2.121v2.818c0 .414.336.75.75.75H6a.75.75 0 0 0 .75-.75v-1.5h1.5A.75.75 0 0 0 9 19.5V18h1.5a.75.75 0 0 0 .53-.22l2.658-2.658c.19-.189.517-.288.906-.22A6.75 6.75 0 1 0 15.75 1.5Zm0 3a.75.75 0 0 0 0 1.5A2.25 2.25 0 0 1 18 8.25a.75.75 0 0 0 1.5 0 3.75 3.75 0 0 0-3.75-3.75Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/badbehavior/ui/actions.py
Normal file
1
src/common/core/badbehavior/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
119
src/common/core/badbehavior/ui/template.html
Normal file
119
src/common/core/badbehavior/ui/template.html
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
{% extends "base.html" %} {% block content %} {% set items = [{"code" : 400,
|
||||
"count" : 24}, {"code" : 403, "count" : 845}, {"code" : 402, "count" : 12}]%}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ bad_behavior_info or "Ban IP generating too much 'bad' HTTP status
|
||||
code in a period of time." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
BAD BEHAVIOR
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ bad_behavior_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5"
|
||||
>total ip bans</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
aria-label="version"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-red-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="stroke-none scale-75 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="m6.72 5.66 11.62 11.62A8.25 8.25 0 0 0 6.72 5.66Zm10.56 12.68L5.66 6.72a8.25 8.25 0 0 0 11.62 11.62ZM5.105 5.106c3.807-3.808 9.98-3.808 13.788 0 3.808 3.807 3.808 9.98 0 13.788-3.807 3.808-9.98 3.808-13.788 0-3.808-3.807-3.808-9.98 0-13.788Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
{% if items|length != 0 %}
|
||||
<div
|
||||
class="2xl:col-span-4 3xl:col-span-3 w-full md:max-w-[350px] overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">
|
||||
BAD BEHAVIOR LIST
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[250px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-6 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Error code
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-6 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Count
|
||||
</p>
|
||||
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full">
|
||||
{% for item in items %}
|
||||
<li
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-6 m-0 my-1"
|
||||
>
|
||||
{{item['code']}}
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-6 m-0 my-1"
|
||||
>
|
||||
{{item['count']}}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/blacklist/ui/actions.py
Normal file
1
src/common/core/blacklist/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
236
src/common/core/blacklist/ui/template.html
Normal file
236
src/common/core/blacklist/ui/template.html
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ blacklist_info or "Deny access based on internal and external
|
||||
IP/network/rDNS/ASN blacklists." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
URL
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ blacklist_url_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-red-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M19.902 4.098a3.75 3.75 0 0 0-5.304 0l-4.5 4.5a3.75 3.75 0 0 0 1.035 6.037.75.75 0 0 1-.646 1.353 5.25 5.25 0 0 1-1.449-8.45l4.5-4.5a5.25 5.25 0 1 1 7.424 7.424l-1.757 1.757a.75.75 0 1 1-1.06-1.06l1.757-1.757a3.75 3.75 0 0 0 0-5.304Zm-7.389 4.267a.75.75 0 0 1 1-.353 5.25 5.25 0 0 1 1.449 8.45l-4.5 4.5a5.25 5.25 0 1 1-7.424-7.424l1.757-1.757a.75.75 0 1 1 1.06 1.06l-1.757 1.757a3.75 3.75 0 1 0 5.304 5.304l4.5-4.5a3.75 3.75 0 0 0-1.035-6.037.75.75 0 0 1-.354-1Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
IP
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ blacklist_ip_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-lime-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-50 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M3.53 2.47a.75.75 0 0 0-1.06 1.06l18 18a.75.75 0 1 0 1.06-1.06l-18-18ZM20.25 5.507v11.561L5.853 2.671c.15-.043.306-.075.467-.094a49.255 49.255 0 0 1 11.36 0c1.497.174 2.57 1.46 2.57 2.93ZM3.75 21V6.932l14.063 14.063L12 18.088l-7.165 3.583A.75.75 0 0 1 3.75 21Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
RDNS
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ blacklist_rdns_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-indigo-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M11.625 16.5a1.875 1.875 0 1 0 0-3.75 1.875 1.875 0 0 0 0 3.75Z"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm6 16.5c.66 0 1.277-.19 1.797-.518l1.048 1.048a.75.75 0 0 0 1.06-1.06l-1.047-1.048A3.375 3.375 0 1 0 11.625 18Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
<path
|
||||
d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
ASN
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ blacklist_asn_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-blue-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
User Agent
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ blacklist_user_agent_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-amber-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-50 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/bunkernet/ui/actions.py
Normal file
1
src/common/core/bunkernet/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
215
src/common/core/bunkernet/ui/template.html
Normal file
215
src/common/core/bunkernet/ui/template.html
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- status -->
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
{% if bunkernet_status %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-6 2xl:col-span-3 3xl:col-span-2 w-fit h-fit transition hover:scale-102 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="mx-1 flex justify-start items-center">
|
||||
<h5 class="mb-0 font-bold dark:text-white/90 mr-4">STATUS</h5>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-8 h-8 fill-green-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<p
|
||||
class="mx-1 transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
Active
|
||||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-6 2xl:col-span-3 3xl:col-span-2 w-fit h-fit transition hover:scale-102 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="mx-1 flex justify-start items-center">
|
||||
<h5 class="mb-0 font-bold dark:text-white/90 mr-4">STATUS</h5>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-8 h-8 fill-red-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm-1.72 6.97a.75.75 0 1 0-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 1 0 1.06 1.06L12 13.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L13.06 12l1.72-1.72a.75.75 0 1 0-1.06-1.06L12 10.94l-1.72-1.72Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<p
|
||||
class="mx-1 transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
Inactive
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- end status -->
|
||||
</div>
|
||||
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ bunkernet_info or "BunkerNet is a crowdsourced database of malicious
|
||||
requests shared between all BunkerWeb instances over the world. " }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<!-- test-->
|
||||
<div
|
||||
class="transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">TEST</h5>
|
||||
<p
|
||||
class="my-2 transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80 text-center"
|
||||
>
|
||||
Use the next button to ping BunkerNet (better change limit request
|
||||
settings before).
|
||||
</p>
|
||||
|
||||
<div class="flex justify-center mt-4">
|
||||
<button type="button" class="edit-btn text-sm" onclick="ping()">
|
||||
Ping BunkerNet
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<hr
|
||||
class="h-px mx-0 mt-3 mb-2 bg-transparent bg-gradient-to-r from-transparent via-black/40 to-transparent dark:bg-gradient-to-r dark:from-transparent dark:via-white dark:to-transparent"
|
||||
/>
|
||||
|
||||
<div id="response-div" class="flex justify-center items-center">
|
||||
<div id="no-test" class="flex justify-center items-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 stroke-gray-600"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"
|
||||
/>
|
||||
</svg>
|
||||
<p class="mb-0 ml-1 font-semibold text-gray-600 text-base uppercase">
|
||||
UNKNOWN
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="hidden flex justify-center items-center"
|
||||
id="response-success"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 stroke-green-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
|
||||
/>
|
||||
</svg>
|
||||
<p class="mb-0 ml-1 font-semibold text-green-500 text-base uppercase">
|
||||
SUCCESS
|
||||
</p>
|
||||
</div>
|
||||
<div class="hidden flex justify-center items-center" id="response-failed">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 stroke-red-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"
|
||||
/>
|
||||
</svg>
|
||||
<p class="mb-0 ml-1 font-semibold text-red-500 text-base uppercase">
|
||||
FAILED
|
||||
</p>
|
||||
</div>
|
||||
<div class="hidden flex justify-center items-center" id="response-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 stroke-red-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18.364 18.364A9 9 0 0 0 5.636 5.636m12.728 12.728A9 9 0 0 1 5.636 5.636m12.728 12.728L5.636 5.636"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<p class="mb-0 ml-1 font-semibold text-red-500 text-base uppercase">
|
||||
FAILED
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end test -->
|
||||
<script async>
|
||||
function ping() {
|
||||
let data = new FormData();
|
||||
data.set("csrf_token", "{{ csrf_token() }}");
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "{{ url_for('plugins') }}/bunkernet", true);
|
||||
xhr.send(data);
|
||||
|
||||
xhr.onload = function () {
|
||||
document.getElementById("no-test").classList.add("hidden");
|
||||
if (xhr.status == 200) {
|
||||
document.getElementById("response-failed").classList.remove("hidden");
|
||||
document.getElementById("response-none").classList.add("hidden");
|
||||
document.getElementById("response-success").classList.add("hidden");
|
||||
} else if (xhr.status == 403) {
|
||||
document
|
||||
.getElementById("response-success")
|
||||
.classList.remove("hidden");
|
||||
document.getElementById("response-none").classList.add("hidden");
|
||||
document.getElementById("response-failed").classList.add("hidden");
|
||||
} else {
|
||||
document.getElementById("response-none").classList.remove("hidden");
|
||||
document.getElementById("response-success").classList.add("hidden");
|
||||
document.getElementById("response-failed").classList.add("hidden");
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/cors/ui/actions.py
Normal file
1
src/common/core/cors/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
66
src/common/core/cors/ui/template.html
Normal file
66
src/common/core/cors/ui/template.html
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ cors_info or "Cross-Origin Resource Sharing lets you manage how your
|
||||
service can be contacted from different origins." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
CORS
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ cors_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5"
|
||||
>request blocked</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-red-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="scale-75 leading-none text-lg relative fill-red-700 stroke-white"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/country/ui/actions.py
Normal file
1
src/common/core/country/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
111
src/common/core/country/ui/template.html
Normal file
111
src/common/core/country/ui/template.html
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ country_info or "The country security feature allows you to apply
|
||||
policy based on the country of the IP address of clients (blacklist /
|
||||
whitelist)." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
Country
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ country_blacklist_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5"
|
||||
>blacklist request blocked</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-red-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="scale-75 leading-none text-lg relative fill-red-700 stroke-white"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
Country
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ country_blacklist_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-green-500 mx-0.5"
|
||||
>whitelist request passed</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-green-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-75 leading-none text-lg relative stroke-green-700 fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/customcert/ui/actions.py
Normal file
1
src/common/core/customcert/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
87
src/common/core/customcert/ui/template.html
Normal file
87
src/common/core/customcert/ui/template.html
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
{% extends "base.html" %} {% block content %} {% set items = [ {"server_name" :
|
||||
"www.example.com", "cn" : "Let's encrypt", "expire" : "15/11/2024"},
|
||||
{"server_name" : "app1.com", "cn" : "Self signed", "expire" : "11/01/2028"},
|
||||
{"server_name" : "test.2.fr", "cn" : "Default", "expire" : "31/08/2035"} ]%}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-4 2xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ custom_certificate_info or "Custom certificates allow you to get
|
||||
HTTPS / SSL / TLS on your requests." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if items|length != 0 %}
|
||||
|
||||
<div
|
||||
class="col-span-12 md:col-span-8 3xl:col-span-9 w-full xl:max-w-[600px] overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">
|
||||
CUSTOM CERTIFICATE LIST
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[400px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Server name
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
CN
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Expiry date
|
||||
</p>
|
||||
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full">
|
||||
{% for item in items %}
|
||||
<li
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['server_name']}}
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['cn']}}
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['expire']}}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/db/ui/actions.py
Normal file
1
src/common/core/db/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
107
src/common/core/db/ui/template.html
Normal file
107
src/common/core/db/ui/template.html
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ db_info or "BunkerWeb securely stores its current configuration in
|
||||
a backend database, which contains essential data for smooth
|
||||
operation." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<!-- driver-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">DB</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center mt-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out font-bold mb-0 font-sans text-sm leading-normal uppercase dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
DRIVER
|
||||
<span
|
||||
class="ml-1 font-semibold transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ db_driver or "unknown" }}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="mx-1 flex justify-start items-center mt-1 mb-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out font-bold mb-0 font-sans text-sm leading-normal uppercase dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
VERSION
|
||||
<span
|
||||
class="ml-1 font-semibold transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ db_version or "unknown" }}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end driver -->
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
SIZE
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ db_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-sky-500 mx-0.5">
|
||||
MB used on database
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-sky-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M21 6.375c0 2.692-4.03 4.875-9 4.875S3 9.067 3 6.375 7.03 1.5 12 1.5s9 2.183 9 4.875Z"
|
||||
/>
|
||||
<path
|
||||
d="M12 12.75c2.685 0 5.19-.586 7.078-1.609a8.283 8.283 0 0 0 1.897-1.384c.016.121.025.244.025.368C21 12.817 16.97 15 12 15s-9-2.183-9-4.875c0-.124.009-.247.025-.368a8.285 8.285 0 0 0 1.897 1.384C6.809 12.164 9.315 12.75 12 12.75Z"
|
||||
/>
|
||||
<path
|
||||
d="M12 16.5c2.685 0 5.19-.586 7.078-1.609a8.282 8.282 0 0 0 1.897-1.384c.016.121.025.244.025.368 0 2.692-4.03 4.875-9 4.875s-9-2.183-9-4.875c0-.124.009-.247.025-.368a8.284 8.284 0 0 0 1.897 1.384C6.809 15.914 9.315 16.5 12 16.5Z"
|
||||
/>
|
||||
<path
|
||||
d="M12 20.25c2.685 0 5.19-.586 7.078-1.609a8.282 8.282 0 0 0 1.897-1.384c.016.121.025.244.025.368 0 2.692-4.03 4.875-9 4.875s-9-2.183-9-4.875c0-.124.009-.247.025-.368a8.284 8.284 0 0 0 1.897 1.384C6.809 19.664 9.315 20.25 12 20.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/dnsbl/ui/actions.py
Normal file
1
src/common/core/dnsbl/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
97
src/common/core/dnsbl/ui/template.html
Normal file
97
src/common/core/dnsbl/ui/template.html
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
{% extends "base.html" %} {% block content %} {% set items = [ {"server_name" :
|
||||
"www.example.com", "status" : "ok"}, {"server_name" : "app1.com", "status" :
|
||||
"ok"}, {"server_name" : "test.2.fr", "status" : "ko"} ]%}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-4 2xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ dnsbl_info or "Deny access based on external DNSBL servers." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if items|length != 0 %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-8 3xl:col-span-9 w-full xl:max-w-[600px] overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">DNSBL LIST</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[400px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-8 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Server name
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Status
|
||||
</p>
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full">
|
||||
{% for item in items %}
|
||||
<li
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-8 m-0 my-1"
|
||||
>
|
||||
{{item['server_name']}}
|
||||
</p>
|
||||
{% if item['status'] == "ko"%}
|
||||
<div class="col-span-4 ml-2 m-0 my-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-6 h-6 fill-red-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm-1.72 6.97a.75.75 0 1 0-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 1 0 1.06 1.06L12 13.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L13.06 12l1.72-1.72a.75.75 0 1 0-1.06-1.06L12 10.94l-1.72-1.72Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-span-4 ml-2 m-0 my-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-6 h-6 fill-green-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/errors/ui/actions.py
Normal file
1
src/common/core/errors/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
71
src/common/core/errors/ui/template.html
Normal file
71
src/common/core/errors/ui/template.html
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
{% extends "base.html" %} {% block content %} {% set items = [ {"count" : 74,
|
||||
"code" : "403"}, {"count" : 82, "code" : "404"}, {"count" : "32", "code" :
|
||||
"400"} ]%}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-4 2xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ dnsbl_info or "Deny access based on external DNSBL servers." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if items|length != 0 %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-8 3xl:col-span-9 w-full md:max-w-[400px] overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">ERRORS LIST</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[350px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-8 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Code error
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Count
|
||||
</p>
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full">
|
||||
{% for item in items %}
|
||||
<li
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
class="ml-1 dark:text-gray-400 dark:opacity-80 text-sm col-span-8 m-0 my-1"
|
||||
>
|
||||
{{item['code']}}
|
||||
</p>
|
||||
<p
|
||||
class="ml-1 dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['count']}}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/greylist/ui/actions.py
Normal file
1
src/common/core/greylist/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
236
src/common/core/greylist/ui/template.html
Normal file
236
src/common/core/greylist/ui/template.html
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ greylist_info or "Allow access while keeping security features
|
||||
based on internal and external IP/network/rDNS/ASN greylists. " }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
URL
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ greylist_url_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-red-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M19.902 4.098a3.75 3.75 0 0 0-5.304 0l-4.5 4.5a3.75 3.75 0 0 0 1.035 6.037.75.75 0 0 1-.646 1.353 5.25 5.25 0 0 1-1.449-8.45l4.5-4.5a5.25 5.25 0 1 1 7.424 7.424l-1.757 1.757a.75.75 0 1 1-1.06-1.06l1.757-1.757a3.75 3.75 0 0 0 0-5.304Zm-7.389 4.267a.75.75 0 0 1 1-.353 5.25 5.25 0 0 1 1.449 8.45l-4.5 4.5a5.25 5.25 0 1 1-7.424-7.424l1.757-1.757a.75.75 0 1 1 1.06 1.06l-1.757 1.757a3.75 3.75 0 1 0 5.304 5.304l4.5-4.5a3.75 3.75 0 0 0-1.035-6.037.75.75 0 0 1-.354-1Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
IP
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ greylist_ip_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-lime-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-50 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M3.53 2.47a.75.75 0 0 0-1.06 1.06l18 18a.75.75 0 1 0 1.06-1.06l-18-18ZM20.25 5.507v11.561L5.853 2.671c.15-.043.306-.075.467-.094a49.255 49.255 0 0 1 11.36 0c1.497.174 2.57 1.46 2.57 2.93ZM3.75 21V6.932l14.063 14.063L12 18.088l-7.165 3.583A.75.75 0 0 1 3.75 21Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
RDNS
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ greylist_rdns_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-indigo-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M11.625 16.5a1.875 1.875 0 1 0 0-3.75 1.875 1.875 0 0 0 0 3.75Z"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm6 16.5c.66 0 1.277-.19 1.797-.518l1.048 1.048a.75.75 0 0 0 1.06-1.06l-1.047-1.048A3.375 3.375 0 1 0 11.625 18Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
<path
|
||||
d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
ASN
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ greylist_asn_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-blue-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
User Agent
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ greylist_user_agent_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5">
|
||||
denied
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-amber-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-50 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/letsencrypt/ui/actions.py
Normal file
1
src/common/core/letsencrypt/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
86
src/common/core/letsencrypt/ui/template.html
Normal file
86
src/common/core/letsencrypt/ui/template.html
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
{% extends "base.html" %} {% block content %} {% set items = [ {"server_name" :
|
||||
"www.example.com", "cn" : "Let's encrypt", "expire" : "15/11/2024"},
|
||||
{"server_name" : "app1.com", "cn" : "Self signed", "expire" : "11/01/2028"},
|
||||
{"server_name" : "test.2.fr", "cn" : "Default", "expire" : "31/08/2035"} ]%}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-4 2xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ lets_encrypt_info or "Let's Encrypt certificates for secure HTTP
|
||||
requests." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if items|length != 0 %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-8 3xl:col-span-9 w-full xl:max-w-[600px] overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">
|
||||
LET'S ENCRYPT LIST
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[400px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Server name
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
CN
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Expiry date
|
||||
</p>
|
||||
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full">
|
||||
{% for item in items %}
|
||||
<li
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['server_name']}}
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['cn']}}
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['expire']}}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/limit/ui/actions.py
Normal file
1
src/common/core/limit/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
74
src/common/core/limit/ui/template.html
Normal file
74
src/common/core/limit/ui/template.html
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
{% extends "base.html" %} {% block content %} {% set items = [ {"url" :
|
||||
"http://www.example.com", "count" : 24},{"url" : "http://www.example.com",
|
||||
"count" : 24} ]%}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-4 2xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ limit_info or "Limit maximum number of requests and connections." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if items|length != 0 %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-8 3xl:col-span-9 w-full xl:max-w-[600px] overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">
|
||||
LIMIT AND REQUEST LIST
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[500px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-8 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
URL
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Count
|
||||
</p>
|
||||
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full">
|
||||
{% for item in items %}
|
||||
<li
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
class="ml-1 dark:text-gray-400 dark:opacity-80 text-sm col-span-8 m-0 my-1"
|
||||
>
|
||||
{{item['url']}}
|
||||
</p>
|
||||
<p
|
||||
class="ml-1 dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['count']}}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/misc/ui/actions.py
Normal file
1
src/common/core/misc/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
108
src/common/core/misc/ui/template.html
Normal file
108
src/common/core/misc/ui/template.html
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ misc_info or "Miscellaneous settings (methods, servers...)." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
DEFAULT SERVER DISABLED
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ default_server_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-sky-500 mx-0.5">
|
||||
total
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-orange-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.55] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M4.08 5.227A3 3 0 0 1 6.979 3H17.02a3 3 0 0 1 2.9 2.227l2.113 7.926A5.228 5.228 0 0 0 18.75 12H5.25a5.228 5.228 0 0 0-3.284 1.153L4.08 5.227Z"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5.25 13.5a3.75 3.75 0 1 0 0 7.5h13.5a3.75 3.75 0 1 0 0-7.5H5.25Zm10.5 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm3.75-.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
DISALLOWED METHODS
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ disallowed_methods_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-sky-500 mx-0.5">
|
||||
count
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-lime-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-50 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M18.75 12.75h1.5a.75.75 0 0 0 0-1.5h-1.5a.75.75 0 0 0 0 1.5ZM12 6a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 12 6ZM12 18a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 12 18ZM3.75 6.75h1.5a.75.75 0 1 0 0-1.5h-1.5a.75.75 0 0 0 0 1.5ZM5.25 18.75h-1.5a.75.75 0 0 1 0-1.5h1.5a.75.75 0 0 1 0 1.5ZM3 12a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 3 12ZM9 3.75a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5ZM12.75 12a2.25 2.25 0 1 1 4.5 0 2.25 2.25 0 0 1-4.5 0ZM9 15.75a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/modsecurity/ui/actions.py
Normal file
1
src/common/core/modsecurity/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
64
src/common/core/modsecurity/ui/template.html
Normal file
64
src/common/core/modsecurity/ui/template.html
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ modsec_info or "ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx that is developed by Trustwave's SpiderLabs." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
MODSECURITY
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">{{ modsec_count or "unknown" }}</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-red-500 mx-0.5"
|
||||
>request blocked
|
||||
</span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-red-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="scale-75 leading-none text-lg relative fill-red-700 stroke-white"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/redis/ui/actions.py
Normal file
1
src/common/core/redis/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
214
src/common/core/redis/ui/template.html
Normal file
214
src/common/core/redis/ui/template.html
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- status -->
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
{% if redis_status %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-6 2xl:col-span-3 3xl:col-span-2 w-fit h-fit transition hover:scale-102 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="mx-1 flex justify-start items-center">
|
||||
<h5 class="mb-0 font-bold dark:text-white/90 mr-4">STATUS</h5>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-8 h-8 fill-green-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<p
|
||||
class="mx-1 transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
Active
|
||||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-6 2xl:col-span-3 3xl:col-span-2 w-fit h-fit transition hover:scale-102 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="mx-1 flex justify-start items-center">
|
||||
<h5 class="mb-0 font-bold dark:text-white/90 mr-4">STATUS</h5>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-8 h-8 fill-red-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm-1.72 6.97a.75.75 0 1 0-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 1 0 1.06 1.06L12 13.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L13.06 12l1.72-1.72a.75.75 0 1 0-1.06-1.06L12 10.94l-1.72-1.72Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<p
|
||||
class="mx-1 transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
Inactive
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- end status -->
|
||||
</div>
|
||||
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ redis_info or "Redis server configuration when using BunkerWeb in
|
||||
cluster mode. " }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<!-- test-->
|
||||
<div
|
||||
class="transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">TEST</h5>
|
||||
<p
|
||||
class="my-2 transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80 text-center"
|
||||
>
|
||||
Use the next button to ping Redis.
|
||||
</p>
|
||||
|
||||
<div class="flex justify-center mt-4">
|
||||
<button type="button" class="edit-btn text-sm" onclick="ping()">
|
||||
Ping Redis
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<hr
|
||||
class="h-px mx-0 mt-3 mb-2 bg-transparent bg-gradient-to-r from-transparent via-black/40 to-transparent dark:bg-gradient-to-r dark:from-transparent dark:via-white dark:to-transparent"
|
||||
/>
|
||||
|
||||
<div id="response-div" class="flex justify-center items-center">
|
||||
<div id="no-test" class="flex justify-center items-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 stroke-gray-600"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"
|
||||
/>
|
||||
</svg>
|
||||
<p class="mb-0 ml-1 font-semibold text-gray-600 text-base uppercase">
|
||||
UNKNOWN
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="hidden flex justify-center items-center"
|
||||
id="response-success"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 stroke-green-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
|
||||
/>
|
||||
</svg>
|
||||
<p class="mb-0 ml-1 font-semibold text-green-500 text-base uppercase">
|
||||
SUCCESS
|
||||
</p>
|
||||
</div>
|
||||
<div class="hidden flex justify-center items-center" id="response-failed">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 stroke-red-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"
|
||||
/>
|
||||
</svg>
|
||||
<p class="mb-0 ml-1 font-semibold text-red-500 text-base uppercase">
|
||||
FAILED
|
||||
</p>
|
||||
</div>
|
||||
<div class="hidden flex justify-center items-center" id="response-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-6 h-6 stroke-red-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18.364 18.364A9 9 0 0 0 5.636 5.636m12.728 12.728A9 9 0 0 1 5.636 5.636m12.728 12.728L5.636 5.636"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<p class="mb-0 ml-1 font-semibold text-red-500 text-base uppercase">
|
||||
FAILED
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end test -->
|
||||
<script async>
|
||||
function ping() {
|
||||
let data = new FormData();
|
||||
data.set("csrf_token", "{{ csrf_token() }}");
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "{{ url_for('plugins') }}/bunkernet", true);
|
||||
xhr.send(data);
|
||||
|
||||
xhr.onload = function () {
|
||||
document.getElementById("no-test").classList.add("hidden");
|
||||
if (xhr.status == 200) {
|
||||
document.getElementById("response-failed").classList.remove("hidden");
|
||||
document.getElementById("response-none").classList.add("hidden");
|
||||
document.getElementById("response-success").classList.add("hidden");
|
||||
} else if (xhr.status == 403) {
|
||||
document
|
||||
.getElementById("response-success")
|
||||
.classList.remove("hidden");
|
||||
document.getElementById("response-none").classList.add("hidden");
|
||||
document.getElementById("response-failed").classList.add("hidden");
|
||||
} else {
|
||||
document.getElementById("response-none").classList.remove("hidden");
|
||||
document.getElementById("response-success").classList.add("hidden");
|
||||
document.getElementById("response-failed").classList.add("hidden");
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/reversescan/ui/actions.py
Normal file
1
src/common/core/reversescan/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
78
src/common/core/reversescan/ui/template.html
Normal file
78
src/common/core/reversescan/ui/template.html
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
{% extends "base.html" %} {% block content %} {% set items = [ {"port" : 4000,
|
||||
"count" : 400}, {"port" : 4400, "count" : 780}, {"port" : 5000, "count" : 40},
|
||||
]%}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-4 2xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ reversescan_info or "Reverse scan is a feature designed to detect
|
||||
open ports by establishing TCP connections with clients' IP addresses.
|
||||
Consider adding this feature if you want to detect possible open proxies
|
||||
or connections from servers." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if items|length != 0 %}
|
||||
|
||||
<div
|
||||
class="col-span-12 md:col-span-8 3xl:col-span-9 w-full xl:max-w-[500px] overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">
|
||||
REVERSE SCAN LIST
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[400px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-5 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Port
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-7 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Block count
|
||||
</p>
|
||||
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full">
|
||||
{% for item in items %}
|
||||
<li
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-5 m-0 my-1"
|
||||
>
|
||||
{{item['port']}}
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-7 m-0 my-1"
|
||||
>
|
||||
{{item['count']}}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/selfsigned/ui/actions.py
Normal file
1
src/common/core/selfsigned/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
86
src/common/core/selfsigned/ui/template.html
Normal file
86
src/common/core/selfsigned/ui/template.html
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
{% extends "base.html" %} {% block content %} {% set items = [ {"server_name" :
|
||||
"www.example.com", "cn" : "Let's encrypt", "expire" : "15/11/2024"},
|
||||
{"server_name" : "app1.com", "cn" : "Self signed", "expire" : "11/01/2028"},
|
||||
{"server_name" : "test.2.fr", "cn" : "Default", "expire" : "31/08/2035"} ]%}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-4 2xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ lets_encrypt_info or "Selfsigned certificates for secure HTTP
|
||||
requests." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if items|length != 0 %}
|
||||
<div
|
||||
class="col-span-12 md:col-span-8 3xl:col-span-9 w-full xl:max-w-[600px] overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">
|
||||
SELFSIGNED LIST
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[400px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Server name
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
CN
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-4 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Expiry date
|
||||
</p>
|
||||
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full">
|
||||
{% for item in items %}
|
||||
<li
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['server_name']}}
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['cn']}}
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-4 m-0 my-1"
|
||||
>
|
||||
{{item['expire']}}
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
1
src/common/core/whitelist/ui/actions.py
Normal file
1
src/common/core/whitelist/ui/actions.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Spoofing an action file
|
||||
236
src/common/core/whitelist/ui/template.html
Normal file
236
src/common/core/whitelist/ui/template.html
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<div class="col-span-12 grid grid-cols-12 gap-4">
|
||||
<!-- info-->
|
||||
<div
|
||||
class="h-fit transition hover:scale-102 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div class="mx-1 flex justify-start items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
{{ whitelist_info or "Allow access based on internal and external
|
||||
IP/network/rDNS/ASN whitelists." }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
URL
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ whitelist_url_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-green-500 mx-0.5">
|
||||
passed
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-red-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M19.902 4.098a3.75 3.75 0 0 0-5.304 0l-4.5 4.5a3.75 3.75 0 0 0 1.035 6.037.75.75 0 0 1-.646 1.353 5.25 5.25 0 0 1-1.449-8.45l4.5-4.5a5.25 5.25 0 1 1 7.424 7.424l-1.757 1.757a.75.75 0 1 1-1.06-1.06l1.757-1.757a3.75 3.75 0 0 0 0-5.304Zm-7.389 4.267a.75.75 0 0 1 1-.353 5.25 5.25 0 0 1 1.449 8.45l-4.5 4.5a5.25 5.25 0 1 1-7.424-7.424l1.757-1.757a.75.75 0 1 1 1.06 1.06l-1.757 1.757a3.75 3.75 0 1 0 5.304 5.304l4.5-4.5a3.75 3.75 0 0 0-1.035-6.037.75.75 0 0 1-.354-1Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
IP
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ whitelist_ip_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-green-500 mx-0.5">
|
||||
passed
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-lime-600"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-50 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M3.53 2.47a.75.75 0 0 0-1.06 1.06l18 18a.75.75 0 1 0 1.06-1.06l-18-18ZM20.25 5.507v11.561L5.853 2.671c.15-.043.306-.075.467-.094a49.255 49.255 0 0 1 11.36 0c1.497.174 2.57 1.46 2.57 2.93ZM3.75 21V6.932l14.063 14.063L12 18.088l-7.165 3.583A.75.75 0 0 1 3.75 21Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
RDNS
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ whitelist_rdns_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-green-500 mx-0.5">
|
||||
passed
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-indigo-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M11.625 16.5a1.875 1.875 0 1 0 0-3.75 1.875 1.875 0 0 0 0 3.75Z"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm6 16.5c.66 0 1.277-.19 1.797-.518l1.048 1.048a.75.75 0 0 0 1.06-1.06l-1.047-1.048A3.375 3.375 0 1 0 11.625 18Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
<path
|
||||
d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
ASN
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ whitelist_asn_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-green-500 mx-0.5">
|
||||
passed
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-blue-700"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-[0.6] leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-fit dark:brightness-110 max-h-none sm:max-h-28 hover:scale-102 transition col-span-12 md:col-span-6 2xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<!-- text -->
|
||||
<div>
|
||||
<p
|
||||
class="mb-2 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-60"
|
||||
>
|
||||
User Agent
|
||||
</p>
|
||||
<h5 class="mb-1 font-bold dark:text-white/90">
|
||||
{{ whitelist_user_agent_count or "unknown" }}
|
||||
</h5>
|
||||
|
||||
<p class="mb-0 dark:text-white dark:opacity-60">
|
||||
<span class="font-bold leading-normal text-sm text-green-500 mx-0.5">
|
||||
passed
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- end text -->
|
||||
<!-- icon -->
|
||||
<div
|
||||
role="img"
|
||||
class="dark:brightness-90 inline-block w-12 h-12 text-center rounded-circle bg-amber-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="scale-50 leading-none text-lg relative fill-white"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end icon -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -386,7 +386,6 @@ class Database:
|
|||
for plugin in plugins:
|
||||
settings = {}
|
||||
jobs = []
|
||||
page = False
|
||||
if "id" not in plugin:
|
||||
settings = plugin
|
||||
plugin = {
|
||||
|
|
@ -400,7 +399,7 @@ class Database:
|
|||
else:
|
||||
settings = plugin.pop("settings", {})
|
||||
jobs = plugin.pop("jobs", [])
|
||||
page = plugin.pop("page", False)
|
||||
plugin.pop("page", False)
|
||||
|
||||
db_plugin = session.query(Plugins).filter_by(id=plugin["id"]).first()
|
||||
if db_plugin:
|
||||
|
|
@ -549,61 +548,60 @@ class Database:
|
|||
session.query(Jobs_cache).filter(Jobs_cache.job_name == job["name"]).delete()
|
||||
session.query(Jobs).filter(Jobs.name == job["name"]).update(updates)
|
||||
|
||||
if page:
|
||||
core_ui_path = Path(sep, "usr", "share", "bunkerweb", "core", plugin["id"], "ui")
|
||||
path_ui = core_ui_path if core_ui_path.exists() else Path(sep, "etc", "bunkerweb", "plugins", plugin["id"], "ui")
|
||||
core_ui_path = Path(sep, "usr", "share", "bunkerweb", "core", plugin["id"], "ui")
|
||||
path_ui = core_ui_path if core_ui_path.exists() else Path(sep, "etc", "bunkerweb", "plugins", plugin["id"], "ui")
|
||||
|
||||
if path_ui.exists():
|
||||
if {"template.html", "actions.py"}.issubset(listdir(str(path_ui))):
|
||||
db_plugin_page = (
|
||||
session.query(Plugin_pages)
|
||||
.with_entities(
|
||||
Plugin_pages.template_checksum,
|
||||
Plugin_pages.actions_checksum,
|
||||
)
|
||||
.filter_by(plugin_id=plugin["id"])
|
||||
.first()
|
||||
if path_ui.exists():
|
||||
if {"template.html", "actions.py"}.issubset(listdir(str(path_ui))):
|
||||
db_plugin_page = (
|
||||
session.query(Plugin_pages)
|
||||
.with_entities(
|
||||
Plugin_pages.template_checksum,
|
||||
Plugin_pages.actions_checksum,
|
||||
)
|
||||
template = path_ui.joinpath("template.html").read_bytes()
|
||||
actions = path_ui.joinpath("actions.py").read_bytes()
|
||||
template_checksum = sha256(template).hexdigest()
|
||||
actions_checksum = sha256(actions).hexdigest()
|
||||
.filter_by(plugin_id=plugin["id"])
|
||||
.first()
|
||||
)
|
||||
template = path_ui.joinpath("template.html").read_bytes()
|
||||
actions = path_ui.joinpath("actions.py").read_bytes()
|
||||
template_checksum = sha256(template).hexdigest()
|
||||
actions_checksum = sha256(actions).hexdigest()
|
||||
|
||||
if db_plugin_page:
|
||||
updates = {}
|
||||
if template_checksum != db_plugin_page.template_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.template_file: template,
|
||||
Plugin_pages.template_checksum: template_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if actions_checksum != db_plugin_page.actions_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.actions_file: actions,
|
||||
Plugin_pages.actions_checksum: actions_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if updates:
|
||||
self.__logger.warning(f'Page for plugin "{plugin["id"]}" already exists, updating it with the new values')
|
||||
session.query(Plugin_pages).filter(Plugin_pages.plugin_id == plugin["id"]).update(updates)
|
||||
continue
|
||||
|
||||
if db_plugin:
|
||||
self.__logger.warning(f'Page for plugin "{plugin["id"]}" does not exist, creating it')
|
||||
|
||||
to_put.append(
|
||||
Plugin_pages(
|
||||
plugin_id=plugin["id"],
|
||||
template_file=template,
|
||||
template_checksum=template_checksum,
|
||||
actions_file=actions,
|
||||
actions_checksum=actions_checksum,
|
||||
if db_plugin_page:
|
||||
updates = {}
|
||||
if template_checksum != db_plugin_page.template_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.template_file: template,
|
||||
Plugin_pages.template_checksum: template_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if actions_checksum != db_plugin_page.actions_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.actions_file: actions,
|
||||
Plugin_pages.actions_checksum: actions_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if updates:
|
||||
self.__logger.warning(f'Page for plugin "{plugin["id"]}" already exists, updating it with the new values')
|
||||
session.query(Plugin_pages).filter(Plugin_pages.plugin_id == plugin["id"]).update(updates)
|
||||
continue
|
||||
|
||||
if db_plugin:
|
||||
self.__logger.warning(f'Page for plugin "{plugin["id"]}" does not exist, creating it')
|
||||
|
||||
to_put.append(
|
||||
Plugin_pages(
|
||||
plugin_id=plugin["id"],
|
||||
template_file=template,
|
||||
template_checksum=template_checksum,
|
||||
actions_file=actions,
|
||||
actions_checksum=actions_checksum,
|
||||
)
|
||||
)
|
||||
|
||||
try:
|
||||
session.add_all(to_put)
|
||||
|
|
@ -623,23 +621,42 @@ class Database:
|
|||
|
||||
if config:
|
||||
config.pop("DATABASE_URI", None)
|
||||
db_services = session.query(Services).with_entities(Services.id, Services.method).all()
|
||||
db_ids = [service.id for service in db_services]
|
||||
db_services = session.query(Services).with_entities(Services.id, Services.method, Services.is_draft).all()
|
||||
db_ids: Dict[str, dict] = {service.id: {"method": service.method, "is_draft": service.is_draft} for service in db_services}
|
||||
missing_ids = []
|
||||
services = config.get("SERVER_NAME", [])
|
||||
|
||||
if isinstance(services, str):
|
||||
services = services.split(" ")
|
||||
|
||||
if db_services:
|
||||
missing_ids = [service.id for service in db_services if (service.method == method) and service.id not in services]
|
||||
missing_ids = [service.id for service in db_services if service.method == method and service.id not in services]
|
||||
|
||||
if missing_ids:
|
||||
# Remove services that are no longer in the list
|
||||
session.query(Services).filter(Services.id.in_(missing_ids)).delete()
|
||||
|
||||
drafts = {service for service in services if config.pop(f"{service}_IS_DRAFT", "no") == "yes"}
|
||||
db_drafts = {service.id for service in db_services if service.is_draft}
|
||||
|
||||
if db_drafts:
|
||||
missing_drafts = [service.id for service in db_services if service.method == method and service.id not in drafts and service.id not in missing_ids]
|
||||
|
||||
if missing_drafts:
|
||||
# Remove drafts that are no longer in the list
|
||||
session.query(Services).filter(Services.id.in_(missing_drafts)).update({Services.is_draft: False})
|
||||
|
||||
for draft in drafts:
|
||||
if draft not in db_drafts:
|
||||
if draft not in db_ids:
|
||||
to_put.append(Services(id=draft, method=method, is_draft=True))
|
||||
db_ids[draft] = {"method": method, "is_draft": True}
|
||||
elif method == db_ids[draft]["method"]:
|
||||
session.query(Services).filter(Services.id == draft).update({Services.is_draft: True})
|
||||
|
||||
if config.get("MULTISITE", "no") == "yes":
|
||||
global_values = []
|
||||
for key, value in deepcopy(config).items():
|
||||
for key, value in config.copy().items():
|
||||
suffix = 0
|
||||
original_key = deepcopy(key)
|
||||
if self.suffix_rx.search(key):
|
||||
|
|
@ -655,8 +672,8 @@ class Database:
|
|||
continue
|
||||
|
||||
if server_name not in db_ids:
|
||||
to_put.append(Services(id=server_name, method=method))
|
||||
db_ids.append(server_name)
|
||||
to_put.append(Services(id=server_name, method=method, is_draft=server_name in drafts))
|
||||
db_ids[server_name] = {"method": method, "is_draft": server_name in drafts}
|
||||
|
||||
key = key.replace(f"{server_name}_", "")
|
||||
setting = session.query(Settings).with_entities(Settings.default).filter_by(id=key).first()
|
||||
|
|
@ -888,7 +905,7 @@ class Database:
|
|||
|
||||
return message
|
||||
|
||||
def get_config(self, methods: bool = False) -> Dict[str, Any]:
|
||||
def get_config(self, methods: bool = False, with_drafts: bool = False) -> Dict[str, Any]:
|
||||
"""Get the config from the database"""
|
||||
with self.__db_session() as session:
|
||||
config = {}
|
||||
|
|
@ -924,8 +941,14 @@ class Database:
|
|||
|
||||
is_multisite = config.get("MULTISITE", {"value": "no"})["value"] == "yes" if methods else config.get("MULTISITE", "no") == "yes"
|
||||
|
||||
if with_drafts:
|
||||
services = session.query(Services).with_entities(Services.id, Services.is_draft).all()
|
||||
else:
|
||||
services = session.query(Services).with_entities(Services.id, Services.is_draft).filter_by(is_draft=False).all()
|
||||
|
||||
if is_multisite:
|
||||
for service in session.query(Services).with_entities(Services.id).all():
|
||||
for service in services:
|
||||
config[f"{service.id}_IS_DRAFT"] = "yes" if service.is_draft else "no"
|
||||
checked_settings = []
|
||||
for key, value in deepcopy(config).items():
|
||||
original_key = key
|
||||
|
|
@ -964,7 +987,7 @@ class Database:
|
|||
}
|
||||
)
|
||||
|
||||
servers = " ".join(service.id for service in session.query(Services).all())
|
||||
servers = " ".join(service.id for service in services)
|
||||
config["SERVER_NAME"] = servers if not methods else {"value": servers, "global": True, "method": "default"}
|
||||
|
||||
return config
|
||||
|
|
@ -993,35 +1016,26 @@ class Database:
|
|||
)
|
||||
]
|
||||
|
||||
def get_services_settings(self, methods: bool = False) -> List[Dict[str, Any]]:
|
||||
def get_services_settings(self, methods: bool = False, with_drafts: bool = False) -> List[Dict[str, Any]]:
|
||||
"""Get the services' configs from the database"""
|
||||
services = []
|
||||
config = self.get_config(methods=methods)
|
||||
with self.__db_session() as session:
|
||||
service_names = [service.id for service in session.query(Services).with_entities(Services.id).all()]
|
||||
for service in service_names:
|
||||
service_settings = []
|
||||
tmp_config = deepcopy(config)
|
||||
config = self.get_config(methods=methods, with_drafts=with_drafts)
|
||||
service_names = config["SERVER_NAME"]["value"].split(" ") if methods else config["SERVER_NAME"].split(" ")
|
||||
for service in service_names:
|
||||
service_settings = []
|
||||
tmp_config = deepcopy(config)
|
||||
|
||||
for key, value in deepcopy(tmp_config).items():
|
||||
if key.startswith(f"{service}_"):
|
||||
setting = key.replace(f"{service}_", "")
|
||||
service_settings.append(setting)
|
||||
tmp_config[setting] = tmp_config.pop(key)
|
||||
elif any(key.startswith(f"{s}_") for s in service_names):
|
||||
tmp_config.pop(key)
|
||||
elif key not in service_settings:
|
||||
tmp_config[key] = (
|
||||
{
|
||||
"value": value["value"],
|
||||
"global": value["global"],
|
||||
"method": value["method"],
|
||||
}
|
||||
if methods
|
||||
else value
|
||||
)
|
||||
for key, value in deepcopy(tmp_config).items():
|
||||
if key.startswith(f"{service}_"):
|
||||
setting = key.replace(f"{service}_", "")
|
||||
service_settings.append(setting)
|
||||
tmp_config[setting] = tmp_config.pop(key)
|
||||
elif any(key.startswith(f"{s}_") for s in service_names):
|
||||
tmp_config.pop(key)
|
||||
elif key not in service_settings:
|
||||
tmp_config[key] = {"value": value["value"], "global": value["global"], "method": value["method"]} if methods else value
|
||||
|
||||
services.append(tmp_config)
|
||||
services.append(tmp_config)
|
||||
|
||||
return services
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ class Services(Base):
|
|||
|
||||
id = Column(String(64), primary_key=True)
|
||||
method = Column(METHODS_ENUM, nullable=False)
|
||||
is_draft = Column(Boolean, default=False, nullable=False)
|
||||
|
||||
settings = relationship("Services_settings", back_populates="service", cascade="all")
|
||||
custom_configs = relationship("Custom_configs", back_populates="service", cascade="all")
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
"context": "global",
|
||||
"default": "no",
|
||||
"help": "Internal use : set to yes when BW is loading.",
|
||||
"id": "internal-use",
|
||||
"label": "internal use",
|
||||
"id": "internal-use-loading",
|
||||
"label": "internal use loading",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
"help": "List of the virtual hosts served by bunkerweb.",
|
||||
"id": "server-name",
|
||||
"label": "Server name",
|
||||
"regex": "^(?! )( ?((?=[^ ]{1,255}( |$))[^ ]+)(?!.* \\2))*$",
|
||||
"regex": "^((\\S{1,255})(?!.*\\s\\2(\\s|$)))?(\\s(\\S{1,255})(?!.*\\s\\5(\\s|$)))*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WORKER_PROCESSES": {
|
||||
|
|
@ -288,5 +288,14 @@
|
|||
"label": "Use IPv6",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"IS_DRAFT": {
|
||||
"context": "multisite",
|
||||
"default": "no",
|
||||
"help": "Internal use : set to yes when the service is in draft mode.",
|
||||
"id": "internal-use-draft",
|
||||
"label": "internal use draft",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
},
|
||||
{
|
||||
"id": "modsecurity",
|
||||
"name": "ModSecurity v3.0.11",
|
||||
"name": "ModSecurity v3.0.12",
|
||||
"url": "https://github.com/SpiderLabs/ModSecurity.git",
|
||||
"commit": "bbde9381cbccb49ea73f6194b08b478adc53f3bc",
|
||||
"commit": "5f44383236b94ef8066529861d0b4d603f9b3bcb",
|
||||
"post_install": "patch --forward src/deps/src/modsecurity/configure.ac src/deps/misc/modsecurity.patch && rm -rf src/deps/src/modsecurity/others/libinjection"
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11]
|
||||
os: [macos-12]
|
||||
compiler: [clang]
|
||||
configure:
|
||||
- {label: "with parser generation", opt: "--enable-parser-generation" }
|
||||
|
|
|
|||
8
src/deps/src/modsecurity/CHANGES
vendored
8
src/deps/src/modsecurity/CHANGES
vendored
|
|
@ -1,3 +1,11 @@
|
|||
v3.0.12 - 2024-Jan-30
|
||||
---------------------
|
||||
|
||||
- Change REQUEST_FILENAME and REQUEST_BASENAME behavior
|
||||
[Issue #3048 - @martinhsv, @theMiddleBlue, @theseion, @M4tteoP, @airween]
|
||||
- Set the minimum security protocol version for SecRemoteRules
|
||||
[Issue security/code-scanning/2 - @airween]
|
||||
|
||||
v3.0.11 - 2023-Dec-06
|
||||
---------------------
|
||||
|
||||
|
|
|
|||
30
src/deps/src/modsecurity/README.md
vendored
30
src/deps/src/modsecurity/README.md
vendored
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
<img src="https://github.com/SpiderLabs/ModSecurity/raw/v3/master/others/modsec.png" width="50%">
|
||||
<img src="https://github.com/owasp-modsecurity/ModSecurity/raw/v3/master/others/modsec.png" width="50%">
|
||||
|
||||

|
||||
[](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
[](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
[](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
[](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
[](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||

|
||||
[](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
|
||||
[](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
|
||||
[](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
|
||||
[](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
|
||||
[](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
|
||||
|
||||
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ capability to load/interpret rules written in the ModSecurity SecRules format
|
|||
and apply them to HTTP content provided by your application via Connectors.
|
||||
|
||||
If you are looking for ModSecurity for Apache (aka ModSecurity v2.x), it is still under maintenance and available:
|
||||
[here](https://github.com/SpiderLabs/ModSecurity/tree/v2/master).
|
||||
[here](https://github.com/owasp-modsecurity/ModSecurity/tree/v2/master).
|
||||
|
||||
### What is the difference between this project and the old ModSecurity (v2.x.x)?
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ As a result of this goal we have rearchitected Libmodsecurity such that it is no
|
|||
|
||||
### It is no longer just a module.
|
||||
|
||||
The 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/SpiderLabs/ModSecurity-nginx).
|
||||
The 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/owasp-modsecurity/ModSecurity-nginx).
|
||||
|
||||
Keeping these connectors separated allows each project to have different release cycles, issues and development trees. Additionally, it means that when you install ModSecurity v3 you only get exactly what you need, no extras you won't be using.
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ $ sudo make install
|
|||
```
|
||||
|
||||
Details on distribution specific builds can be found in our Wiki:
|
||||
[Compilation Recipes](https://github.com/SpiderLabs/ModSecurity/wiki/Compilation-recipes)
|
||||
[Compilation Recipes](https://github.com/owasp-modsecurity/ModSecurity/wiki/Compilation-recipes)
|
||||
|
||||
### Windows
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ is one.
|
|||
### Security issue
|
||||
|
||||
Please do not make public any security issue. Contact us at:
|
||||
security@modsecurity.org reporting the issue. Once the problem is fixed your
|
||||
modsecurity@owasp.org reporting the issue. Once the problem is fixed your
|
||||
credit will be given.
|
||||
|
||||
## Feature request
|
||||
|
|
|
|||
2
src/deps/src/modsecurity/SECURITY.md
vendored
2
src/deps/src/modsecurity/SECURITY.md
vendored
|
|
@ -6,4 +6,4 @@ The latest versions of both v2.9.x and v3.0.x are supported.
|
|||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
For information on how to report a security issue, please see https://github.com/SpiderLabs/ModSecurity#security-issue
|
||||
For information on how to report a security issue, please see https://github.com/owasp-modsecurity/ModSecurity#security-issue
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ namespace modsecurity {
|
|||
|
||||
#define MODSECURITY_MAJOR "3"
|
||||
#define MODSECURITY_MINOR "0"
|
||||
#define MODSECURITY_PATCHLEVEL "11"
|
||||
#define MODSECURITY_PATCHLEVEL "12"
|
||||
#define MODSECURITY_TAG ""
|
||||
#define MODSECURITY_TAG_NUM "100"
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ namespace modsecurity {
|
|||
MODSECURITY_MINOR "." MODSECURITY_PATCHLEVEL \
|
||||
MODSECURITY_TAG
|
||||
|
||||
#define MODSECURITY_VERSION_NUM 30110100
|
||||
#define MODSECURITY_VERSION_NUM 30120100
|
||||
|
||||
#define MODSECURITY_CHECK_VERSION(a) (MODSECURITY_VERSION_NUM <= a)
|
||||
|
||||
|
|
|
|||
26
src/deps/src/modsecurity/src/transaction.cc
vendored
26
src/deps/src/modsecurity/src/transaction.cc
vendored
|
|
@ -463,6 +463,14 @@ int Transaction::processURI(const char *uri, const char *method,
|
|||
|
||||
size_t pos_raw_query = uri_s.find("?");
|
||||
|
||||
std::string path_info_raw;
|
||||
if (pos_raw_query == std::string::npos) {
|
||||
path_info_raw = std::string(uri_s, 0);
|
||||
} else {
|
||||
path_info_raw = std::string(uri_s, 0, pos_raw_query);
|
||||
}
|
||||
std::string path_info = utils::uri_decode(path_info_raw);
|
||||
|
||||
m_uri_decoded = utils::uri_decode(uri_s);
|
||||
|
||||
size_t var_size = pos_raw_query;
|
||||
|
|
@ -477,15 +485,8 @@ int Transaction::processURI(const char *uri, const char *method,
|
|||
m_variableRequestProtocol.set("HTTP/" + std::string(http_version),
|
||||
m_variableOffset + requestLine.size() + 1);
|
||||
|
||||
|
||||
size_t pos_query = m_uri_decoded.find("?");
|
||||
if (pos_query != std::string::npos) {
|
||||
m_uri_no_query_string_decoded = std::unique_ptr<std::string>(
|
||||
new std::string(m_uri_decoded, 0, pos_query));
|
||||
} else {
|
||||
m_uri_no_query_string_decoded = std::unique_ptr<std::string>(
|
||||
new std::string(m_uri_decoded));
|
||||
}
|
||||
m_uri_no_query_string_decoded = std::unique_ptr<std::string>(
|
||||
new std::string(path_info));
|
||||
|
||||
|
||||
if (pos_raw_query != std::string::npos) {
|
||||
|
|
@ -495,12 +496,7 @@ int Transaction::processURI(const char *uri, const char *method,
|
|||
+ std::string(method).size() + 1);
|
||||
}
|
||||
|
||||
std::string path_info;
|
||||
if (pos_query == std::string::npos) {
|
||||
path_info = std::string(m_uri_decoded, 0);
|
||||
} else {
|
||||
path_info = std::string(m_uri_decoded, 0, pos_query);
|
||||
}
|
||||
|
||||
if (var_size == std::string::npos) {
|
||||
var_size = uri_s.size();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ bool HttpsClient::download(const std::string &uri) {
|
|||
headers_chunk = curl_slist_append(headers_chunk, m_key.c_str());
|
||||
}
|
||||
|
||||
/* Make it TLS 1.x only. */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
|
||||
/* Make it TLS 1.2 at least. */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
||||
|
||||
/* those are the default options, but lets make sure */
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing Variables :: PATH_INFO (1/3)",
|
||||
"title":"Testing Variables :: PATH_INFO (1/4)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing Variables :: PATH_INFO (2/3)",
|
||||
"title":"Testing Variables :: PATH_INFO (2/4)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing Variables :: PATH_INFO (3/3)",
|
||||
"title":"Testing Variables :: PATH_INFO (3/4)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -130,5 +130,49 @@
|
|||
"SecRuleEngine On",
|
||||
"SecRule PATH_INFO \"@contains test \" \"id:1,phase:3,pass,t:trim\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing Variables :: PATH_INFO (4/4)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
},
|
||||
"server":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":80
|
||||
},
|
||||
"request":{
|
||||
"headers":{
|
||||
"Host":"localhost",
|
||||
"User-Agent":"curl/7.38.0",
|
||||
"Accept":"*/*",
|
||||
"Content-Length":"27",
|
||||
"Content-Type":"application/x-www-form-urlencoded"
|
||||
},
|
||||
"uri":"/one/t%3fo/three?key=value",
|
||||
"method":"POST",
|
||||
"body":[
|
||||
"param1=value1¶m2=value2"
|
||||
]
|
||||
},
|
||||
"response":{
|
||||
"headers":{
|
||||
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
|
||||
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
|
||||
"Content-Type":"text/html"
|
||||
},
|
||||
"body":[
|
||||
"no need."
|
||||
]
|
||||
},
|
||||
"expected":{
|
||||
"http_code": 403
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"SecRule PATH_INFO \"@contains three\" \"id:1,phase:2,deny,status:403,t:trim\""
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ COPY --chown=root:scheduler src/bw/misc/country.mmdb /var/tmp/bunkerweb/country.
|
|||
RUN chmod 770 /var/tmp/bunkerweb/asn.mmdb /var/tmp/bunkerweb/country.mmdb
|
||||
|
||||
# Fix CVEs
|
||||
RUN apk add --no-cache "sqlite-libs>=3.41.2-r3"
|
||||
RUN apk add --no-cache "libcrypto3>=3.1.4-r5" "libssl3>=3.1.4-r5" "sqlite-libs>=3.41.2-r3"
|
||||
|
||||
VOLUME /data /etc/nginx
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ RUN apk add --no-cache bash && \
|
|||
ln -s /proc/1/fd/2 /var/log/bunkerweb/ui.log
|
||||
|
||||
# Fix CVEs
|
||||
RUN apk add --no-cache "libcrypto3>=3.1.4-r3" "libssl3>=3.1.4-r3" "sqlite-libs>=3.41.2-r3"
|
||||
RUN apk add --no-cache "libcrypto3>=3.1.4-r5" "libssl3>=3.1.4-r5" "sqlite-libs>=3.41.2-r3"
|
||||
|
||||
VOLUME /data /etc/nginx
|
||||
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ LOG_RX = re_compile(r"^(?P<date>\d+/\d+/\d+\s\d+:\d+:\d+)\s\[(?P<level>[a-z]+)\]
|
|||
REVERSE_PROXY_PATH = re_compile(r"^(?P<host>https?://.{1,255}(:((6553[0-5])|(655[0-2]\d)|(65[0-4]\d{2})|(6[0-4]\d{3})|([1-5]\d{4})|([0-5]{0,5})|(\d{1,4})))?)$")
|
||||
|
||||
|
||||
def manage_bunkerweb(method: str, *args, operation: str = "reloads"):
|
||||
def manage_bunkerweb(method: str, *args, operation: str = "reloads", is_draft: bool = False):
|
||||
# Do the operation
|
||||
error = False
|
||||
if method == "services":
|
||||
|
|
@ -224,27 +224,27 @@ def manage_bunkerweb(method: str, *args, operation: str = "reloads"):
|
|||
deleted = False
|
||||
|
||||
if operation == "new":
|
||||
operation, error = app.config["CONFIG"].new_service(args[0])
|
||||
operation, error = app.config["CONFIG"].new_service(args[0], is_draft=is_draft)
|
||||
elif operation == "edit":
|
||||
if args[1].split(" ")[0] != args[2].split(" ")[0] and service_custom_confs:
|
||||
for service_custom_conf in service_custom_confs:
|
||||
if listdir(service_custom_conf):
|
||||
move(service_custom_conf, service_custom_conf.replace(f"{sep}{args[1].split(' ')[0]}", f"{sep}{args[2].split(' ')[0]}"))
|
||||
moved = True
|
||||
operation, error = app.config["CONFIG"].edit_service(args[1], args[0], check_changes=not moved)
|
||||
operation, error = app.config["CONFIG"].edit_service(args[1], args[0], check_changes=not is_draft and not moved, is_draft=is_draft)
|
||||
elif operation == "delete":
|
||||
for service_custom_conf in glob(join(sep, "etc", "bunkerweb", "configs", "*", args[2].split(" ")[0])):
|
||||
if listdir(service_custom_conf):
|
||||
rmtree(service_custom_conf, ignore_errors=True)
|
||||
deleted = True
|
||||
operation, error = app.config["CONFIG"].delete_service(args[2], check_changes=not deleted)
|
||||
operation, error = app.config["CONFIG"].delete_service(args[2], check_changes=not is_draft and not deleted)
|
||||
|
||||
if error:
|
||||
app.config["TO_FLASH"].append({"content": operation, "type": "error"})
|
||||
else:
|
||||
app.config["TO_FLASH"].append({"content": operation, "type": "success"})
|
||||
|
||||
if moved or deleted:
|
||||
if not is_draft and (moved or deleted):
|
||||
changes = ["config", "custom_configs"]
|
||||
error = app.config["CONFIGFILES"].save_configs(check_changes=False)
|
||||
if error:
|
||||
|
|
@ -693,17 +693,17 @@ def instances():
|
|||
def services():
|
||||
if request.method == "POST":
|
||||
# Check operation
|
||||
if "operation" not in request.form or request.form["operation"] not in (
|
||||
"new",
|
||||
"edit",
|
||||
"delete",
|
||||
):
|
||||
if "operation" not in request.form or request.form["operation"] not in ("new", "edit", "delete"):
|
||||
flash("Missing operation parameter on /services.", "error")
|
||||
return redirect(url_for("loading", next=url_for("services")))
|
||||
elif "is_draft" not in request.form or request.form["is_draft"] not in ("yes", "no"):
|
||||
flash("Missing is_draft parameter on /services.", "error")
|
||||
return redirect(url_for("loading", next=url_for("services")))
|
||||
|
||||
# Check variables
|
||||
variables = deepcopy(request.form.to_dict())
|
||||
del variables["csrf_token"]
|
||||
is_draft = variables.pop("is_draft") == "yes"
|
||||
|
||||
if "OLD_SERVER_NAME" not in request.form and request.form["operation"] == "edit":
|
||||
flash("Missing OLD_SERVER_NAME parameter.", "error")
|
||||
|
|
@ -717,7 +717,7 @@ def services():
|
|||
del variables["OLD_SERVER_NAME"]
|
||||
|
||||
# Edit check fields and remove already existing ones
|
||||
config = app.config["CONFIG"].get_config(methods=False)
|
||||
config = app.config["CONFIG"].get_config(methods=False, with_drafts=True)
|
||||
server_name = variables["SERVER_NAME"].split(" ")[0]
|
||||
for variable, value in deepcopy(variables).items():
|
||||
if variable.endswith("SCHEMA"):
|
||||
|
|
@ -732,11 +732,8 @@ def services():
|
|||
if variable in variables and variable != "SERVER_NAME" and value == config.get(f"{server_name}_{variable}" if request.form["operation"] == "edit" else variable, None):
|
||||
del variables[variable]
|
||||
|
||||
if request.form["operation"] == "edit" and len(variables) == 1 and "SERVER_NAME" in variables and variables["SERVER_NAME"] == request.form.get("OLD_SERVER_NAME", ""):
|
||||
flash(
|
||||
"The service was not edited because no values were changed.",
|
||||
"error",
|
||||
)
|
||||
if (config.get(f"{server_name}_IS_DRAFT", "no") == "yes") == is_draft and request.form["operation"] == "edit" and len(variables) == 1 and "SERVER_NAME" in variables and variables["SERVER_NAME"] == request.form.get("OLD_SERVER_NAME", ""):
|
||||
flash("The service was not edited because no values were changed.", "error")
|
||||
return redirect(url_for("loading", next=url_for("services")))
|
||||
elif request.form["operation"] == "new" and not variables:
|
||||
flash("The service was not created because all values had the default value.", "error")
|
||||
|
|
@ -767,22 +764,22 @@ def services():
|
|||
target=manage_bunkerweb,
|
||||
name="Reloading instances",
|
||||
args=("services", variables, request.form.get("OLD_SERVER_NAME", ""), variables.get("SERVER_NAME", "")),
|
||||
kwargs={"operation": request.form["operation"]},
|
||||
kwargs={"operation": request.form["operation"], "is_draft": is_draft},
|
||||
).start()
|
||||
|
||||
message = ""
|
||||
|
||||
if request.form["operation"] == "new":
|
||||
message = f"Creating service {variables.get('SERVER_NAME', '').split(' ')[0]}"
|
||||
message = f"Creating {'draft ' if is_draft else ''}service {variables.get('SERVER_NAME', '').split(' ')[0]}"
|
||||
elif request.form["operation"] == "edit":
|
||||
message = f"Saving configuration for service {request.form.get('OLD_SERVER_NAME', '').split(' ')[0]}"
|
||||
message = f"Saving configuration for {'draft ' if is_draft else ''}service {request.form.get('OLD_SERVER_NAME', '').split(' ')[0]}"
|
||||
elif request.form["operation"] == "delete":
|
||||
message = f"Deleting service {request.form.get('SERVER_NAME', '').split(' ')[0]}"
|
||||
message = f"Deleting {'draft ' if is_draft else ''}service {request.form.get('SERVER_NAME', '').split(' ')[0]}"
|
||||
|
||||
return redirect(url_for("loading", next=url_for("services"), message=message))
|
||||
|
||||
# Display services
|
||||
services = app.config["CONFIG"].get_services()
|
||||
services = app.config["CONFIG"].get_services(with_drafts=True)
|
||||
return render_template(
|
||||
"services.html",
|
||||
services=[
|
||||
|
|
@ -792,6 +789,7 @@ def services():
|
|||
"full_value": service["SERVER_NAME"]["value"],
|
||||
"method": service["SERVER_NAME"]["method"],
|
||||
},
|
||||
"IS_DRAFT": service.pop("IS_DRAFT", "no"),
|
||||
"USE_REVERSE_PROXY": service["USE_REVERSE_PROXY"],
|
||||
"SERVE_FILES": service["SERVE_FILES"],
|
||||
"REMOTE_PHP": service["REMOTE_PHP"],
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ class Config:
|
|||
plugins_settings = self.get_plugins_settings()
|
||||
for service in services_conf:
|
||||
server_name = service["SERVER_NAME"].split(" ")[0]
|
||||
if not server_name:
|
||||
continue
|
||||
|
||||
for k in service:
|
||||
key_without_server_name = k.replace(f"{server_name}_", "")
|
||||
if plugins_settings[key_without_server_name]["context"] != "global" if key_without_server_name in plugins_settings else True:
|
||||
|
|
@ -98,7 +101,7 @@ class Config:
|
|||
def get_settings(self) -> dict:
|
||||
return self.__settings
|
||||
|
||||
def get_config(self, methods: bool = True) -> dict:
|
||||
def get_config(self, methods: bool = True, with_drafts: bool = False) -> dict:
|
||||
"""Get the nginx variables env file and returns it as a dict
|
||||
|
||||
Returns
|
||||
|
|
@ -106,9 +109,9 @@ class Config:
|
|||
dict
|
||||
The nginx variables env file as a dict
|
||||
"""
|
||||
return self.__db.get_config(methods=methods)
|
||||
return self.__db.get_config(methods=methods, with_drafts=with_drafts)
|
||||
|
||||
def get_services(self, methods: bool = True) -> list[dict]:
|
||||
def get_services(self, methods: bool = True, with_drafts: bool = False) -> list[dict]:
|
||||
"""Get nginx's services
|
||||
|
||||
Returns
|
||||
|
|
@ -116,7 +119,7 @@ class Config:
|
|||
list
|
||||
The services
|
||||
"""
|
||||
return self.__db.get_services_settings(methods=methods)
|
||||
return self.__db.get_services_settings(methods=methods, with_drafts=with_drafts)
|
||||
|
||||
def check_variables(self, variables: dict, _global: bool = False) -> int:
|
||||
"""Testify that the variables passed are valid
|
||||
|
|
@ -163,7 +166,7 @@ class Config:
|
|||
def reload_config(self) -> None:
|
||||
self.__gen_conf(self.get_config(methods=False), self.get_services(methods=False))
|
||||
|
||||
def new_service(self, variables: dict) -> Tuple[str, int]:
|
||||
def new_service(self, variables: dict, is_draft: bool = False) -> Tuple[str, int]:
|
||||
"""Creates a new service from the given variables
|
||||
|
||||
Parameters
|
||||
|
|
@ -181,23 +184,17 @@ class Config:
|
|||
Exception
|
||||
raise this if the service already exists
|
||||
"""
|
||||
services = self.get_services(methods=False)
|
||||
services = self.get_services(methods=False, with_drafts=True)
|
||||
server_name_splitted = variables["SERVER_NAME"].split(" ")
|
||||
for service in services:
|
||||
if service["SERVER_NAME"] == variables["SERVER_NAME"] or service["SERVER_NAME"] in server_name_splitted:
|
||||
return (
|
||||
f"Service {service['SERVER_NAME'].split(' ')[0]} already exists.",
|
||||
1,
|
||||
)
|
||||
return f"Service {service['SERVER_NAME'].split(' ')[0]} already exists.", 1
|
||||
|
||||
services.append(variables)
|
||||
self.__gen_conf(self.get_config(methods=False), services)
|
||||
return (
|
||||
f"Configuration for {variables['SERVER_NAME'].split(' ')[0]} has been generated.",
|
||||
0,
|
||||
)
|
||||
services.append(variables | {"IS_DRAFT": "yes" if is_draft else "no"})
|
||||
self.__gen_conf(self.get_config(methods=False), services, check_changes=not is_draft)
|
||||
return f"Configuration for {variables['SERVER_NAME'].split(' ')[0]} has been generated.", 0
|
||||
|
||||
def edit_service(self, old_server_name: str, variables: dict, *, check_changes: bool = True) -> Tuple[str, int]:
|
||||
def edit_service(self, old_server_name: str, variables: dict, *, check_changes: bool = True, is_draft: bool = False) -> Tuple[str, int]:
|
||||
"""Edits a service
|
||||
|
||||
Parameters
|
||||
|
|
@ -212,22 +209,19 @@ class Config:
|
|||
str
|
||||
the confirmation message
|
||||
"""
|
||||
services = self.get_services(methods=False)
|
||||
services = self.get_services(methods=False, with_drafts=True)
|
||||
changed_server_name = old_server_name != variables["SERVER_NAME"]
|
||||
server_name_splitted = variables["SERVER_NAME"].split(" ")
|
||||
old_server_name_splitted = old_server_name.split(" ")
|
||||
for i, service in enumerate(deepcopy(services)):
|
||||
if service["SERVER_NAME"] == variables["SERVER_NAME"] or service["SERVER_NAME"] in server_name_splitted:
|
||||
if changed_server_name and service["SERVER_NAME"].split(" ")[0] != old_server_name_splitted[0]:
|
||||
return (
|
||||
f"Service {service['SERVER_NAME'].split(' ')[0]} already exists.",
|
||||
1,
|
||||
)
|
||||
return f"Service {service['SERVER_NAME'].split(' ')[0]} already exists.", 1
|
||||
services.pop(i)
|
||||
elif changed_server_name and (service["SERVER_NAME"] == old_server_name or service["SERVER_NAME"] in old_server_name_splitted):
|
||||
services.pop(i)
|
||||
|
||||
services.append(variables)
|
||||
services.append(variables | {"IS_DRAFT": "yes" if is_draft else "no"})
|
||||
config = self.get_config(methods=False)
|
||||
|
||||
if changed_server_name and server_name_splitted[0] != old_server_name_splitted[0]:
|
||||
|
|
@ -236,10 +230,7 @@ class Config:
|
|||
config.pop(k)
|
||||
|
||||
self.__gen_conf(config, services, check_changes=check_changes)
|
||||
return (
|
||||
f"Configuration for {old_server_name_splitted[0]} has been edited.",
|
||||
0,
|
||||
)
|
||||
return f"Configuration for {old_server_name_splitted[0]} has been edited.", 0
|
||||
|
||||
def edit_global_conf(self, variables: dict) -> str:
|
||||
"""Edits the global conf
|
||||
|
|
@ -277,7 +268,7 @@ class Config:
|
|||
"""
|
||||
service_name = service_name.split(" ")[0]
|
||||
full_env = self.get_config(methods=False)
|
||||
services = self.get_services(methods=False)
|
||||
services = self.get_services(methods=False, with_drafts=True)
|
||||
new_services = []
|
||||
found = False
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
3459
src/ui/static/css/plugins.css
Normal file
3459
src/ui/static/css/plugins.css
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -21,7 +21,7 @@ class Filter {
|
|||
setTimeout(() => {
|
||||
const value = document
|
||||
.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text="reason"]`
|
||||
`[data-${this.prefix}-setting-select-text="reason"]`,
|
||||
)
|
||||
.textContent.trim();
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ class Dropdown {
|
|||
const btn = e.target.closest("button");
|
||||
const btnValue = btn.getAttribute("value");
|
||||
const btnSetting = btn.getAttribute(
|
||||
`data-${this.prefix}-setting-select-dropdown-btn`
|
||||
`data-${this.prefix}-setting-select-dropdown-btn`,
|
||||
);
|
||||
//stop if same value to avoid new fetching
|
||||
const isSameVal = this.isSameValue(btnSetting, btnValue);
|
||||
|
|
@ -185,7 +185,7 @@ class Dropdown {
|
|||
|
||||
closeAllDrop() {
|
||||
const drops = document.querySelectorAll(
|
||||
`[data-${this.prefix}-setting-select-dropdown]`
|
||||
`[data-${this.prefix}-setting-select-dropdown]`,
|
||||
);
|
||||
drops.forEach((drop) => {
|
||||
drop.classList.add("hidden");
|
||||
|
|
@ -193,8 +193,8 @@ class Dropdown {
|
|||
document
|
||||
.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
|
||||
`data-${this.prefix}-setting-select-dropdown`
|
||||
)}"]`
|
||||
`data-${this.prefix}-setting-select-dropdown`,
|
||||
)}"]`,
|
||||
)
|
||||
.classList.remove("rotate-180");
|
||||
});
|
||||
|
|
@ -202,7 +202,7 @@ class Dropdown {
|
|||
|
||||
isSameValue(btnSetting, value) {
|
||||
const selectCustom = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`,
|
||||
);
|
||||
const currVal = selectCustom.textContent;
|
||||
return currVal === value ? true : false;
|
||||
|
|
@ -210,30 +210,30 @@ class Dropdown {
|
|||
|
||||
setSelectNewValue(btnSetting, value) {
|
||||
const selectCustom = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
selectCustom.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text]`
|
||||
`[data-${this.prefix}-setting-select-text]`,
|
||||
).textContent = value;
|
||||
}
|
||||
|
||||
hideDropdown(btnSetting) {
|
||||
//hide dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
|
||||
);
|
||||
dropdownEl.classList.add("hidden");
|
||||
dropdownEl.classList.remove("flex");
|
||||
//svg effect
|
||||
const dropdownChevron = document.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`
|
||||
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
}
|
||||
|
||||
changeDropBtnStyle(btnSetting, selectedBtn) {
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
|
||||
);
|
||||
//reset dropdown btns
|
||||
const btnEls = dropdownEl.querySelectorAll("button");
|
||||
|
|
@ -243,7 +243,7 @@ class Dropdown {
|
|||
"bg-primary",
|
||||
"dark:bg-primary",
|
||||
"text-gray-300",
|
||||
"text-gray-300"
|
||||
"text-gray-300",
|
||||
);
|
||||
btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700");
|
||||
});
|
||||
|
|
@ -251,7 +251,7 @@ class Dropdown {
|
|||
selectedBtn.classList.remove(
|
||||
"bg-white",
|
||||
"dark:bg-slate-700",
|
||||
"text-gray-700"
|
||||
"text-gray-700",
|
||||
);
|
||||
selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
|
||||
}
|
||||
|
|
@ -262,10 +262,10 @@ class Dropdown {
|
|||
.getAttribute(`data-${this.prefix}-setting-select`);
|
||||
//toggle dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`,
|
||||
);
|
||||
const dropdownChevron = document.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${attribute}"]`
|
||||
`svg[data-${this.prefix}-setting-select="${attribute}"]`,
|
||||
);
|
||||
dropdownEl.classList.toggle("hidden");
|
||||
dropdownEl.classList.toggle("flex");
|
||||
|
|
@ -318,7 +318,7 @@ class Unban {
|
|||
setTimeout(() => {
|
||||
// Check if at least one item is selected
|
||||
const selected = this.listEl.querySelectorAll(
|
||||
`input[data-checked="true"]`
|
||||
`input[data-checked="true"]`,
|
||||
);
|
||||
|
||||
// Case true, enable unban button
|
||||
|
|
@ -340,7 +340,7 @@ class Unban {
|
|||
if (this.unbanBtn.hasAttribute("disabled")) return;
|
||||
// Get all selected items
|
||||
const selected = this.listEl.querySelectorAll(
|
||||
`input[data-checked="true"]`
|
||||
`input[data-checked="true"]`,
|
||||
);
|
||||
const getDatas = [];
|
||||
selected.forEach((el) => {
|
||||
|
|
@ -366,7 +366,7 @@ class AddBanModal {
|
|||
this.listEl = document.querySelector(`[data-bans-add-ban-list]`);
|
||||
this.submitBtn = document.querySelector(`button[data-bans-modal-submit]`);
|
||||
this.removeAllFieldBtn = document.querySelector(
|
||||
"button[data-add-ban-delete-all-item]"
|
||||
"button[data-add-ban-delete-all-item]",
|
||||
);
|
||||
this.formEl = document.querySelector("form[data-ban-add-form]");
|
||||
this.itemCount = 0;
|
||||
|
|
@ -561,7 +561,10 @@ class AddBanModal {
|
|||
setDatepicker(id) {
|
||||
const defaultDate = +(Date.now() + 3600000 * 24);
|
||||
const inpEl = document.querySelector(`input#ban-end-${id}`);
|
||||
inpEl.setAttribute("data-timestamp", defaultDate.toString().substring(0, 10));
|
||||
inpEl.setAttribute(
|
||||
"data-timestamp",
|
||||
defaultDate.toString().substring(0, 10),
|
||||
);
|
||||
|
||||
// instantiate datepicker
|
||||
const dateOptions = {
|
||||
|
|
@ -579,7 +582,10 @@ class AddBanModal {
|
|||
|
||||
// Case pick is before current date
|
||||
if (pickStamp < nowStamp) {
|
||||
inpEl.setAttribute("data-timestamp", defaultDate.toString().substring(0, 10));
|
||||
inpEl.setAttribute(
|
||||
"data-timestamp",
|
||||
defaultDate.toString().substring(0, 10),
|
||||
);
|
||||
return instance.setDate(defaultDate);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,25 +26,53 @@ class ServiceModal {
|
|||
);
|
||||
//container
|
||||
this.container = document.querySelector("main");
|
||||
this.currAction = "";
|
||||
this.currMethod = "";
|
||||
this.init();
|
||||
}
|
||||
|
||||
//store default config data on DOM
|
||||
//to update modal data on new button click
|
||||
|
||||
getActionAndServName(target) {
|
||||
getActionData(target) {
|
||||
const action = target
|
||||
.closest("button")
|
||||
.getAttribute("data-services-action");
|
||||
const serviceName = target
|
||||
.closest("button")
|
||||
.getAttribute("data-services-name");
|
||||
const isDraft =
|
||||
target
|
||||
.closest("[data-services-service]")
|
||||
.querySelector("[data-is-draft]")
|
||||
.getAttribute("data-value") || "no";
|
||||
|
||||
return [action, serviceName];
|
||||
const method =
|
||||
target
|
||||
.closest("[data-services-service]")
|
||||
.querySelector("[data-service-method]")
|
||||
.getAttribute("data-value") || "no";
|
||||
|
||||
this.currMethod = method;
|
||||
|
||||
return [action, serviceName, isDraft, method];
|
||||
}
|
||||
|
||||
init() {
|
||||
this.modal.addEventListener("click", (e) => {
|
||||
// update draft mode
|
||||
try {
|
||||
if (e.target.closest("button").hasAttribute("data-toggle-draft-btn")) {
|
||||
// Get current state
|
||||
const currModeIsDraft = e.target
|
||||
.querySelector('[data-toggle-draft="true"]')
|
||||
.classList.contains("hidden")
|
||||
? true
|
||||
: false;
|
||||
this.setIsDraft(currModeIsDraft, this.currMethod);
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
//close
|
||||
try {
|
||||
if (
|
||||
|
|
@ -63,12 +91,21 @@ class ServiceModal {
|
|||
"edit"
|
||||
) {
|
||||
//set form info and right form
|
||||
const [action, serviceName] = this.getActionAndServName(e.target);
|
||||
const [action, serviceName, isDraft, method] = this.getActionData(
|
||||
e.target
|
||||
);
|
||||
const oldServName = e.target
|
||||
.closest("[data-services-service]")
|
||||
.querySelector("[data-old-service-name]")
|
||||
.getAttribute("data-value");
|
||||
this.setForm(action, serviceName, oldServName, this.formNewEdit);
|
||||
this.setForm(
|
||||
action,
|
||||
serviceName,
|
||||
oldServName,
|
||||
this.formNewEdit,
|
||||
isDraft,
|
||||
method
|
||||
);
|
||||
//get service data and parse it
|
||||
//multiple type logic is launch at same time on relate class
|
||||
const servicesSettings = e.target
|
||||
|
|
@ -90,8 +127,17 @@ class ServiceModal {
|
|||
"clone"
|
||||
) {
|
||||
//set form info and right form
|
||||
const [action, serviceName] = this.getActionAndServName(e.target);
|
||||
this.setForm(action, serviceName, serviceName, this.formNewEdit);
|
||||
const [action, serviceName, isDraft, method] = this.getActionData(
|
||||
e.target
|
||||
);
|
||||
this.setForm(
|
||||
action,
|
||||
serviceName,
|
||||
serviceName,
|
||||
this.formNewEdit,
|
||||
isDraft,
|
||||
method
|
||||
);
|
||||
//set default value with method default
|
||||
//get service data and parse it
|
||||
//multiple type logic is launch at same time on relate class
|
||||
|
|
@ -100,7 +146,7 @@ class ServiceModal {
|
|||
.querySelector("[data-services-settings]")
|
||||
.getAttribute("data-value");
|
||||
const obj = JSON.parse(servicesSettings);
|
||||
this.updateModalData(obj, true);
|
||||
this.updateModalData(obj, true, true);
|
||||
// server name is unset
|
||||
const inpServName = document.querySelector("input#SERVER_NAME");
|
||||
inpServName.getAttribute("value", "");
|
||||
|
|
@ -121,8 +167,17 @@ class ServiceModal {
|
|||
"new"
|
||||
) {
|
||||
//set form info and right form
|
||||
const [action, serviceName] = this.getActionAndServName(e.target);
|
||||
this.setForm(action, serviceName, serviceName, this.formNewEdit);
|
||||
const [action, serviceName, isDraft, method] = this.getActionData(
|
||||
e.target
|
||||
);
|
||||
this.setForm(
|
||||
action,
|
||||
serviceName,
|
||||
serviceName,
|
||||
this.formNewEdit,
|
||||
isDraft,
|
||||
method
|
||||
);
|
||||
//set default value with method default
|
||||
this.setSettingsDefault();
|
||||
//server name is unset
|
||||
|
|
@ -144,8 +199,17 @@ class ServiceModal {
|
|||
"delete"
|
||||
) {
|
||||
//set form info and right form
|
||||
const [action, serviceName] = this.getActionAndServName(e.target);
|
||||
this.setForm(action, serviceName, serviceName, this.formDelete);
|
||||
const [action, serviceName, isDraft, method] = this.getActionData(
|
||||
e.target
|
||||
);
|
||||
this.setForm(
|
||||
action,
|
||||
serviceName,
|
||||
serviceName,
|
||||
this.formDelete,
|
||||
isDraft,
|
||||
method
|
||||
);
|
||||
//show modal
|
||||
this.openModal();
|
||||
}
|
||||
|
|
@ -178,6 +242,7 @@ class ServiceModal {
|
|||
if (
|
||||
inpName === "csrf_token" ||
|
||||
inpName === "OLD_SERVER_NAME" ||
|
||||
inpName === "is_draft" ||
|
||||
inpName === "operation" ||
|
||||
inpName === "settings-filter"
|
||||
)
|
||||
|
|
@ -248,9 +313,46 @@ class ServiceModal {
|
|||
}
|
||||
}
|
||||
|
||||
setForm(action, serviceName, oldServName, formEl) {
|
||||
setIsDraft(isDraft, method) {
|
||||
console.log(isDraft, method);
|
||||
const draftVal = isDraft ? "yes" : "no";
|
||||
|
||||
document.querySelectorAll('input[name="is_draft"]').forEach((inp) => {
|
||||
inp.setAttribute("value", draftVal);
|
||||
inp.value = draftVal;
|
||||
});
|
||||
|
||||
console.log("f");
|
||||
|
||||
//Update draft button
|
||||
const btn = document.querySelector("button[data-toggle-draft-btn]");
|
||||
|
||||
if (
|
||||
(!["ui", "default"].includes(method) && this.currAction !== "clone") ||
|
||||
this.currAction === "delete"
|
||||
) {
|
||||
return btn.classList.add("hidden");
|
||||
}
|
||||
|
||||
btn.classList.remove("hidden");
|
||||
|
||||
const showEl = isDraft ? "true" : "false";
|
||||
btn.querySelectorAll("[data-toggle-draft]").forEach((item) => {
|
||||
if (item.getAttribute("data-toggle-draft") === showEl)
|
||||
item.classList.remove("hidden");
|
||||
if (item.getAttribute("data-toggle-draft") !== showEl)
|
||||
item.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
|
||||
setForm(action, serviceName, oldServName, formEl, isDraft, method) {
|
||||
this.currAction = action;
|
||||
this.setIsDraft(isDraft === "yes" ? true : false, method);
|
||||
|
||||
this.modalTitle.textContent = `${action} ${serviceName}`;
|
||||
|
||||
const operation = action === "clone" ? "new" : action;
|
||||
|
||||
formEl.setAttribute("id", `form-${operation}-${serviceName}`);
|
||||
const opeInp = formEl.querySelector(`input[name="operation"]`);
|
||||
opeInp.setAttribute("value", operation);
|
||||
|
|
@ -326,12 +428,12 @@ class ServiceModal {
|
|||
this.modalTabsHeader.classList.remove("hidden");
|
||||
}
|
||||
|
||||
updateModalData(settings, forceEnabled = false) {
|
||||
updateModalData(settings, forceEnabled = false, setMethodUI = false) {
|
||||
//use this to select inputEl and change value
|
||||
for (const [key, data] of Object.entries(settings)) {
|
||||
//change format to match id
|
||||
const value = data["value"];
|
||||
const method = data["method"];
|
||||
const method = setMethodUI ? "ui" : data["method"];
|
||||
const global = data["global"];
|
||||
try {
|
||||
const inps = this.modal.querySelectorAll(`[name='${key}']`);
|
||||
|
|
@ -342,6 +444,7 @@ class ServiceModal {
|
|||
if (
|
||||
inpName === "csrf_token" ||
|
||||
inpName === "OLD_SERVER_NAME" ||
|
||||
inpName === "is_draft" ||
|
||||
inpName === "operation" ||
|
||||
inpName === "settings-filter"
|
||||
)
|
||||
|
|
@ -461,7 +564,14 @@ class Multiple {
|
|||
const multipleSettings = this.getMultiplesOnly(obj);
|
||||
const sortMultiples =
|
||||
this.sortMultipleByContainerAndSuffixe(multipleSettings);
|
||||
this.setMultipleToDOM(sortMultiples);
|
||||
// Need to set method as ui if clone
|
||||
const isClone =
|
||||
e.target.closest("button").getAttribute("data-services-action") ===
|
||||
"clone"
|
||||
? true
|
||||
: false;
|
||||
|
||||
this.setMultipleToDOM(sortMultiples, isClone);
|
||||
}
|
||||
} catch (err) {}
|
||||
//new service button
|
||||
|
|
@ -664,7 +774,7 @@ class Multiple {
|
|||
}
|
||||
|
||||
//put multiple on the right plugin, on schema container
|
||||
setMultipleToDOM(sortMultObj) {
|
||||
setMultipleToDOM(sortMultObj, setMethodUI = false) {
|
||||
//we loop on each multiple that contains values to render to DOM
|
||||
for (const [schemaCtnrName, multGroupBySuffix] of Object.entries(
|
||||
sortMultObj
|
||||
|
|
@ -692,7 +802,7 @@ class Multiple {
|
|||
//replace input info and disabled state
|
||||
this.setSetting(
|
||||
data["value"],
|
||||
data["method"],
|
||||
setMethodUI ? "ui" : data["method"],
|
||||
data["global"],
|
||||
settingContainer
|
||||
);
|
||||
|
|
@ -769,6 +879,7 @@ class Multiple {
|
|||
if (
|
||||
inpName === "csrf_token" ||
|
||||
inpName === "OLD_SERVER_NAME" ||
|
||||
inpName === "is_draft" ||
|
||||
inpName === "operation" ||
|
||||
inpName === "settings-filter"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ module.exports = {
|
|||
"./templates/*.{html,js}",
|
||||
"./static/js/*.js",
|
||||
"./static/js/utils/*.js",
|
||||
"../common/core/***/**/*.{html,js}",
|
||||
],
|
||||
|
||||
presets: [],
|
||||
|
|
|
|||
1
src/ui/templates/head.html
vendored
1
src/ui/templates/head.html
vendored
|
|
@ -14,6 +14,7 @@
|
|||
<title>BunkerWeb UI</title>
|
||||
<link rel="icon" type="image/x-icon" href="images/favicon.ico" />
|
||||
<!-- tailwind style -->
|
||||
<link rel="stylesheet" type="text/css" href="./css/plugins.css" />
|
||||
<link rel="stylesheet" type="text/css" href="./css/dashboard.css" />
|
||||
|
||||
<script type="module" src="./js/global.js"></script>
|
||||
|
|
|
|||
2
src/ui/templates/header.html
vendored
2
src/ui/templates/header.html
vendored
|
|
@ -1,4 +1,4 @@
|
|||
{% set current_endpoint = url_for(request.endpoint)[1:].split("/")[-1].strip()
|
||||
{% set current_endpoint = url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', ' ').replace('-', ' ')
|
||||
%}
|
||||
|
||||
<!-- header -->
|
||||
|
|
|
|||
20
src/ui/templates/plugins.html
vendored
20
src/ui/templates/plugins.html
vendored
|
|
@ -213,7 +213,7 @@ include "plugins_modal.html" %}
|
|||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">LIST</h5>
|
||||
|
||||
<div data-{{current_endpoint}}-list class="grid grid-cols-12 gap-3">
|
||||
{% for plugin in plugins %} {% if plugin['external'] %}
|
||||
{% for plugin in plugins %}
|
||||
<div
|
||||
data-{{current_endpoint}}-external="{% if plugin['external'] %} external {% else %} internal {% endif %}"
|
||||
class="py-3 min-h-12 relative col-span-12 sm:col-span-6 2xl:col-span-4 3xl:col-span-3 p-1 flex justify-between items-center transition rounded bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800"
|
||||
|
|
@ -228,7 +228,7 @@ include "plugins_modal.html" %}
|
|||
{% if plugin['page']%}
|
||||
<a
|
||||
aria-label="plugin page link"
|
||||
class="hover:-translate-y-px"
|
||||
class="hover:-translate-y-px mx-1"
|
||||
href="{{request.url_root}}plugins?plugin_id={{plugin['id']}}"
|
||||
>
|
||||
<svg
|
||||
|
|
@ -242,6 +242,7 @@ include "plugins_modal.html" %}
|
|||
</svg>
|
||||
</a>
|
||||
{%endif%}
|
||||
{% if plugin['external'] %}
|
||||
<button
|
||||
data-{{current_endpoint}}-action="delete"
|
||||
name="{{plugin['id']}}"
|
||||
|
|
@ -258,21 +259,10 @@ include "plugins_modal.html" %}
|
|||
/>
|
||||
</svg>
|
||||
</button>
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div
|
||||
data-{{current_endpoint}}-external="{% if plugin['external'] %} external {%else%} internal {%endif%}"
|
||||
class="py-3 min-h-12 relative col-span-12 sm:col-span-6 2xl:col-span-4 3xl:col-span-3 p-1 flex justify-between items-center transition rounded bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800"
|
||||
>
|
||||
<p
|
||||
data-{{current_endpoint}}-content
|
||||
class="ml-3 mr-2 break-words mb-0 mb-0 transition duration-300 ease-in-out dark:opacity-90 text-left text-sm md:text-base text-slate-700 dark:text-gray-200"
|
||||
>
|
||||
{{plugin['name']}}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %} {% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
2
src/ui/templates/plugins_modal.html
vendored
2
src/ui/templates/plugins_modal.html
vendored
|
|
@ -50,7 +50,7 @@
|
|||
</div>
|
||||
<!-- action button -->
|
||||
<div class="w-full justify-center flex mt-10">
|
||||
<button
|
||||
<button
|
||||
data-plugins-modal-close
|
||||
class="close-btn mb-4 mr-3 text-base"
|
||||
>
|
||||
|
|
|
|||
38
src/ui/templates/services.html
vendored
38
src/ui/templates/services.html
vendored
|
|
@ -1,8 +1,10 @@
|
|||
{% extends "base.html" %} {% block content %}
|
||||
<!-- actions -->
|
||||
<div
|
||||
<div data-services-service
|
||||
class="col-span-12 relative flex justify-center min-w-0 break-words rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div data-is-draft class="hidden" data-value="no"></div>
|
||||
<div data-service-method class="hidden" data-value="ui"></div>
|
||||
<button
|
||||
data-services-action="new"
|
||||
data-services-name="service"
|
||||
|
|
@ -32,14 +34,33 @@
|
|||
{% else %}{% for services_batched in services|batch(3) %} {% for service in
|
||||
services_batched %} {% set id_server_name =
|
||||
service["SERVER_NAME"]['value'].replace(".", "-") %}
|
||||
<div data-services-service
|
||||
<div data-services-service="{{ service["SERVER_NAME"]['value'] }}"
|
||||
class="my-2 dark:brightness-110 overflow-hidden hover:scale-102 transition col-span-12 lg:col-span-6 3xl:col-span-4 p-4 w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div data-services-settings class="hidden" data-value="{{service['settings']}}"></div>
|
||||
<div data-old-service-name class="hidden" data-value="{{service['SERVER_NAME']['full_value']}}"></div>
|
||||
<h5 class="transition duration-300 ease-in-out text-center sm:text-left mb-1 font-bold dark:text-white/90">
|
||||
{{ service["SERVER_NAME"]['value'] }}
|
||||
</h5>
|
||||
<div data-is-draft class="hidden" data-value="{% if service.get('IS_DRAFT', "no") == "yes" %}yes{%else%}no{%endif%}"></div>
|
||||
<div data-service-method class="hidden" data-value="{{service["SERVER_NAME"]['method']}}"></div>
|
||||
<div class="flex justify-between items-start">
|
||||
<h5 class="transition duration-300 ease-in-out text-center sm:text-left mb-1 font-bold dark:text-white/90">
|
||||
{{ service["SERVER_NAME"]['value'] }}
|
||||
</h5>
|
||||
{% if service.get('IS_DRAFT', "no") == "yes" and service["SERVER_NAME"]['method'] in ["ui", "default"] %}
|
||||
<button class="group relative">
|
||||
<p class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">Draft</p>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 fill-gray-700 dark:fill-gray-300 cursor-pointer-none">
|
||||
<path fill-rule="evenodd" d="M10.5 3.798v5.02a3 3 0 0 1-.879 2.121l-2.377 2.377a9.845 9.845 0 0 1 5.091 1.013 8.315 8.315 0 0 0 5.713.636l.285-.071-3.954-3.955a3 3 0 0 1-.879-2.121v-5.02a23.614 23.614 0 0 0-3 0Zm4.5.138a.75.75 0 0 0 .093-1.495A24.837 24.837 0 0 0 12 2.25a25.048 25.048 0 0 0-3.093.191A.75.75 0 0 0 9 3.936v4.882a1.5 1.5 0 0 1-.44 1.06l-6.293 6.294c-1.62 1.621-.903 4.475 1.471 4.88 2.686.46 5.447.698 8.262.698 2.816 0 5.576-.239 8.262-.697 2.373-.406 3.092-3.26 1.47-4.881L15.44 9.879A1.5 1.5 0 0 1 15 8.818V3.936Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
{% else %}
|
||||
<button class="group relative">
|
||||
<p class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">Online</p>
|
||||
<svg data-toggle-draft="false" data-toggle-draft="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 fill-gray-700 dark:fill-gray-300 cursor-pointer-none">
|
||||
<path d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z" />
|
||||
</svg>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<h6 class="text-center sm:text-left mb-2 font-semibold text-gray-600 dark:text-white/80">{{ service["SERVER_NAME"]['method'] }}</h5>
|
||||
|
||||
<!-- detail list -->
|
||||
|
|
@ -366,10 +387,11 @@
|
|||
|
||||
class="dark:brightness-90 z-20 mx-1 bg-emerald-500 hover:bg-emerald-500/80 focus:bg-emerald-500/80 inline-block p-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 active:opacity-85 hover:shadow-md"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184" />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 fill-white">
|
||||
<path fill-rule="evenodd" d="M17.663 3.118c.225.015.45.032.673.05C19.876 3.298 21 4.604 21 6.109v9.642a3 3 0 0 1-3 3V16.5c0-5.922-4.576-10.775-10.384-11.217.324-1.132 1.3-2.01 2.548-2.114.224-.019.448-.036.673-.051A3 3 0 0 1 13.5 1.5H15a3 3 0 0 1 2.663 1.618ZM12 4.5A1.5 1.5 0 0 1 13.5 3H15a1.5 1.5 0 0 1 1.5 1.5H12Z" clip-rule="evenodd" />
|
||||
<path d="M3 8.625c0-1.036.84-1.875 1.875-1.875h.375A3.75 3.75 0 0 1 9 10.5v1.875c0 1.036.84 1.875 1.875 1.875h1.875A3.75 3.75 0 0 1 16.5 18v2.625c0 1.035-.84 1.875-1.875 1.875h-9.75A1.875 1.875 0 0 1 3 20.625v-12Z" />
|
||||
<path d="M10.5 10.5a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963 5.23 5.23 0 0 0-3.434-1.279h-1.875a.375.375 0 0 1-.375-.375V10.5Z" />
|
||||
</svg>
|
||||
|
||||
</button>
|
||||
|
||||
|
||||
|
|
|
|||
26
src/ui/templates/services_modal.html
vendored
26
src/ui/templates/services_modal.html
vendored
|
|
@ -9,12 +9,24 @@
|
|||
class="overflow-y-auto mx-0 sm:mx-6 lg:mx-8 my-3 px-4 pt-4 pb-8 w-full sm:min-w-[500px] h-[90vh] flex flex-col break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<div class="w-full flex justify-between mb-2">
|
||||
<p
|
||||
data-services-modal-title
|
||||
class="transition duration-300 ease-in-out dark:opacity-90 dark:text-gray-200 mb-2 font-sans font-semibold leading-normal uppercase text-md"
|
||||
>
|
||||
SERVICE MODAL
|
||||
</p>
|
||||
<div class="flex justify-start items-center">
|
||||
<p
|
||||
data-services-modal-title
|
||||
class="transition duration-300 ease-in-out dark:opacity-90 dark:text-gray-200 mb-1 font-sans font-semibold leading-normal uppercase text-md"
|
||||
>
|
||||
SERVICE MODAL
|
||||
</p>
|
||||
<button data-toggle-draft-btn class="transition hover:brightness-75 dark:hover:brightness-110 ml-4 flex items-center border border-gray-700 dark:border-gray-300 rounded py-1 px-2">
|
||||
<p data-toggle-draft="true" class="hidden dark:text-gray-300 mb-0 mr-2 pointer-events-none">Draft</p>
|
||||
<p data-toggle-draft="false" class="hidden dark:text-gray-300 mb-0 mr-2 pointer-events-none">Online</p>
|
||||
<svg data-toggle-draft="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="hidden w-5 h-5 fill-gray-700 dark:fill-gray-300 pointer-events-none">
|
||||
<path fill-rule="evenodd" d="M10.5 3.798v5.02a3 3 0 0 1-.879 2.121l-2.377 2.377a9.845 9.845 0 0 1 5.091 1.013 8.315 8.315 0 0 0 5.713.636l.285-.071-3.954-3.955a3 3 0 0 1-.879-2.121v-5.02a23.614 23.614 0 0 0-3 0Zm4.5.138a.75.75 0 0 0 .093-1.495A24.837 24.837 0 0 0 12 2.25a25.048 25.048 0 0 0-3.093.191A.75.75 0 0 0 9 3.936v4.882a1.5 1.5 0 0 1-.44 1.06l-6.293 6.294c-1.62 1.621-.903 4.475 1.471 4.88 2.686.46 5.447.698 8.262.698 2.816 0 5.576-.239 8.262-.697 2.373-.406 3.092-3.26 1.47-4.881L15.44 9.879A1.5 1.5 0 0 1 15 8.818V3.936Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<svg data-toggle-draft="false" data-toggle-draft="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="hidden w-5 h-5 fill-gray-700 dark:fill-gray-300 pointer-events-none">
|
||||
<path d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
class="-translate-y-1"
|
||||
aria-label="close modal"
|
||||
|
|
@ -66,6 +78,7 @@
|
|||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" id="operation" value="new" name="operation" />
|
||||
<input type="hidden" value="new" name="OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
|
||||
{% include "settings_plugins.html" %}
|
||||
|
||||
|
|
@ -94,6 +107,7 @@
|
|||
>
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" value="delete" name="operation" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
<input type="hidden" value="" name="SERVER_NAME" />
|
||||
|
||||
<div class="flex justify-center">
|
||||
|
|
|
|||
36
src/ui/templates/settings_plugins.html
vendored
36
src/ui/templates/settings_plugins.html
vendored
|
|
@ -3,6 +3,7 @@
|
|||
{% set global_config = config["CONFIG"].get_config() %}
|
||||
{% set plugins = config["CONFIG"].get_plugins() %}
|
||||
<!-- plugin item -->
|
||||
|
||||
{% for plugin in plugins %}
|
||||
|
||||
<div
|
||||
|
|
@ -12,11 +13,31 @@ data-plugin-item="{{plugin['id']}}"
|
|||
>
|
||||
<!-- title and desc -->
|
||||
<div class="col-span-12" data-setting-header>
|
||||
<h5
|
||||
class="transition duration-300 ease-in-out ml-2 font-bold text-md uppercase dark:text-white/90 mb-0"
|
||||
>
|
||||
{{plugin['name']}} <span>{{plugin['version']}}</span>
|
||||
</h5>
|
||||
<div class="flex justify-start items-center">
|
||||
<h5
|
||||
class="transition duration-300 ease-in-out ml-2 font-bold text-md uppercase dark:text-white/90 mb-0"
|
||||
>
|
||||
{{plugin['name']}} <span>{{plugin['version']}}</span>
|
||||
</h5>
|
||||
{% if plugin['page']%}
|
||||
<a
|
||||
target="_blank"
|
||||
aria-label="plugin page link"
|
||||
class="hover:-translate-y-px mx-2"
|
||||
href="{{request.url_root}}plugins?plugin_id={{plugin['id']}}"
|
||||
>
|
||||
<svg
|
||||
class="h-5 w-5 fill-sky-500 dark dark:brightness-90"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
>
|
||||
<path
|
||||
d="M288 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h50.7L169.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L384 141.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32H288zM80 64C35.8 64 0 99.8 0 144V400c0 44.2 35.8 80 80 80H336c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32v80c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h80c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
{%endif%}
|
||||
</div>
|
||||
<div
|
||||
class="transition duration-300 ease-in-out dark:opacity-90 ml-2 text-sm mb-2 dark:text-gray-400"
|
||||
>
|
||||
|
|
@ -26,9 +47,10 @@ data-plugin-item="{{plugin['id']}}"
|
|||
<!-- end title and desc -->
|
||||
<div data-plugin-settings class="w-full grid grid-cols-12">
|
||||
<!-- plugin settings not multiple -->
|
||||
{% for setting, value in plugin["settings"].items() %}{% if setting != "IS_LOADING" and current_endpoint
|
||||
== "global-config" and value['context'] == "global" and not value['multiple'] or current_endpoint ==
|
||||
{% for setting, value in plugin["settings"].items() %}{% if setting not in ["IS_LOADING", "IS_DRAFT"] and current_endpoint
|
||||
== "global-config" and value['context'] == "global" and not value['multiple'] or setting != "IS_DRAFT" and current_endpoint ==
|
||||
"services" and value['context'] == "multisite" and not value['multiple'] %}
|
||||
|
||||
<div data-setting-container
|
||||
class="mx-0 sm:mx-4 my-2 col-span-12 md:mx-6 md:my-3 md:col-span-6 2xl:mx-6 2xl:my-3 2xl:col-span-4"
|
||||
id="form-edit-{{current_endpoint}}-{{ value["id"] }}">
|
||||
|
|
|
|||
|
|
@ -2,11 +2,8 @@ version: "3.5"
|
|||
|
||||
services:
|
||||
bw:
|
||||
# image: bunkerity/bunkerweb:1.5.6
|
||||
# pull_policy: never
|
||||
build:
|
||||
context: ../../..
|
||||
dockerfile: src/bw/Dockerfile
|
||||
image: bunkerity/bunkerweb:1.5.6
|
||||
pull_policy: never
|
||||
labels:
|
||||
- "bunkerweb.INSTANCE=yes"
|
||||
volumes:
|
||||
|
|
@ -40,11 +37,8 @@ services:
|
|||
ipv4_address: 192.168.0.2
|
||||
|
||||
bw-scheduler:
|
||||
# image: bunkerity/bunkerweb-scheduler:1.5.6
|
||||
# pull_policy: never
|
||||
build:
|
||||
context: ../../..
|
||||
dockerfile: src/scheduler/Dockerfile
|
||||
image: bunkerity/bunkerweb-scheduler:1.5.6
|
||||
pull_policy: never
|
||||
depends_on:
|
||||
- bw
|
||||
- bw-docker
|
||||
|
|
|
|||
|
|
@ -106,18 +106,6 @@ cleanup_stack () {
|
|||
if [[ $(sed '20!d' docker-compose.test.yml) = " CUSTOM_CONF_SERVICE_MODSEC_CRS_test_service_conf: 'SecRule REQUEST_FILENAME \"@rx ^/test\" \"id:10001,ctl:ruleRemoveByTag=attack-generic,ctl:ruleRemoveByTag=attack-protocol,nolog\"'" ]] ; then
|
||||
sed -i '20d' docker-compose.test.yml
|
||||
fi
|
||||
|
||||
if [ $end -eq 0 ] ; then
|
||||
echo "💾 Removing bw-docker network ..."
|
||||
|
||||
docker network rm bw-docker
|
||||
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "💾 Network removal failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
sudo rm -rf /etc/bunkerweb/plugins/*
|
||||
sudo sed -i 's@MULTISITE=.*$@MULTISITE=no@' /etc/bunkerweb/variables.env
|
||||
|
|
@ -152,6 +140,18 @@ cleanup_stack () {
|
|||
else
|
||||
docker compose down -v --remove-orphans
|
||||
fi
|
||||
|
||||
if [[ $end -eq 0 && $exit_code = 1 ]] && [ $manual = 0 ] ; then
|
||||
echo "💾 Removing bw-docker network ..."
|
||||
|
||||
docker network rm bw-docker
|
||||
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "💾 Network removal failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
sudo systemctl stop bunkerweb
|
||||
sudo truncate -s 0 /var/log/bunkerweb/error.log
|
||||
|
|
@ -476,6 +476,20 @@ do
|
|||
sed -i 's@bunkerity/bunkerweb:.*$@bunkerity/bunkerweb:'"$older_version"'@' docker-compose.yml
|
||||
sed -i 's@bunkerity/bunkerweb-scheduler:.*$@bunkerity/bunkerweb-scheduler:'"$older_version"'@' docker-compose.yml
|
||||
|
||||
docker pull bunkerity/bunkerweb:"$older_version"
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "💾 Pull for bunkerweb:$older_version failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker pull bunkerity/bunkerweb-scheduler:"$older_version"
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "💾 Pull for bunkerweb-scheduler:$older_version failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
starting_stack
|
||||
|
||||
waiting_stack
|
||||
|
|
|
|||
14
tests/core/letsencrypt/Dockerfile
Normal file
14
tests/core/letsencrypt/Dockerfile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
FROM python:3.12.1-alpine3.18@sha256:fb759579d60cfe1f70b110a27be95aaa7cf758d2fa21cf54fffb71c2ba3f8034
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
COPY requirements.txt .
|
||||
|
||||
RUN MAKEFLAGS="-j $(nproc)" pip install --no-cache-dir --require-hashes --no-deps -r requirements.txt && \
|
||||
rm -f requirements.txt
|
||||
|
||||
WORKDIR /opt/tests
|
||||
|
||||
COPY main.py .
|
||||
|
||||
ENTRYPOINT [ "python3", "main.py" ]
|
||||
17
tests/core/letsencrypt/docker-compose.test.yml
Normal file
17
tests/core/letsencrypt/docker-compose.test.yml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
version: "3.5"
|
||||
|
||||
services:
|
||||
tests:
|
||||
build: .
|
||||
environment:
|
||||
PYTHONUNBUFFERED: "1"
|
||||
AUTO_LETS_ENCRYPT: "no"
|
||||
extra_hosts:
|
||||
- "www.example.com:192.168.0.2"
|
||||
networks:
|
||||
bw-services:
|
||||
ipv4_address: 192.168.0.3
|
||||
|
||||
networks:
|
||||
bw-services:
|
||||
external: true
|
||||
74
tests/core/letsencrypt/docker-compose.yml
Normal file
74
tests/core/letsencrypt/docker-compose.yml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
version: "3.5"
|
||||
|
||||
services:
|
||||
bw:
|
||||
image: bunkerity/bunkerweb:1.5.6
|
||||
pull_policy: never
|
||||
labels:
|
||||
- "bunkerweb.INSTANCE=yes"
|
||||
volumes:
|
||||
- ./index.html:/var/www/html/index.html
|
||||
environment:
|
||||
SERVER_NAME: "www.example.com"
|
||||
API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24 192.168.0.3"
|
||||
HTTP_PORT: "80"
|
||||
HTTPS_PORT: "443"
|
||||
USE_BUNKERNET: "no"
|
||||
USE_BLACKLIST: "no"
|
||||
SEND_ANONYMOUS_REPORT: "no"
|
||||
LOG_LEVEL: "info"
|
||||
|
||||
# ? LETS_ENCRYPT settings
|
||||
AUTO_LETS_ENCRYPT: "no"
|
||||
USE_LETS_ENCRYPT_STAGING: "yes"
|
||||
CUSTOM_CONF_SERVER_HTTP_ready: |
|
||||
location /ready {
|
||||
default_type 'text/plain';
|
||||
rewrite_by_lua_block {
|
||||
ngx.print('ready')
|
||||
ngx.flush(true)
|
||||
ngx.exit(ngx.HTTP_OK)
|
||||
}
|
||||
}
|
||||
networks:
|
||||
bw-universe:
|
||||
bw-services:
|
||||
ipv4_address: 192.168.0.2
|
||||
|
||||
bw-scheduler:
|
||||
image: bunkerity/bunkerweb-scheduler:1.5.6
|
||||
pull_policy: never
|
||||
depends_on:
|
||||
- bw
|
||||
- bw-docker
|
||||
environment:
|
||||
DOCKER_HOST: "tcp://bw-docker:2375"
|
||||
LOG_LEVEL: "info"
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-docker
|
||||
|
||||
bw-docker:
|
||||
image: tecnativa/docker-socket-proxy:nightly
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
CONTAINERS: "1"
|
||||
networks:
|
||||
- bw-docker
|
||||
|
||||
networks:
|
||||
bw-universe:
|
||||
name: bw-universe
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.20.30.0/24
|
||||
bw-services:
|
||||
name: bw-services
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 192.168.0.0/24
|
||||
bw-docker:
|
||||
name: bw-docker
|
||||
0
tests/core/letsencrypt/index.html
Normal file
0
tests/core/letsencrypt/index.html
Normal file
97
tests/core/letsencrypt/main.py
Normal file
97
tests/core/letsencrypt/main.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
from contextlib import suppress
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from os import getenv
|
||||
from socket import create_connection
|
||||
from ssl import CERT_NONE, DER_cert_to_PEM_cert, create_default_context
|
||||
from requests import RequestException, get
|
||||
from traceback import format_exc
|
||||
from time import sleep
|
||||
|
||||
try:
|
||||
ready = False
|
||||
retries = 0
|
||||
while not ready:
|
||||
with suppress(RequestException):
|
||||
resp = get("http://www.example.com/ready", headers={"Host": "www.example.com"}, verify=False, allow_redirects=True)
|
||||
status_code = resp.status_code
|
||||
text = resp.text
|
||||
|
||||
if status_code >= 500:
|
||||
print("❌ An error occurred with the server, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
||||
ready = status_code < 400 and text == "ready"
|
||||
|
||||
if retries > 10:
|
||||
print("❌ The service took too long to be ready, exiting ...", flush=True)
|
||||
exit(1)
|
||||
elif not ready:
|
||||
retries += 1
|
||||
print("⚠️ Waiting for the service to be ready, retrying in 5s ...", flush=True)
|
||||
sleep(5)
|
||||
|
||||
auto_letsencrypt = getenv("AUTO_LETS_ENCRYPT", "no") == "yes"
|
||||
|
||||
print(
|
||||
"ℹ️ Sending a request to http://www.example.com ...",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
try:
|
||||
req = get("http://www.example.com", headers={"Host": "www.example.com"})
|
||||
req.raise_for_status()
|
||||
except RequestException:
|
||||
if not auto_letsencrypt:
|
||||
print(
|
||||
"❌ The request failed even though let's Encrypt isn't activated, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
if not auto_letsencrypt:
|
||||
print("✅ Let's Encrypt isn't activated, as expected ...", flush=True)
|
||||
exit(0)
|
||||
|
||||
print(
|
||||
"ℹ️ Sending a request to https://www.example.com ...",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
try:
|
||||
req = get("https://www.example.com", headers={"Host": "www.example.com"}, verify=False)
|
||||
req.raise_for_status()
|
||||
except RequestException as e:
|
||||
print(
|
||||
f"❌ The request failed even though let's Encrypt is activated:\n{e}\n exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
sleep(1)
|
||||
|
||||
context = create_default_context()
|
||||
context.check_hostname = False
|
||||
context.verify_mode = CERT_NONE
|
||||
with create_connection(("www.example.com", 443)) as sock:
|
||||
with context.wrap_socket(sock, server_hostname="www.example.com") as ssock:
|
||||
# Retrieve the SSL certificate
|
||||
pem_data = DER_cert_to_PEM_cert(ssock.getpeercert(True))
|
||||
|
||||
# Parse the PEM certificate
|
||||
certificate = x509.load_pem_x509_certificate(pem_data.encode(), default_backend())
|
||||
|
||||
common_name = certificate.subject.get_attributes_for_oid(x509.oid.NameOID.COMMON_NAME)[0].value
|
||||
if common_name != "www.example.org":
|
||||
print(
|
||||
f"❌ Let's Encrypt is activated and the Common Name (CN) is not www.example.org (fallback one) but {common_name}, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Let's Encrypt is activated and the Common Name (CN) is the expected one (fallback), as expected ...", flush=True)
|
||||
except SystemExit as e:
|
||||
exit(e.code)
|
||||
except:
|
||||
print(f"❌ Something went wrong, exiting ...\n{format_exc()}", flush=True)
|
||||
exit(1)
|
||||
8
tests/core/letsencrypt/ready.conf
Normal file
8
tests/core/letsencrypt/ready.conf
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
location /ready {
|
||||
default_type 'text/plain';
|
||||
rewrite_by_lua_block {
|
||||
ngx.print('ready')
|
||||
ngx.flush(true)
|
||||
ngx.exit(ngx.HTTP_OK)
|
||||
}
|
||||
}
|
||||
2
tests/core/letsencrypt/requirements.in
Normal file
2
tests/core/letsencrypt/requirements.in
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
cryptography==42.0.1
|
||||
requests==2.31.0
|
||||
263
tests/core/letsencrypt/requirements.txt
Normal file
263
tests/core/letsencrypt/requirements.txt
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.9
|
||||
# by the following command:
|
||||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
certifi==2023.11.17 \
|
||||
--hash=sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1 \
|
||||
--hash=sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474
|
||||
# via
|
||||
# requests
|
||||
# selenium
|
||||
cffi==1.16.0 \
|
||||
--hash=sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc \
|
||||
--hash=sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a \
|
||||
--hash=sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417 \
|
||||
--hash=sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab \
|
||||
--hash=sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520 \
|
||||
--hash=sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36 \
|
||||
--hash=sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743 \
|
||||
--hash=sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8 \
|
||||
--hash=sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed \
|
||||
--hash=sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684 \
|
||||
--hash=sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56 \
|
||||
--hash=sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324 \
|
||||
--hash=sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d \
|
||||
--hash=sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235 \
|
||||
--hash=sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e \
|
||||
--hash=sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088 \
|
||||
--hash=sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000 \
|
||||
--hash=sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7 \
|
||||
--hash=sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e \
|
||||
--hash=sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673 \
|
||||
--hash=sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c \
|
||||
--hash=sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe \
|
||||
--hash=sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2 \
|
||||
--hash=sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098 \
|
||||
--hash=sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8 \
|
||||
--hash=sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a \
|
||||
--hash=sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0 \
|
||||
--hash=sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b \
|
||||
--hash=sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896 \
|
||||
--hash=sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e \
|
||||
--hash=sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9 \
|
||||
--hash=sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2 \
|
||||
--hash=sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b \
|
||||
--hash=sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6 \
|
||||
--hash=sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404 \
|
||||
--hash=sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f \
|
||||
--hash=sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0 \
|
||||
--hash=sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4 \
|
||||
--hash=sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc \
|
||||
--hash=sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936 \
|
||||
--hash=sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba \
|
||||
--hash=sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872 \
|
||||
--hash=sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb \
|
||||
--hash=sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614 \
|
||||
--hash=sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1 \
|
||||
--hash=sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d \
|
||||
--hash=sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969 \
|
||||
--hash=sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b \
|
||||
--hash=sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4 \
|
||||
--hash=sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627 \
|
||||
--hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \
|
||||
--hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357
|
||||
# via cryptography
|
||||
charset-normalizer==3.3.2 \
|
||||
--hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \
|
||||
--hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \
|
||||
--hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \
|
||||
--hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \
|
||||
--hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \
|
||||
--hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \
|
||||
--hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \
|
||||
--hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \
|
||||
--hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \
|
||||
--hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \
|
||||
--hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \
|
||||
--hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \
|
||||
--hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \
|
||||
--hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \
|
||||
--hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \
|
||||
--hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \
|
||||
--hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \
|
||||
--hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \
|
||||
--hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \
|
||||
--hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \
|
||||
--hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \
|
||||
--hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \
|
||||
--hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \
|
||||
--hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \
|
||||
--hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \
|
||||
--hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \
|
||||
--hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \
|
||||
--hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \
|
||||
--hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \
|
||||
--hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \
|
||||
--hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \
|
||||
--hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \
|
||||
--hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \
|
||||
--hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \
|
||||
--hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \
|
||||
--hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \
|
||||
--hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \
|
||||
--hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \
|
||||
--hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \
|
||||
--hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \
|
||||
--hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \
|
||||
--hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \
|
||||
--hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \
|
||||
--hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \
|
||||
--hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \
|
||||
--hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \
|
||||
--hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \
|
||||
--hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \
|
||||
--hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \
|
||||
--hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \
|
||||
--hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \
|
||||
--hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \
|
||||
--hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \
|
||||
--hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \
|
||||
--hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \
|
||||
--hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \
|
||||
--hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \
|
||||
--hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \
|
||||
--hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \
|
||||
--hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \
|
||||
--hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \
|
||||
--hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \
|
||||
--hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \
|
||||
--hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \
|
||||
--hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \
|
||||
--hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \
|
||||
--hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \
|
||||
--hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \
|
||||
--hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \
|
||||
--hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \
|
||||
--hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \
|
||||
--hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \
|
||||
--hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \
|
||||
--hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \
|
||||
--hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \
|
||||
--hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \
|
||||
--hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \
|
||||
--hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \
|
||||
--hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \
|
||||
--hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \
|
||||
--hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \
|
||||
--hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \
|
||||
--hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \
|
||||
--hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \
|
||||
--hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \
|
||||
--hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \
|
||||
--hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \
|
||||
--hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \
|
||||
--hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \
|
||||
--hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561
|
||||
# via requests
|
||||
cryptography==42.0.1 \
|
||||
--hash=sha256:0b7cacc142260ada944de070ce810c3e2a438963ee3deb45aa26fd2cee94c9a4 \
|
||||
--hash=sha256:126e0ba3cc754b200a2fb88f67d66de0d9b9e94070c5bc548318c8dab6383cb6 \
|
||||
--hash=sha256:160fa08dfa6dca9cb8ad9bd84e080c0db6414ba5ad9a7470bc60fb154f60111e \
|
||||
--hash=sha256:16b9260d04a0bfc8952b00335ff54f471309d3eb9d7e8dbfe9b0bd9e26e67881 \
|
||||
--hash=sha256:25ec6e9e81de5d39f111a4114193dbd39167cc4bbd31c30471cebedc2a92c323 \
|
||||
--hash=sha256:265bdc693570b895eb641410b8fc9e8ddbce723a669236162b9d9cfb70bd8d77 \
|
||||
--hash=sha256:2dff7a32880a51321f5de7869ac9dde6b1fca00fc1fef89d60e93f215468e824 \
|
||||
--hash=sha256:2fe16624637d6e3e765530bc55caa786ff2cbca67371d306e5d0a72e7c3d0407 \
|
||||
--hash=sha256:32ea63ceeae870f1a62e87f9727359174089f7b4b01e4999750827bf10e15d60 \
|
||||
--hash=sha256:351db02c1938c8e6b1fee8a78d6b15c5ccceca7a36b5ce48390479143da3b411 \
|
||||
--hash=sha256:430100abed6d3652208ae1dd410c8396213baee2e01a003a4449357db7dc9e14 \
|
||||
--hash=sha256:4d84673c012aa698555d4710dcfe5f8a0ad76ea9dde8ef803128cc669640a2e0 \
|
||||
--hash=sha256:50aecd93676bcca78379604ed664c45da82bc1241ffb6f97f6b7392ed5bc6f04 \
|
||||
--hash=sha256:6ac8924085ed8287545cba89dc472fc224c10cc634cdf2c3e2866fe868108e77 \
|
||||
--hash=sha256:6bfd823b336fdcd8e06285ae8883d3d2624d3bdef312a0e2ef905f332f8e9302 \
|
||||
--hash=sha256:727387886c9c8de927c360a396c5edcb9340d9e960cda145fca75bdafdabd24c \
|
||||
--hash=sha256:7911586fc69d06cd0ab3f874a169433db1bc2f0e40988661408ac06c4527a986 \
|
||||
--hash=sha256:802d6f83233cf9696b59b09eb067e6b4d5ae40942feeb8e13b213c8fad47f1aa \
|
||||
--hash=sha256:8d7efb6bf427d2add2f40b6e1e8e476c17508fa8907234775214b153e69c2e11 \
|
||||
--hash=sha256:9544492e8024f29919eac2117edd8c950165e74eb551a22c53f6fdf6ba5f4cb8 \
|
||||
--hash=sha256:95d900d19a370ae36087cc728e6e7be9c964ffd8cbcb517fd1efb9c9284a6abc \
|
||||
--hash=sha256:9d61fcdf37647765086030d81872488e4cb3fafe1d2dda1d487875c3709c0a49 \
|
||||
--hash=sha256:ab6b302d51fbb1dd339abc6f139a480de14d49d50f65fdc7dff782aa8631d035 \
|
||||
--hash=sha256:b512f33c6ab195852595187af5440d01bb5f8dd57cb7a91e1e009a17f1b7ebca \
|
||||
--hash=sha256:cb2861a9364fa27d24832c718150fdbf9ce6781d7dc246a516435f57cfa31fe7 \
|
||||
--hash=sha256:d3594947d2507d4ef7a180a7f49a6db41f75fb874c2fd0e94f36b89bfd678bf2 \
|
||||
--hash=sha256:d3902c779a92151f134f68e555dd0b17c658e13429f270d8a847399b99235a3f \
|
||||
--hash=sha256:d50718dd574a49d3ef3f7ef7ece66ef281b527951eb2267ce570425459f6a404 \
|
||||
--hash=sha256:e5edf189431b4d51f5c6fb4a95084a75cef6b4646c934eb6e32304fc720e1453 \
|
||||
--hash=sha256:e6edc3a568667daf7d349d7e820783426ee4f1c0feab86c29bd1d6fe2755e009 \
|
||||
--hash=sha256:ed1b2130f5456a09a134cc505a17fc2830a1a48ed53efd37dcc904a23d7b82fa \
|
||||
--hash=sha256:fd33f53809bb363cf126bebe7a99d97735988d9b0131a2be59fbf83e1259a5b7
|
||||
# via -r requirements.in
|
||||
exceptiongroup==1.2.0 \
|
||||
--hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \
|
||||
--hash=sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68
|
||||
# via
|
||||
# trio
|
||||
# trio-websocket
|
||||
h11==0.14.0 \
|
||||
--hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \
|
||||
--hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761
|
||||
# via wsproto
|
||||
idna==3.6 \
|
||||
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
|
||||
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
|
||||
# via
|
||||
# requests
|
||||
# trio
|
||||
outcome==1.3.0.post0 \
|
||||
--hash=sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8 \
|
||||
--hash=sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b
|
||||
# via trio
|
||||
pycparser==2.21 \
|
||||
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
|
||||
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
|
||||
# via cffi
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via urllib3
|
||||
requests==2.31.0 \
|
||||
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
|
||||
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
|
||||
# via -r requirements.in
|
||||
selenium==4.16.0 \
|
||||
--hash=sha256:aec71f4e6ed6cb3ec25c9c1b5ed56ae31b6da0a7f17474c7566d303f84e6219f \
|
||||
--hash=sha256:b2e987a445306151f7be0e6dfe2aa72a479c2ac6a91b9d5ef2d6dd4e49ad0435
|
||||
# via -r requirements.in
|
||||
sniffio==1.3.0 \
|
||||
--hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \
|
||||
--hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384
|
||||
# via trio
|
||||
sortedcontainers==2.4.0 \
|
||||
--hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \
|
||||
--hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0
|
||||
# via trio
|
||||
trio==0.24.0 \
|
||||
--hash=sha256:c3bd3a4e3e3025cd9a2241eae75637c43fe0b9e88b4c97b9161a55b9e54cd72c \
|
||||
--hash=sha256:ffa09a74a6bf81b84f8613909fb0beaee84757450183a7a2e0b47b455c0cac5d
|
||||
# via
|
||||
# selenium
|
||||
# trio-websocket
|
||||
trio-websocket==0.11.1 \
|
||||
--hash=sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f \
|
||||
--hash=sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638
|
||||
# via selenium
|
||||
urllib3==2.1.0 \
|
||||
--hash=sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3 \
|
||||
--hash=sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54
|
||||
# via
|
||||
# requests
|
||||
# selenium
|
||||
wsproto==1.2.0 \
|
||||
--hash=sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065 \
|
||||
--hash=sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736
|
||||
# via trio-websocket
|
||||
216
tests/core/letsencrypt/test.sh
Executable file
216
tests/core/letsencrypt/test.sh
Executable file
|
|
@ -0,0 +1,216 @@
|
|||
#!/bin/bash
|
||||
|
||||
integration=$1
|
||||
|
||||
if [ -z "$integration" ] ; then
|
||||
echo "🔒 Please provide an integration name as argument ❌"
|
||||
exit 1
|
||||
elif [ "$integration" != "docker" ] && [ "$integration" != "linux" ] ; then
|
||||
echo "🔒 Integration \"$integration\" is not supported ❌"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔒 Building letsencrypt stack for integration \"$integration\" ..."
|
||||
|
||||
# Starting stack
|
||||
if [ "$integration" == "docker" ] ; then
|
||||
docker compose pull bw-docker
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🔒 Pull failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
docker compose -f docker-compose.test.yml build
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🔒 Build failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
sudo systemctl stop bunkerweb
|
||||
echo "AUTO_LETS_ENCRYPT=no" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
echo "USE_LETS_ENCRYPT_STAGING=yes" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
sudo touch /var/www/html/index.html
|
||||
sudo cp ready.conf /etc/bunkerweb/configs/server-http
|
||||
fi
|
||||
|
||||
manual=0
|
||||
end=0
|
||||
cleanup_stack () {
|
||||
exit_code=$?
|
||||
if [[ $end -eq 1 || $exit_code = 1 ]] || [[ $end -eq 0 && $exit_code = 0 ]] && [ $manual = 0 ] ; then
|
||||
if [ "$integration" == "docker" ] ; then
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@AUTO_LETS_ENCRYPT: "yes"@AUTO_LETS_ENCRYPT: "no"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@USE_LETS_ENCRYPT_STAGING: "no"@USE_LETS_ENCRYPT_STAGING: "yes"@' {} \;
|
||||
else
|
||||
sudo sed -i '$ d' /etc/bunkerweb/variables.env
|
||||
sudo sed -i '$ d' /etc/bunkerweb/variables.env
|
||||
unset AUTO_LETS_ENCRYPT
|
||||
fi
|
||||
if [[ $end -eq 1 && $exit_code = 0 ]] ; then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "🔒 Cleaning up current stack ..."
|
||||
|
||||
if [ "$integration" == "docker" ] ; then
|
||||
docker compose down -v --remove-orphans
|
||||
else
|
||||
sudo systemctl stop bunkerweb
|
||||
sudo truncate -s 0 /var/log/bunkerweb/error.log
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🔒 Cleanup failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔒 Cleaning up current stack done ✅"
|
||||
}
|
||||
|
||||
# Cleanup stack on exit
|
||||
trap cleanup_stack EXIT
|
||||
|
||||
for test in "deactivated" "fallback"
|
||||
do
|
||||
if [ "$test" = "deactivated" ] ; then
|
||||
echo "🔒 Running tests without letsencrypt ..."
|
||||
elif [ "$test" = "fallback" ] ; then
|
||||
echo "🔒 Running tests with letsencrypt activated and fallback to default cert ..."
|
||||
if [ "$integration" == "docker" ] ; then
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@AUTO_LETS_ENCRYPT: "no"@AUTO_LETS_ENCRYPT: "yes"@' {} \;
|
||||
else
|
||||
sudo sed -i 's@AUTO_LETS_ENCRYPT=no$@AUTO_LETS_ENCRYPT=yes@' /etc/bunkerweb/variables.env
|
||||
export AUTO_LETS_ENCRYPT="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "🔒 Starting stack ..."
|
||||
if [ "$integration" == "docker" ] ; then
|
||||
docker compose up -d
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🔒 Up failed, retrying ... ⚠️"
|
||||
manual=1
|
||||
cleanup_stack
|
||||
manual=0
|
||||
docker compose up -d
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🔒 Up failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
sudo systemctl start bunkerweb
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🔒 Start failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if stack is healthy
|
||||
echo "🔒 Waiting for stack to be healthy ..."
|
||||
i=0
|
||||
if [ "$integration" == "docker" ] ; then
|
||||
while [ $i -lt 120 ] ; do
|
||||
containers=("letsencrypt-bw-1" "letsencrypt-bw-scheduler-1")
|
||||
healthy="true"
|
||||
for container in "${containers[@]}" ; do
|
||||
check="$(docker inspect --format "{{json .State.Health }}" "$container" | grep "healthy")"
|
||||
if [ "$check" = "" ] ; then
|
||||
healthy="false"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$healthy" = "true" ] ; then
|
||||
echo "🔒 Docker stack is healthy ✅"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i+1))
|
||||
done
|
||||
if [ $i -ge 120 ] ; then
|
||||
docker compose logs
|
||||
echo "🔒 Docker stack is not healthy ❌"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
healthy="false"
|
||||
retries=0
|
||||
while [[ $healthy = "false" && $retries -lt 5 ]] ; do
|
||||
while [ $i -lt 120 ] ; do
|
||||
if sudo grep -q "BunkerWeb is ready" "/var/log/bunkerweb/error.log" ; then
|
||||
echo "🔒 Linux stack is healthy ✅"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i+1))
|
||||
done
|
||||
if [ $i -ge 120 ] ; then
|
||||
sudo journalctl -u bunkerweb --no-pager
|
||||
echo "🛡️ Showing BunkerWeb error logs ..."
|
||||
sudo cat /var/log/bunkerweb/error.log
|
||||
echo "🛡️ Showing BunkerWeb access logs ..."
|
||||
sudo cat /var/log/bunkerweb/access.log
|
||||
echo "🔒 Linux stack is not healthy ❌"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if sudo journalctl -u bunkerweb --no-pager | grep -q "SYSTEMCTL - ❌ " ; then
|
||||
echo "🔒 ⚠ Linux stack got an issue, restarting ..."
|
||||
sudo journalctl --rotate
|
||||
sudo journalctl --vacuum-time=1s
|
||||
manual=1
|
||||
cleanup_stack
|
||||
manual=0
|
||||
sudo systemctl start bunkerweb
|
||||
retries=$((retries+1))
|
||||
else
|
||||
healthy="true"
|
||||
fi
|
||||
done
|
||||
if [ "$retries" -ge 5 ] ; then
|
||||
echo "🔒 Linux stack could not be healthy ❌"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start tests
|
||||
|
||||
if [ "$integration" == "docker" ] ; then
|
||||
docker compose -f docker-compose.test.yml up --abort-on-container-exit --exit-code-from tests
|
||||
else
|
||||
python3 main.py
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🔒 Test \"$test\" failed ❌"
|
||||
echo "🛡️ Showing BunkerWeb and BunkerWeb Scheduler logs ..."
|
||||
if [ "$integration" == "docker" ] ; then
|
||||
docker compose logs bw bw-scheduler
|
||||
else
|
||||
sudo journalctl -u bunkerweb --no-pager
|
||||
echo "🛡️ Showing BunkerWeb error logs ..."
|
||||
sudo cat /var/log/bunkerweb/error.log
|
||||
echo "🛡️ Showing BunkerWeb access logs ..."
|
||||
sudo cat /var/log/bunkerweb/access.log
|
||||
fi
|
||||
exit 1
|
||||
else
|
||||
echo "🔒 Test \"$test\" succeeded ✅"
|
||||
fi
|
||||
|
||||
manual=1
|
||||
cleanup_stack
|
||||
manual=0
|
||||
|
||||
echo " "
|
||||
done
|
||||
|
||||
end=1
|
||||
echo "🔒 Tests are done ! ✅"
|
||||
|
|
@ -147,7 +147,7 @@ def access_page(
|
|||
|
||||
title = driver_wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div/header/div/nav/h6")))
|
||||
|
||||
if title.text != name.replace(" ", "_").title():
|
||||
if title.text != name.title():
|
||||
print(f"Didn't get redirected to {name} page, exiting ...", flush=True)
|
||||
exit(1)
|
||||
except TimeoutException:
|
||||
|
|
@ -538,17 +538,11 @@ with driver_func() as driver:
|
|||
|
||||
print("Checking the services page ...", flush=True)
|
||||
|
||||
try:
|
||||
service = safe_get_element(driver, By.XPATH, "//div[@data-services-service='']", error=True)
|
||||
except TimeoutException:
|
||||
print("Services not found, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
||||
if service.find_element(By.TAG_NAME, "h5").text.strip() != "www.example.com":
|
||||
if safe_get_element(driver, By.XPATH, "//div[@data-services-service='www.example.com']//h5").text.strip() != "www.example.com":
|
||||
print("The service is not present, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
||||
if service.find_element(By.TAG_NAME, "h6").text.strip() != "ui":
|
||||
if safe_get_element(driver, By.XPATH, "//div[@data-services-service='www.example.com']//h6").text.strip() != "ui":
|
||||
print(
|
||||
"The service should have been created by the ui, exiting ...",
|
||||
flush=True,
|
||||
|
|
@ -559,7 +553,7 @@ with driver_func() as driver:
|
|||
|
||||
assert_button_click(
|
||||
driver,
|
||||
service.find_element(By.XPATH, ".//button[@data-services-action='edit']"),
|
||||
"//div[@data-services-service='www.example.com']//button[@data-services-action='edit']",
|
||||
)
|
||||
|
||||
try:
|
||||
|
|
@ -637,15 +631,9 @@ with driver_func() as driver:
|
|||
flush=True,
|
||||
)
|
||||
|
||||
try:
|
||||
service = safe_get_element(driver, By.XPATH, "//div[@data-services-service='']", error=True)
|
||||
except TimeoutException:
|
||||
print("Services not found, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
||||
assert_button_click(
|
||||
driver,
|
||||
service.find_element(By.XPATH, ".//button[@data-services-action='edit']"),
|
||||
"//div[@data-services-service='www.example.com']//button[@data-services-action='edit']",
|
||||
)
|
||||
|
||||
modal = safe_get_element(driver, By.XPATH, "//div[@data-services-modal='']")
|
||||
|
|
@ -717,13 +705,7 @@ with driver_func() as driver:
|
|||
sleep(5)
|
||||
|
||||
try:
|
||||
services = safe_get_element(
|
||||
driver,
|
||||
By.XPATH,
|
||||
"//div[@data-services-service='']",
|
||||
multiple=True,
|
||||
error=True,
|
||||
)
|
||||
services = safe_get_element(driver, By.XPATH, "//div[@data-services-service]", multiple=True, error=True)
|
||||
except TimeoutException:
|
||||
print("Services not found, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
|
@ -732,13 +714,11 @@ with driver_func() as driver:
|
|||
print("The service hasn't been created, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
||||
service = services[0]
|
||||
|
||||
if service.find_element(By.TAG_NAME, "h5").text.strip() != "app1.example.com":
|
||||
if safe_get_element(driver, By.XPATH, "//div[@data-services-service='app1.example.com']//h5").text.strip() != "app1.example.com":
|
||||
print('The service "app1.example.com" is not present, exiting ...', flush=True)
|
||||
exit(1)
|
||||
|
||||
if service.find_element(By.TAG_NAME, "h6").text.strip() != "ui":
|
||||
if safe_get_element(driver, By.XPATH, "//div[@data-services-service='app1.example.com']//h6").text.strip() != "ui":
|
||||
print(
|
||||
"The service should have been created by the ui, exiting ...",
|
||||
flush=True,
|
||||
|
|
@ -843,13 +823,7 @@ with driver_func() as driver:
|
|||
sleep(5)
|
||||
|
||||
try:
|
||||
services = safe_get_element(
|
||||
driver,
|
||||
By.XPATH,
|
||||
"//div[@data-services-service='']",
|
||||
multiple=True,
|
||||
error=True,
|
||||
)
|
||||
services = safe_get_element(driver, By.XPATH, "//div[@data-services-service]", multiple=True, error=True)
|
||||
except TimeoutException:
|
||||
print("Services not found, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
|
@ -858,13 +832,11 @@ with driver_func() as driver:
|
|||
print("The service hasn't been created, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
||||
service = services[1]
|
||||
|
||||
if service.find_element(By.TAG_NAME, "h5").text.strip() != "app2.example.com":
|
||||
if safe_get_element(driver, By.XPATH, "//div[@data-services-service='app2.example.com']//h5").text.strip() != "app2.example.com":
|
||||
print('The service "app2.example.com" is not present, exiting ...', flush=True)
|
||||
exit(1)
|
||||
|
||||
if service.find_element(By.TAG_NAME, "h6").text.strip() != "ui":
|
||||
if safe_get_element(driver, By.XPATH, "//div[@data-services-service='app2.example.com']//h6").text.strip() != "ui":
|
||||
print(
|
||||
"The service should have been created by the ui, exiting ...",
|
||||
flush=True,
|
||||
|
|
@ -972,13 +944,7 @@ with driver_func() as driver:
|
|||
)
|
||||
|
||||
try:
|
||||
services = safe_get_element(
|
||||
driver,
|
||||
By.XPATH,
|
||||
"//div[@data-services-service='']",
|
||||
multiple=True,
|
||||
error=True,
|
||||
)
|
||||
services = safe_get_element(driver, By.XPATH, "//div[@data-services-service='']", multiple=True, error=True)
|
||||
except TimeoutException:
|
||||
print("Services not found, exiting ...", flush=True)
|
||||
exit(1)
|
||||
|
|
|
|||
Loading…
Reference in a new issue