Add lockout user for forgot password

Hide lockout user from users list
This commit is contained in:
amcmanu3 2024-01-16 15:36:14 -05:00
parent c89dbed26c
commit 3d4153f941
7 changed files with 102 additions and 4 deletions

View File

@ -1,5 +1,9 @@
import logging
import typing as t
import datetime
import os
import json
from apscheduler.schedulers.background import BackgroundScheduler
from app.classes.models.servers import HelperServers
from app.classes.models.users import HelperUsers
@ -22,6 +26,7 @@ class UsersController:
self.helper = helper
self.users_helper = users_helper
self.authentication = authentication
self.scheduler = BackgroundScheduler(timezone="Etc/UTC")
_permissions_props = {
"name": {
@ -353,3 +358,41 @@ class UsersController:
def delete_user_api_key(self, key_id: str):
return self.users_helper.delete_user_api_key(key_id)
# **********************************************************************************
# Lockout Methods
# **********************************************************************************
def start_anti_lockout(self, app_dir):
lockout_pass = self.helper.create_pass()
self.users_helper.add_user(
"anti-lockout-user",
None,
password=lockout_pass,
email="",
enabled=True,
superuser=True,
theme="ronald",
)
with open(
os.path.join(app_dir, "app", "config", "anti-lockout.txt"),
"w",
encoding="utf-8",
) as cred_file:
cred_file.write(
json.dumps(
{"username": "anti-lockout-user", "password": lockout_pass},
indent=4,
)
)
os.chmod(os.path.join(app_dir, "app", "config", "anti-lockout.txt"), 0o600)
self.scheduler.add_job(
self.stop_anti_lockout,
"interval",
hours=1,
id="anti-lockout-watcher",
start_date=datetime.datetime.now(),
)
def stop_anti_lockout(self):
self.scheduler.remove_all_jobs()
self.users_helper.remove_user(self.get_id_by_name("anti-lockout-user"))

View File

@ -103,7 +103,9 @@ class HelperUsers:
@staticmethod
def get_all_users():
query = Users.select().where(Users.username != "system")
query = Users.select().where(
Users.username != "system", Users.username != "anti-lockout-user"
)
return query
@staticmethod

View File

@ -12,6 +12,7 @@ from app.classes.shared.file_helpers import FileHelpers
from app.classes.shared.main_controller import Controller
from app.classes.shared.translation import Translation
from app.classes.shared.main_models import DatabaseShortcuts
from app.classes.models.users import DoesNotExist
logger = logging.getLogger(__name__)
auth_log = logging.getLogger("auth")
@ -91,7 +92,10 @@ class BaseHandler(tornado.web.RequestHandler):
t.Dict[str, t.Any]: The token's payload.
t.Dict[str, t.Any]: The user's data from the database.
"""
return self.controller.authentication.check(self.get_cookie("token"))
try:
return self.controller.authentication.check(self.get_cookie("token"))
except DoesNotExist:
return None
def autobleach(self, name, text):
for r in self.redactables:

View File

@ -79,6 +79,7 @@ from app.classes.web.routes.api.crafty.stats.stats import ApiCraftyHostStatsHand
from app.classes.web.routes.api.crafty.clogs.index import ApiCraftyLogIndexHandler
from app.classes.web.routes.api.crafty.imports.index import ApiImportFilesIndexHandler
from app.classes.web.routes.api.crafty.exe_cache import ApiCraftyJarCacheIndexHandler
from app.classes.web.routes.api.crafty.antilockout.index import ApiCraftyLockoutHandler
def api_handlers(handler_args):
@ -94,6 +95,11 @@ def api_handlers(handler_args):
ApiAuthInvalidateTokensHandler,
handler_args,
),
(
r"/api/v2/crafty/resetPass/?",
ApiCraftyLockoutHandler,
handler_args,
),
(
r"/api/v2/crafty/announcements/?",
ApiAnnounceIndexHandler,

View File

@ -0,0 +1,24 @@
import logging
from app.classes.web.base_api_handler import BaseApiHandler
logger = logging.getLogger(__name__)
class ApiCraftyLockoutHandler(BaseApiHandler):
def get(self):
if self.controller.users.get_id_by_name("anti-lockout-user"):
return self.finish_json(
425, {"status": "error", "data": "Lockout recovery already in progress"}
)
self.controller.users.start_anti_lockout(self.controller.project_root)
lockout_msg = (
"Lockout account has been activated for 1 hour."
" Please find credentials in confg/anti-lockout.txt"
)
return self.finish_json(
200,
{
"status": "ok",
"data": lockout_msg,
},
)

View File

@ -112,8 +112,8 @@
<div class="form-check form-check-flat mt-0">
&nbsp;
</div>
<a href="#" class="text-small forgot-password ">{{ translate('login', 'forgotPassword',
data['lang']) }}</a>
<button onclick="resetPass()" id="#resetPass" form="" class="btn btn-outline-primary btn-sm forgot-password ">{{ translate('login', 'forgotPassword',
data['lang']) }}</button>
</div>
<div class="text-block text-center my-3">
@ -146,6 +146,7 @@
<script src="/static/assets/js/shared/misc.js"></script>
<script src="/static/assets/js/shared/settings.js"></script>
<script src="/static/assets/js/shared/todolist.js"></script>
<script src="../static/assets/vendors/js/bootbox.min.js"></script>
<!-- endinject -->
<script>
$(document).ready(function () {
@ -160,8 +161,24 @@
});
}
});
async function resetPass(){
let res = await fetch(`/api/v2/crafty/resetPass/`, {
method: 'GET',
});
let responseData = await res.json();
console.log(responseData);
bootbox.alert(responseData.data)
}
</script>
<style>
.modal-content {
background-color: rgb(34, 36, 55) !important;
color: lightgray;
text-align: center;
}
</style>
</body>
</html>

View File

@ -388,6 +388,8 @@ if __name__ == "__main__":
# Master config.json in helpers.py
Console.info("Checking for remote changes to config.json")
controller.get_config_diff()
# Delete anti-lockout-user
controller.users.stop_anti_lockout()
Console.info("Remote change complete.")
# startup the web server