mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
building out databases and config files
This commit is contained in:
parent
2f12f95ab2
commit
85a69954ea
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
**/logs
|
||||
*.log
|
||||
*.sqlite
|
||||
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
@ -17,6 +17,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from OpenSSL import crypto
|
||||
from argon2 import PasswordHasher
|
||||
|
||||
except ModuleNotFoundError as e:
|
||||
logger.critical("Import Error: Unable to load {} module".format(e, e.name))
|
||||
@ -29,23 +30,24 @@ class Helpers:
|
||||
self.root_dir = os.path.abspath(os.path.curdir)
|
||||
self.config_dir = os.path.join(self.root_dir, 'app', 'config')
|
||||
self.session_file = os.path.join(self.root_dir, 'session.lock')
|
||||
self.settings_file = os.path.join(self.root_dir, 'config.ini')
|
||||
self.webroot = os.path.join(self.root_dir, 'app', 'frontend')
|
||||
self.db_path = os.path.join(self.root_dir, 'app', 'config', 'commander.sqlite')
|
||||
self.db_path = os.path.join(self.root_dir, 'commander.sqlite')
|
||||
self.passhasher = PasswordHasher()
|
||||
self.exiting = False
|
||||
|
||||
def get_setting(self, section, key):
|
||||
config_file = os.path.join(self.config_dir, 'config.ini')
|
||||
|
||||
try:
|
||||
our_config = configparser.ConfigParser()
|
||||
our_config.read(config_file)
|
||||
our_config.read(self.settings_file)
|
||||
|
||||
if our_config.has_option(section, key):
|
||||
return our_config[section][key]
|
||||
|
||||
except Exception as e:
|
||||
logger.critical("Config File Error: Unable to read {} due to {}".format(config_file, e))
|
||||
console.critical("Config File Error: Unable to read {} due to {}".format(config_file, e))
|
||||
logger.critical("Config File Error: Unable to read {} due to {}".format(self.settings_file, e))
|
||||
console.critical("Config File Error: Unable to read {} due to {}".format(self.settings_file, e))
|
||||
|
||||
return False
|
||||
|
||||
@ -82,6 +84,17 @@ class Helpers:
|
||||
console.critical("Unable to create exit file!")
|
||||
sys.exit(1)
|
||||
|
||||
def encode_pass(self, password):
|
||||
return self.passhasher.hash(password)
|
||||
|
||||
def verify_pass(self, password, currenthash):
|
||||
try:
|
||||
self.passhasher.verify(currenthash, password)
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def check_writeable(path: str):
|
||||
filename = os.path.join(path, "tempfile.txt")
|
||||
@ -97,20 +110,20 @@ class Helpers:
|
||||
return False
|
||||
|
||||
def ensure_logging_setup(self):
|
||||
log_file = os.path.join(os.path.curdir, 'app', 'logs', 'commander.log')
|
||||
log_file = os.path.join(os.path.curdir, 'logs', 'commander.log')
|
||||
|
||||
logger.info("Checking app directory writable")
|
||||
|
||||
writeable = self.check_writeable(os.path.join(os.path.curdir, 'app'))
|
||||
writeable = self.check_writeable(self.root_dir)
|
||||
|
||||
# if not writeable, let's bomb out
|
||||
if not writeable:
|
||||
logger.critical("Unable to write to app directory!")
|
||||
logger.critical("Unable to write to {} directory!".format(self.root_dir))
|
||||
sys.exit(1)
|
||||
|
||||
# ensure the log directory is there
|
||||
try:
|
||||
os.makedirs(os.path.join(os.path.curdir, 'app', 'logs'))
|
||||
os.makedirs(os.path.join(self.root_dir, 'logs'))
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
@ -121,9 +134,9 @@ class Helpers:
|
||||
console.critical("Unable to open log file!")
|
||||
sys.exit(1)
|
||||
|
||||
# del any old session.log file as this is a new session
|
||||
# del any old session.lock file as this is a new session
|
||||
try:
|
||||
os.remove(os.path.join(os.path.curdir, "app", "logs", "session.log"))
|
||||
os.remove(self.session_file)
|
||||
except:
|
||||
pass
|
||||
|
||||
@ -308,4 +321,5 @@ class Helpers:
|
||||
"""
|
||||
return ''.join(random.choice(chars) for x in range(size))
|
||||
|
||||
|
||||
helper = Helpers()
|
||||
|
103
app/classes/shared/models.py
Normal file
103
app/classes/shared/models.py
Normal file
@ -0,0 +1,103 @@
|
||||
import sys
|
||||
import logging
|
||||
import datetime
|
||||
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.shared.console import console
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from peewee import *
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
|
||||
except ModuleNotFoundError as e:
|
||||
logger.critical("Import Error: Unable to load {} module".format(e, e.name))
|
||||
console.critical("Import Error: Unable to load {} module".format(e, e.name))
|
||||
sys.exit(1)
|
||||
|
||||
database = SqliteDatabase(helper.db_path, pragmas={
|
||||
'journal_mode': 'wal',
|
||||
'cache_size': -1024 * 10})
|
||||
|
||||
|
||||
class BaseModel(Model):
|
||||
class Meta:
|
||||
database = database
|
||||
|
||||
|
||||
class Users(BaseModel):
|
||||
user_id = AutoField()
|
||||
created = DateTimeField(default=datetime.datetime.now)
|
||||
last_login = DateTimeField(default=datetime.datetime.now)
|
||||
last_ip = CharField(default="")
|
||||
username = CharField(default="")
|
||||
password = CharField(default="")
|
||||
enabled = BooleanField(default=True)
|
||||
api_token = CharField(default="")
|
||||
allowed_servers = CharField(default="[]")
|
||||
|
||||
class Meta:
|
||||
table_name = "users"
|
||||
|
||||
|
||||
class Host_Stats(BaseModel):
|
||||
time = DateTimeField(default=datetime.datetime.now)
|
||||
boot_time = CharField(default="")
|
||||
cpu_usage = FloatField(default=0)
|
||||
cpu_cores = IntegerField(default=0)
|
||||
cpu_cur_freq = FloatField(default=0)
|
||||
cpu_max_freq = FloatField(default=0)
|
||||
mem_percent = FloatField(default=0)
|
||||
mem_usage = CharField(default="")
|
||||
mem_total = CharField(default="")
|
||||
disk_percent = FloatField(default=0)
|
||||
disk_usage = CharField(default="")
|
||||
disk_total = CharField(default="")
|
||||
|
||||
class Meta:
|
||||
table_name = "host_stats"
|
||||
|
||||
|
||||
class Webhooks(BaseModel):
|
||||
id = AutoField()
|
||||
name = CharField(max_length=64, unique=True)
|
||||
method = CharField(default="POST")
|
||||
url = CharField(unique=True)
|
||||
event = CharField(default="")
|
||||
send_data = BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
table_name = "webhooks"
|
||||
|
||||
|
||||
class Backups(BaseModel):
|
||||
directories = CharField()
|
||||
storage_location = CharField()
|
||||
max_backups = IntegerField()
|
||||
server_id = IntegerField()
|
||||
|
||||
class Meta:
|
||||
table_name = 'backups'
|
||||
|
||||
class db_builder:
|
||||
|
||||
@staticmethod
|
||||
def create_tables():
|
||||
with database:
|
||||
database.create_tables([
|
||||
Backups,
|
||||
Users,
|
||||
Host_Stats,
|
||||
Webhooks
|
||||
])
|
||||
|
||||
def default_settings(self):
|
||||
Users.insert({
|
||||
Users.username: 'Admin',
|
||||
Users.password: helper.encode_pass('asdfasdf'),
|
||||
Users.api_token: helper.random_string_generator(32),
|
||||
Users.enabled: True
|
||||
}).execute()
|
||||
|
||||
installer = db_builder()
|
@ -38,9 +38,12 @@ class PublicHandler(BaseHandler):
|
||||
self.clear_cookie("user")
|
||||
self.clear_cookie("user_data")
|
||||
|
||||
error = bleach.clean(self.get_argument('error', ""))
|
||||
template = "public/404.html"
|
||||
# print(page)
|
||||
|
||||
if page is None:
|
||||
self.redirect("public/login")
|
||||
|
||||
error = bleach.clean(self.get_argument('error', ""))
|
||||
|
||||
if error:
|
||||
error_msg = "Invalid Login!"
|
||||
@ -57,3 +60,44 @@ class PublicHandler(BaseHandler):
|
||||
|
||||
self.render(template, data=context)
|
||||
|
||||
def post(self, page=None):
|
||||
|
||||
if page == 'login':
|
||||
next_page = "/public/login"
|
||||
|
||||
entered_email = bleach.clean(self.get_argument('email'))
|
||||
entered_password = bleach.clean(self.get_argument('password'))
|
||||
|
||||
user_data = Users.get_or_none(Users.email_address == entered_email)
|
||||
|
||||
# if we already have a user with this email...
|
||||
if not user_data:
|
||||
next_page = "/public/login?error=Login_Failed"
|
||||
self.redirect(next_page)
|
||||
return False
|
||||
|
||||
login_result = helper.verify_pass(entered_password, user_data.password)
|
||||
|
||||
# Valid Login
|
||||
if login_result:
|
||||
self.set_current_user(entered_email)
|
||||
logger.info("User: {} Logged in from IP: {}".format(entered_email, self.get_remote_ip()))
|
||||
|
||||
Users.update({
|
||||
Users.last_ip: self.get_remote_ip()
|
||||
}).execute()
|
||||
|
||||
cookie_data = {
|
||||
"user_email": user_data.email_address,
|
||||
"user_id": user_data,
|
||||
"account_type": str(user_data.account_type).upper(),
|
||||
|
||||
}
|
||||
|
||||
self.set_secure_cookie('user_data', json.dumps(cookie_data))
|
||||
|
||||
next_page = "/pro/dashboard"
|
||||
self.redirect(next_page)
|
||||
else:
|
||||
self.redirect("/public/login")
|
||||
|
||||
|
@ -84,7 +84,10 @@ class webserver:
|
||||
debug_errors = helper.get_setting("WEB", 'show_errors')
|
||||
cookie_secret = helper.get_setting("WEB", 'cookie_secret')
|
||||
|
||||
if cookie_secret.lower == "random" or cookie_secret is False:
|
||||
if cookie_secret is False:
|
||||
cookie_secret = helper.random_string_generator(32)
|
||||
|
||||
if cookie_secret.lower == "random":
|
||||
cookie_secret = helper.random_string_generator(32)
|
||||
|
||||
if not lang:
|
||||
@ -114,6 +117,7 @@ class webserver:
|
||||
|
||||
handlers = [
|
||||
(r'/', PublicHandler),
|
||||
(r'/public/(.*)', PublicHandler),
|
||||
]
|
||||
|
||||
app = tornado.web.Application(
|
||||
|
@ -17,7 +17,7 @@
|
||||
"main_file_handler": {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"formatter": "commander",
|
||||
"filename": "app/logs/commander.log",
|
||||
"filename": "logs/commander.log",
|
||||
"maxBytes": 5242880,
|
||||
"backupCount": 20,
|
||||
"encoding": "utf8"
|
||||
@ -25,7 +25,7 @@
|
||||
"session_file_handler": {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"formatter": "commander",
|
||||
"filename": "app/logs/session.log",
|
||||
"filename": "logs/session.log",
|
||||
"backupCount": 0,
|
||||
"encoding": "utf8"
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
<img src="/static/assets/images/logo_long.jpg">
|
||||
</div>
|
||||
<form action="/public/login" method="post">
|
||||
{% raw xsrf_form_html() %}
|
||||
<div class="form-group">
|
||||
<label class="label">Email</label>
|
||||
<div class="input-group">
|
||||
|
5
main.py
5
main.py
@ -8,7 +8,7 @@ import logging.config
|
||||
""" Our custom classes / pip packages """
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.shared.helpers import helper
|
||||
|
||||
from app.classes.shared.models import installer
|
||||
from app.classes.shared.tasks import tasks_manager
|
||||
|
||||
def do_intro():
|
||||
@ -89,6 +89,9 @@ if __name__ == '__main__':
|
||||
# this should always be last
|
||||
tasks_manager.start_main_kill_switch_watcher()
|
||||
|
||||
installer.create_tables()
|
||||
installer.default_settings()
|
||||
|
||||
# our main loop
|
||||
while True:
|
||||
if tasks_manager.get_main_thread_run_status():
|
||||
|
Loading…
Reference in New Issue
Block a user