mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Merge pull request #834 from bunkerity/dev
Merge branch "dev" into branch "ui"
This commit is contained in:
commit
bba9879047
35 changed files with 484 additions and 253 deletions
2
.github/workflows/container-build.yml
vendored
2
.github/workflows/container-build.yml
vendored
|
|
@ -115,7 +115,7 @@ jobs:
|
|||
# Check OS vulnerabilities
|
||||
- name: Check OS vulnerabilities
|
||||
if: ${{ inputs.CACHE_SUFFIX != 'arm' }}
|
||||
uses: aquasecurity/trivy-action@91713af97dc80187565512baba96e4364e983601 # master
|
||||
uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca # v0.16.1
|
||||
with:
|
||||
vuln-type: os
|
||||
skip-dirs: /root/.cargo
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
- [MISC] Fallback to default HTTPS certificate to prevent errors
|
||||
- [MISC] Various internal improvements in LUA code
|
||||
- [MISC] Updated Python Docker image to 3.12.1-alpine3.18 in Dockerfiles
|
||||
- [MISC] Switch gunicorn worker_class back to gevent in web UI
|
||||
- [DEPS] Updated ModSecurity to v3.0.11
|
||||
|
||||
## v1.5.4 - 2023/12/04
|
||||
|
|
|
|||
|
|
@ -425,9 +425,9 @@ pygments==2.17.2 \
|
|||
--hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \
|
||||
--hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367
|
||||
# via mkdocs-material
|
||||
pymdown-extensions==10.6 \
|
||||
--hash=sha256:561eb3a5f3c3c2512952a4d6f5b311aa124b7147bd54a3ea0f36ce030c7e3dd9 \
|
||||
--hash=sha256:e4531379e0d74b329ff264217ef5b8b1a37bed3afe36f98001b74ecff52215c0
|
||||
pymdown-extensions==10.7 \
|
||||
--hash=sha256:6ca215bc57bc12bf32b414887a68b810637d039124ed9b2e5bd3325cbb2c050c \
|
||||
--hash=sha256:c0d64d5cf62566f59e6b2b690a4095c931107c250a8c8e1351c1de5f6b036deb
|
||||
# via mkdocs-material
|
||||
pyparsing==3.1.1 \
|
||||
--hash=sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb \
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ copyright: Copyright © <script>document.write(new Date().getFullYear())</sc
|
|||
|
||||
nav:
|
||||
- Introduction: 'index.md'
|
||||
- Migrating from 1.4.X: 'migrating.md'
|
||||
- Migrating: 'migrating.md'
|
||||
- Concepts: 'concepts.md'
|
||||
- Integrations: 'integrations.md'
|
||||
- Quickstart guide: 'quickstart-guide.md'
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ function cachestore:get(key)
|
|||
local callback = function(key, cs)
|
||||
-- Connect to redis
|
||||
-- luacheck: ignore 431
|
||||
local ok, err, _ = cs:connect()
|
||||
local ok, err, _ = cs:connect(true)
|
||||
if not ok then
|
||||
return nil, "can't connect to redis : " .. err, nil
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ local logger = clogger:new("CLUSTERSTORE")
|
|||
local get_variable = utils.get_variable
|
||||
local is_cosocket_available = utils.is_cosocket_available
|
||||
local ERR = ngx.ERR
|
||||
local INFO = ngx.INFO
|
||||
local tonumber = tonumber
|
||||
local tostring = tostring
|
||||
local random = math.random
|
||||
|
||||
function clusterstore:initialize(pool)
|
||||
|
|
@ -112,7 +114,7 @@ function clusterstore:connect(readonly)
|
|||
return false, "error while connecting to sentinels : " .. err
|
||||
end
|
||||
if readonly then
|
||||
redis_clients, err = rs.get_slaves(redis_sentinel, self.options.master_name)
|
||||
local redis_clients, err = rs.get_slaves(redis_sentinel, self.options.master_name)
|
||||
if redis_clients then
|
||||
redis_client = redis_clients[random(#redis_clients)]
|
||||
else
|
||||
|
|
@ -130,7 +132,13 @@ function clusterstore:connect(readonly)
|
|||
return false, "error while getting redis client : " .. err
|
||||
end
|
||||
-- Everything went well
|
||||
return true, "success", self.redis_client:get_reused_times()
|
||||
local times, err = self.redis_client:get_reused_times()
|
||||
if times == nil then
|
||||
self:close()
|
||||
return false, "error while getting reused times : " .. err
|
||||
end
|
||||
logger:log(INFO, "redis reused times = " .. tostring(times))
|
||||
return true, "success", times
|
||||
end
|
||||
|
||||
function clusterstore:close()
|
||||
|
|
|
|||
|
|
@ -164,12 +164,12 @@ helpers.call_plugin = function(plugin, method)
|
|||
return true, ret
|
||||
end
|
||||
|
||||
helpers.fill_ctx = function()
|
||||
helpers.fill_ctx = function(no_ref)
|
||||
-- Return errors as table
|
||||
local errors = {}
|
||||
-- Try to load saved ctx
|
||||
local request = get_request()
|
||||
if request then
|
||||
if no_ref ~= true and request then
|
||||
apply_ref()
|
||||
end
|
||||
local ctx = ngx.ctx
|
||||
|
|
|
|||
|
|
@ -637,7 +637,7 @@ utils.is_banned = function(ip)
|
|||
end
|
||||
-- Connect
|
||||
local clusterstore = require "bunkerweb.clusterstore":new()
|
||||
local ok, err = clusterstore:connect()
|
||||
local ok, err = clusterstore:connect(true)
|
||||
if not ok then
|
||||
return nil, "can't connect to redis server : " .. err
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ from sys import path as sys_path
|
|||
from typing import Tuple
|
||||
|
||||
|
||||
if join(sep, "usr", "share", "bunkerweb", "utils") not in sys_path:
|
||||
sys_path.append(join(sep, "usr", "share", "bunkerweb", "utils"))
|
||||
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("utils",), ("db",))]:
|
||||
if deps_path not in sys_path:
|
||||
sys_path.append(deps_path)
|
||||
|
||||
from API import API # type: ignore
|
||||
from ApiCaller import ApiCaller # type: ignore
|
||||
from Database import Database # type: ignore
|
||||
from logger import setup_logger # type: ignore
|
||||
|
||||
|
||||
|
|
@ -40,21 +42,13 @@ def format_remaining_time(seconds):
|
|||
class CLI(ApiCaller):
|
||||
def __init__(self):
|
||||
self.__logger = setup_logger("CLI", getenv("LOG_LEVEL", "INFO"))
|
||||
db_path = Path(sep, "usr", "share", "bunkerweb", "db")
|
||||
variables_path = Path(sep, "etc", "nginx", "variables.env")
|
||||
self.__variables = {}
|
||||
if variables_path.is_file():
|
||||
self.__variables = dotenv_values(variables_path)
|
||||
|
||||
if not db_path.is_dir():
|
||||
self.__variables = dotenv_values(join(sep, "etc", "nginx", "variables.env"))
|
||||
else:
|
||||
if str(db_path) not in sys_path:
|
||||
sys_path.append(str(db_path))
|
||||
|
||||
from Database import Database # type: ignore
|
||||
|
||||
db = Database(
|
||||
self.__logger,
|
||||
sqlalchemy_string=getenv("DATABASE_URI", None),
|
||||
)
|
||||
self.__variables = db.get_config()
|
||||
db = Database(self.__logger, sqlalchemy_string=self.__variables.get("DATABASE_URI", None))
|
||||
self.__variables = db.get_config()
|
||||
|
||||
self.__integration = self.__detect_integration()
|
||||
self.__use_redis = self.__variables.get("USE_REDIS", "no") == "yes"
|
||||
|
|
@ -102,12 +96,7 @@ class CLI(ApiCaller):
|
|||
self.__logger.error("USE_REDIS is set to yes but REDIS_HOST is not set, disabling redis")
|
||||
self.__use_redis = False
|
||||
|
||||
if not db_path.is_dir() or self.__integration not in (
|
||||
"kubernetes",
|
||||
"swarm",
|
||||
"autoconf",
|
||||
):
|
||||
# Docker & Linux case
|
||||
if self.__integration == "linux":
|
||||
super().__init__(
|
||||
[
|
||||
API(
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ server {
|
|||
|
||||
-- Fill ctx
|
||||
logger:log(INFO, "filling ngx.ctx ...")
|
||||
local ok, ret, errors, ctx = fill_ctx()
|
||||
local ok, ret, errors, ctx = fill_ctx(true)
|
||||
if not ok then
|
||||
logger:log(ERR, "fill_ctx() failed : " .. ret)
|
||||
elseif errors then
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ function redis:init_worker()
|
|||
return self:ret(true, "init_worker not needed")
|
||||
end
|
||||
-- Check redis connection
|
||||
local ok, err = self.clusterstore:connect()
|
||||
local ok, err = self.clusterstore:connect(true)
|
||||
if not ok then
|
||||
return self:ret(false, "redis connect error : " .. err)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -61,6 +61,12 @@ function sessions:init()
|
|||
["REDIS_TIMEOUT"] = "",
|
||||
["REDIS_KEEPALIVE_IDLE"] = "",
|
||||
["REDIS_KEEPALIVE_POOL"] = "",
|
||||
["REDIS_USERNAME"] = "",
|
||||
["REDIS_PASSWORD"] = "",
|
||||
["REDIS_SENTINEL_HOSTS"] = "",
|
||||
["REDIS_SENTINEL_USERNAME"] = "",
|
||||
["REDIS_SENTINEL_PASSWORD"] = "",
|
||||
["REDIS_SENTINEL_MASTER"] = ""
|
||||
}
|
||||
for k, _ in pairs(redis_vars) do
|
||||
local value, err = get_variable(k, false)
|
||||
|
|
@ -105,6 +111,8 @@ function sessions:init()
|
|||
config.storage = "redis"
|
||||
config.redis = {
|
||||
prefix = "sessions_",
|
||||
username = redis_vars["REDIS_USERNAME"],
|
||||
password = redis_vars["REDIS_PASSWORD"],
|
||||
connect_timeout = tonumber(redis_vars["REDIS_TIMEOUT"]),
|
||||
send_timeout = tonumber(redis_vars["REDIS_TIMEOUT"]),
|
||||
read_timeout = tonumber(redis_vars["REDIS_TIMEOUT"]),
|
||||
|
|
@ -112,10 +120,27 @@ function sessions:init()
|
|||
pool = "bw-redis",
|
||||
pool_size = tonumber(redis_vars["REDIS_KEEPALIVE_POOL"]),
|
||||
ssl = redis_vars["REDIS_SSL"] == "yes",
|
||||
host = redis_vars["REDIS_HOST"],
|
||||
port = tonumber(redis_vars["REDIS_PORT"]),
|
||||
database = tonumber(redis_vars["REDIS_DATABASE"]),
|
||||
database = tonumber(redis_vars["REDIS_DATABASE"])
|
||||
}
|
||||
if redis_vars["REDIS_SENTINEL_HOSTS"] ~= "" then
|
||||
config.redis.master = redis_vars["REDIS_SENTINEL_MASTER"]
|
||||
config.redis.role = "master"
|
||||
config.redis.sentinel_username = redis_vars["REDIS_SENTINEL_USERNAME"]
|
||||
config.redis.sentinel_password = redis_vars["REDIS_SENTINEL_PASSWORD"]
|
||||
config.redis.sentinels = {}
|
||||
for sentinel_host in redis_vars["REDIS_SENTINEL_HOSTS"]:gmatch("%S+") do
|
||||
local shost, sport = sentinel_host:match("([^:]+):?(%d*)")
|
||||
if sport == "" then
|
||||
sport = 26379
|
||||
else
|
||||
sport = tonumber(sport)
|
||||
end
|
||||
table.insert(config.redis.sentinels, {host = shost, port = sport})
|
||||
end
|
||||
else
|
||||
config.redis.host = redis_vars["REDIS_HOST"]
|
||||
config.redis.port = tonumber(redis_vars["REDIS_PORT"])
|
||||
end
|
||||
end
|
||||
session_init(config)
|
||||
return self:ret(true, "sessions init successful")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
cryptography==41.0.7
|
||||
psycopg2-binary==2.9.9
|
||||
PyMySQL==1.1.0
|
||||
sqlalchemy==2.0.24
|
||||
sqlalchemy==2.0.25
|
||||
|
|
|
|||
|
|
@ -225,56 +225,56 @@ pymysql==1.1.0 \
|
|||
--hash=sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96 \
|
||||
--hash=sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7
|
||||
# via -r requirements.in
|
||||
sqlalchemy==2.0.24 \
|
||||
--hash=sha256:00d76fe5d7cdb5d84d625ce002ce29fefba0bfd98e212ae66793fed30af73931 \
|
||||
--hash=sha256:07cc423892f2ceda9ae1daa28c0355757f362ecc7505b1ab1a3d5d8dc1c44ac6 \
|
||||
--hash=sha256:0bb7cedcddffca98c40bb0becd3423e293d1fef442b869da40843d751785beb3 \
|
||||
--hash=sha256:1ca7903d5e7db791a355b579c690684fac6304478b68efdc7f2ebdcfe770d8d7 \
|
||||
--hash=sha256:1d9b3fd5eca3c0b137a5e0e468e24ca544ed8ca4783e0e55341b7ed2807518ee \
|
||||
--hash=sha256:2587e108463cc2e5b45a896b2e7cc8659a517038026922a758bde009271aed11 \
|
||||
--hash=sha256:29e51f848f843bbd75d74ae64ab1ab06302cb1dccd4549d1f5afe6b4a946edb2 \
|
||||
--hash=sha256:2a479aa1ab199178ff1956b09ca8a0693e70f9c762875d69292d37049ffd0d8f \
|
||||
--hash=sha256:37e89d965b52e8b20571b5d44f26e2124b26ab63758bf1b7598a0e38fb2c4005 \
|
||||
--hash=sha256:38732884eabc64982a09a846bacf085596ff2371e4e41d20c0734f7e50525d01 \
|
||||
--hash=sha256:396f05c552f7fa30a129497c41bef5b4d1423f9af8fe4df0c3dcd38f3e3b9a14 \
|
||||
--hash=sha256:4a1d4856861ba9e73bac05030cec5852eabfa9ef4af8e56c19d92de80d46fc34 \
|
||||
--hash=sha256:56a0e90a959e18ac5f18c80d0cad9e90cb09322764f536e8a637426afb1cae2f \
|
||||
--hash=sha256:57ef6f2cb8b09a042d0dbeaa46a30f2df5dd1e1eb889ba258b0d5d7d6011b81c \
|
||||
--hash=sha256:5f801d85ba4753d4ed97181d003e5d3fa330ac7c4587d131f61d7f968f416862 \
|
||||
--hash=sha256:6db686a1d9f183c639f7e06a2656af25d4ed438eda581de135d15569f16ace33 \
|
||||
--hash=sha256:6db97656fd3fe3f7e5b077f12fa6adb5feb6e0b567a3e99f47ecf5f7ea0a09e3 \
|
||||
--hash=sha256:6f5e75de91c754365c098ac08c13fdb267577ce954fa239dd49228b573ca88d7 \
|
||||
--hash=sha256:7a6209e689d0ff206c40032b6418e3cfcfc5af044b3f66e381d7f1ae301544b4 \
|
||||
--hash=sha256:7ae5d44517fe81079ce75cf10f96978284a6db2642c5932a69c82dbae09f009a \
|
||||
--hash=sha256:83fa6df0e035689df89ff77a46bf8738696785d3156c2c61494acdcddc75c69d \
|
||||
--hash=sha256:8f358f5cfce04417b6ff738748ca4806fe3d3ae8040fb4e6a0c9a6973ccf9b6e \
|
||||
--hash=sha256:9036ebfd934813990c5b9f71f297e77ed4963720db7d7ceec5a3fdb7cd2ef6ce \
|
||||
--hash=sha256:95bae3d38f8808d79072da25d5e5a6095f36fe1f9d6c614dd72c59ca8397c7c0 \
|
||||
--hash=sha256:9aaaaa846b10dfbe1bda71079d0e31a7e2cebedda9409fa7dba3dfed1ae803e8 \
|
||||
--hash=sha256:9b8d0e8578e7f853f45f4512b5c920f6a546cd4bed44137460b2a56534644205 \
|
||||
--hash=sha256:9bafaa05b19dc07fa191c1966c5e852af516840b0d7b46b7c3303faf1a349bc9 \
|
||||
--hash=sha256:9f29c7f0f4b42337ec5a779e166946a9f86d7d56d827e771b69ecbdf426124ac \
|
||||
--hash=sha256:9f992e0f916201731993eab8502912878f02287d9f765ef843677ff118d0e0b1 \
|
||||
--hash=sha256:a04191a7c8d77e63f6fc1e8336d6c6e93176c0c010833e74410e647f0284f5a1 \
|
||||
--hash=sha256:a0f611b431b84f55779cbb7157257d87b4a2876b067c77c4f36b15e44ced65e2 \
|
||||
--hash=sha256:a3c2753bf4f48b7a6024e5e8a394af49b1b12c817d75d06942cae03d14ff87b3 \
|
||||
--hash=sha256:a5cd7d30e47f87b21362beeb3e86f1b5886e7d9b0294b230dde3d3f4a1591375 \
|
||||
--hash=sha256:acc58b7c2e40235712d857fdfc8f2bda9608f4a850d8d9ac0dd1fc80939ca6ac \
|
||||
--hash=sha256:adbd67dac4ebf54587198b63cd30c29fd7eafa8c0cab58893d9419414f8efe4b \
|
||||
--hash=sha256:b35c35e3923ade1e7ac44e150dec29f5863513246c8bf85e2d7d313e3832bcfb \
|
||||
--hash=sha256:c6910eb4ea90c0889f363965cd3c8c45a620ad27b526a7899f0054f6c1b9219e \
|
||||
--hash=sha256:cc889fda484d54d0b31feec409406267616536d048a450fc46943e152700bb79 \
|
||||
--hash=sha256:ccfd336f96d4c9bbab0309f2a565bf15c468c2d8b2d277a32f89c5940f71fcf9 \
|
||||
--hash=sha256:d8e7e8a150e7b548e7ecd6ebb9211c37265991bf2504297d9454e01b58530fc6 \
|
||||
--hash=sha256:db09e424d7bb89b6215a184ca93b4f29d7f00ea261b787918a1af74143b98c06 \
|
||||
--hash=sha256:e17e7e27af178d31b436dda6a596703b02a89ba74a15e2980c35ecd9909eea3a \
|
||||
--hash=sha256:e69290b921b7833c04206f233d6814c60bee1d135b09f5ae5d39229de9b46cd4 \
|
||||
--hash=sha256:e8398593ccc4440ce6dffcc4f47d9b2d72b9fe7112ac12ea4a44e7d4de364db1 \
|
||||
--hash=sha256:e9d036e343a604db3f5a6c33354018a84a1d3f6dcae3673358b404286204798c \
|
||||
--hash=sha256:ea490564435b5b204d8154f0e18387b499ea3cedc1e6af3b3a2ab18291d85aa7 \
|
||||
--hash=sha256:f073321a79c81e1a009218a21089f61d87ee5fa3c9563f6be94f8b41ff181812 \
|
||||
--hash=sha256:f0cc0b486a56dff72dddae6b6bfa7ff201b0eeac29d4bc6f0e9725dc3c360d71 \
|
||||
--hash=sha256:fcf84fe93397a0f67733aa2a38ed4eab9fc6348189fc950e656e1ea198f45668
|
||||
sqlalchemy==2.0.25 \
|
||||
--hash=sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9 \
|
||||
--hash=sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d \
|
||||
--hash=sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e \
|
||||
--hash=sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669 \
|
||||
--hash=sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d \
|
||||
--hash=sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5 \
|
||||
--hash=sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002 \
|
||||
--hash=sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e \
|
||||
--hash=sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd \
|
||||
--hash=sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215 \
|
||||
--hash=sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24 \
|
||||
--hash=sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39 \
|
||||
--hash=sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62 \
|
||||
--hash=sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900 \
|
||||
--hash=sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf \
|
||||
--hash=sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735 \
|
||||
--hash=sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4 \
|
||||
--hash=sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23 \
|
||||
--hash=sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9 \
|
||||
--hash=sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c \
|
||||
--hash=sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de \
|
||||
--hash=sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7 \
|
||||
--hash=sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625 \
|
||||
--hash=sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f \
|
||||
--hash=sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a \
|
||||
--hash=sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4 \
|
||||
--hash=sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643 \
|
||||
--hash=sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018 \
|
||||
--hash=sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9 \
|
||||
--hash=sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5 \
|
||||
--hash=sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08 \
|
||||
--hash=sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3 \
|
||||
--hash=sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3 \
|
||||
--hash=sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed \
|
||||
--hash=sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95 \
|
||||
--hash=sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6 \
|
||||
--hash=sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0 \
|
||||
--hash=sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84 \
|
||||
--hash=sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f \
|
||||
--hash=sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d \
|
||||
--hash=sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2 \
|
||||
--hash=sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5 \
|
||||
--hash=sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570 \
|
||||
--hash=sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7 \
|
||||
--hash=sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c \
|
||||
--hash=sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf \
|
||||
--hash=sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3 \
|
||||
--hash=sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed \
|
||||
--hash=sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5
|
||||
# via -r requirements.in
|
||||
typing-extensions==4.9.0 \
|
||||
--hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
|
||||
|
|
|
|||
|
|
@ -114,9 +114,9 @@ docker==7.0.0 \
|
|||
--hash=sha256:12ba681f2777a0ad28ffbcc846a69c31b4dfd9752b47eb425a274ee269c5e14b \
|
||||
--hash=sha256:323736fb92cd9418fc5e7133bc953e11a9da04f4483f828b527db553f1e7e5a3
|
||||
# via -r requirements.in
|
||||
google-auth==2.25.2 \
|
||||
--hash=sha256:42f707937feb4f5e5a39e6c4f343a17300a459aaf03141457ba505812841cc40 \
|
||||
--hash=sha256:473a8dfd0135f75bb79d878436e568f2695dce456764bf3a02b6f8c540b1d256
|
||||
google-auth==2.26.0 \
|
||||
--hash=sha256:11f56129d30902cc9f4b93ed0c84ef7323f7328e6520eab1716740f3171afe35 \
|
||||
--hash=sha256:5d8bf0a5143baa45368c3d08bf157babda468db1c5dd987cd2c824b788524196
|
||||
# via kubernetes
|
||||
idna==3.6 \
|
||||
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ export PYTHONPATH=/usr/share/bunkerweb/deps/python/:/usr/share/bunkerweb/ui/
|
|||
|
||||
# Create the ui.env file if it doesn't exist
|
||||
if [ ! -f /etc/bunkerweb/ui.env ]; then
|
||||
echo "ADMIN_USERNAME=admin" > /etc/bunkerweb/ui.env
|
||||
echo "ADMIN_PASSWORD=changeme" >> /etc/bunkerweb/ui.env
|
||||
echo "ADMIN_USERNAME=" > /etc/bunkerweb/ui.env
|
||||
echo "ADMIN_PASSWORD=" >> /etc/bunkerweb/ui.env
|
||||
fi
|
||||
|
||||
# Function to start the UI
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ reuse_port = True
|
|||
pidfile = join(sep, "var", "run", "bunkerweb", "ui.pid")
|
||||
worker_tmp_dir = join(sep, "dev", "shm")
|
||||
tmp_upload_dir = join(sep, "var", "tmp", "bunkerweb", "ui")
|
||||
worker_class = "gthread"
|
||||
worker_class = "gevent"
|
||||
threads = 1
|
||||
workers = 1
|
||||
graceful_timeout = 0
|
||||
|
|
|
|||
137
src/ui/main.py
137
src/ui/main.py
|
|
@ -18,28 +18,17 @@ for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in ((
|
|||
if deps_path not in sys_path:
|
||||
sys_path.append(deps_path)
|
||||
|
||||
from gevent import monkey
|
||||
|
||||
monkey.patch_all()
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from copy import deepcopy
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from dateutil.parser import parse as dateutil_parse
|
||||
from docker import DockerClient
|
||||
from docker.errors import (
|
||||
NotFound as docker_NotFound,
|
||||
APIError as docker_APIError,
|
||||
DockerException,
|
||||
)
|
||||
from flask import (
|
||||
Flask,
|
||||
Response,
|
||||
flash,
|
||||
jsonify,
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
send_file,
|
||||
session,
|
||||
url_for,
|
||||
)
|
||||
from docker.errors import NotFound as docker_NotFound, APIError as docker_APIError, DockerException
|
||||
from flask import Flask, Response, flash, jsonify, redirect, render_template, request, send_file, session, url_for
|
||||
from flask_login import current_user, LoginManager, login_required, login_user, logout_user
|
||||
from flask_wtf.csrf import CSRFProtect, CSRFError, generate_csrf
|
||||
from glob import glob
|
||||
|
|
@ -67,7 +56,7 @@ from src.Instances import Instances
|
|||
from src.ConfigFiles import ConfigFiles
|
||||
from src.Config import Config
|
||||
from src.ReverseProxied import ReverseProxied
|
||||
from src.User import User
|
||||
from src.User import AnonymousUser, User
|
||||
|
||||
from utils import check_settings, get_b64encoded_qr_image, path_to_dict
|
||||
from Database import Database # type: ignore
|
||||
|
|
@ -119,6 +108,7 @@ app.logger.setLevel(gunicorn_logger.level)
|
|||
login_manager = LoginManager()
|
||||
login_manager.init_app(app)
|
||||
login_manager.login_view = "login"
|
||||
login_manager.anonymous_user = AnonymousUser
|
||||
PLUGIN_KEYS = ["id", "name", "description", "version", "stream", "settings"]
|
||||
|
||||
INTEGRATION = "Linux"
|
||||
|
|
@ -177,14 +167,14 @@ if USER:
|
|||
updated = True
|
||||
|
||||
if updated:
|
||||
ret = db.update_ui_user(USER.get_id(), USER.password_hash, USER.is_two_factor_enabled, app.config["USER"].secret_token)
|
||||
ret = db.update_ui_user(USER.get_id(), USER.password_hash, USER.is_two_factor_enabled, USER.secret_token)
|
||||
if ret:
|
||||
app.logger.error(f"Couldn't update the admin user in the database: {ret}")
|
||||
stop(1)
|
||||
app.logger.info("The admin user was updated successfully")
|
||||
else:
|
||||
app.logger.error("The admin user wasn't created manually. You can't change it from the environment variables.")
|
||||
elif getenv("FLASK_DEBUG", False) or getenv("ADMIN_USERNAME") and getenv("ADMIN_PASSWORD"):
|
||||
elif getenv("ADMIN_USERNAME") and getenv("ADMIN_PASSWORD"):
|
||||
if not getenv("FLASK_DEBUG", False):
|
||||
if len(getenv("ADMIN_USERNAME", "admin")) > 256:
|
||||
app.logger.error("The admin username is too long. It must be less than 256 characters.")
|
||||
|
|
@ -220,6 +210,7 @@ try:
|
|||
LAST_RELOAD=0,
|
||||
TO_FLASH=[],
|
||||
DARK_MODE=False,
|
||||
CURRENT_TOTP_TOKEN=None,
|
||||
)
|
||||
except FileNotFoundError as e:
|
||||
app.logger.error(repr(e), e.filename)
|
||||
|
|
@ -318,7 +309,12 @@ def set_csp_header(response):
|
|||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return app.config["USER"] if app.config["USER"] and user_id == app.config["USER"].get_id() else None
|
||||
db_user = db.get_ui_user()
|
||||
if not db_user:
|
||||
app.logger.warning("Couldn't get the admin user from the database.")
|
||||
return None
|
||||
user = User(**db_user)
|
||||
return user if user_id == user.get_id() else None
|
||||
|
||||
|
||||
@app.errorhandler(CSRFError)
|
||||
|
|
@ -334,14 +330,14 @@ def handle_csrf_error(_):
|
|||
flash("Wrong CSRF token !", "error")
|
||||
if not app.config["USER"]:
|
||||
return render_template("setup.html"), 403
|
||||
return render_template("login.html", is_totp=app.config["USER"].is_two_factor_enabled), 403
|
||||
return render_template("login.html", is_totp=current_user.is_two_factor_enabled), 403
|
||||
|
||||
|
||||
@app.before_request
|
||||
def before_request():
|
||||
if app.config["USER"] and current_user.is_authenticated:
|
||||
if current_user.is_authenticated:
|
||||
passed = True
|
||||
if not session.get("totp_validated", False) and app.config["USER"].is_two_factor_enabled and "/totp" not in request.path and not request.path.startswith(("/css", "/images", "/js", "/json", "/webfonts")):
|
||||
if not session.get("totp_validated", False) and current_user.is_two_factor_enabled and "/totp" not in request.path and not request.path.startswith(("/css", "/images", "/js", "/json", "/webfonts")):
|
||||
return redirect(url_for("totp", next=request.form.get("next")))
|
||||
elif session.get("ip") != request.remote_addr:
|
||||
passed = False
|
||||
|
|
@ -378,13 +374,15 @@ def check():
|
|||
|
||||
@app.route("/setup", methods=["GET", "POST"])
|
||||
def setup():
|
||||
if app.config["USER"]:
|
||||
if current_user.is_authenticated: # type: ignore
|
||||
return redirect(url_for("home"))
|
||||
return redirect(url_for("login"), 301)
|
||||
if current_user.is_authenticated: # type: ignore
|
||||
return redirect(url_for("home"))
|
||||
|
||||
db_config = app.config["CONFIG"].get_config(methods=False)
|
||||
|
||||
for server_name in db_config["SERVER_NAME"].split(" "):
|
||||
if db_config.get(f"{server_name}_USE_UI", "no") == "yes":
|
||||
return redirect(url_for("login"), 301)
|
||||
|
||||
if request.method == "POST":
|
||||
if not request.form:
|
||||
flash("Missing form data.", "error")
|
||||
|
|
@ -481,14 +479,14 @@ def totp():
|
|||
flash("Missing token parameter.", "error")
|
||||
return redirect(url_for("totp"))
|
||||
|
||||
if not app.config["USER"].check_otp(request.form["totp_token"]):
|
||||
if not current_user.check_otp(request.form["totp_token"]):
|
||||
flash("The token is invalid.", "error")
|
||||
return redirect(url_for("totp"))
|
||||
|
||||
session["totp_validated"] = True
|
||||
redirect(url_for("loading", next=request.form.get("next") or url_for("home")))
|
||||
|
||||
if app.config["USER"] and (not app.config["USER"].is_two_factor_enabled or session.get("totp_validated", False)):
|
||||
if not current_user.is_two_factor_enabled or session.get("totp_validated", False):
|
||||
return redirect(url_for("home"))
|
||||
|
||||
return render_template("totp.html", dark_mode=app.config["DARK_MODE"])
|
||||
|
|
@ -565,7 +563,7 @@ def profile():
|
|||
error = False
|
||||
|
||||
if "curr_password" in request.form:
|
||||
if not app.config["USER"].check_password(request.form["curr_password"]):
|
||||
if not current_user.check_password(request.form["curr_password"]):
|
||||
flash("The current password is incorrect.", "error")
|
||||
error = True
|
||||
|
||||
|
|
@ -594,12 +592,12 @@ def profile():
|
|||
if error:
|
||||
return redirect(url_for("profile"))
|
||||
|
||||
app.config["USER"] = User(
|
||||
request.form.get("admin_username") or app.config["USER"].get_id(),
|
||||
user = User(
|
||||
request.form.get("admin_username") or current_user.get_id(),
|
||||
request.form.get("admin_password") or request.form["curr_password"],
|
||||
is_two_factor_enabled=app.config["USER"].is_two_factor_enabled,
|
||||
secret_token=app.config["USER"].secret_token,
|
||||
method=app.config["USER"].method,
|
||||
is_two_factor_enabled=current_user.is_two_factor_enabled,
|
||||
secret_token=current_user.secret_token,
|
||||
method=current_user.method,
|
||||
)
|
||||
|
||||
session.clear()
|
||||
|
|
@ -609,57 +607,54 @@ def profile():
|
|||
flash("Missing totp_token parameter.", "error")
|
||||
return redirect(url_for("profile"))
|
||||
|
||||
if not app.config["USER"].check_password(request.form.get("totp_password", "")):
|
||||
if not current_user.check_password(request.form.get("totp_password", "")):
|
||||
flash("The current password is incorrect.", "error")
|
||||
error = True
|
||||
|
||||
if not app.config["USER"].check_otp(request.form["totp_token"]):
|
||||
if not current_user.check_otp(request.form["totp_token"], secret=app.config["CURRENT_TOTP_TOKEN"]):
|
||||
flash("The token is invalid.", "error")
|
||||
error = True
|
||||
|
||||
app.logger.warning(request.form["totp_password"])
|
||||
|
||||
if error:
|
||||
return redirect(url_for("profile"))
|
||||
|
||||
app.logger.warning("TOTP validated")
|
||||
session["totp_validated"] = not current_user.is_two_factor_enabled
|
||||
|
||||
session["totp_validated"] = not app.config["USER"].is_two_factor_enabled
|
||||
|
||||
if app.config["USER"].is_two_factor_enabled:
|
||||
app.config["USER"].secret_token = None
|
||||
|
||||
app.config["USER"].is_two_factor_enabled = session["totp_validated"]
|
||||
|
||||
app.logger.warning(app.config["USER"])
|
||||
user = User(
|
||||
current_user.get_id(),
|
||||
request.form["totp_password"],
|
||||
is_two_factor_enabled=session["totp_validated"],
|
||||
secret_token=None if current_user.is_two_factor_enabled else app.config["CURRENT_TOTP_TOKEN"],
|
||||
method=current_user.method,
|
||||
)
|
||||
app.config["CURRENT_TOTP_TOKEN"] = None
|
||||
else:
|
||||
flash("Missing form data.", "error")
|
||||
return redirect(url_for("profile"))
|
||||
|
||||
ret = db.update_ui_user(
|
||||
app.config["USER"].get_id(),
|
||||
app.config["USER"].password_hash,
|
||||
app.config["USER"].is_two_factor_enabled,
|
||||
app.config["USER"].secret_token if app.config["USER"].is_two_factor_enabled else None,
|
||||
user.get_id(),
|
||||
user.password_hash,
|
||||
user.is_two_factor_enabled,
|
||||
user.secret_token if user.is_two_factor_enabled else None,
|
||||
)
|
||||
if ret:
|
||||
app.logger.error(f"Couldn't update the admin user in the database: {ret}")
|
||||
flash(f"Couldn't update the admin user in the database: {ret}", "error")
|
||||
return redirect(url_for("profile"))
|
||||
|
||||
app.logger.warning("User updated")
|
||||
|
||||
return redirect(url_for("profile"))
|
||||
|
||||
secret_token = ""
|
||||
totp_qr_image = ""
|
||||
|
||||
if not app.config["USER"].is_two_factor_enabled:
|
||||
app.config["USER"].refresh_totp()
|
||||
secret_token = app.config["USER"].secret_token
|
||||
totp_qr_image = get_b64encoded_qr_image(app.config["USER"].get_authentication_setup_uri())
|
||||
if not current_user.is_two_factor_enabled:
|
||||
current_user.refresh_totp()
|
||||
secret_token = current_user.secret_token
|
||||
totp_qr_image = get_b64encoded_qr_image(current_user.get_authentication_setup_uri())
|
||||
app.config["CURRENT_TOTP_TOKEN"] = secret_token
|
||||
|
||||
return render_template("profile.html", username=app.config["USER"].get_id(), is_totp=app.config["USER"].is_two_factor_enabled, secret_token=secret_token, totp_qr_image=totp_qr_image, dark_mode=app.config["DARK_MODE"])
|
||||
return render_template("profile.html", username=current_user.get_id(), is_totp=current_user.is_two_factor_enabled, secret_token=secret_token, totp_qr_image=totp_qr_image, dark_mode=app.config["DARK_MODE"])
|
||||
|
||||
|
||||
@app.route("/instances", methods=["GET", "POST"])
|
||||
|
|
@ -1658,15 +1653,26 @@ def jobs_download():
|
|||
|
||||
@app.route("/login", methods=["GET", "POST"])
|
||||
def login():
|
||||
if not app.config["USER"]:
|
||||
return redirect(url_for("setup"))
|
||||
elif current_user.is_authenticated: # type: ignore
|
||||
return redirect(url_for("home"))
|
||||
|
||||
fail = False
|
||||
if request.method == "POST" and "username" in request.form and "password" in request.form:
|
||||
app.logger.warning(f"Login attempt from {request.remote_addr} with username \"{request.form['username']}\"")
|
||||
if app.config["USER"].get_id() == request.form["username"] and app.config["USER"].check_password(request.form["password"]):
|
||||
db_user = db.get_ui_user()
|
||||
if not db_user:
|
||||
app.logger.error("Couldn't get user from database")
|
||||
stop(1)
|
||||
user = User(**db_user)
|
||||
|
||||
if user.get_id() == request.form["username"] and user.check_password(request.form["password"]):
|
||||
# log the user in
|
||||
session["ip"] = request.remote_addr
|
||||
session["user_agent"] = request.headers.get("User-Agent")
|
||||
session["totp_validated"] = False
|
||||
login_user(app.config["USER"], duration=timedelta(hours=1))
|
||||
login_user(user, duration=timedelta(hours=1))
|
||||
|
||||
# redirect him to the page he originally wanted or to the home page
|
||||
return redirect(url_for("loading", next=request.form.get("next") or url_for("home")))
|
||||
|
|
@ -1674,13 +1680,8 @@ def login():
|
|||
flash("Invalid username or password", "error")
|
||||
fail = True
|
||||
|
||||
if not app.config["USER"]:
|
||||
return redirect(url_for("setup"))
|
||||
elif current_user.is_authenticated: # type: ignore
|
||||
return redirect(url_for("home"))
|
||||
|
||||
kwargs = {
|
||||
"is_totp": app.config["USER"].is_two_factor_enabled,
|
||||
"is_totp": current_user.is_two_factor_enabled,
|
||||
} | ({"error": "Invalid username or password"} if fail else {})
|
||||
|
||||
return render_template("login.html", **kwargs), 401 if fail else 200
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ beautifulsoup4==4.12.2
|
|||
Flask==3.0.0
|
||||
Flask-Login==0.6.3
|
||||
Flask_WTF==1.2.1
|
||||
gunicorn[gthread]==21.2.0
|
||||
gunicorn[gevent]==21.2.0
|
||||
importlib-metadata==7.0.1
|
||||
pyotp==2.9.0
|
||||
python_dateutil==2.8.2
|
||||
|
|
|
|||
|
|
@ -60,6 +60,108 @@ flask-wtf==1.2.1 \
|
|||
--hash=sha256:8bb269eb9bb46b87e7c8233d7e7debdf1f8b74bf90cc1789988c29b37a97b695 \
|
||||
--hash=sha256:fa6793f2fb7e812e0fe9743b282118e581fb1b6c45d414b8af05e659bd653287
|
||||
# via -r requirements.in
|
||||
gevent==23.9.1 \
|
||||
--hash=sha256:272cffdf535978d59c38ed837916dfd2b5d193be1e9e5dcc60a5f4d5025dd98a \
|
||||
--hash=sha256:2c7b5c9912378e5f5ccf180d1fdb1e83f42b71823483066eddbe10ef1a2fcaa2 \
|
||||
--hash=sha256:36a549d632c14684bcbbd3014a6ce2666c5f2a500f34d58d32df6c9ea38b6535 \
|
||||
--hash=sha256:4368f341a5f51611411ec3fc62426f52ac3d6d42eaee9ed0f9eebe715c80184e \
|
||||
--hash=sha256:43daf68496c03a35287b8b617f9f91e0e7c0d042aebcc060cadc3f049aadd653 \
|
||||
--hash=sha256:455e5ee8103f722b503fa45dedb04f3ffdec978c1524647f8ba72b4f08490af1 \
|
||||
--hash=sha256:45792c45d60f6ce3d19651d7fde0bc13e01b56bb4db60d3f32ab7d9ec467374c \
|
||||
--hash=sha256:4e24c2af9638d6c989caffc691a039d7c7022a31c0363da367c0d32ceb4a0648 \
|
||||
--hash=sha256:52b4abf28e837f1865a9bdeef58ff6afd07d1d888b70b6804557e7908032e599 \
|
||||
--hash=sha256:52e9f12cd1cda96603ce6b113d934f1aafb873e2c13182cf8e86d2c5c41982ea \
|
||||
--hash=sha256:5f3c781c84794926d853d6fb58554dc0dcc800ba25c41d42f6959c344b4db5a6 \
|
||||
--hash=sha256:62d121344f7465e3739989ad6b91f53a6ca9110518231553fe5846dbe1b4518f \
|
||||
--hash=sha256:65883ac026731ac112184680d1f0f1e39fa6f4389fd1fc0bf46cc1388e2599f9 \
|
||||
--hash=sha256:707904027d7130ff3e59ea387dddceedb133cc742b00b3ffe696d567147a9c9e \
|
||||
--hash=sha256:72c002235390d46f94938a96920d8856d4ffd9ddf62a303a0d7c118894097e34 \
|
||||
--hash=sha256:7532c17bc6c1cbac265e751b95000961715adef35a25d2b0b1813aa7263fb397 \
|
||||
--hash=sha256:78eebaf5e73ff91d34df48f4e35581ab4c84e22dd5338ef32714264063c57507 \
|
||||
--hash=sha256:7c1abc6f25f475adc33e5fc2dbcc26a732608ac5375d0d306228738a9ae14d3b \
|
||||
--hash=sha256:7c28e38dcde327c217fdafb9d5d17d3e772f636f35df15ffae2d933a5587addd \
|
||||
--hash=sha256:7ccf0fd378257cb77d91c116e15c99e533374a8153632c48a3ecae7f7f4f09fe \
|
||||
--hash=sha256:921dda1c0b84e3d3b1778efa362d61ed29e2b215b90f81d498eb4d8eafcd0b7a \
|
||||
--hash=sha256:a2898b7048771917d85a1d548fd378e8a7b2ca963db8e17c6d90c76b495e0e2b \
|
||||
--hash=sha256:a3c5e9b1f766a7a64833334a18539a362fb563f6c4682f9634dea72cbe24f771 \
|
||||
--hash=sha256:ada07076b380918829250201df1d016bdafb3acf352f35e5693b59dceee8dd2e \
|
||||
--hash=sha256:b101086f109168b23fa3586fccd1133494bdb97f86920a24dc0b23984dc30b69 \
|
||||
--hash=sha256:bf456bd6b992eb0e1e869e2fd0caf817f0253e55ca7977fd0e72d0336a8c1c6a \
|
||||
--hash=sha256:bf7af500da05363e66f122896012acb6e101a552682f2352b618e541c941a011 \
|
||||
--hash=sha256:c3e5d2fa532e4d3450595244de8ccf51f5721a05088813c1abd93ad274fe15e7 \
|
||||
--hash=sha256:c84d34256c243b0a53d4335ef0bc76c735873986d478c53073861a92566a8d71 \
|
||||
--hash=sha256:d163d59f1be5a4c4efcdd13c2177baaf24aadf721fdf2e1af9ee54a998d160f5 \
|
||||
--hash=sha256:d57737860bfc332b9b5aa438963986afe90f49645f6e053140cfa0fa1bdae1ae \
|
||||
--hash=sha256:dbb22a9bbd6a13e925815ce70b940d1578dbe5d4013f20d23e8a11eddf8d14a7 \
|
||||
--hash=sha256:dcb8612787a7f4626aa881ff15ff25439561a429f5b303048f0fca8a1c781c39 \
|
||||
--hash=sha256:dd6c32ab977ecf7c7b8c2611ed95fa4aaebd69b74bf08f4b4960ad516861517d \
|
||||
--hash=sha256:de350fde10efa87ea60d742901e1053eb2127ebd8b59a7d3b90597eb4e586599 \
|
||||
--hash=sha256:e1ead6863e596a8cc2a03e26a7a0981f84b6b3e956101135ff6d02df4d9a6b07 \
|
||||
--hash=sha256:ed7a048d3e526a5c1d55c44cb3bc06cfdc1947d06d45006cc4cf60dedc628904 \
|
||||
--hash=sha256:f632487c87866094546a74eefbca2c74c1d03638b715b6feb12e80120960185a \
|
||||
--hash=sha256:fae8d5b5b8fa2a8f63b39f5447168b02db10c888a3e387ed7af2bd1b8612e543 \
|
||||
--hash=sha256:fde6402c5432b835fbb7698f1c7f2809c8d6b2bd9d047ac1f5a7c1d5aa569303
|
||||
# via gunicorn
|
||||
greenlet==3.0.3 \
|
||||
--hash=sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67 \
|
||||
--hash=sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6 \
|
||||
--hash=sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257 \
|
||||
--hash=sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4 \
|
||||
--hash=sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676 \
|
||||
--hash=sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61 \
|
||||
--hash=sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc \
|
||||
--hash=sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca \
|
||||
--hash=sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7 \
|
||||
--hash=sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728 \
|
||||
--hash=sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305 \
|
||||
--hash=sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6 \
|
||||
--hash=sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379 \
|
||||
--hash=sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414 \
|
||||
--hash=sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04 \
|
||||
--hash=sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a \
|
||||
--hash=sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf \
|
||||
--hash=sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491 \
|
||||
--hash=sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559 \
|
||||
--hash=sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e \
|
||||
--hash=sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274 \
|
||||
--hash=sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb \
|
||||
--hash=sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b \
|
||||
--hash=sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9 \
|
||||
--hash=sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b \
|
||||
--hash=sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be \
|
||||
--hash=sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506 \
|
||||
--hash=sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405 \
|
||||
--hash=sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113 \
|
||||
--hash=sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f \
|
||||
--hash=sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5 \
|
||||
--hash=sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230 \
|
||||
--hash=sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d \
|
||||
--hash=sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f \
|
||||
--hash=sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a \
|
||||
--hash=sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e \
|
||||
--hash=sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61 \
|
||||
--hash=sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6 \
|
||||
--hash=sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d \
|
||||
--hash=sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71 \
|
||||
--hash=sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22 \
|
||||
--hash=sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2 \
|
||||
--hash=sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3 \
|
||||
--hash=sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067 \
|
||||
--hash=sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc \
|
||||
--hash=sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881 \
|
||||
--hash=sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3 \
|
||||
--hash=sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e \
|
||||
--hash=sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac \
|
||||
--hash=sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53 \
|
||||
--hash=sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0 \
|
||||
--hash=sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b \
|
||||
--hash=sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83 \
|
||||
--hash=sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41 \
|
||||
--hash=sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c \
|
||||
--hash=sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf \
|
||||
--hash=sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da \
|
||||
--hash=sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33
|
||||
# via gevent
|
||||
gunicorn==21.2.0 \
|
||||
--hash=sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0 \
|
||||
--hash=sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033
|
||||
|
|
@ -261,6 +363,12 @@ regex==2023.12.25 \
|
|||
--hash=sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa \
|
||||
--hash=sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31 \
|
||||
--hash=sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988
|
||||
# via gevent
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
setuptools==69.0.3 \
|
||||
--hash=sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05 \
|
||||
--hash=sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78
|
||||
# via -r requirements.in
|
||||
six==1.16.0 \
|
||||
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
|
||||
|
|
@ -289,3 +397,47 @@ zipp==3.17.0 \
|
|||
--hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
|
||||
--hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
|
||||
# via importlib-metadata
|
||||
zope-event==5.0 \
|
||||
--hash=sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26 \
|
||||
--hash=sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd
|
||||
# via gevent
|
||||
zope-interface==6.1 \
|
||||
--hash=sha256:0c8cf55261e15590065039696607f6c9c1aeda700ceee40c70478552d323b3ff \
|
||||
--hash=sha256:13b7d0f2a67eb83c385880489dbb80145e9d344427b4262c49fbf2581677c11c \
|
||||
--hash=sha256:1f294a15f7723fc0d3b40701ca9b446133ec713eafc1cc6afa7b3d98666ee1ac \
|
||||
--hash=sha256:239a4a08525c080ff833560171d23b249f7f4d17fcbf9316ef4159f44997616f \
|
||||
--hash=sha256:2f8d89721834524a813f37fa174bac074ec3d179858e4ad1b7efd4401f8ac45d \
|
||||
--hash=sha256:2fdc7ccbd6eb6b7df5353012fbed6c3c5d04ceaca0038f75e601060e95345309 \
|
||||
--hash=sha256:34c15ca9248f2e095ef2e93af2d633358c5f048c49fbfddf5fdfc47d5e263736 \
|
||||
--hash=sha256:387545206c56b0315fbadb0431d5129c797f92dc59e276b3ce82db07ac1c6179 \
|
||||
--hash=sha256:43b576c34ef0c1f5a4981163b551a8781896f2a37f71b8655fd20b5af0386abb \
|
||||
--hash=sha256:57d0a8ce40ce440f96a2c77824ee94bf0d0925e6089df7366c2272ccefcb7941 \
|
||||
--hash=sha256:5a804abc126b33824a44a7aa94f06cd211a18bbf31898ba04bd0924fbe9d282d \
|
||||
--hash=sha256:67be3ca75012c6e9b109860820a8b6c9a84bfb036fbd1076246b98e56951ca92 \
|
||||
--hash=sha256:6af47f10cfc54c2ba2d825220f180cc1e2d4914d783d6fc0cd93d43d7bc1c78b \
|
||||
--hash=sha256:6dc998f6de015723196a904045e5a2217f3590b62ea31990672e31fbc5370b41 \
|
||||
--hash=sha256:70d2cef1bf529bff41559be2de9d44d47b002f65e17f43c73ddefc92f32bf00f \
|
||||
--hash=sha256:7ebc4d34e7620c4f0da7bf162c81978fce0ea820e4fa1e8fc40ee763839805f3 \
|
||||
--hash=sha256:964a7af27379ff4357dad1256d9f215047e70e93009e532d36dcb8909036033d \
|
||||
--hash=sha256:97806e9ca3651588c1baaebb8d0c5ee3db95430b612db354c199b57378312ee8 \
|
||||
--hash=sha256:9b9bc671626281f6045ad61d93a60f52fd5e8209b1610972cf0ef1bbe6d808e3 \
|
||||
--hash=sha256:9ffdaa5290422ac0f1688cb8adb1b94ca56cee3ad11f29f2ae301df8aecba7d1 \
|
||||
--hash=sha256:a0da79117952a9a41253696ed3e8b560a425197d4e41634a23b1507efe3273f1 \
|
||||
--hash=sha256:a41f87bb93b8048fe866fa9e3d0c51e27fe55149035dcf5f43da4b56732c0a40 \
|
||||
--hash=sha256:aa6fd016e9644406d0a61313e50348c706e911dca29736a3266fc9e28ec4ca6d \
|
||||
--hash=sha256:ad54ed57bdfa3254d23ae04a4b1ce405954969c1b0550cc2d1d2990e8b439de1 \
|
||||
--hash=sha256:b012d023b4fb59183909b45d7f97fb493ef7a46d2838a5e716e3155081894605 \
|
||||
--hash=sha256:b51b64432eed4c0744241e9ce5c70dcfecac866dff720e746d0a9c82f371dfa7 \
|
||||
--hash=sha256:bbe81def9cf3e46f16ce01d9bfd8bea595e06505e51b7baf45115c77352675fd \
|
||||
--hash=sha256:c9559138690e1bd4ea6cd0954d22d1e9251e8025ce9ede5d0af0ceae4a401e43 \
|
||||
--hash=sha256:e30506bcb03de8983f78884807e4fd95d8db6e65b69257eea05d13d519b83ac0 \
|
||||
--hash=sha256:e33e86fd65f369f10608b08729c8f1c92ec7e0e485964670b4d2633a4812d36b \
|
||||
--hash=sha256:e441e8b7d587af0414d25e8d05e27040d78581388eed4c54c30c0c91aad3a379 \
|
||||
--hash=sha256:e8bb9c990ca9027b4214fa543fd4025818dc95f8b7abce79d61dc8a2112b561a \
|
||||
--hash=sha256:ef43ee91c193f827e49599e824385ec7c7f3cd152d74cb1dfe02cb135f264d83 \
|
||||
--hash=sha256:ef467d86d3cfde8b39ea1b35090208b0447caaabd38405420830f7fd85fbdd56 \
|
||||
--hash=sha256:f89b28772fc2562ed9ad871c865f5320ef761a7fcc188a935e21fe8b31a38ca9 \
|
||||
--hash=sha256:fddbab55a2473f1d3b8833ec6b7ac31e8211b0aa608df5ab09ce07f3727326de
|
||||
# via
|
||||
# zope-event
|
||||
# zope-interface
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
from typing import Optional
|
||||
|
||||
from bcrypt import checkpw, hashpw, gensalt
|
||||
from flask_login import UserMixin
|
||||
from flask_login import AnonymousUserMixin, UserMixin
|
||||
from pyotp import random_base32
|
||||
from pyotp.totp import TOTP
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ class User(UserMixin):
|
|||
self.is_two_factor_enabled = is_two_factor_enabled
|
||||
self.secret_token = secret_token
|
||||
self.method = method
|
||||
self.__totp = None
|
||||
self.__totp = TOTP(secret_token) if secret_token else None
|
||||
|
||||
@property
|
||||
def password_hash(self) -> bytes:
|
||||
|
|
@ -66,7 +66,7 @@ class User(UserMixin):
|
|||
self.secret_token = random_base32()
|
||||
self.__totp = TOTP(self.secret_token)
|
||||
|
||||
def check_otp(self, otp: str) -> bool:
|
||||
def check_otp(self, otp: str, *, secret: Optional[str] = None) -> bool:
|
||||
"""
|
||||
Check if the otp is correct by comparing it to the stored secret token
|
||||
|
||||
|
|
@ -74,9 +74,64 @@ class User(UserMixin):
|
|||
:return: The otp is being checked against the secret token. If the otp is correct,
|
||||
the user is returned.
|
||||
"""
|
||||
if secret:
|
||||
return TOTP(secret).verify(otp, valid_window=3)
|
||||
if not self.__totp:
|
||||
return False
|
||||
return self.__totp.verify(otp, valid_window=3)
|
||||
|
||||
def __repr__(self):
|
||||
return f"User({self.id!r}, {self.__password!r}, {self.is_two_factor_enabled!r}, {self.secret_token!r}, {self.method!r})"
|
||||
|
||||
|
||||
class AnonymousUser(AnonymousUserMixin):
|
||||
def __init__(self):
|
||||
self.id = None
|
||||
self.is_two_factor_enabled = False
|
||||
self.secret_token = None
|
||||
self.method = "manual"
|
||||
|
||||
@property
|
||||
def password_hash(self) -> None:
|
||||
"""
|
||||
Get the password hash
|
||||
|
||||
:return: The password hash
|
||||
"""
|
||||
return None
|
||||
|
||||
def update_password(self, password: str):
|
||||
"""
|
||||
Set the password by hashing it
|
||||
|
||||
:param password: The password to be hashed
|
||||
"""
|
||||
self.__password = hashpw(password.encode("utf-8"), gensalt(rounds=13))
|
||||
|
||||
def check_password(self, password: str):
|
||||
"""
|
||||
Check if the password is correct by hashing it and comparing it to the stored hash
|
||||
|
||||
:param password: The password to be checked
|
||||
:return: The password is being checked against the password hash. If the password is correct,
|
||||
the user is returned.
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_authentication_setup_uri(self) -> str:
|
||||
return ""
|
||||
|
||||
def refresh_totp(self):
|
||||
return
|
||||
|
||||
def check_otp(self, otp: str, *, secret: Optional[str] = None) -> bool:
|
||||
"""
|
||||
Check if the otp is correct by comparing it to the stored secret token
|
||||
|
||||
:param otp: The otp to be checked
|
||||
:return: The otp is being checked against the secret token. If the otp is correct,
|
||||
the user is returned.
|
||||
"""
|
||||
if secret:
|
||||
return TOTP(secret).verify(otp, valid_window=3)
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
cryptography==41.0.7
|
||||
psycopg2-binary==2.9.9
|
||||
PyMySQL==1.1.0
|
||||
sqlalchemy==2.0.24
|
||||
sqlalchemy==2.0.25
|
||||
|
|
|
|||
|
|
@ -225,56 +225,56 @@ pymysql==1.1.0 \
|
|||
--hash=sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96 \
|
||||
--hash=sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7
|
||||
# via -r requirements.in
|
||||
sqlalchemy==2.0.24 \
|
||||
--hash=sha256:00d76fe5d7cdb5d84d625ce002ce29fefba0bfd98e212ae66793fed30af73931 \
|
||||
--hash=sha256:07cc423892f2ceda9ae1daa28c0355757f362ecc7505b1ab1a3d5d8dc1c44ac6 \
|
||||
--hash=sha256:0bb7cedcddffca98c40bb0becd3423e293d1fef442b869da40843d751785beb3 \
|
||||
--hash=sha256:1ca7903d5e7db791a355b579c690684fac6304478b68efdc7f2ebdcfe770d8d7 \
|
||||
--hash=sha256:1d9b3fd5eca3c0b137a5e0e468e24ca544ed8ca4783e0e55341b7ed2807518ee \
|
||||
--hash=sha256:2587e108463cc2e5b45a896b2e7cc8659a517038026922a758bde009271aed11 \
|
||||
--hash=sha256:29e51f848f843bbd75d74ae64ab1ab06302cb1dccd4549d1f5afe6b4a946edb2 \
|
||||
--hash=sha256:2a479aa1ab199178ff1956b09ca8a0693e70f9c762875d69292d37049ffd0d8f \
|
||||
--hash=sha256:37e89d965b52e8b20571b5d44f26e2124b26ab63758bf1b7598a0e38fb2c4005 \
|
||||
--hash=sha256:38732884eabc64982a09a846bacf085596ff2371e4e41d20c0734f7e50525d01 \
|
||||
--hash=sha256:396f05c552f7fa30a129497c41bef5b4d1423f9af8fe4df0c3dcd38f3e3b9a14 \
|
||||
--hash=sha256:4a1d4856861ba9e73bac05030cec5852eabfa9ef4af8e56c19d92de80d46fc34 \
|
||||
--hash=sha256:56a0e90a959e18ac5f18c80d0cad9e90cb09322764f536e8a637426afb1cae2f \
|
||||
--hash=sha256:57ef6f2cb8b09a042d0dbeaa46a30f2df5dd1e1eb889ba258b0d5d7d6011b81c \
|
||||
--hash=sha256:5f801d85ba4753d4ed97181d003e5d3fa330ac7c4587d131f61d7f968f416862 \
|
||||
--hash=sha256:6db686a1d9f183c639f7e06a2656af25d4ed438eda581de135d15569f16ace33 \
|
||||
--hash=sha256:6db97656fd3fe3f7e5b077f12fa6adb5feb6e0b567a3e99f47ecf5f7ea0a09e3 \
|
||||
--hash=sha256:6f5e75de91c754365c098ac08c13fdb267577ce954fa239dd49228b573ca88d7 \
|
||||
--hash=sha256:7a6209e689d0ff206c40032b6418e3cfcfc5af044b3f66e381d7f1ae301544b4 \
|
||||
--hash=sha256:7ae5d44517fe81079ce75cf10f96978284a6db2642c5932a69c82dbae09f009a \
|
||||
--hash=sha256:83fa6df0e035689df89ff77a46bf8738696785d3156c2c61494acdcddc75c69d \
|
||||
--hash=sha256:8f358f5cfce04417b6ff738748ca4806fe3d3ae8040fb4e6a0c9a6973ccf9b6e \
|
||||
--hash=sha256:9036ebfd934813990c5b9f71f297e77ed4963720db7d7ceec5a3fdb7cd2ef6ce \
|
||||
--hash=sha256:95bae3d38f8808d79072da25d5e5a6095f36fe1f9d6c614dd72c59ca8397c7c0 \
|
||||
--hash=sha256:9aaaaa846b10dfbe1bda71079d0e31a7e2cebedda9409fa7dba3dfed1ae803e8 \
|
||||
--hash=sha256:9b8d0e8578e7f853f45f4512b5c920f6a546cd4bed44137460b2a56534644205 \
|
||||
--hash=sha256:9bafaa05b19dc07fa191c1966c5e852af516840b0d7b46b7c3303faf1a349bc9 \
|
||||
--hash=sha256:9f29c7f0f4b42337ec5a779e166946a9f86d7d56d827e771b69ecbdf426124ac \
|
||||
--hash=sha256:9f992e0f916201731993eab8502912878f02287d9f765ef843677ff118d0e0b1 \
|
||||
--hash=sha256:a04191a7c8d77e63f6fc1e8336d6c6e93176c0c010833e74410e647f0284f5a1 \
|
||||
--hash=sha256:a0f611b431b84f55779cbb7157257d87b4a2876b067c77c4f36b15e44ced65e2 \
|
||||
--hash=sha256:a3c2753bf4f48b7a6024e5e8a394af49b1b12c817d75d06942cae03d14ff87b3 \
|
||||
--hash=sha256:a5cd7d30e47f87b21362beeb3e86f1b5886e7d9b0294b230dde3d3f4a1591375 \
|
||||
--hash=sha256:acc58b7c2e40235712d857fdfc8f2bda9608f4a850d8d9ac0dd1fc80939ca6ac \
|
||||
--hash=sha256:adbd67dac4ebf54587198b63cd30c29fd7eafa8c0cab58893d9419414f8efe4b \
|
||||
--hash=sha256:b35c35e3923ade1e7ac44e150dec29f5863513246c8bf85e2d7d313e3832bcfb \
|
||||
--hash=sha256:c6910eb4ea90c0889f363965cd3c8c45a620ad27b526a7899f0054f6c1b9219e \
|
||||
--hash=sha256:cc889fda484d54d0b31feec409406267616536d048a450fc46943e152700bb79 \
|
||||
--hash=sha256:ccfd336f96d4c9bbab0309f2a565bf15c468c2d8b2d277a32f89c5940f71fcf9 \
|
||||
--hash=sha256:d8e7e8a150e7b548e7ecd6ebb9211c37265991bf2504297d9454e01b58530fc6 \
|
||||
--hash=sha256:db09e424d7bb89b6215a184ca93b4f29d7f00ea261b787918a1af74143b98c06 \
|
||||
--hash=sha256:e17e7e27af178d31b436dda6a596703b02a89ba74a15e2980c35ecd9909eea3a \
|
||||
--hash=sha256:e69290b921b7833c04206f233d6814c60bee1d135b09f5ae5d39229de9b46cd4 \
|
||||
--hash=sha256:e8398593ccc4440ce6dffcc4f47d9b2d72b9fe7112ac12ea4a44e7d4de364db1 \
|
||||
--hash=sha256:e9d036e343a604db3f5a6c33354018a84a1d3f6dcae3673358b404286204798c \
|
||||
--hash=sha256:ea490564435b5b204d8154f0e18387b499ea3cedc1e6af3b3a2ab18291d85aa7 \
|
||||
--hash=sha256:f073321a79c81e1a009218a21089f61d87ee5fa3c9563f6be94f8b41ff181812 \
|
||||
--hash=sha256:f0cc0b486a56dff72dddae6b6bfa7ff201b0eeac29d4bc6f0e9725dc3c360d71 \
|
||||
--hash=sha256:fcf84fe93397a0f67733aa2a38ed4eab9fc6348189fc950e656e1ea198f45668
|
||||
sqlalchemy==2.0.25 \
|
||||
--hash=sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9 \
|
||||
--hash=sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d \
|
||||
--hash=sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e \
|
||||
--hash=sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669 \
|
||||
--hash=sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d \
|
||||
--hash=sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5 \
|
||||
--hash=sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002 \
|
||||
--hash=sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e \
|
||||
--hash=sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd \
|
||||
--hash=sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215 \
|
||||
--hash=sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24 \
|
||||
--hash=sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39 \
|
||||
--hash=sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62 \
|
||||
--hash=sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900 \
|
||||
--hash=sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf \
|
||||
--hash=sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735 \
|
||||
--hash=sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4 \
|
||||
--hash=sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23 \
|
||||
--hash=sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9 \
|
||||
--hash=sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c \
|
||||
--hash=sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de \
|
||||
--hash=sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7 \
|
||||
--hash=sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625 \
|
||||
--hash=sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f \
|
||||
--hash=sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a \
|
||||
--hash=sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4 \
|
||||
--hash=sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643 \
|
||||
--hash=sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018 \
|
||||
--hash=sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9 \
|
||||
--hash=sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5 \
|
||||
--hash=sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08 \
|
||||
--hash=sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3 \
|
||||
--hash=sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3 \
|
||||
--hash=sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed \
|
||||
--hash=sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95 \
|
||||
--hash=sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6 \
|
||||
--hash=sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0 \
|
||||
--hash=sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84 \
|
||||
--hash=sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f \
|
||||
--hash=sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d \
|
||||
--hash=sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2 \
|
||||
--hash=sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5 \
|
||||
--hash=sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570 \
|
||||
--hash=sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7 \
|
||||
--hash=sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c \
|
||||
--hash=sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf \
|
||||
--hash=sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3 \
|
||||
--hash=sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed \
|
||||
--hash=sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5
|
||||
# via -r requirements.in
|
||||
typing-extensions==4.9.0 \
|
||||
--hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ async-timeout==4.0.3 \
|
|||
--hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \
|
||||
--hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028
|
||||
# via redis
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ async-timeout==4.0.3 \
|
|||
--hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \
|
||||
--hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028
|
||||
# via redis
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
|
|
@ -1588,7 +1588,7 @@ location /hello {
|
|||
access_page(
|
||||
driver,
|
||||
driver_wait,
|
||||
"//button[@id='profile-button' and @class='valid-btn']",
|
||||
"//button[@id='totp-button' and @class='valid-btn']",
|
||||
"profile",
|
||||
)
|
||||
|
||||
|
|
@ -1667,7 +1667,7 @@ location /hello {
|
|||
access_page(
|
||||
driver,
|
||||
driver_wait,
|
||||
"//button[@id='profile-button' and @class='delete-btn']",
|
||||
"//button[@id='totp-button' and @class='delete-btn']",
|
||||
"profile",
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
#
|
||||
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
|
||||
#
|
||||
attrs==23.1.0 \
|
||||
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
|
||||
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
|
||||
attrs==23.2.0 \
|
||||
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
|
||||
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
# via
|
||||
# outcome
|
||||
# trio
|
||||
|
|
|
|||
Loading…
Reference in a new issue