mirror of https://github.com/Aidaho12/haproxy-wi
parent
71ed2cc756
commit
85d745f7dd
|
@ -32,7 +32,7 @@ def before_request():
|
|||
|
||||
|
||||
def register_api(view, endpoint, url, pk='listener_id', pk_type='int'):
|
||||
view_func = view.as_view(endpoint)
|
||||
view_func = view.as_view(endpoint, True)
|
||||
bp.add_url_rule(url, view_func=view_func, methods=['POST'])
|
||||
bp.add_url_rule(f'{url}/<{pk_type}:{pk}>', view_func=view_func, methods=['GET', 'PUT', 'PATCH', 'DELETE'])
|
||||
|
||||
|
|
|
@ -469,30 +469,6 @@ def update_db_v_4_3_0():
|
|||
print("An error occurred:", e)
|
||||
|
||||
|
||||
def update_db_v_7_1_2():
|
||||
try:
|
||||
Setting.delete().where(Setting.param == 'stats_user').execute()
|
||||
Setting.delete().where(Setting.param == 'stats_password').execute()
|
||||
Setting.delete().where(Setting.param == 'stats_port').execute()
|
||||
Setting.delete().where(Setting.param == 'stats_page').execute()
|
||||
except Exception as e:
|
||||
print("An error occurred:", e)
|
||||
else:
|
||||
print("Updating... DB has been updated to version 7.1.2")
|
||||
|
||||
|
||||
def update_db_v_7_1_2_1():
|
||||
try:
|
||||
migrate(
|
||||
migrator.add_column('cred', 'passphrase', CharField(null=True))
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'duplicate column name: passphrase' or str(e) == '(1060, "Duplicate column name \'passphrase\'")':
|
||||
print('Updating... DB has been updated to version 7.1.2-1')
|
||||
else:
|
||||
print("An error occurred:", e)
|
||||
|
||||
|
||||
def update_db_v_7_2_0():
|
||||
try:
|
||||
if mysql_enable:
|
||||
|
@ -620,9 +596,26 @@ def update_db_v_8():
|
|||
print("An error occurred:", e)
|
||||
|
||||
|
||||
def update_db_v_8_0_2():
|
||||
try:
|
||||
if mysql_enable:
|
||||
migrate(
|
||||
migrator.add_column('cred', 'shared', IntegerField(default=0)),
|
||||
)
|
||||
else:
|
||||
migrate(
|
||||
migrator.add_column('cred', 'shared', IntegerField(constraints=[SQL('DEFAULT 0')])),
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'duplicate column name: shared' or str(e) == '(1060, "Duplicate column name \'shared\'")':
|
||||
print('Updating... DB has been updated to version 8.0.2')
|
||||
else:
|
||||
print("An error occurred:", e)
|
||||
|
||||
|
||||
def update_ver():
|
||||
try:
|
||||
Version.update(version='8.0.1').execute()
|
||||
Version.update(version='8.0.2').execute()
|
||||
except Exception:
|
||||
print('Cannot update version')
|
||||
|
||||
|
@ -640,12 +633,11 @@ def update_all():
|
|||
if check_ver() is None:
|
||||
update_db_v_3_4_5_22()
|
||||
update_db_v_4_3_0()
|
||||
update_db_v_7_1_2()
|
||||
update_db_v_7_1_2_1()
|
||||
update_db_v_7_2_0()
|
||||
update_db_v_7_2_0_1()
|
||||
update_db_v_7_2_3()
|
||||
update_db_v_7_3_1()
|
||||
update_db_v_7_4()
|
||||
update_db_v_8()
|
||||
update_db_v_8_0_2()
|
||||
update_ver()
|
||||
|
|
|
@ -2,6 +2,8 @@ import os
|
|||
import sys
|
||||
import traceback
|
||||
|
||||
from app.modules.roxywi.exception import RoxywiConflictError
|
||||
|
||||
|
||||
def out_error(error):
|
||||
error = str(error)
|
||||
|
@ -11,3 +13,11 @@ def out_error(error):
|
|||
function_name = stk[0][2]
|
||||
error = f'{error} in function: {function_name} in file: {file_name}'
|
||||
raise Exception(f'error: {error}')
|
||||
|
||||
|
||||
def not_unique_error(error):
|
||||
if error.args[0] == 1062:
|
||||
col = error.args[1].split('key ')[1]
|
||||
else:
|
||||
col = error.args[0].split(': ')[-1]
|
||||
raise RoxywiConflictError(f'{col} must be uniq')
|
||||
|
|
|
@ -4,8 +4,15 @@ from app.modules.roxywi.exception import RoxywiResourceNotFound
|
|||
|
||||
|
||||
def select_ssh(**kwargs):
|
||||
if kwargs.get("group") and kwargs.get("cred_id"):
|
||||
query = Cred.select().where((Cred.id == kwargs.get('cred_id')) & (Cred.group_id == kwargs.get('group')))
|
||||
if kwargs.get("group") and kwargs.get("cred_id") and kwargs.get("not_shared"):
|
||||
query = Cred.select().where(
|
||||
((Cred.id == kwargs.get('cred_id')) & (Cred.group_id == kwargs.get('group')))
|
||||
)
|
||||
elif kwargs.get("group") and kwargs.get("cred_id"):
|
||||
query = Cred.select().where(
|
||||
((Cred.id == kwargs.get('cred_id')) & (Cred.group_id == kwargs.get('group'))) |
|
||||
(Cred.shared == 1)
|
||||
)
|
||||
elif kwargs.get("name") is not None:
|
||||
query = Cred.select().where(Cred.name == kwargs.get('name'))
|
||||
elif kwargs.get("id") is not None:
|
||||
|
@ -13,7 +20,7 @@ def select_ssh(**kwargs):
|
|||
elif kwargs.get("serv") is not None:
|
||||
query = Cred.select().join(Server, on=(Cred.id == Server.cred_id)).where(Server.ip == kwargs.get('serv'))
|
||||
elif kwargs.get("group") is not None:
|
||||
query = Cred.select().where(Cred.group_id == kwargs.get("group"))
|
||||
query = Cred.select().where((Cred.group_id == kwargs.get("group")) | (Cred.shared == 1))
|
||||
else:
|
||||
query = Cred.select()
|
||||
try:
|
||||
|
@ -26,11 +33,11 @@ def select_ssh(**kwargs):
|
|||
return query_res
|
||||
|
||||
|
||||
def insert_new_ssh(name, enable, group, username, password):
|
||||
def insert_new_ssh(name, enable, group, username, password, shared):
|
||||
if password is None:
|
||||
password = 'None'
|
||||
try:
|
||||
return Cred.insert(name=name, key_enabled=enable, group_id=group, username=username, password=password).execute()
|
||||
return Cred.insert(name=name, key_enabled=enable, group_id=group, username=username, password=password, shared=shared).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
@ -45,21 +52,22 @@ def delete_ssh(ssh_id):
|
|||
return True
|
||||
|
||||
|
||||
def update_ssh(cred_id, name, enable, group, username, password):
|
||||
def update_ssh(cred_id: int, name: str, enable: int, group: int, username: str, password: bytes, shared: int):
|
||||
if password is None:
|
||||
password = 'None'
|
||||
|
||||
cred_update = Cred.update(name=name, key_enabled=enable, group_id=group, username=username, password=password).where(
|
||||
Cred.id == cred_id)
|
||||
cred_update = Cred.update(
|
||||
name=name, key_enabled=enable, group_id=group, username=username, password=password, shared=shared
|
||||
).where(Cred.id == cred_id)
|
||||
try:
|
||||
cred_update.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
||||
def update_ssh_passphrase(name: str, passphrase: str):
|
||||
def update_ssh_passphrase(cred_id: int, passphrase: str):
|
||||
try:
|
||||
Cred.update(passphrase=passphrase).where(Cred.name == name).execute()
|
||||
Cred.update(passphrase=passphrase).where(Cred.id == cred_id).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
|
|
@ -196,6 +196,7 @@ class Cred(BaseModel):
|
|||
password = CharField(null=True)
|
||||
group_id = IntegerField(constraints=[SQL('DEFAULT 1')])
|
||||
passphrase = CharField(null=True)
|
||||
shared = IntegerField(constraints=[SQL('DEFAULT 0')])
|
||||
|
||||
class Meta:
|
||||
table_name = 'cred'
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from peewee import IntegrityError
|
||||
|
||||
from app.modules.db.db_model import mysql_enable, connect, Server, SystemInfo
|
||||
from app.modules.db.common import out_error
|
||||
from app.modules.db.common import out_error, not_unique_error
|
||||
from app.modules.roxywi.exception import RoxywiResourceNotFound
|
||||
|
||||
|
||||
|
@ -10,9 +12,10 @@ def add_server(hostname, ip, group, type_ip, enable, master, cred, port, desc, h
|
|||
port=port, description=desc, haproxy=haproxy, nginx=nginx, apache=apache, firewall_enable=firewall
|
||||
).execute()
|
||||
return server_id
|
||||
except IntegrityError as e:
|
||||
not_unique_error(e)
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
return False
|
||||
|
||||
|
||||
def delete_server(server_id):
|
||||
|
|
|
@ -139,6 +139,7 @@ class CredRequest(BaseModel):
|
|||
password: Optional[EscapedString] = None
|
||||
key_enabled: Optional[bool] = 1
|
||||
group_id: Optional[int] = None
|
||||
shared: Optional[int] = 0
|
||||
|
||||
|
||||
class CredUploadRequest(BaseModel):
|
||||
|
|
|
@ -16,7 +16,8 @@ import app.modules.db.history as history_sql
|
|||
import app.modules.db.ha_cluster as ha_sql
|
||||
import app.modules.roxy_wi_tools as roxy_wi_tools
|
||||
from app.modules.roxywi.class_models import ErrorResponse
|
||||
from app.modules.roxywi.exception import RoxywiResourceNotFound, RoxywiGroupMismatch, RoxywiGroupNotFound
|
||||
from app.modules.roxywi.exception import RoxywiResourceNotFound, RoxywiGroupMismatch, RoxywiGroupNotFound, \
|
||||
RoxywiPermissionError
|
||||
|
||||
get_config_var = roxy_wi_tools.GetConfigVar()
|
||||
|
||||
|
@ -334,5 +335,7 @@ def handler_exceptions_for_json_data(ex: Exception, main_ex_mes: str) -> tuple[d
|
|||
return handle_json_exceptions(ex, 'Group not found'), 404
|
||||
elif isinstance(ex, RoxywiGroupMismatch):
|
||||
return handle_json_exceptions(ex, 'Resource not found in group'), 404
|
||||
elif isinstance(ex, RoxywiPermissionError):
|
||||
return handle_json_exceptions(ex, 'You cannot edit this resource'), 403
|
||||
else:
|
||||
return handle_json_exceptions(ex, main_ex_mes), 500
|
||||
|
|
|
@ -31,3 +31,17 @@ class RoxywiValidationError(Exception):
|
|||
|
||||
def __init__(self, message='Validation error'):
|
||||
super(RoxywiValidationError, self).__init__(message)
|
||||
|
||||
|
||||
class RoxywiPermissionError(Exception):
|
||||
""" This class represents an exception raised when a permission error occurs. """
|
||||
|
||||
def __init__(self, message='Forbidden'):
|
||||
super(RoxywiPermissionError, self).__init__(message)
|
||||
|
||||
|
||||
class RoxywiConflictError(Exception):
|
||||
""" This class represents an exception raised when a conflict error occurs."""
|
||||
|
||||
def __init__(self, message='Conflict'):
|
||||
super(RoxywiConflictError, self).__init__(message)
|
||||
|
|
|
@ -13,14 +13,13 @@ import app.modules.common.common as common
|
|||
from app.modules.server import ssh_connection
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.roxy_wi_tools as roxy_wi_tools
|
||||
from app.modules.roxywi.class_models import IdResponse, IdDataResponse
|
||||
from app.modules.roxywi.class_models import IdResponse, IdDataResponse, CredRequest
|
||||
|
||||
error_mess = common.error_mess
|
||||
get_config = roxy_wi_tools.GetConfigVar()
|
||||
|
||||
|
||||
def return_ssh_keys_path(server_ip: str, **kwargs) -> dict:
|
||||
lib_path = get_config.get_config_var('main', 'lib_path')
|
||||
ssh_settings = {}
|
||||
if kwargs.get('id'):
|
||||
sshs = cred_sql.select_ssh(id=kwargs.get('id'))
|
||||
|
@ -43,10 +42,10 @@ def return_ssh_keys_path(server_ip: str, **kwargs) -> dict:
|
|||
else:
|
||||
passphrase = ssh.passphrase
|
||||
|
||||
ssh_key = _return_correct_ssh_file(ssh)
|
||||
ssh_settings.setdefault('enabled', ssh.key_enabled)
|
||||
ssh_settings.setdefault('user', ssh.username)
|
||||
ssh_settings.setdefault('password', password)
|
||||
ssh_key = f'{lib_path}/keys/{ssh.name}.pem' if ssh.key_enabled == 1 else ''
|
||||
ssh_settings.setdefault('key', ssh_key)
|
||||
ssh_settings.setdefault('passphrase', passphrase)
|
||||
|
||||
|
@ -66,10 +65,8 @@ def ssh_connect(server_ip):
|
|||
return ssh
|
||||
|
||||
|
||||
def create_ssh_cred(name: str, password: str, group: int, username: str, enable: int, is_api: int) -> dict:
|
||||
group_name = group_sql.get_group_name_by_id(group)
|
||||
def create_ssh_cred(name: str, password: str, group: int, username: str, enable: int, is_api: int, shared: int) -> dict:
|
||||
lang = roxywi_common.get_user_lang_for_flask()
|
||||
name = f'{name}_{group_name}'
|
||||
if password and password != "''":
|
||||
try:
|
||||
password = crypt_password(password)
|
||||
|
@ -79,43 +76,20 @@ def create_ssh_cred(name: str, password: str, group: int, username: str, enable:
|
|||
password = ''
|
||||
|
||||
try:
|
||||
last_id = cred_sql.insert_new_ssh(name, enable, group, username, password)
|
||||
last_id = cred_sql.insert_new_ssh(name, enable, group, username, password, shared)
|
||||
except Exception as e:
|
||||
return roxywi_common.handle_json_exceptions(e, 'Cannot create new SSH credentials')
|
||||
roxywi_common.logging('RMON server', f'New SSH credentials {name} has been created', roxywi=1, login=1)
|
||||
roxywi_common.logging('Roxy-WI server', f'New SSH credentials {name} has been created', roxywi=1, login=1)
|
||||
|
||||
if is_api:
|
||||
return IdResponse(id=last_id).model_dump(mode='json')
|
||||
else:
|
||||
data = render_template('ajax/new_ssh.html', groups=group_sql.select_groups(), sshs=cred_sql.select_ssh(name=name), lang=lang)
|
||||
data = render_template('ajax/new_ssh.html',
|
||||
groups=group_sql.select_groups(), sshs=cred_sql.select_ssh(name=name), lang=lang, adding=1
|
||||
)
|
||||
return IdDataResponse(id=last_id, data=data).model_dump(mode='json')
|
||||
|
||||
|
||||
def create_ssh_cred_api(name: str, enable: str, group: str, username: str, password: str) -> bool:
|
||||
group_name = group_sql.get_group_name_by_id(group)
|
||||
name = common.checkAjaxInput(name)
|
||||
name = f'{name}_{group_name}'
|
||||
enable = common.checkAjaxInput(enable)
|
||||
username = common.checkAjaxInput(username)
|
||||
password = common.checkAjaxInput(password)
|
||||
|
||||
if password != '':
|
||||
try:
|
||||
password = crypt_password(password)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
if username is None or name is None:
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
cred_sql.insert_new_ssh(name, enable, group, username, password)
|
||||
roxywi_common.logging('Roxy-WI server', f'New SSH credentials {name} has been created', roxywi=1)
|
||||
return True
|
||||
except Exception as e:
|
||||
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot create SSH credentials {name}', roxywi=1)
|
||||
|
||||
|
||||
def upload_ssh_key(ssh_id: int, key: str, passphrase: str) -> None:
|
||||
key = key.replace("'", "")
|
||||
ssh = cred_sql.get_ssh(ssh_id)
|
||||
|
@ -123,37 +97,23 @@ def upload_ssh_key(ssh_id: int, key: str, passphrase: str) -> None:
|
|||
lib_path = get_config.get_config_var('main', 'lib_path')
|
||||
full_dir = f'{lib_path}/keys/'
|
||||
name = ssh.name
|
||||
ssh_keys = f'{name}.pem'
|
||||
ssh_keys = f'{full_dir}{name}_{group_name}.pem'
|
||||
|
||||
try:
|
||||
key = paramiko.pkey.load_private_key(key, password=passphrase)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
if key != '':
|
||||
try:
|
||||
key = paramiko.pkey.load_private_key(key, password=passphrase)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
try:
|
||||
_ = name.split('_')[1]
|
||||
split_name = True
|
||||
except Exception:
|
||||
split_name = False
|
||||
try:
|
||||
key.write_private_key_file(ssh_keys)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
if not os.path.isfile(ssh_keys) and not split_name:
|
||||
name = f'{ssh.name}_{group_name}'
|
||||
|
||||
if not os.path.exists(full_dir):
|
||||
os.makedirs(full_dir)
|
||||
|
||||
ssh_keys = f'{full_dir}{name}.pem'
|
||||
|
||||
try:
|
||||
key.write_private_key_file(ssh_keys)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
try:
|
||||
os.chmod(ssh_keys, 0o600)
|
||||
except IOError as e:
|
||||
roxywi_common.logging('RMON server', e.args[0], roxywi=1)
|
||||
raise Exception(e)
|
||||
try:
|
||||
os.chmod(ssh_keys, 0o600)
|
||||
except IOError as e:
|
||||
raise Exception(e)
|
||||
|
||||
if passphrase:
|
||||
try:
|
||||
|
@ -168,54 +128,48 @@ def upload_ssh_key(ssh_id: int, key: str, passphrase: str) -> None:
|
|||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
roxywi_common.logging("RMON server", f"A new SSH cert has been uploaded {ssh_keys}", roxywi=1, login=1)
|
||||
roxywi_common.logging("Roxy-WI server", f"A new SSH cert has been uploaded {ssh_keys}", roxywi=1, login=1)
|
||||
|
||||
|
||||
def update_ssh_key(ssh_id: int, name: str, password: str, enable: int, username: str, group: int) -> None:
|
||||
lib_path = get_config.get_config_var('main', 'lib_path')
|
||||
def update_ssh_key(body: CredRequest, group_id: int, ssh_id: int) -> None:
|
||||
ssh = cred_sql.get_ssh(ssh_id)
|
||||
ssh_key_name = f'{lib_path}/keys/{ssh.name}.pem'
|
||||
new_ssh_key_name = f'{lib_path}/keys/{name}.pem'
|
||||
ssh_key_name = _return_correct_ssh_file(ssh)
|
||||
|
||||
if password != '':
|
||||
if body.password != '' and body.password is not None:
|
||||
try:
|
||||
password = crypt_password(password)
|
||||
body.password = crypt_password(body.password)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
if ssh.key_enabled == 1 and os.path.isfile(ssh_key_name):
|
||||
if os.path.isfile(ssh_key_name):
|
||||
new_ssh_key_name = _return_correct_ssh_file(body)
|
||||
os.rename(ssh_key_name, new_ssh_key_name)
|
||||
os.chmod(new_ssh_key_name, 0o600)
|
||||
|
||||
try:
|
||||
cred_sql.update_ssh(ssh_id, name, enable, group, username, password)
|
||||
roxywi_common.logging('RMON server', f'The SSH credentials {name} has been updated ', roxywi=1, login=1)
|
||||
cred_sql.update_ssh(ssh_id, body.name, body.key_enabled, group_id, body.username, body.password, body.shared)
|
||||
roxywi_common.logging('Roxy-WI server', f'The SSH credentials {body.name} has been updated ', roxywi=1, login=1)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
|
||||
def delete_ssh_key(ssh_id) -> str:
|
||||
lib_path = get_config.get_config_var('main', 'lib_path')
|
||||
def delete_ssh_key(ssh_id) -> None:
|
||||
name = ''
|
||||
ssh_enable = 0
|
||||
ssh_key_name = ''
|
||||
|
||||
for sshs in cred_sql.select_ssh(id=ssh_id):
|
||||
ssh_enable = sshs.key_enabled
|
||||
name = sshs.name
|
||||
ssh_key_name = f'{lib_path}/keys/{sshs.name}.pem'
|
||||
|
||||
if ssh_enable == 1:
|
||||
try:
|
||||
os.remove(ssh_key_name)
|
||||
except Exception:
|
||||
pass
|
||||
if sshs.key_enabled == 1:
|
||||
ssh_key_name = _return_correct_ssh_file(sshs)
|
||||
try:
|
||||
os.remove(ssh_key_name)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
cred_sql.delete_ssh(ssh_id)
|
||||
roxywi_common.logging('Roxy-WI server', f'The SSH credentials {name} has deleted', roxywi=1, login=1)
|
||||
return 'ok'
|
||||
except Exception as e:
|
||||
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot delete SSH credentials {name}', roxywi=1, login=1)
|
||||
raise e
|
||||
|
||||
|
||||
def crypt_password(password: str) -> bytes:
|
||||
|
@ -248,12 +202,11 @@ def decrypt_password(password: str) -> str:
|
|||
return decryp_pass
|
||||
|
||||
|
||||
def get_creds(group_id: int = None, cred_id: int = None) -> list:
|
||||
def get_creds(group_id: int = None, cred_id: int = None, not_shared: bool = False) -> list:
|
||||
json_data = []
|
||||
lib_path = get_config.get_config_var('main', 'lib_path')
|
||||
|
||||
if group_id and cred_id:
|
||||
creds = cred_sql.select_ssh(group=group_id, cred_id=cred_id)
|
||||
creds = cred_sql.select_ssh(group=group_id, cred_id=cred_id, not_shared=not_shared)
|
||||
elif group_id:
|
||||
creds = cred_sql.select_ssh(group=group_id)
|
||||
else:
|
||||
|
@ -262,15 +215,33 @@ def get_creds(group_id: int = None, cred_id: int = None) -> list:
|
|||
for cred in creds:
|
||||
cred_dict = model_to_dict(cred)
|
||||
cred_dict['name'] = cred_dict['name'].replace("'", "")
|
||||
ssh_key_file = f'{lib_path}/keys/{cred_dict["name"]}.pem'
|
||||
if os.path.isfile(ssh_key_file):
|
||||
with open(ssh_key_file, 'rb') as key:
|
||||
cred_dict['private_key'] = base64.b64encode(key.read()).decode('utf-8')
|
||||
|
||||
if cred.key_enabled == 1:
|
||||
ssh_key_file = _return_correct_ssh_file(cred)
|
||||
if os.path.isfile(ssh_key_file):
|
||||
with open(ssh_key_file, 'rb') as key:
|
||||
cred_dict['private_key'] = base64.b64encode(key.read()).decode('utf-8')
|
||||
else:
|
||||
cred_dict['private_key'] = ''
|
||||
else:
|
||||
cred_dict['private_key'] = ''
|
||||
if cred_dict['password']:
|
||||
cred_dict['password'] = decrypt_password(cred_dict['password'])
|
||||
try:
|
||||
cred_dict['password'] = decrypt_password(cred_dict['password'])
|
||||
except Exception:
|
||||
pass
|
||||
if cred_dict['passphrase']:
|
||||
cred_dict['passphrase'] = decrypt_password(cred_dict['passphrase'])
|
||||
json_data.append(cred_dict)
|
||||
return json_data
|
||||
|
||||
|
||||
def _return_correct_ssh_file(cred: CredRequest) -> str:
|
||||
lib_path = get_config.get_config_var('main', 'lib_path')
|
||||
group_name = group_sql.get_group_name_by_id(cred.group_id)
|
||||
# if not cred.key_enabled:
|
||||
# return ''
|
||||
if group_name not in cred.name:
|
||||
return f'{lib_path}/keys/{cred.name}_{group_name}.pem'
|
||||
else:
|
||||
return f'{lib_path}/keys/{cred.name}.pem'
|
||||
|
|
|
@ -61,6 +61,10 @@ function addCreds(dialog_id) {
|
|||
if ($('#new-ssh_enable').is(':checked')) {
|
||||
ssh_enable = '1';
|
||||
}
|
||||
let ssh_shared = 0;
|
||||
if ($('#new-ssh_shared').is(':checked')) {
|
||||
ssh_shared = '1';
|
||||
}
|
||||
let valid = true;
|
||||
let allFields = $([]).add(ssh_add_div).add($('#ssh_user'))
|
||||
allFields.removeClass("ui-state-error");
|
||||
|
@ -71,7 +75,8 @@ function addCreds(dialog_id) {
|
|||
"name": ssh_add_div.val(),
|
||||
"group_id": $('#new-sshgroup').val(),
|
||||
"username": $('#ssh_user').val(),
|
||||
"pass": $('#ssh_pass').val(),
|
||||
"password": $('#ssh_pass').val(),
|
||||
"shared": ssh_shared,
|
||||
"key_enabled": ssh_enable,
|
||||
}
|
||||
$.ajax({
|
||||
|
@ -113,10 +118,14 @@ function sshKeyEnableShow(id) {
|
|||
function updateSSH(id) {
|
||||
toastr.clear();
|
||||
let ssh_enable = 0;
|
||||
let ssh_shared = 0;
|
||||
let ssh_name_val = $('#ssh_name-' + id).val();
|
||||
if ($('#ssh_enable-' + id).is(':checked')) {
|
||||
ssh_enable = '1';
|
||||
}
|
||||
if ($('#ssh_shared-' + id).is(':checked')) {
|
||||
ssh_shared = '1';
|
||||
}
|
||||
let group = $('#sshgroup-' + id).val();
|
||||
if (group === undefined || group === null) {
|
||||
group = $('#new-sshgroup').val();
|
||||
|
@ -127,6 +136,7 @@ function updateSSH(id) {
|
|||
"key_enabled": ssh_enable,
|
||||
"username": $('#ssh_user-' + id).val(),
|
||||
"password": $('#ssh_pass-' + id).val(),
|
||||
"shared": ssh_shared,
|
||||
}
|
||||
$.ajax({
|
||||
url: "/server/cred/" + id,
|
||||
|
|
|
@ -221,7 +221,7 @@ function createHaClusterStep1(edited=false, cluster_id=0, clean=true) {
|
|||
toastr.error('error: Wrong VIP');
|
||||
return false;
|
||||
}
|
||||
jsonData = createJsonCluster('#enabled-check div div span');
|
||||
let jsonData = createJsonCluster('#enabled-check div div span');
|
||||
if (!validateSlaves(jsonData)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
{% if adding %}
|
||||
{% import 'languages/'+lang|default('en')+'.html' as lang %}
|
||||
{% endif %}
|
||||
{% for ssh in sshs %}
|
||||
<tr style="width: 50%;" id="ssh-table-{{ssh.id}}" class="ssh-table-{{ssh.id}}">
|
||||
<td class="first-collumn padding10">
|
||||
|
@ -24,6 +26,13 @@
|
|||
</select>
|
||||
</td>
|
||||
{% endif %}
|
||||
<td class="first-collumn" valign="top" style="padding-top: 15px;">
|
||||
{% if ssh.shared == 1 %}
|
||||
<label for="ssh_shared-{{ssh.id}}"></label><input type="checkbox" id="ssh_shared-{{ssh.id}}" checked>
|
||||
{% else %}
|
||||
<label for="ssh_shared-{{ssh.id}}"></label><input type="checkbox" id="ssh_shared-{{ssh.id}}">
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="padding-top: 15px;">
|
||||
<p>
|
||||
<input type="text" id="ssh_user-{{ssh.id}}" class="form-control" value="{{ssh.username.replace("'", "")}}">
|
||||
|
@ -39,4 +48,16 @@
|
|||
<a class="delete" onclick="confirmDeleteSsh({{ssh.id}})" title="{{lang.words.delete|title()}} {{ssh.name}}" style="cursor: pointer;"></a>
|
||||
</td>
|
||||
</tr>
|
||||
{% if ssh.shared and g.user_params['group_id']|string() != ssh.group_id|string() %}
|
||||
<script>
|
||||
$( function() {
|
||||
$('#sshgroup-{{ssh.id}}').selectmenu('disable');
|
||||
$('#ssh_shared-{{ssh.id}}').checkboxradio('disable');
|
||||
$('#ssh_enable-{{ssh.id}}').checkboxradio('disable');
|
||||
$('#ssh_name-{{ ssh.id }}').prop('readonly', true);
|
||||
$('#ssh_user-{{ ssh.id }}').prop('readonly', true);
|
||||
$('#ssh_pass-{{ ssh.id }}').prop('readonly', true);
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
|
@ -11,54 +11,13 @@
|
|||
{% if g.user_params['role'] == 1 %}
|
||||
<td style="width: 25%;">{{lang.words.group|title()}}</td>
|
||||
{% endif %}
|
||||
<td>{{ lang.words.shared|title() }}</td>
|
||||
<td style="width: 100%;" class="help_cursor" id="ssh-user-name-td">
|
||||
<span title="Enter SSH user name. If SSH key disabled, enter password for SSH user">{{lang.words.username|title()}}</span>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% for ssh in sshs %}
|
||||
<tr style="width: 50%;" id="ssh-table-{{ssh.id}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="first-collumn padding10">
|
||||
{% set id = 'ssh_name-' + ssh.id|string() %}
|
||||
{{ input(id, value=ssh.name.replace("'", ""), size='15') }}
|
||||
</td>
|
||||
<td class="first-collumn" valign="top" style="padding-top: 15px;">
|
||||
{% if ssh.key_enabled == 1 %}
|
||||
<label for="ssh_enable-{{ssh.id}}">{{lang.words.enable|title()}} SSH {{lang.words.key}}</label><input type="checkbox" id="ssh_enable-{{ssh.id}}" checked>
|
||||
{% else %}
|
||||
<label for="ssh_enable-{{ssh.id}}">{{lang.words.enable|title()}} SSH {{lang.words.key}}</label><input type="checkbox" id="ssh_enable-{{ssh.id}}">
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if g.user_params['role'] == 1 %}
|
||||
<td>
|
||||
<select id="sshgroup-{{ssh.id}}" name="sshgroup-{{ssh.id}}">
|
||||
{% for group in groups %}
|
||||
{% if ssh.group_id == group.group_id %}
|
||||
<option value="{{ group.group_id }}" selected>{{ group.name }}</option>
|
||||
{% else %}
|
||||
<option value="{{ group.group_id }}">{{ group.name }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
{% endif %}
|
||||
<td style="padding-top: 15px;">
|
||||
<p>
|
||||
{% set id = 'ssh_user-' + ssh.id|string() %}
|
||||
{{ input(id, value=ssh.username, title='SSH user name') }}
|
||||
</p>
|
||||
{% if ssh.key_enabled == 1 %}
|
||||
<input type="password" id="ssh_pass-{{ssh.id}}" class="form-control" title="User password, if SSH key is disabled" value="{{ ssh.password }}" style="display: none;" autocomplete="new-password">
|
||||
{% else %}
|
||||
<input type="password" id="ssh_pass-{{ssh.id}}" class="form-control" title="User password, if SSH key is disabled" value="{{ ssh.password }}" autocomplete="new-password">
|
||||
{% endif %}
|
||||
<br>
|
||||
</td>
|
||||
<td>
|
||||
<a class="delete" onclick="confirmDeleteSsh({{ssh.id}})" title="{{lang.words.delete|title()}} SSH {{lang.words.creds}} {{ssh.name}}" style="cursor: pointer;"></a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% include 'ajax/new_ssh.html' %}
|
||||
</table>
|
||||
<br /><span class="add-button" title="{{lang.words.add|title()}} SSH" id="add-ssh-button">+ {{lang.words.add|title()}}</span>
|
||||
<br /><br />
|
||||
|
|
|
@ -127,6 +127,12 @@
|
|||
<label for="new-ssh_enable">{{lang.words.enabled|title()}} SSH {{lang.words.key}}</label><input type="checkbox" id="new-ssh_enable" checked>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="padding20">{{lang.words.shared|title()}}</td>
|
||||
<td>
|
||||
<label for="new-ssh_shared"></label><input type="checkbox" id="new-ssh_shared">
|
||||
</td>
|
||||
</tr>
|
||||
{% if g.user_params['role'] == 1 %}
|
||||
<tr>
|
||||
<td class="padding20">{{lang.words.group|title()}}</td>
|
||||
|
|
|
@ -952,5 +952,6 @@
|
|||
"listeners": "listeners",
|
||||
"weight": "weight",
|
||||
"where": "where",
|
||||
"shared": "shared"
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -952,5 +952,6 @@
|
|||
"listeners": "les auditeurs",
|
||||
"weight": "poids",
|
||||
"where": "où",
|
||||
"shared": "commun"
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -952,5 +952,6 @@
|
|||
"listeners": "ouvintes",
|
||||
"weight": "peso",
|
||||
"where": "onde",
|
||||
"shared": "partilhado"
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -952,5 +952,6 @@
|
|||
"listeners": "слушатели",
|
||||
"weight": "вес",
|
||||
"where": "где",
|
||||
"shared": "общий"
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -9,8 +9,9 @@ import app.modules.db.cred as cred_sql
|
|||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.server.ssh as ssh_mod
|
||||
from app.middleware import get_user_params, page_for_admin, check_group
|
||||
from app.modules.roxywi.exception import RoxywiGroupMismatch, RoxywiResourceNotFound
|
||||
from app.modules.roxywi.class_models import BaseResponse, GroupQuery, CredRequest, CredUploadRequest
|
||||
from app.modules.db.db_model import Cred
|
||||
from app.modules.roxywi.exception import RoxywiGroupMismatch, RoxywiResourceNotFound, RoxywiPermissionError
|
||||
from app.modules.roxywi.class_models import BaseResponse, GroupQuery, CredRequest, CredUploadRequest, ErrorResponse
|
||||
from app.modules.common.common_classes import SupportClass
|
||||
|
||||
|
||||
|
@ -65,12 +66,15 @@ class CredView(MethodView):
|
|||
private_key:
|
||||
type: 'string'
|
||||
description: 'SSH private key in base64 encoded format'
|
||||
shared:
|
||||
type: 'integer'
|
||||
description: 'Is shared credential for other groups or not'
|
||||
404:
|
||||
description: 'Credential not found'
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(query)
|
||||
try:
|
||||
creds = ssh_mod.get_creds(group_id=group_id, cred_id=cred_id)
|
||||
creds = ssh_mod.get_creds(group_id=group_id, cred_id=cred_id, not_shared=True)
|
||||
return jsonify(creds), 200
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get credentials')
|
||||
|
@ -109,13 +113,16 @@ class CredView(MethodView):
|
|||
password:
|
||||
type: string
|
||||
description: The password
|
||||
shared:
|
||||
type: 'integer'
|
||||
description: 'Is shared credential for other groups or not'
|
||||
responses:
|
||||
201:
|
||||
description: Credential addition successful
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(body)
|
||||
try:
|
||||
return ssh_mod.create_ssh_cred(body.name, body.password, group_id, body.username, body.key_enabled, self.is_api)
|
||||
return ssh_mod.create_ssh_cred(body.name, body.password, group_id, body.username, body.key_enabled, self.is_api, body.shared)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create new cred')
|
||||
|
||||
|
@ -157,18 +164,24 @@ class CredView(MethodView):
|
|||
password:
|
||||
type: string
|
||||
description: The password
|
||||
shared:
|
||||
type: 'integer'
|
||||
description: 'Is shared credential for other groups or not'
|
||||
responses:
|
||||
201:
|
||||
description: Credential update successful
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(body)
|
||||
ssh = self._get_ssh(cred_id)
|
||||
if ssh.shared and g.user_params['role'] != 1 and int(group_id) != int(ssh.group_id):
|
||||
return roxywi_common.handler_exceptions_for_json_data(RoxywiPermissionError(), 'You cannot change shared parameters')
|
||||
try:
|
||||
self._check_is_correct_group(cred_id)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, ''), 404
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, '')
|
||||
|
||||
try:
|
||||
ssh_mod.update_ssh_key(cred_id, body.name, body.password, body.key_enabled, body.username, group_id)
|
||||
ssh_mod.update_ssh_key(body, group_id, cred_id)
|
||||
return BaseResponse().model_dump(mode='json'), 201
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update SSH key')
|
||||
|
@ -192,7 +205,7 @@ class CredView(MethodView):
|
|||
try:
|
||||
self._check_is_correct_group(cred_id)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, ''), 404
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, '')
|
||||
|
||||
try:
|
||||
ssh_mod.delete_ssh_key(cred_id)
|
||||
|
@ -245,16 +258,19 @@ class CredView(MethodView):
|
|||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot upload SSH key')
|
||||
|
||||
@staticmethod
|
||||
def _check_is_correct_group(cred_id: int):
|
||||
def _check_is_correct_group(self, cred_id: int):
|
||||
if g.user_params['role'] == 1:
|
||||
return True
|
||||
ssh = self._get_ssh(cred_id)
|
||||
if int(ssh.group_id) != int(g.user_params['group_id']):
|
||||
raise RoxywiGroupMismatch
|
||||
|
||||
@staticmethod
|
||||
def _get_ssh(cred_id: int) -> Cred:
|
||||
try:
|
||||
ssh = cred_sql.get_ssh(cred_id)
|
||||
return cred_sql.get_ssh(cred_id)
|
||||
except RoxywiResourceNotFound:
|
||||
raise RoxywiResourceNotFound
|
||||
if ssh.group_id != g.user_params['group_id']:
|
||||
raise RoxywiGroupMismatch
|
||||
|
||||
|
||||
class CredsView(MethodView):
|
||||
|
@ -306,6 +322,9 @@ class CredsView(MethodView):
|
|||
private_key:
|
||||
type: 'string'
|
||||
description: 'SSH private key in base64 encoded format'
|
||||
shared:
|
||||
type: 'integer'
|
||||
description: 'Is shared credential for other groups or not'
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(query)
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue